本文共 2683 字,大约阅读时间需要 8 分钟。
memcached 是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态 Web 应用的速度、提高可扩展性
memcached 作为高速运行的分布式缓存服务器,具有以下的特点。协议简单:
memcached 的服务器客户端通信并不使用复杂的 XML 等格式,而使用简单的基于文本行的协议。因此,通过 telnet 也能在 memcached 上保存数据、取得数据。基于 libevent 的事件处理:
libevent 是个程序库,它将 Linux 的 epoll、BSD 类操作系统的 kqueue 等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥 O(1)的性能。memcached 使用这个 libevent 库,因此能在 Linux、BSD、Solaris 等操作系统上发挥其高性能内置内存存储方式:
为了提高性能,memcached 中保存的数据都存储在 memcached 内置的内存存储空间中。由于数据仅存在于内存中,因此重启 memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于 LRU(Least Recently Used)算法自动删除不使用的缓存。memcached 本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。memcached 不互相通信的分布式:
memcached 尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached 不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。Slab Allocator 的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题。
Slab Allocation 的原理相当简单。将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk 的集合) 而且,slab allocator 还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是重复使用。memcached 根据收到的数据的大小,选择最适合数据大小的 slab。memcached 中保存着slab 内空闲 chunk 的列表,根据该列表选择 chunk,然后将数据缓存于其中。
Slab Allocator 的缺点: 由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将 100 字节的数据缓存到 128 字节的 chunk 中,剩余的 28 字节就浪费了数据不会真正从memcached 中消失,memcached 不会释放已分配的内存。记录超时后,客户端就无法再看见该记录,其存储空间即可重复使用。
memcached 内部不会监视记录是否过期,而是在 get 时查看记录的时间戳,检查记录是否过期。这种技术被称为 lazy(惰性)expiration。因此,memcached 不会在过期监视上耗费 CPU 时间。
memcached 会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当 memcached 的内存空间不足时(无法从 slab class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。
不过,有时LRU可能会带来一些麻烦,这时候就可以禁用LRU机制,禁用之后如果memcached地内存空间不足时,memcached 返回报错。memcached 虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。是完全由客户端程序库实现的。这种分布式是 memcached 的最大特点。
下面假设 memcached 服务器有 node1~node3 三台,应用程序要保存键名为“tokyo”、“kanagawa”、“chiba”、“saitama”、“gunma”的数据
首先向 memcached 中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的 memcached 服务器。服务器选定后,即命令它保存“tokyo”及其值 接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送 get 命令。只要数据没有因为某些原因被删除,就能获得保存的值。根据余数计算分散:
Cache::Memcached 的分布式方法简单来说,就是“根据服务器台数的余数进行分散”。求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器。根据余数计算分散地缺点:
余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。那就是当添加或移除服务器时,缓存重组的代价相当巨大。添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而影响缓存的命中率。Consistent Hashing 如下所示:首先求出 memcached 服务器(节点)的哈希值,并将其配置到 0~232的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过 232仍然找不到服务器,就会保存到第一台 memcached 服务器上。
从上图的状态中添加一台 memcached 服务器。余数分布式算法由于保存键的服务器会发生巨大变化而影响缓存的命中率,但 Consistent Hashing 中,只有在 continuum 上增加服务器的地点逆时针方向的第一台服务器上的键会受到影响 因此,Consistent Hashing 最大限度地抑制了键的重新分布。转载地址:http://fanwi.baihongyu.com/