memcache是一套开放源的分布式高速缓存系统。由服务端和客户端组成,以守护程序(监听)方式运行于一个或多个服务器中,随时会接收客户端的链接和操做。memcache主要把数据对象缓存到内存中,经过在内存里维护一个统一的巨大的hash表。简单的说就是将数据调用到内存中,而后从内存中读取,从而大大提升读取速度。memcache基于一个存储键/值对的hashmap进行存储对象到内存中。memcache是用C写的,可是客户端能够用任何语言来编写,并经过memcached协议与守护进程通讯。html
特性: node
了解memcache一些基本信息后,在来尝试在windows下安装memcache服务端。算法
步骤:windows
1.窗口+R:输入cmd
2.进行G盘: 输入 G:
3.进行Memcached for window 32/64的安装目录:输入 cd CK\memcached_en32or64\x64
4.安装memcached:输入 memcached -d install
5.启动服务:输入 memcached -d start缓存
启动服务后在Windows进程中能够看到memcached.exe.服务器
memcached -d start|stop|shutdown|restart|uninstall|install 启动|中止|关闭|重启|卸载|安装。分布式
安装步骤不是很复杂。第一:找到文件(memcached.exe)路径。第二: memcached -d install 就OK..ide
基本默认参数说明:memcached
-p 监听的端口
-l 链接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时链接数,默认是1024
-f 块大小增加因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助函数
服务器操做完成后,咱们能够在本机telnet 到服务测试一个下。(若是提示telnet命令不存在,须要去控件面板开启windows的tel服务功能, win7的开启tel功能操做步骤是:【控制面板】->【程序和功能】->【打开或关闭window功能】,而后找到并勾选tel相关便可。其余window系统步骤相似。)
测试telnet是否正常运行 telnet 172.21.0.192 11211
进入后先按ctrl+]启动回示功能,不然没法看到输入信息。回示功能启动成功后以下图:
而后按回车输入参数stats:
安装和测试工做已完成..
有不少C#版本的Memcached客户端程序。在这里咱们使用的是Memcached.ClientLibrary.dll客户端调用方法,调用须要二个DLL:
Memcached.ClientLibrary.dll (Memcached客户端类库)
log4net.dll (log4net是为Memcached提供日志记录) DLL下载地址:【点击下载】
在项目中引用这个二个dll,引用log4net.dll后还需进行一系列配置工做。在上篇博客中有对log4net的配置介绍。
注意:Memcached.ClientLibrary.dll和log4net.dll有版本对应关系。
2.若是使用WinForm或控制台应用程序把log4net的配置文件独立出现,和写在App.config里面须要小小设置一下。
如图:Log4Net.config属性“复制到输出目录”:“始终复制”。否则在bin目录下找不到对应配置信息会产生报错。
memcache基于一个存储键/值对的hashmap进行存储对象到内存中。因此咱们能够理解为主要在操做hashmap的键值对。
如下是一些简单操做[增,删,改,查,设置过时时间]:
//参数设置 string SockIOPoolName = "Test_SockIOPoolName"; string[] MemcacheServiceList = { "172.21.0.192:11211" }; //设置链接池 SockIOPool SPool = SockIOPool.GetInstance(SockIOPoolName); SPool.SetServers(MemcacheServiceList); SPool.Initialize(); //实例化Client MemcachedClient MClient = new MemcachedClient(); MClient.PoolName = SockIOPoolName; Console.WriteLine("1.建立memcache缓存Hello World"); MClient.Add("Key1001", "Hello World"); Console.WriteLine("2.查询缓存信息{0}", MClient.Get("Key1001")); Console.WriteLine("3.修改memcache缓存Hello World"); MClient.Set("Key1001", "Hello World - 修改版"); Console.WriteLine("4.查询缓存信息{0}", MClient.Get("Key1001")); if (MClient.KeyExists("Key1001")) { Console.WriteLine("5.删除memcache缓存"); MClient.Delete("Key1001"); } if (MClient.KeyExists("Key1001")) Console.WriteLine(MClient.Get("Key1001")); else Console.WriteLine("6.删除已删除"); Student stud = new Student() { id = "10001", name = "张三" }; MClient.Add("student", stud); Student Get_stud = MClient.Get("student") as Student; Console.WriteLine("6.缓存实体对象:{0} {1}", Get_stud.id, Get_stud.name); MClient.Add("Key1002", "我已设置过时时间1分钟", DateTime.Now.AddMinutes(1)); while (true) { if (MClient.KeyExists("Key1002")) { Console.WriteLine("key:Key1002 Value:{0},当前时间:{1}", MClient.Get("Key1002"), DateTime.Now); Thread.Sleep(20000); } else { Console.WriteLine("key:Key1002 我已过时,当前时间:{0}", DateTime.Now); break; } }
输出结果:
Memcached缓存过时机制:
好比键key1002在2015-04-09 13:54 :18 我设置他的值为:”我已设置过时时间1分钟“。他的过时时间为1分钟。等到2015-04-09 13:55 :18时数据应该过时,但在内存中仍是会保存这条数据,而是等客户端来请求这条数据时判断数据是否过时。过时就直接删除返回空。若是内存满了memcached会把最长时间未使用到期的缓存记录给删除,腾出空间继续使用。
下面假设memcached服务器有node1~node3三台,应用程序要保存键名为“tokyo”、“kanagawa”、“chiba”、“saitama”、“gunma”的数据。
首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的memcached服务器。服务器选定后,即命令它保存“tokyo”及其值。
一样,“kanagawa”、“chiba”、“saitama”、“gunma”都是先选择服务器再保存。接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库经过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,而后发送get命令。只要数据没有由于某些缘由被删除,就能得到保存的值。
这样,将不一样的键保存到不一样的服务器上,就实现了memcached的分布式。memcached服务器增多后,键就会分散,即便一台memcached服务器发生故障没法链接,也不会影响其余的缓存,系统依然能继续运行。 (参考:memcached全面剖析)
//参数 string[] MemcacheServiceList = { "172.21.0.192:11211", "172.21.0.28:11211", "172.21.13.246:11211" }; //设置链接池 SockIOPool SPool = SockIOPool.GetInstance(); SPool.SetServers(MemcacheServiceList); SPool.Initialize(); MemcachedClient MClient = new MemcachedClient(); MClient.FlushAll(); int count = 5; var time = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { MClient.Add(i.ToString(), "value" + i); } Console.WriteLine("memcached缓存建立成功。耗时:{0}",time.ElapsedTicks); time = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { if (MClient.KeyExists(i.ToString())) { Console.WriteLine("key:{0}.value:{1}", i, MClient.Get(i.ToString())); } else { Console.WriteLine("--------未能查询到数据key:{0}--------",i); } } Console.WriteLine("memcached缓存数据查询完成。耗时:{0}", time.ElapsedTicks); SPool.Shutdown();