分布式缓存Memcached
Memcached是LiveJournal(http://www.livejournal.com/)旗下的Danga Interactive(http://www.danga.com/)公司开发的一款高效的分布式内存缓存服务器,它是一个开源的项目,既支持Linux,Mac os等系统,还支持windows系统。
在Memcached项目官网上,http://memcached.org/,可以看到他现在的用户列表,Wikipedia(http://www.wikipedia.org/),Twitter(http://www.twitter.com/),Youtube(http://www.youtube.com/),Digg(http://www.digg.com/),WordPress.com(http://wordpress.com/)等等都是世界相当相当出名的互联网网站。
Libevent事件机制
Memcached基于libevent事件处理,用相关资料上描述,libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。
Memcached服务器,缓存数据都是以Key-value hash表的内存存储,最大key不超过250个字符,最大value项默认不超过1M,因此重启程序和服务器都会导致数据丢失,但它会消耗更低的CPU,因此可以用配置一般内存大点的服务器作为memcached服务器。在内容超过制定缓存大小后,会用LRU,最近最少使用算法删除不使用的数据,默认超时时间为30天。Memcached服务器之间互不通信,分布式算法在客户端,由客户端选择把数据存储到哪台memcached 服务器上,比如.net客户端,一般默认采用key的hashcode来模memcached服务器数量取余的值,作为选择当前key-value存储的服务器,当然系统足够庞大后,可以编写更加复杂和为具体项目做的算法。
下面我以windows下memcached 服务器和.net的memcached客户端为例,介绍下它的安装和使用。
我用的windows下memcached1.2.6版本,在http://code.jellycan.com/memcached/可以下载,.net客户端采用的https://sourceforge.net/projects/memcacheddotnet/下的开源客户端,当然也可以参考memcached服务器的协议接口,编写自定义的客户端。
下载好memcached服务器端后,解压到比如D:\memcached-1.2.6,在cmd命令控制台下,输入d:\memcached\memcached.exe -d install就安装好memcached的windows服务,然后输入d:\memcached\memcached.exe -d start则启动该服务,客户端就可以连接了,默认端口是11211,最大内存为64M,一般会修改,输入d:\memcached\memcached.exe -p 12345 -m 1024 -d start,其中-d install 安装为Windows服务, -m 使用的最大内存(MB),默认64M, 还有-l 绑定的IP,-c 最大并发连接数,默认1024,但一般不会起作用,需要修改注册表,在注册表找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server, 找到ImagePath项,把"d:\memcached\memcached.exe" -d runservice的后面加上-p 11111 -m 1024 -c 2048,重启后则把端口改为11111,最大内存为1024M。
现在根据.net客户端的接口,可以直接写个demo代码,代码如下:
2
3 {
4
5 //可以通过app.config配置
6
7 string[] serverlist = { "127.0.0.1:11211" };
8
9 //多个如下:
10
11 //string[] serverlist = { "127.0.0.1:11211,192.168.1.1:11211" };
12
13
14
15 SockIOPool pool = SockIOPool.GetInstance();
16
17 pool.SetServers(serverlist);
18
19
20
21 //pool.InitConnections = 3;
22
23 //pool.MinConnections = 3;
24
25 //pool.MaxConnections = 5;
26
27
28
29 //pool.SocketConnectTimeout = 1000;
30
31 //pool.SocketTimeout = 3000;
32
33
34
35 //pool.MaintenanceSleep = 30;
36
37 //pool.Failover = true;
38
39 //pool.Nagle = false;
40
41
42
43 pool.Initialize();
44
45
46
47 MemcachedClient mc = new MemcachedClient();
48
49 mc.EnableCompression = false;
50
51
52
53 //mc.FlushAll();
54
55
56
57 string input = "test of string";
58
59 mc.Set("foo", input);
60
61 string s = (string)mc.Get("foo");
62
63
64
65 mc.Add("foo", "foo2");
66
67
68
69 Datas d = new Datas();
70
71 d.a = 2;
72
73 d.b = "222222";
74
75
76
77 //d.c = new byte[1024*1024*2];
78
79
80
81 mc.Set("classV", d);
82
83
84
85 Datas d2 = (Datas)mc.Get("classV");
86
87
88
89 Console.ReadKey();
90
91 }
不同版本的客户端,接口不一样,但思想基本一样,SockIOPool设置服务器列表,代理里有部分注释,可以参考。MemcachedClient创建一个对象,就可以用了,它提供get,set,add,delete等方法,这里需要注意,如果同一个key已经有值了,再用add将不能修改,该方法会返回false,表示没有插入服务器,因此建议用set,像服务器添加值由于最大有默认1M限制,因此超过1M,也会插入不成功,返回false。
同样我们可以在服务器通过telnet 端口连接上去,直接输入命令查看和添加数据。如telenet 11211,stats命令查看基本配置,get key获取对应key的值等。同样插入对象必须支持序列化,否则将直接抛异常。
对Memcached简单介绍就到这里,欢迎感兴趣的同学多讨论。