Memcached简介
memcached是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但被许多网站使用。这是一套开放源代码软件,以BSD license授权发布。
memcached缺乏认证以及安全管制,这代表应该将memcached服务器放置在防火墙后。
memcached的API使用三十二比特的循环冗余校验(CRC-32)计算键值后,将数据分散在不同的机器上。当表格满了以后,接下来新增的数据会以LRU机制替换掉。由于memcached通常只是当作缓存系统使用,所以使用memcached的应用程序在写回较慢的系统时(像是后端的数据库)需要额外的代码更新memcached内的数据。
为什么选择Memcached
-
高并发访问数据库的痛点:死锁
-
磁盘IO之痛
-
多客户端共享缓存
-
Net+Memory>>IO
-
读写性能完美 1s:读取可以1w次
-
简单集群搭建Cluster
-
开源
-
没有提供主从赋值功能,也没有提供容灾等功能,所以所有的代码都只是考虑性能最佳(Redis)
-
学习成本非常低,入门非常容易
-
丰富的成功案例
Memcached基本原理
Socket 服务器端
数据:键值对存储
内存处理的算法
- 本质就是一个大的哈希表。key最大长度是255个字符。
- 内存模型:Memcache预先将可支配的内存空间进行分区(Slab),每个分区里再分成多个块(Chunk)大小1MB,但同一个分区里:块的长度(bytes)是固定的。
- 插入数据:查找适合自己长度的块,然后插入,会有内存浪费。
- LRU,闲置>过期 >最少访问
- 惰性删除:它并没有提供监控数据过期的机制,而是惰性的,当查询到某个key数据时,如果过期那么直接抛弃。
集群搭建原理
- Memcache服务器端并没有提供集群功能,但是通过客户端的驱动程序实现了集群配置。
客户端实现集群的原理
- 首先客户端配置多台集群机器的ip和端口的列表。然后客户端驱动程序在写入之前,首先对key做哈希处理得到哈希值后对总的机器的个数进行取余然后就选择余数对应的机器。
Windows下使用Memcached
- 下载Memcached:http://www.memcached.org.cn/
- 将服务程序拷贝到一个磁盘上的目录
- 安装服务:cmd→Memcached.exe -d install 打开服务监控窗口可以查看服务是否启动。
- 启动服务:cmd→Memcached.exe -d start(restart重启,stop关闭服务)
- 检查服务是否启动:连接到Memcache控制台:telnet ServerIP 11211 输入命令:stats检查当前服务状态。
- 卸载服务:Memcached.exe -d uninstall(先关闭服务)
Stats统计项
实战测试
1、下载安装Memcached服务端
下载完成后解压到桌面,如下截图
两种安装方式,a:双击memcached.exe安装。b:安装到Windows服务中。这里,我们推荐使用第二种安装方式。
确认下服务是否安装并启动
telnet链接到Memcached服务,并查看其stats统计项
- 以管理员身份启动命令控制行
- 输入 telnet 127.0.0.1 11211 (注意:这里写实际Memcached服务端IP地址,我这里是本机127.0.0.1)
- 输入stats并回车
2、测试Mamcached的读写操作(set和get方法)
创建一个控制台应用程序,添加应用,并编写如下代码
1 /// <summary> 2 /// 测试MemCahed 3 /// </summary> 4 /// <param name="args"></param> 5 static void Main(string[] args) 6 { 7 string[] serverlist = { "127.0.0.1:11211", "10.0.0.132:11211" }; 8 9 //初始化池 10 SockIOPool pool = SockIOPool.GetInstance(); 11 pool.SetServers(serverlist); 12 13 pool.InitConnections = 3; 14 pool.MinConnections = 3; 15 pool.MaxConnections = 5; 16 17 pool.SocketConnectTimeout = 1000; 18 pool.SocketTimeout = 3000; 19 20 pool.MaintenanceSleep = 30; 21 pool.Failover = true; 22 23 pool.Nagle = false; 24 pool.Initialize(); 25 26 // 获得客户端实例 27 MemcachedClient mc = new MemcachedClient(); 28 mc.EnableCompression = false; 29 30 Console.WriteLine("------------测 试-----------"); 31 mc.Set("test", "my value"); //存储数据到缓存服务器,这里将字符串"my value"缓存,key 是"test" 32 33 if (mc.KeyExists("test")) //测试缓存存在key为test的项目 34 { 35 Console.WriteLine("test is Exists"); 36 Console.WriteLine(mc.Get("test").ToString()); //在缓存中获取key为test的项目 37 } 38 else 39 { 40 Console.WriteLine("test not Exists"); 41 } 42 43 Console.ReadLine(); 44 45 mc.Delete("test"); //移除缓存中key为test的项目 46 47 if (mc.KeyExists("test")) 48 { 49 Console.WriteLine("test is Exists"); 50 Console.WriteLine(mc.Get("test").ToString()); 51 } 52 else 53 { 54 Console.WriteLine("test not Exists"); 55 } 56 Console.ReadLine(); 57 58 SockIOPool.GetInstance().Shutdown(); //关闭池, 关闭sockets 59 60 } 61
启动调试,显示结果如下。
3、封装MemcachedHelper类
1 public class MemcachedHelper 2 { 3 private static readonly MemcachedClient mc = null; 4 5 /// <summary> 6 /// 构造函数,默认连接127.0.0.1:11211 7 /// </summary> 8 static MemcacheHelper() 9 { 10 //最好放在配置文件中 11 string[] serverlist = { "127.0.0.1:11211", "10.0.0.132:11211" }; 12 13 //初始化池 14 SockIOPool pool = SockIOPool.GetInstance(); 15 pool.SetServers(serverlist); 16 17 pool.InitConnections = 3; 18 pool.MinConnections = 3; 19 pool.MaxConnections = 5; 20 21 pool.SocketConnectTimeout = 1000; 22 pool.SocketTimeout = 3000; 23 24 pool.MaintenanceSleep = 30; 25 pool.Failover = true; 26 27 pool.Nagle = false; 28 pool.Initialize(); 29 30 // 获得客户端实例 31 mc = new MemcachedClient(); 32 mc.EnableCompression = false; 33 } 34 35 /// <summary> 36 /// 存储数据 37 /// </summary> 38 /// <param name="key">键</param> 39 /// <param name="value">值</param> 40 /// <returns></returns> 41 public static bool Set(string key, object value) 42 { 43 return mc.Set(key, value); 44 } 45 46 /// <summary> 47 /// 存储数据并指定过期时间 48 /// </summary> 49 /// <param name="key">键</param> 50 /// <param name="value">值</param> 51 /// <param name="time">过期时间,注意默认最大30天</param> 52 /// <returns></returns> 53 public static bool Set(string key, object value, DateTime time) 54 { 55 return mc.Set(key, value, time); 56 } 57 58 /// <summary> 59 /// 根据键获取数据 60 /// </summary> 61 /// <param name="key">键</param> 62 /// <returns></returns> 63 public static object Get(string key) 64 { 65 return mc.Get(key); 66 } 67 68 /// <summary> 69 /// 根据键删除数据 70 /// </summary> 71 /// <param name="key">键</param> 72 /// <returns></returns> 73 public static bool Delete(string key) 74 { 75 if (mc.KeyExists(key)) 76 { 77 return mc.Delete(key); 78 79 } 80 return false; 81 } 82 83 }
至此已全部完成。
作者:Jeremy.Wu
出处:https://www.cnblogs.com/jeremywucnblog/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。