Memcached笔记

.NET内置内存缓存

  asp.net 中是有缓存的实现:HttpContext.Cache,缓存的数据是放到 Web 服务器的进程内存里。

  在控制台、WinForm、子线程、SignalR 等不支持 HttpContext 的地方还可以使用MemoryCache.Default(System.Runtime.Caching 这个程序集中),HttpContext.Cache 其实就是对 MemoryCache 的封装。

1 //写入:
2 MemoryCache.Default.Add("age", 666, DateTimeOffset.Now.AddMinutes(1));
3 //读取:
4 if(MemoryCache.Default.Contains("name"))
5 {
6 int age = (int)MemoryCache.Default["age"]; 
7 }
View Code

  进程内缓存最大的优点就是效率高。在可预期数据量不大的情况下推荐使用。

  如果数据量比较大或者集群服务器比较多,就要用单独的分布式缓存。

Memcached

  Memcached 是一个专门用来做缓存的服务器,而且缓存的数据都在内存中。

  Memcached就相当于一个 Dictionary 键值对集合,保存的是键值对,然后根据 key 取 value。

  当然 web 服务器和 Memcached 之间还是要网络间通讯,效率还是没有进程内缓存效率高。Memcached 程序重启之后数据就会消失

.Net 连接 memcached

  Install-Package EnyimMemcached

  Memcache 存入的是键值对。Memcache 存入数据的 3 中模式 Set、Replace、Add

  • Set:存在则覆盖、不存在则新增
  • Replace:如果存在则覆盖并返回true。如果不存在则不处里并返回false
  • Add:如果不存在则新增并返回true,如果存在则不处理并返回false
1 MemcachedClientConfiguration mcConfig = new MemcachedClientConfiguration();
2 mcConfig.AddServer("127.0.0.1:11211");//必须指定端口
3 using (MemcachedClient client = new MemcachedClient(mcConfig))
4 {
5 client.Store(Enyim.Caching.Memcached.StoreMode.Set, "name", "yzk");
6 }
View Code

  如果保存普通类对象,则对象必须可序列化

  设置过期时间:设置最后一个 TimeSpan 类型的参数

//如果之前对于同一个 Key 设置过一个过期时间,之后又设置过一个,以最后一次的为准
client.Store(Enyim.Caching.Memcached.StoreMode.Set, "name", "yzk",TimeSpan.FromSeconds(5));

  读取:client.Get("name"),如果找不到,则返回 null。当然也可以用

   public bool TryGet(string key, out object value)。当然还支持泛型的 public T Get<T>(string key)。

  Remove(string key)则是删除一个 key 对应的内容。

    与 Store、Get、Remove 配套的还有 ExecuteXXX 方法,唯一区别就是返回值信息更详细。

  Key 的选择:Memcaced 就相当于一个大键值对,不同系统放到 Memcached 中的数据都是不隔离的,因此设定 Key 的时候要选择好 Key,这样就不容易冲突。

    建议规则“系统名字_模块名字_业务 Key”,比如“Shop_Admin_FilterWords”

Cas 操作

  用来解决并发问题:读出一个值,做一些判断或者处理,再写回,有可能有并发的问题

  Cas 是 Memcached 1.2.5 之后引入的特性,类似于数据库的“乐观锁”,查询的时候查出一个 cas值,在写入的时候带着这个 cas 值,如果发现 cas 值已经变了,则说明已经有别人改过了

Memcached集群

  memcached 重启之后短时间内大量的请求会涌入数据库,给数据库造成压力,解决这个的方法就是使用集群,有多台 Memcached 服务器提供服务。

  当 memcached 服务器压力大了之后也有必要搞 memcached 集群来分担压力。

  Memcached 服务器的“雪崩”问题:如果所有缓存设置过期时间一样,那么每隔一段时间就会造成一次数据库访问的高峰

    解决的方法就是缓存时间设置不一样,比如加上一个随机数。

  Memcached 的集群实现很简单,集群节点直接不进行通讯、同步,只要在多个服务器上启动多个 Memcached 服务器即可,客户端决定把数据写入不同的实例,不搞主从复制,每个数据库实例保存一部分内容。

  然后 mcConfig.AddServer("127.0.0.1:11211");添加多个服务器 ip 地址,然后客户端根据自己的算法决定把数据写入哪个 Memcached 实例,取数据库的时候再根据同样的定位算法去哪台服务器上去取。

  节点定位算法有很多种,最常用的有两种 Ketama、VBucket。Ketama 是根据 Key 算出一个 hash 值,根据 hash 值再算到服务器;

  而 VBucket 也是根据 key 算出 hash 值,但是不是直接根据 hash 值算出服务地址,而是维护一个 VBucket 表,在表中指定不同的 hash 值由不同的服务器处理,还可以临时改变指向。

  建议用 Ketama 就可以了。节点定位算法会自动处理故障服务器。mcConfig.NodeLocatorFactory = new KetamaNodeLocatorFactory()。缓存要求都不高。

 

posted @ 2017-11-07 16:50  大胖儿在努力  阅读(162)  评论(0)    收藏  举报