memcached搭建缓存系统
一、概念
Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提升性能。
二、适用场合
1.分布式应用。由于memcached本身基于分布式的系统,所以尤其适合大型的分布式系统。
2.数据库前段缓存。数据库常常是网站系统的瓶颈。数据库的大并发量访问,常常造成网站内存溢出。当然我们也可以使用Hibernate的缓存机制。但memcached是基于分布式的,并可独立于网站应用本身,所以更适合大型网站进行应用的拆分。
3.服务器间数据共享。举例来讲,我们将网站的登录系统、查询系统拆分为两个应用,放在不同的服务器上,并进行集群,那这个时候用户登录后,登录信息如何从登录系统服务器同步到查询系统服务器呢?这时候,我们便可以使用memcached,登录系统将登录信息缓存起来,查询系统便可以获得登录信息,就像获取本地信息一样。
三、不适用场合
那些不需要“分布”的,不需要共享的,或者干脆规模小到只有一台服务器的应用,memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要资源
四、Memcached的工作机制
Memcached通过在内存中开辟一块区域来维持一个大的hash表来加快页面访问速度,虽然和数据库是独立的,但是目前主要用来缓存数据库的数据。允许多个server通过网络形成一个大的hash,用户不必关心数据存放在哪,只调用相关接口就可。存放在内存的数据通过LRU算法进行淘汰出内存。同时可以通过删除和设置失效时间来淘汰存放在内存的数据。
五、windows下的安装
这里介绍windows环境的安装。
1.下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached (下载地址:http://download.csdn.net/detail/huwei2003/9458650 )
2.在cmd下输入 'c:\memcached\memcached.exe -d install' 安装
3.再输入: 'c:\memcached\memcached.exe -d start' 启动。
以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。
以上可以通过一个批处理文件来一次性完成,如下
echo start install memcached
cd D:\dbtech\memcached\memcached-1.2.6-win32-bin\
D:\dbtech\memcached\memcached-1.2.6-win32-bin\memcached.exe -d install
echo start memcached service
D:\dbtech\memcached\memcached-1.2.6-win32-bin\memcached.exe -d start
echo end
pause
把这些放在一个txt里,把后缀改成bat,再运行(win7下要以管理员身份运行),即可完成安装和启动,打开服务,可看到"memcached Server"该服务已启动
在命令行 telnet ip 11211 进入后输入 stats 可以看到信息 如下:
stats
STAT pid 2756
STAT uptime 180
STAT time 1457677147
STAT version 1.4.13
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT curr_connections 15
STAT total_connections 16
STAT connection_structures 16
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 1
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 0
STAT delete_misses 1
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 144
STAT bytes_written 1060
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT bytes 89
STAT curr_items 0
STAT total_items 0
STAT evictions 0
STAT reclaimed 0
END
再用其它工具写入缓存可以看到
STAT curr_items 1
STAT total_items 1
有变化
六、客户端
Memcached本身是使用C开发的,客户端可以是php、C#、或者java。我是做java的,所以这里只介绍基于java的客户端。
我在网上看到基于java的客户端有两个
1.java_memcached-release_2.6.3
1)简介
这是比较通用的Memcached客户端框架。具体原创不详。
2)依赖的jar
A.commons-pool-1.5.6.jar
B.java_memcached-release_2.6.3.jar
C.slf4j-api-1.6.1.jar
D.slf4j-simple-1.6.1.jar
2.alisoft-xplatform-asf-cache-2.5.1
1)简介
这个东东是阿里软件的架构师岑文初进行封装的。里面的注释都是中文的,比较好。
2)依赖的jar
A.alisoft-xplatform-asf-cache-2.5.1.jar
B.commons-logging-1.0.4.jar
C.hessian-3.0.1.jar
D.log4j-1.2.9.jar
E.stax-api-1.0.1.jar
F.wstx-asl-2.0.2.jar
七 Memcached在.NET中的应用
一.Memcached服务器端的安装(此处将其作为系统服务安装)
下载文件:memcached 1.2.1 for Win32 binaries (Dec 23, 2006)
下载地址:http://jehiah.cz/projects/memcached-win32/files/memcached-1.2.1-win32.zip
1.解压缩文件到c:\memcached
2.命令行输入 c:\memcached\memcached.exe -d install'
3.命令行输入 c:\memcached\memcached.exe -d start ,该命令启动 Memcached ,默认监听端口为 11211
通过 memcached.exe -h 可以查看其帮助,查看memcache状态,telnet 192.168.0.98 11211。输入stats查询状态
stats
STAT pid 8601
STAT uptime 696
STAT time 1245832689
STAT version 1.2.0
STAT pointer_size 64
STAT rusage_user 0.007998
STAT rusage_system 0.030995
STAT curr_items 1
STAT total_items 1
STAT bytes 76
STAT curr_connections 2
STAT total_connections 4
STAT connection_structures 3
STAT cmd_get 1
STAT cmd_set 1
STAT get_hits 1//命中次数
STAT get_misses 0 //失效次数
STAT bytes_read 97
STAT bytes_written 620
STAT limit_maxbytes 134217728
END
-d选项是启动一个守护进程
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB
-u是运行Memcache的用户
-l是监听的服务器IP地址,如果有多个地址的话,我这里假定指定了服务器的IP地址为本机ip地址
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口
-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定
-P是设置保存Memcache的pid文件
二..NET memcached client library(memcached的.NET客户端类库)
下载memcached的.NET客户端类库,下载地址:https://sourceforge.net/projects/memcacheddotnet/里面有.net1.1 和 .net2.0的两种版本,里面还有.NET应用memcached的例子。
三.应用
1.新建ASP.NET站点,将Commons.dll,ICSharpCode.SharpZipLib.dll,log4net.dll,Memcached.ClientLibrary.dll添加到web引用。
2.为了进行后续的测试,我们创建两个aspx页面,memcache.aspx和nomemcache.aspx,memcache.aspx是使用MemcacheClient类加入了缓存机制的页面。nomemcache.aspx是没有加入缓存机制的页面,直接连接的数据库。一会我们通过观察数据库事件和进行压力测试来测试在压力测试的情况下应用程序的性能。
3.memcache.aspx.cs中添加对Memcached.ClientLibrary.dll的引用,即:using Memcached.ClientLibrary;Page_Load()中加入如下代码。
protected void Page_Load(object sender, EventArgs e)
{
string[] serverlist = new string[] { "127.0.0.1:11211" };
string poolName = "MemcacheIOPool";
SockIOPool pool = SockIOPool.GetInstance(poolName);
//设置连接池的初始容量,最小容量,最大容量,Socket 读取超时时间,Socket连接超时时间
pool.SetServers(serverlist);
pool.InitConnections = 1;
pool.MinConnections = 1;
pool.MaxConnections = 500;
pool.SocketConnectTimeout = 1000;
pool.SocketTimeout = 3000;
pool.MaintenanceSleep = 30;
pool.Failover = true;
pool.Nagle = false;
pool.Initialize();//容器初始化
//实例化一个客户端
MemcachedClient mc = new MemcachedClient();
mc.PoolName = poolName;
mc.EnableCompression = false;
string key = "user_info";//key值
object obj = new object();
if (mc.KeyExists(key)) //测试缓存中是否存在key的值
{
obj = mc.Get(key);
User user2 = (User)obj;
Response.Write("
" + user2.Name + "," + user2.Pwd + "
");
}
else {
string conStr = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(conStr);
conn.Open();
string sql = "Select * From T_User Where id=1";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader dr = cmd.ExecuteReader();
User user = new User();
while (dr.Read())
{
user.Name = dr["name"].ToString();
user.Pwd = dr["pwd"].ToString();
}
dr.Close();
conn.Close();
mc.Set(key, user, System.DateTime.Now.AddMinutes(2)); //存储数据到缓存服务器,这里将user这个对象缓存,key 是"user_info1"
Response.Write("
姓名:" + user.Name + ",密码:" + user.Pwd + "
");
}
}
4.nomemcache.aspx是没有加缓存机制的直接连接数据库的页面。nomemcache.aspx.cs中的代码:
protected void Page_Load(object sender, EventArgs e)
{
string conStr = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(conStr);
conn.Open();
string sql = "Select * From T_User Where id=2";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader dr = cmd.ExecuteReader();
User user = new User();
while (dr.Read())
{
user.Name = dr["name"].ToString();
user.Pwd = dr["pwd"].ToString();
}
dr.Close();
conn.Close();
Response.Write("
姓名:" + user.Name + ",密码:" + user.Pwd + "
");
}
}
5.测试
测试memcache.aspx页面,该测试的主要目的是访问memcache.aspx页面,看是否看该页面走的是memcached而非访问的数据库(第一次是访问数据库)。首先,我们运行memcache.aspx页面,通过Sql Server Profiler来查看运行memcache.aspx页面对数据库的操作情况。第一次运行memcache.aspx的时候,Sql Server Profiler里面显示memcache.aspx对数据库的操作,即执行了Select * From T_User Where id=1。
memcache.aspx页面上第一次运行的时候显示如下信息:
通过读取数据库得到的数据:
姓名:lucy,密码:lucy。
接着我们刷新memcache.aspx页面,页面上还显示上述信息:
通过读取缓存得到的数据:
姓名:lucy,密码:lucy
但从Sql Server Profiler观察,memcache.aspx页面没有对数据库进行任何操作。说明我们第二次访问该页面是读取的缓存,接着不停的刷新页面,都显示的是通过读取缓存得到的数据。直到到达缓存失效时间。
测试nomemcache.aspx,我们运行nomemcache.aspx页面,每刷新一次(包括第一次),Sql Server Profiler都记录了,nomemcache.aspx页面对数据库进行的操作,即之行了Select * From T_User Where id=2语句。说明每访问一次该页面,都要进行一次数据库的访问操作。
注意:memcached存储object时,如果是自定义的类,必须是可序列化的,即要有[Serializable] 这个属性,否则存储不了,取出来也是null
四.压力测试以及性能分析
这里我们使用Microsoft Web Application Stress Tool对web进行压力测试,Microsoft Web Application Stress Tool 是由微软的网站测试人员所开发,专门用来进行实际网站压力测试的一套工具。透过这套功能强大的压力测试工具,您可以使用少量的客户端计算机仿真大量用户上 线对网站服务所可能造成的影响,在网站实际上线之前先对您所设计的网站进行如同真实环境下的测试,以找出系统潜在的问题,对系统进行进一步的调整、设置工 作。就是因为这些特性,才使它具备了DOS轰炸的功能。
1、工具简单设置
打开Web Application Stress Tool,很简洁的一个页面,上面是工具栏,左下方是功能选项,右下方是详细设置选项。在对目标Web服务器进行压力测试之前,先对它进行一些必要的设置。
(1).在“settings”的功能设置中(如下图),一个是Stress level (threads)这里是指定程序在后台用多少线程进行请求,也就是相当于模拟多少个客户机的连接,更加形象的就是说设置多少轰炸的线程数。一般填写 500~1000,因为这个线程数是根据本机的承受力来设置的,如果你对自己的机器配置有足够信心的话,那么设置的越高,轰炸的效果越好。
(2).在“Test Run Time”中来指定一次压力测试需要持续的时间,分为天、小时、分、秒几个单位级别,你根据实际情况来设置吧!这里面设置测试时间为1分钟。
(3).其余的选项大家可以根据自己的情况设置。
2、压力测试
步骤1:在工具中点右键,选择Add命令,增加了一个新的测试项目:memcache,对它进行设置,在主选项中的server中填写要测试的服务器的IP地址,这里我们是在本机上进行测试,所以填写localhost。在下方选择测试的Web连接方式,这里的方式Verb选择 get,path选择要测试的Web页面路径,这里填写/WebMemCache/memcache.aspx,即加入缓存的memcache.aspx页面(如下图)。
步骤2:在“Settings”的功能设置中将Stress level (threads)线程数设置为500。完毕后,点工具中的灰色三角按钮即可进行测试(如下图)。
同理,我们在建一个nomemcach的项目用来测试nomemcache.aspx页面。Memcach和nomemcach测试完毕后,点击工具栏上的Reports按钮查看测试报告:
3.性能分析
Memcache.aspx的测试报告:
Overview
================================================================================
Report name: 2009-7-20 10:52:00
Run on: 2009-7-20 10:52:00
Run length: 00:01:12
Web Application Stress Tool Version:1.1.293.1
Number of test clients: 1
Number of hits: 2696
Requests per Second: 44.93
Socket Statistics
--------------------------------------------------------------------------------
Socket Connects: 3169
Total Bytes Sent (in KB): 646.80
Bytes Sent Rate (in KB/s): 10.78
Total Bytes Recv (in KB): 2019.37
Bytes Recv Rate (in KB/s): 33.65
Socket Errors
--------------------------------------------------------------------------------
Connect: 0
Send: 0
Recv: 0
Timeouts: 0
RDS Results
--------------------------------------------------------------------------------
Successful Queries: 0
Page Summary
Page Hits TTFB Avg TTLB Avg Auth Query
================================================================================
GET /WebMemCache/memcache.aspx 2696 1.94 1.95 No No
Nomemcache.aspx的测试报告:
Overview
================================================================================
Report name: 2009-7-20 10:54:01
Run on: 2009-7-20 10:54:01
Run length: 00:01:12
Web Application Stress Tool Version:1.1.293.1
Number of test clients: 1
Number of hits: 2577
Requests per Second: 42.95
Socket Statistics
--------------------------------------------------------------------------------
Socket Connects: 2860
Total Bytes Sent (in KB): 589.32
Bytes Sent Rate (in KB/s): 9.82
Total Bytes Recv (in KB): 1932.75
Bytes Recv Rate (in KB/s): 32.21
Socket Errors
--------------------------------------------------------------------------------
Connect: 0
Send: 0
Recv: 0
Timeouts: 0
RDS Results
--------------------------------------------------------------------------------
Successful Queries: 0
Page Summary
Page Hits TTFB Avg TTLB Avg Auth Query
================================================================================
GET /WebMemCache/nomemcache.aspx 2577 4.75 4.79 No No
从测试报告上看出memcache.aspx页面在一分钟内的Hits(命中次数)2696,平均TTFB是(Total Time to First Byte)1.94,平均TTLB(Total Time to Last Byte)是1.95。这些参数都低于nomemcache.aspx。另外memcache.aspx的Requests per Second(每秒请求的次数)是 44.93高于nomemcache.aspx页面的42.95.这些参数都说明memcache.aspx页面的执行性能要高于nomemcache.aspx页面。缓存起到了提高性能的作用。当然我这里面进行的测试只是模拟500个用户在1分钟内的访问对Web服务器性能的影响。
总结
本文简单介绍了Memcached的基本原理,特点以及工作方式,接下来介绍了Windows下Memcached服务器端程序的安装方法、在.NET应用程序中使用.NET memcached client library。接下来通过运行分析程序来了解memcached的工作原理机制,最后通过压力测试工具对没有加入Memcached机制的页面和加入Memcached页面进行了压力测试,对比加入Memcached机制前后Web应用程序的性能。了解Memcached内部构造, 就能知道如何在应用程序中使用memcached才能使Web应用的速度更上一层楼。提升web应用程序的性能和访问速度。
附:linux下memcached安装部署
下载安装
下载了,我到了其官方(http://memcached.org/),目前最新的下载版本是1.4.24
还要再安装libevent这个软件,从官方(http://monkey.org/~provos/libevent/)下载,目前最新的稳定版是2.0.22
下载后,将其上传到了/home/apps/下面
执行以下命令
cd /home/apps
tar zxvf memcached-1.4.24.tar.gz
tar zxvf libevent-2.0.22-stable.tar.gz
#安装libevent
cd /home/apps/libevent-2.0.22-stable./configure --prefix=/home/memcached/libevent-2.0.22-stable
make
make install
#安装memcache
cd /home/apps/memcached-1.4.24./configure --prefix=/home/memcached/memcached-1.4.24 --with-libevent=/home/memcached/libevent-2.0.22-stable
make
make install
可能存在的问题
1 启动memcache服务
进入bin目录,执行:./memcached -d -m 1024 -u blue,但是系统说有一个共享库没有加载,共享库的名称为:libevent-1.4.so.2
首先要查看一下memcached 这个命令用到的链接库地址在哪儿。执行如下命令可以查看:
LD_DEBUG=libs /usr/local/memcached/bin/memcached -v
显示出memcache从哪些地方找libevent-1.4.so.2这个文件,所以,我们只有将libevent-1.4.so.2这个文件指定到上面任意一个目录即可。这里我们将其指定到/lib64/下面。做一个软连接即可。命令如下:
ln -s /usr/local/lib/libevent-1.4.so.2 /usr/lib/libevent-1.4.so.2
在启动一下memcache服务:./memcached -d -m 1024 -u blue就可以了
本次安装没有出现上述的问题,安装玩启动即可成功
制作开机自启动
把下面的内容存入 /etc/init.d/memcachedvi /etc/init.d/memcached
==begin==
#!/bin/sh
#
# memcached: MemCached Daemon
#
# chkconfig: - 90 25
# description: MemCached Daemon
#
# Source function library.
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
#[ ${NETWORKING} = "no" ] && exit 0
#[ -r /etc/sysconfig/dund ] || exit 0
#. /etc/sysconfig/dund
#[ -z "$DUNDARGS" ] && exit 0
MEMCACHED="/home/memcache/memcached-1.4.24/bin/memcached"
SERVER_PORT="11211"
[ -f $MEMCACHED ] || exit 1
start()
{
echo -n $"Starting memcached: "
daemon $MEMCACHED -u root -d -m 2048 -p $SERVER_PORT -P /tmp/memcached.pid -vv >> /tmp/memcached.log 2>&1
echo
}
stop()
{
echo -n $"Shutting down memcached: "
killproc memcached
echo
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 3
start
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
==end==
chmod 777 /etc/init.d/memcached
chkconfig --add memcached #添加memcached到服务项
chkconfig --level 2345 memcached on #设置开机启动
/etc/init.d/memcached start 启动服务
检查服务:
1、查看启动的memcache服务:
netstat -lp | grep memcached
2、查看memcache的进程号(根据进程号,可以结束memcache服务:“kill -9 进程号”)
ps aux | grep memcached
查看日志
tail -200 /tmp/memcached.log
注:日志输出实在启动脚本里配置的
daemon $MEMCACHED -u root -d -m 2048 -p $SERVER_PORT -P /tmp/memcached.pid -vv >> /tmp/memcached.log 2>&1