标签:
一、Memcached是什么?
Memcached是一个高性能的分布式内存对象缓存系统,可以在内存中缓存数据和对象来减少读取数据库的次数,从而提醒性能。Memcached基于一个K/V对的hashmap。
二、Memcached的特征
1. 协议简单:基于文本协议和二进制协议进行通信
2. 基于libevent的事件处理
3. 内置内存存储方式
数据存储在内存中,重启服务或系统后数据会全部消失
当内存容量达到指定值后,基于LRU(Least Recently Used)算法自动删除不适用的缓存。
4. memcached不互相通信的分布式
服务端没有分布式供能,取决于客户端的实现。
三、Memcached安装
安装命令:
sc create "Memcached Server1" start= auto binPath= "?D:\Tools\memcached\memcached.exe -d runservice -m 32 -p 11220 -l 127.0.0.1" DisplayName= "Memcached Server1"
PS:修改下服务名字及端口号,就可以在一台电脑上配置多个服务了。
启动命令:
sc start "Memcached Server1"
卸载命令:
sc delete "Memcached Server1"
参数详解:
-d选项是启动一个守护进程,
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB,
-u是运行Memcache的用户,我这里是root,
-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.0.200,
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口,
-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定,
-P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid,
四、Memcached内存存储机制:Slab Allocation
Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块, 以完全解决内存碎片问题。
Slab术语:
Page: 分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。
Chunk: 用于缓存记录的内存空间
Slab Class: 特定大小的chunk的组。
memcached根据收到的数据的大小,选择最适合数据大小的slab(图2)。 memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk, 然后将数据缓存于其中
接下来,我们看一下具体的例子应用,看看chunk是怎么分配的?
var str = "我是中国人"; for (var i = 0; i < 100; i++) { var temp = str; for (int j = 0; j < i; j++) { temp += str; } client.Store(StoreMode.Set, "k" + i, temp); } Console.WriteLine("chunk_size\tchunks_per_page\tchunk_key_num"); foreach (var item in GetSlabsItemList()) { Console.WriteLine("{0}\t\t{1}\t\t{2}",item.chunk_size, item.chunks_per_page, item.items_number); } Console.ReadKey();生成了100个K/V对,每一对数据量都会递增,我们看看结果怎么样,如图:
chunk_size表示chunk块的大小,也可以看出目前所有的chunk块的总数。
chunk_key_num表示当前chunk包含了多少个key。
结合上图应该更好理解了。
五、实战Memcached
本次实战使用Enyim作为客户端,具体配置如下。
app.config: <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="enyim.com"> <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" /> </sectionGroup> </configSections> <enyim.com> <memcached protocol="Binary"> <servers> <add address="127.0.0.1" port="11220" /> <add address="127.0.0.1" port="11221" /> <add address="127.0.0.1" port="11222" /> </servers> </memcached> </enyim.com> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> </configuration> 实现代码: class Program { private static MemcachedClient client = new MemcachedClient("enyim.com/memcached"); static void Main(string[] args) { var max = 10000; for (var i = 0; i < max; i++) { client.Store(StoreMode.Set, "k" + i, "v" + i); } for (var i = 0; i < max; i++) { Console.WriteLine(client.Get("k" + i)); } ServerStats ss = client.Stats(); foreach (var endpoint in ss.GetRaw("All")) { Console.WriteLine("endpoint: {0}", endpoint.Key); IPEndPoint ipendpoint = new IPEndPoint(endpoint.Key.Address, endpoint.Key.Port); Console.WriteLine("\t\tStatItem.ItemCount:{0}", ss.GetRaw(ipendpoint, StatItem.ItemCount)); Console.WriteLine("\t\tStatItem.UsedBytes:{0}", ss.GetRaw(ipendpoint, StatItem.UsedBytes)); Console.WriteLine("\t\tStatItem.MaxBytes:{0}", ss.GetRaw(ipendpoint, StatItem.MaxBytes)); } Console.ReadKey(); } }
从代码中,可以看出,我采用了多个服务的方式,然后我插入了10000个K/V对,Enyim客户端会根据算法将数据划分到不同的memcached服务中,结果如下。
分布式算法参考:http://xiexiejiao.cn/java/memcached-consistent-hashing.html
参考资料:
http://kb.cnblogs.com/page/42731/
http://kb.cnblogs.com/page/42732/
http://kb.cnblogs.com/page/42733/
http://kb.cnblogs.com/page/42734/
http://xiexiejiao.cn/java/memcached-consistent-hashing.html
标签:
原文地址:http://www.cnblogs.com/loveyx/p/5326310.html