首页 > 代码库 > 实现一个基于WCF的分布式缓存系统
实现一个基于WCF的分布式缓存系统
前言:
用到分布式的东西很多了,一直想做一个简单的分布式小项目练练手学习下。后来决定来一个简单的分布式缓存的系统。
在企业应用开发中缓存的用例不胜枚举,但是每次更多的是单机的部署与使用,没有对应的需求是一个原因,另一个原因总是好高骛远做过的总是不想再进行修正。
这次的分布式就从最简单的分布式缓存开始。说简单是因为没有实现分布式缓存高深的寻址,或者对备份处理的牛X实现。只是实现了“分布”这个目的,不足之处还请大家指导。
分布的实现方式有哪些?
既然做“分布”,当然要看看主流的“分布”实现方式。小弟简单的在网上搜罗了一下,常见的方式有两种(或者说是最简单的):
- 交由客户端分布;
- 交由服务端分布;
针对于第一种,最显而易见的是MM的实现,如:
string[] serverlist = { "10.0.0.131:11211", "10.0.0.132:11211" }; MemcachedClient mc = new MemcachedClient(); mc.Set("test", "my value");
这3行代码是我们再使用MM时候常用的,可以把值放在指定的集群上。
针对于第二种,交由服务端又可以分为两种实现:
- 主目标服务器维护着一个Cache集群,每当主Server接收到一个缓存请求时,则通知集群机器进行缓存。
- 第二种类似于上一条的实现,只不过是交由一个后台线程去做通知工作。
两种很类似,但是要想达到最优的效果应该需要一个强有力的算法去支撑了。
制定策略
既然分析了这两种实现的方式,个人更喜欢第二种中的第一种,起码在角色上更加的清晰。
虽然图画的有点惨,但是大致说明了问题,就是Client通知ServerHost缓存,ServerHost帮助分布式,当Client请求缓存值时,Serverhost则呼叫离Client最近的Host返回cache值。
但是考虑到万一ServerHost挂掉了,真个系统是不是就瘫痪了,于是修改方案:
也就没有了ServerHost每一个Host都起到了ServerHost的功效。
代码实现:
每个Host是一个控制台作为Wcf的host,当然最好的情况应该是使用WindowsServer:
class Program { static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(DistributedCache.Services.NetCacheService)); try { host.Open(); Console.WriteLine("NetCacheService Service Started"); Console.ReadKey(); } catch (Exception ex) { Console.WriteLine(ex.Message); if (ex.InnerException != null) { Console.WriteLine("\n" + ex.InnerException.Message); } } finally { host.Close(); } Console.ReadKey(); } }
在CacheService上提供的简单API:
[ServiceContract] public interface INetCacheService { [OperationContract] String AppendCache(String key, Object value); [OperationContract] String RemoveCache(String key); [OperationContract] String ClearCache(); [OperationContract] Object GetCache(String key); }
每一个Client对应着自己的Host:
static void Main(string[] args) { DistributedCacheService.INetCacheService service = new DistributedCacheService.NetCacheServiceClient(); string value = http://www.mamicode.com/"test string"; service.AppendCache("zhazha", value); System.Console.WriteLine("set ‘zhazha‘ value : [{0}] to {1} succeed!", value, "172.16.15.121"); System.Console.Read(); }
为了达到动态管理分布Server的目的:
首先两个IP的集群:
<appSettings> <add key="hostIP" value=http://www.mamicode.com/"172.16.15.121:9876,172.16.15.205:9876"/> </appSettings>
缓存集群的同步:
HttpRuntime.Cache.Insert(key, value, null, DateTime.UtcNow.AddMinutes(EXPIRETIME), TimeSpan.Zero); System.Console.WriteLine("{0} : localhost write cache succeed!", DateTime.Now.ToString()); string[] hostIP = ChannelFactory.GetHost(); object obj = null; CacheService02.INetCacheService service = null; for (int i = 0; i < hostIP.Length; i++) { service = ChannelFactory.CreateWCFServiceByURI<CacheService02.INetCacheService>(hostIP[i]); obj = service.GetCache(key); if (null == obj) { service.AppendCache(key, value); System.Console.WriteLine("{0} : {1} write cache succeed!", DateTime.Now.ToString(), hostIP[i]); } } System.Console.WriteLine("{0} : write cache succeed!", DateTime.Now.ToString()); return "Success";
测试结果:
我们验证了从121机器上请求缓存,然后121的Host挂掉了,仍旧可以通过集群中的205拿到对应的缓存值。
结语:
虽然整个一套实现的很简陋,但是基本达到了一个“分布”的效果,想了下如果需要优化的地方:
- 可以讲缓存操作的API更加丰富些;
- 通过跨平台的技术(如:node)实现Host跨平台;
- 客户端对于Host的使用应该更加的简洁;
- 等等;
File path: https://github.com/zhangcj/NetCache