设为首页 收藏本站
查看: 1429|回复: 0

[经验分享] 缓存应用--Memcached分布式缓存简介(二)

[复制链接]

尚未签到

发表于 2015-9-2 10:34:27 | 显示全部楼层 |阅读模式
1 命令行查看状态
   很多时候我们需要去查看Memcached 的使用状态,比如Memcached 的运行时间,使用状态等等。在Windows系统中我们可以使用telnet 命令来查看Memcached 的相关运行情况。
    开始—>运行àcmd 运行得到如下:
   DSC0000.jpg
  输入telnet命令: telnet 服务地址 端口
   DSC0001.jpg
  Memcached 的默认端口号是11211
      输入stats 命令: 在这里屏幕是空白,看不到输入的内容,回车之后可以看到Memcached的运行相关信息。
   DSC0002.jpg
  Pid: Memcached 服务器中的进程编号

  Uptime:Memcached服务器启动之后所经历的时间,单位秒
  Time: 当前系统时间,单位秒
  Version: Memcached 的版本号
  pointer_size:服务器所在主机操作系统的指针大小,一般为32或64
  curr_items:表示当前缓存中存放的所有缓存对象的数量
  total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括已经删除的对象
  bytes:表示系统存储缓存对象所使用的存储空间,单位为字节
  curr_connections:表示当前系统打开的连接数
  total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数
  cmd_get: 查询缓存的次数,即使不成功也算一次
  cmd_set: 保存数据的次数,当然这里只保存成功的次数
  get_hits:表示获取数据成功的次数。
  get_misses:表示获取数据失败的次数。
  evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象
  bytes_read:memcached服务器从网络读取的总的字节数
  bytes_written:memcached服务器发送到网络的总的字节数
  limit_maxbytes:memcached服务缓存允许使用的最大字节数
  threads:被请求的工作线程的总数量
     缓存命中率 = get_hits / cmd_get * 100% ;
2 Memcached 存储机制
        关于Memcached的存储机制,在网上搜了一下讲解基本上都是千篇一律的。

  memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在之前的版本中,Memcached存储会导致很多内存碎片,从而加重了操作系统对内存管理的负担。Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块, 以完全解决内存碎片问题。
借用一张图说明一下:         DSC0003.jpg
  Slab Allocation 将分配的内存分割成各种尺寸的chunk (块),并把大小相同尺寸的chunk分为一组,就如上图一样:分割了 88b,112b,144b等尺寸。其实Slab Allocation还有重复利用内存的功能,也就是说分配的内存不会释放,而是重复利用。

  当存储数据的时候,它会自动去查找最为匹配的chunk,然后将数据存储到其中。比如我存储数据的大小为110B,那么它会存储到112B的chunk中。
      上面的问题来了,我存储只需要110B,但是我存储到112B的chunk中。如下图(借用):
   DSC0004.jpg
      那么在110b的存储中会浪费2B的内存空间
至于如何完全解决这个内存空间浪费的问题,还没有很好的方案,不过Memcached的 增长因子(Growth Factor)能够适当解决此问题。目前Memcached的默认增长因子      是1.25,也就是说会以原有的最大值基础上乘以1.25 来分配空间。

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

           Memcached 还是用了一种Lazy Expiration (延迟过期[姑且这样翻译]) 技术,就是Memcached不会去监视服务器上的数据是否过期,而是等待get的时候检查时间戳是否过期,减少Memcached在监控数据上所用到的时间。
          Memcached 不会去释放已经使用的内存空间,但是如果分配的内存空间已经满了,而Memcached 是如何去保证内存空间的重复使用呢!Memcached 是用了 Least Recently Used(LRU) 机制来协调内存空间的使用。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 }
  上面的代码没有注释,因为提交不了这么长的代码,去掉了注释。代码大家可以看懂的,这里不做过多的讲解。
   学习例子源码下载

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-108638-1-1.html 上篇帖子: memcached的安装 下篇帖子: Memcached的使用探讨
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表