zoukankan      html  css  js  c++  java
  • 缓存应用Memcached分布式缓存简介(二)

    1 命令行查看状态

      很多时候我们需要去查看Memcached 的使用状态,比如Memcached 的运行时间,使用状态等等。在Windows系统中我们可以使用telnet 命令来查看Memcached 的相关运行情况。

      开始—>运行àcmd 运行得到如下:

     

    输入telnet命令: telnet 服务地址 端口 

     

    Memcached 的默认端口号是11211
          输入stats 命令: 在这里屏幕是空白,看不到输入的内容,回车之后可以看到Memcached的运行相关信息。 

     

    Pid: Memcached 服务器中的进程编号

       UptimeMemcached服务器启动之后所经历的时间,单位秒

       Time 当前系统时间,单位秒

      Version: Memcached 的版本号

      pointer_size:服务器所在主机操作系统的指针大小,一般为3264

      curr_items:表示当前缓存中存放的所有缓存对象的数量

      total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括已经删除的对象

      bytes:表示系统存储缓存对象所使用的存储空间,单位为字节

      curr_connections:表示当前系统打开的连接数

      total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数

      cmd_get 查询缓存的次数,即使不成功也算一次

      cmd_set 保存数据的次数,当然这里只保存成功的次数

      get_hits:表示获取数据成功的次数。

      get_misses:表示获取数据失败的次数。

      evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象

      bytes_readmemcached服务器从网络读取的总的字节数

      bytes_writtenmemcached服务器发送到网络的总的字节数

      limit_maxbytesmemcached服务缓存允许使用的最大字节数

      threads:被请求的工作线程的总数量

     

         缓存命中率 = get_hits / cmd_get * 100% ; 

    2 Memcached 存储机制

           关于Memcached的存储机制,在网上搜了一下讲解基本上都是千篇一律的。

    memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在之前的版本中,Memcached存储会导致很多内存碎片,从而加重了操作系统对内存管理的负担。Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块, 以完全解决内存碎片问题。

     借用一张图说明一下: 

         

    Slab Allocation 将分配的内存分割成各种尺寸的chunk (),并把大小相同尺寸的chunk分为一组,就如上图一样:分割了 88b,112b,144b等尺寸。其实Slab Allocation还有重复利用内存的功能,也就是说分配的内存不会释放,而是重复利用。

    当存储数据的时候,它会自动去查找最为匹配的chunk,然后将数据存储到其中。比如我存储数据的大小为110B,那么它会存储到112Bchunk中。

         上面的问题来了,我存储只需要110B,但是我存储到112Bchunk中。如下图(借用) 

     

        那么在110b的存储中会浪费2B的内存空间
    至于如何完全解决这个内存空间浪费的问题,还没有很好的方案,不过Memcached 增长因子(Growth Factor)能够适当解决此问题。目前Memcached的默认增长因子      是1.25,也就是说会以原有的最大值基础上乘以1.25 来分配空间。 

    3 Memcached 对内存资源的有效利用

    之前已经提到过了,Memcached 会重复利用已经分配的内存,也就是说不会去删除已有的数据而且释放内存空间,而是数据过期之后,用户将数据不可见。

             Memcached 还是用了一种Lazy Expiration (延迟过期[姑且这样翻译]) 技术,就是Memcached不会去监视服务器上的数据是否过期,而是等待get的时候检查时间戳是否过期,减少Memcached在监控数据上所用到的时间。

              Memcached 不会去释放已经使用的内存空间,但是如果分配的内存空间已经满了,而Memcached 是如何去保证内存空间的重复使用呢!Memcached 是用了 Least Recently UsedLRU 机制来协调内存空间的使用。LRU 意思就是最少最近使用,当此处内存空间数据最长时间没有使用,而且使用次数很少,在存储新的数据的同时就会覆盖此处空间。 

    4 Memcached 客户端使用简单封装

    本文很多都是理论上的分析,这些大多也是从网络上看来的,根据自己的理解和实际的应用做了一些总结。有时候我们使用Memcached的客户端时并不是那么的友好,这里对其做了一下简单的封装,抽象出来了一个接口:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Collections;
     6 
     7 namespace MemcachedTest
     8 {
     9     public interface ICache
    10     {
    11         bool ContainKey(string argKey);
    12 
    13         bool Add(string argKey,object argValue);
    14 
    15         bool Add(string argKey, object argValue, DateTime argDateExpiration);
    16 
    17         bool Add<T>(string argKey, T entity) where T : class;
    18 
    19         bool Add<T>(string argKey, T entity, DateTime argDateExpiration) where T : class;
    20 
    21         bool Set(string argKey, object argValue);
    22 
    23         bool Set(string argKey, object argValue, DateTime argDateExpiration);
    24 
    25         bool Set<T>(string argKey, T entity) where T : class;
    26 
    27         bool Set<T>(string argKey, T entity, DateTime argDateExpiration) where T : class;
    28 
    29         bool Replace(string argKey,object argValue);
    30 
    31         bool Replace(string argKey,object argValue,DateTime argDateExpiration);
    32 
    33         bool Replace<T>(string argKey, T entity) where T : class;
    34 
    35         bool Replace<T>(string argKey, T entity, DateTime argDateExpiration) where T : class;
    36 
    37         object Get(string argKey);
    38 
    39         T Get<T>(string argKey);
    40 
    41         bool Remove(string argKey);
    42 
    43         bool Remove(string argKey, DateTime argDateExpiration);
    44 
    45         bool Remove();
    46 
    47         bool Remove(ArrayList servers);
    48 
    49     }

    50 } 

    下面这段代码对上面的接口进行了实现,里面的代码大多数人应该能够看懂,是比较简单的代码封装,如果能够了解本人上一篇的简单应用,对于这个封装的理解应该没有难度。实现代码如下:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using Memcached.ClientLibrary;
      6 using System.Collections;
      7 
      8 namespace MemcachedTest
      9 {
     10     public class Memcache:ICache
     11     {
     12         private MemcachedClient client;
     13         private static Memcache memcache;
     14 
     15         /// <summary>
     16         /// 构造方法
     17         /// </summary>
     18         protected Memcache()
     19         {
     20             SockIOPool pool = SockIOPool.GetInstance();
     21             string[] servers = { "127.0.0.1:11211" };
     22             pool.SetServers(servers);
     23             pool.MinConnections = 3;
     24             pool.MaxConnections = 5;
     25             pool.InitConnections = 3;
     26             pool.SocketConnectTimeout = 5000;
     27             pool.Initialize();
     28             this.client = new MemcachedClient();
     29             client.EnableCompression = false;
     30         }
     31 
     32         public static Memcache Instance()
     33         {
     34             if (memcache == null)
     35             {
     36                 memcache = new Memcache();
     37             }
     38             return memcache;
     39         }
     40 
     41 
     42         /// <summary>
     43         /// 判断是否包含某个键
     44         /// </summary>
     45         /// <param name="argKey">键值</param>
     46         /// <returns></returns>
     47         public bool ContainKey(string argKey)
     48         {
     49             return client.KeyExists(argKey);
     50         }
     51 
     52         /// <summary>
     53         /// 添加缓存数据
     54         /// </summary>
     55         /// <param name="argKey">键值</param>
     56         /// <param name="argValue">存储值</param>
     57         /// <returns></returns>
     58         public bool Add(string argKey, object argValue)
     59         {
     60             return client.Add(argKey,argValue);
     61         }
     62 
     63         /// <summary>
     64         /// 添加缓存数据
     65         /// </summary>
     66         /// <param name="argKey">键值</param>
     67         /// <param name="argValue">存储值</param>
     68         /// <param name="argDateExpiration">过期时间</param>
     69         /// <returns></returns>
     70         public bool Add(string argKey, object argValue, DateTime argDateExpiration)
     71         {
     72             return client.Add(argKey, argValue, argDateExpiration);
     73         }
     74 
     75         /// <summary>
     76         /// 添加缓存数据
     77         /// </summary>
     78         /// <typeparam name="T">存储对象类型</typeparam>
     79         /// <param name="argKey">键值</param>
     80         /// <param name="entity">存储值</param>
     81         /// <returns></returns>
     82         public bool Add<T>(string argKey, T entity) where T : class
     83         {
     84             return client.Add(argKey, entity);
     85         }
     86 
     87         /// <summary>
     88         /// 添加缓存数据
     89         /// </summary>
     90         /// <typeparam name="T">存储对象类型</typeparam>
     91         /// <param name="argKey">键值</param>
     92         /// <param name="entity">存储值</param>
     93         /// <param name="argDateExpiration">过期时间</param>
     94         /// <returns></returns>
     95         public bool Add<T>(string argKey, T entity, DateTime argDateExpiration) where T : class
     96         {
     97             return client.Add(argKey, entity, argDateExpiration);
     98         }
     99 
    100         /// <summary>
    101         /// 添加缓存数据,如果存在则替换原有数据
    102         /// </summary>
    103         /// <param name="argKey">键值</param>
    104         /// <param name="argValue">存储值</param>
    105         /// <returns></returns>
    106         public bool Set(string argKey, object argValue)
    107         {
    108             if (ContainKey(argKey))
    109             {
    110                 return false;
    111             }
    112             return client.Set(argKey, argValue);
    113         }
    114 
    115         /// <summary>
    116         /// 添加缓存数据,如果存在则替换原有数据
    117         /// </summary>
    118         /// <param name="argKey">键值</param>
    119         /// <param name="argValue">存储值</param>
    120         /// <param name="argDateExpiration">过期时间</param>
    121         /// <returns></returns>
    122         public bool Set(string argKey, object argValue, DateTime argDateExpiration)
    123         {
    124             if (ContainKey(argKey))
    125             {
    126                 return false;
    127             }
    128             return client.Set(argKey, argValue, argDateExpiration);
    129         }
    130 
    131         /// <summary>
    132         /// 添加缓存数据,如果存在则替换原有数据
    133         /// </summary>
    134         /// <typeparam name="T">存储对象类型</typeparam>
    135         /// <param name="argKey">键值</param>
    136         /// <param name="entity">存储值</param>
    137         /// <returns></returns>
    138         public bool Set<T>(string argKey, T entity) where T : class
    139         {
    140             if (ContainKey(argKey))
    141             {
    142                 return false;
    143             }
    144             return client.Set(argKey, entity);
    145         }
    146 
    147         /// <summary>
    148         /// 添加缓存数据,如果存在则替换原有数据
    149         /// </summary>
    150         /// <typeparam name="T">存储对象类型</typeparam>
    151         /// <param name="argKey">键值</param>
    152         /// <param name="entity">存储值</param>
    153         /// <param name="argDateExpiration">过期时间</param>
    154         /// <returns></returns>
    155         public bool Set<T>(string argKey, T entity, DateTime argDateExpiration) where T : class
    156         {
    157             if (ContainKey(argKey))
    158             {
    159                 return false;
    160             }
    161             return client.Set(argKey, entity, argDateExpiration);
    162         }
    163 
    164 
    165         /// <summary>
    166         /// 替换原有缓存
    167         /// </summary>
    168         /// <param name="argKey">键值</param>
    169         /// <param name="argValue">存储值</param>
    170         /// <returns></returns>
    171         public bool Replace(string argKey, object argValue)
    172         {
    173             return client.Replace(argKey,argValue);
    174         }
    175 
    176         /// <summary>
    177         /// 替换原有缓存
    178         /// </summary>
    179         /// <param name="argKey">键值</param>
    180         /// <param name="argValue">存储值</param>
    181         /// <param name="argDateExpiration">过期时间</param>
    182         /// <returns></returns>
    183         public bool Replace(string argKey, object argValue, DateTime argDateExpiration)
    184         {
    185             return client.Replace(argKey,argValue,argDateExpiration);
    186         }
    187 
    188         public bool Replace<T>(string argKey, T entity) where T : class
    189         {
    190             return client.Replace(argKey,entity);
    191         }
    192 
    193         public bool Replace<T>(string argKey, T entity, DateTime argDateExpiration) where T : class
    194         {
    195             return client.Replace(argKey, entity,argDateExpiration);
    196         }
    197 
    198         public object Get(string argKey)
    199         {
    200             return client.Get(argKey);
    201         }
    202 
    203         public T Get<T>(string argKey)
    204         {
    205             T entity=default(T);
    206             entity = (T)client.Get(argKey);
    207             return entity;
    208         }
    209 
    210         public bool Remove(string argKey)
    211         {
    212             return client.Delete(argKey);
    213         }
    214 
    215         public bool Remove(string argKey, DateTime argDateExpiration)
    216         {
    217             return client.Delete(argKey,argDateExpiration);
    218         }
    219 
    220         public bool Remove()
    221         {
    222             return client.FlushAll();
    223         }
    224 
    225         public bool Remove(ArrayList servers)
    226         {
    227             return client.FlushAll(servers);
    228         }
    229     }

    230 } 

    上面的代码没有注释,因为提交不了这么长的代码,去掉了注释。代码大家可以看懂的,这里不做过多的讲解。 

      学习例子源码下载 

  • 相关阅读:
    巴科斯范式和sql语言
    mysql 视图
    1503
    mysql SQL_CALC_FOUND_ROWS
    create table xxx as select 与 create table xxx like
    mysql 1030 Got error 28 from storage engine
    python -- 装饰器入门
    12C新特性 -- 共享asm口令文件
    MySQL子查询的优化
    MySQL的explain
  • 原文地址:https://www.cnblogs.com/qingyuan/p/1976661.html
Copyright © 2011-2022 走看看