Memcached分析

什么是memcached

问题:传统的Web应用都将数据保存到DB中,应用服务器从DB中读取数据、处理数据并在浏览器中显示。但是随着数据量增大、访问的集中、就会出现DB的负担加重、数据库响应变慢、导致整个系统响应延迟增加。

memcached就是为了解决这个问题而出现的,memcached是高性能的分布式内存缓存服务器。它通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
在这里插入图片描述

memcached特征

  • 1.协议简单

memcached使用简单文本行的协议,因此通过telnet也能在memcached上保存数据,取得数据。

  • 2.基于libevent的事件处理

libevent是一个程序库,它将linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。
memcached使用这个libevent库,因此在linux、BSD等操作系统上发挥高性能。

  • 3.内置内存存储方式

memcached中保存的数据都存储在内存中。由于数据仅存储在内存中,因此重启memcached、重启操作系统会导致全部数据的丢失。内容容量达到指定值之后,就基于LRU算法自动删除不使用的缓存。

memcached本身是为缓存而设计的服务器,因此没有考虑数据的永久性问题。

  • 4.memcached不互相通信的分布式

各个memcahced不会互相通信已共享信息,如何进行分布式,是由客户端来实现的

memcahced的内存存储机制

Memcached利用slab allocation机制来分配和管理内存,它按照预先规定的大小,将分配的内存分割成特定长度的内存块,再把尺寸相同的内存块分成组,数据在存放时,根据键值 大小去匹配slab大小,找就近的slab存放,所以存在空间浪费现象。

slab allocation机制

在这里插入图片描述

  • 一个memcached服务器有多个memcached实例,一个memcached实例有多个slab,一个slab有多个内存空间page块,一个page块有多个chunk

  • slab class :memcached会自动根据设置的chunk size以及当前分配给memcached创建一系列slab class,单个slab class中的chunk大小是一样的,而每个slab class中的chunk大小根据设置的chunk_size*growth_factor^(i-1),其中i表示第几个slab class

  • page:memcached中的内存是已page为单位分配给每个slab class,然后每个slab class根据它的chunk大小,计算出各自能够存储的item的数量,默认page大小为1M。而每一页能够存放多少个item,这取决于chunk_size的大小。

  • chunk:可以理解为memcached中存储数据的最小单元,每个存储在memcached中的item都会分配一个符合它大小的chunk,chunk的数量决定了memcached存储item的数量,默认的chunk为48byte。

优势:Memcached的内存管理制效率高,而且不会造成内存碎片

缺点:导致空间浪费。因为每个 Chunk都分配了特定长度的内存空间,所以变长数据无法充分利用这些空间。如下图所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就浪费掉了
在这里插入图片描述

memcached的分布式算法

  • 现实说明:根据memcached特征第四条,memcached是不互相通信的分布式,是由客户端来实现分布式,如下图所示
    在这里插入图片描述

当向memcached集群存入/取出key/value时,memcache客户端会根据一定算法计算存入那台服务器,步骤如下:

第一步:选择服务器,所以如何选择服务器就至关重要,也就是选择什么样算法; 第二步:存取数据

余数算法——不推荐

余数算法:先求得键的整数散列值,再除以服务器数量,根据余数存储那台服务器

CRC($key)%N

该算法下,客户端首先根据key来计算CRC,然后结果对服务器数进行取模得到memcached服务器节点,对于这种方式有两个问题值得说明一下:

  • 当选择到的服务器无法连接的时候,一种解决办法是将尝试的连接次数加到key后面,然后重新进行hash,这种做法也叫rehash。

  • 第二个问题也是这种方法的致命的缺点,尽管余数计算分散发相当简单,数据分散也很优秀,当添加或者移除服务器的时候,缓存重组的代价相当大。

优点:简单、高效;
缺点:扩展性差,服务器数量变更时或者当一台memcached服务器出现故障,几乎所有的缓存都会失效

散列算法(一致性hash算法)——推荐

  • 散列算法理论基础:

首先求出memcached服务器节点的哈希值,并将其分配到0~2^32 的圆上,这个圆我们可以把它叫做值域,然后用同样的方法求出存储数据键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上,如果超过0~2^32仍找不到,就会保存在第一台memcached服务器上:
在这里插入图片描述

  • 如果从上图的状态中添加一台memcached 服务器,对于余数算法来说,增加和删除服务器节点缓存重组代价较大;对于散列算法,如下图所示, 新添/删除server时, 只在圆上增加服务器的逆时针方向的第一台服务器上的键会受到影响

  • 影响说明:node5被放在了node4与node2之间,本来映射到node2和node4之间的区域都会找到node4,当有node5的时候,node5和node4之间的还是找到node4,而node5和node2之间的此时会找到node5,因此当添加一台服务器的时候受影响的仅仅是node5和node2区间
    在这里插入图片描述

Memcached的数据清除算法

LRU。每个slab会维护一个队列,刚插入的数据在队头,经常get的数据也会移动到队头,这样较老或者访问较少的数据相对都留在队尾。该算法从队尾开始淘汰。当slab分配不到足够的内存时,首先会检查队尾是否有过期数据。如果有的话会直接将其覆盖为新的对象,如果没有,会开始淘汰队尾的对象。

Slab是一个内存块,它是memcached一次申请内存的最小单位。Slab的大小固定为1M(1048576 Byte),一个slab由若干个大小相等的chunk组成。每个chunk中都保存了一个item结构体、一对key和value。
在这里插入图片描述

Memcached的工作流程

1、先检查客户端的请求数据是否在memcached中,如有,直接把请求数据返回,不再对数据库进行任何操作;如果请求的数据不在memcached中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中(memcached客户端不负责,需要程序明确实现);

2、每次更新数据库的同时更新memcached中的数据,保证一致性;当分配给memcached内存空间用完之后,会使用LRU(Least Recently Used,最近最少使用)策略加上到期失效策略,失效数据首先被替换,然后再替换掉最近未使用的数据。

memcached的API使用32位元的循环冗余校验(CRC-32)计算键值后,将资料分散在不同的机器上。当表格满了以后,接下来新增的资料会以LRU机制替换掉。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon)是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信

Memcached 和 Redis的区别?

1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)等数据结构的存储。memcache支持简单的数据类型,String。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中
4、 redis的速度比memcached快很多
5、Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的IO复用模型。
在这里插入图片描述
小结:

  • 有持久化需求或者对数据结构和处理有高级要求的应用,选择redis,其他简单的key/value存储,选择memcached。
  • 对于两者的选择需要要看具体的应用场景,如果需要缓存的数据只是key-value这样简单的结构时,则还是采用memcache,它也足够的稳定可靠。
  • 如果涉及到存储,排序等一系列复杂的操作时,毫无疑问选择redis。

参考资料:
https://www.cnblogs.com/weixing/p/5522903.html
https://www.cnblogs.com/hukey/p/5605498.html
https://blog.csdn.net/waicyuyan/article/details/79698030

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值