您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 资本运营 > Discuz!NT中集成Memcached分布式缓存
Discuz!NT中集成Memcached分布式缓存大约在两年前我写过一篇关于Discuz!NT缓存架构的文章,在那篇文章的结尾介绍了在IIS中如果开启多个应用程序池会造成多个缓存实例之间数据同步的问题。虽然给出了一个解决方案,但无形中却把压力转移到了磁盘I/O上(多个进程并发访问cache.config文件)。其实从那时起我就开始关注有什么更好的方案,当然今天本文中所说的Memcached,以及Velocity等这类的分布式缓存方案之前都考虑过,但一直未能决定该使用那个。起码Velocity要在.net4.0之后才会提供,虽然是原生态,但有些远水解不了近火。我想真正等到Velocity能堪当重任还要等上一段时间。于是我就开始将注意力转移到了Memcached,必定有Facebook这只“超级小白鼠”使用它并且反响还不错。所以就开始尝试动手在产品中集成Memcached。其实在之前的那篇关于Discuz!NT缓存架构的文章中已提到过,使用了设计模式中的“策略模式”来构造。所以为了与以往使用缓存的代码格式相兼容,所以这里采用新添加MemCachedStrategy(MemCached策略)来构造一个缓存策略类以便于当管理后台开启“MemCached”时以“MemCached策略模式”来做为当前系统默认的策略模式。其代码段如下(Discuz.Cache/MemCached.cs):///summary///MemCache缓存策略类////summarypublicclassMemCachedStrategy:Discuz.Cache.ICacheStrategy{///summary///添加指定ID的对象////summary///paramname=objId/param///paramname=o/parampublicvoidAddObject(stringobjId,objecto){RemoveObject(objId);if(TimeOut0){MemCachedManager.CacheClient.Set(objId,o,System.DateTime.Now.AddMinutes(TimeOut));}else{MemCachedManager.CacheClient.Set(objId,o);}}///summary///添加指定ID的对象(关联指定文件组)////summary///paramname=objId/param///paramname=o/param///paramname=files/parampublicvoidAddObjectWithFileChange(stringobjId,objecto,string[]files){;}///summary///添加指定ID的对象(关联指定键值组)////summary///paramname=objId/param///paramname=o/param///paramname=dependKey/parampublicvoidAddObjectWithDepend(stringobjId,objecto,string[]dependKey){;}///summary///移除指定ID的对象////summary///paramname=objId/parampublicvoidRemoveObject(stringobjId){if(MemCachedManager.CacheClient.KeyExists(objId))MemCachedManager.CacheClient.Delete(objId);}///summary///返回指定ID的对象////summary///paramname=objId/param///returns/returnspublicobjectRetrieveObject(stringobjId){returnMemCachedManager.CacheClient.Get(objId);}///summary///到期时间////summarypublicintTimeOut{set;get;}}上面类实现的接口Discuz.Cache.ICacheStrategy定义如下:///summary///公共缓存策略接口////summarypublicinterfaceICacheStrategy{///summary///添加指定ID的对象////summary///paramname=objId/param///paramname=o/paramvoidAddObject(stringobjId,objecto);///summary///添加指定ID的对象(关联指定文件组)////summary///paramname=objId/param///paramname=o/param///paramname=files/paramvoidAddObjectWithFileChange(stringobjId,objecto,string[]files);///summary///添加指定ID的对象(关联指定键值组)////summary///paramname=objId/param///paramname=o/param///paramname=dependKey/paramvoidAddObjectWithDepend(stringobjId,objecto,string[]dependKey);///summary///移除指定ID的对象////summary///paramname=objId/paramvoidRemoveObject(stringobjId);///summary///返回指定ID的对象////summary///paramname=objId/param///returns/returnsobjectRetrieveObject(stringobjId);///summary///到期时间////summaryintTimeOut{set;get;}}当然在MemCachedStrategy类中还有一个对象要加以说明,就是MemCachedManager,该类主要是对Memcached一些常操作和相关初始化实例调用的“封装”,下面是是其变量定义和初始化构造方法的代码:///summary///MemCache管理操作类////summarypublicsealedclassMemCachedManager{#region静态方法和属性privatestaticMemcachedClientmc=null;privatestaticSockIOPoolpool=null;privatestaticMemCachedConfigInfomemCachedConfigInfo=MemCachedConfigs.GetConfig();privatestaticstring[]serverList=null;staticMemCachedManager(){CreateManager();}privatestaticvoidCreateManager(){serverList=Utils.SplitString(memCachedConfigInfo.ServerList,rn);pool=SockIOPool.GetInstance(memCachedConfigInfo.PoolName);pool.SetServers(serverList);pool.InitConnections=memCachedConfigInfo.IntConnections;//初始化链接数pool.MinConnections=memCachedConfigInfo.MinConnections;//最少链接数pool.MaxConnections=memCachedConfigInfo.MaxConnections;//最大连接数pool.SocketConnectTimeout=memCachedConfigInfo.SocketConnectTimeout;//Socket链接超时时间pool.SocketTimeout=memCachedConfigInfo.SocketTimeout;//Socket超时时间pool.MaintenanceSleep=memCachedConfigInfo.MaintenanceSleep;//维护线程休息时间pool.Failover=memCachedConfigInfo.FailOver;//失效转移(一种备份操作模式)pool.Nagle=memCachedConfigInfo.Nagle;//是否用nagle算法启动socketpool.HashingAlgorithm=HashingAlgorithm.NewCompatibleHash;pool.Initialize();mc=newMemcachedClient();mc.PoolName=memCachedConfigInfo.PoolName;mc.EnableCompression=false;}///summary///缓存服务器地址列表////summarypublicstaticstring[]ServerList{set{if(value!=null)serverList=value;}get{returnserverList;}}///summary///客户端缓存操作对象////summarypublicstaticMemcachedClientCacheClient{get{if(mc==null)CreateManager();returnmc;}}publicstaticvoidDispose(){if(pool!=null)pool.Shutdown();}上面代码中构造方法会初始化一个池来管理执行Socket链接,并提供静态属性CacheClient以便MemCachedStrategy来调用。当然我还在这个管理操作类中添加了几个方法分别用于检测当前有效的分布式缓存服务器的列表,向指定(或全部)缓存服务器发送特定stats命令来获取当前缓存服务器上的数据信息和内存分配信息等,相应的方法如下(详情见注释):///summary///获取当前缓存键值所存储在的服务器////summary///paramname=key当前缓存键/param///returns当前缓存键值所存储在的服务器/returnspublicstaticstringGetSocketHost(stringkey){stringhostName=;SockIOsock=null;try{sock=SockIOPool.GetInstance(memCachedConfigInfo.PoolName).GetSock(key);if(sock!=null){hostName=sock.Host;}}finally{if(sock!=null)sock.Close();}returnhostName;}///summary///获取有效的服务器地址////summary///returns有效的服务器地/returnspublicstaticstring[]GetConnectedSocketHost(){SockIOsock=null;stringconnectedHost=null;foreach(stringhostNa
本文标题:Discuz!NT中集成Memcached分布式缓存
链接地址:https://www.777doc.com/doc-5038034 .html