缓存
Memcached 不可持久化
Redis 可持久化
Memcached
https://www.jianshu.com/p/e5b11670c3bb
https://www.jianshu.com/u/99ee95856388
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。Memcached基于一个存储键/值对的hashmap。
Menceched 通过预分配指定的内存空间来存取数据,所有的数据都保存在 memcached 内置的内存中。
Memcached 是为缓存系统设计的,因此没有考虑数据的容灾问题,和机器的内存一样,重启机器将会丢失,如果希望服务重启数据依然能保留,那么就需要 sina 网开发的 Memcachedb 持久性内存缓冲系统,当然还有常见的 NOSQL 服务如 redis。
Memcached数据访问模型
添加新的键值对数据
从图中可以看出,Memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能,而是完全由客户端程序库实现的。服务端之间没有任何联系,数据存取都是通过客户端的算法实现的。当客户端要存取数据时,首先会通过算法查找自己维护的服务器哈希列表,找到对应的服务器后,再将数据存往指定服务器。例如:上图中应用程序要新增一个<'tokyo',data>的键值对,它同过set操作提交给Memcached客户端,客户端通过一定的哈希算法(比如:一般的求余函数或者强大的一致性Hash算法)从服务器列表中计算出一个要存储的服务器地址,最后将该键值对存储到计算出来的服务器里边。
获取已存在的键值对数据
上图中应用程序想要获取Key为‘tokyo’的Value,于是它向Memcached客户端提交了一个Get请求,Memcached客户端还是通过算法从服务器列表查询哪台服务器存有Key为‘tokyo’的Value(即选择刚刚Set到了哪台服务器),如果查到,则向查到的服务器请求返回Key为‘tokyo’的数据。
Memcached分布式的核心—一致性Hash算法
一致性Hash算法通过一个叫做一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射,如下图所示:

具体算法过程是:
先构造一个长度为0~2^32(2的32次幂)个的整数环(又称:一致性Hash环),根据节点名称的Hash值将缓存服务器节点放置在这个Hash环中,如上图中的node1,node2等;
根据需要缓存的数据的KEY值计算得到其Hash值,如上图中右半部分的“键”,计算其Hash值后离node2很近;
在Hash环上顺时针查找距离这个KEY的Hash值最近的缓存服务器节点,完成KEY到服务器的Hash映射查找,如上图中离右边这个键的Hash值最近的顺时针方向的服务器节点是node2,因此这个KEY会到node2中读取数据;
当缓存服务器集群需要扩容的时候,只需要将新加入的节点名称(如node5)的Hash值放入一致性Hash环中,由于KEY总是顺时针查找距离其最近的节点,因此新加入的节点只影响整个环中的一部分。如下图中所示,添加node5后,只影响右边逆时针方向的三个Key/Value对数据,只占整个Hash环中的一小部分。
Memcached与Redis的对比
- 如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。
- 如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。
- 因此,我们可以得出一个结论:在简单的Key/Value应用场景(例如缓存),Memcached拥有更高的读写性能;而在数据持久化和数据同步场景,Redis拥有更加强大的功能和更为丰富的数据类型;
需要慎重考虑的部分
- Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
- Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高
- 从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,各个节点可以交流,可拓展行、可维护性更强大。
MongoDB不支持事务。
分布式缓存redis
https://juejin.im/entry/56baa0cfc4c97100522945d3
数据同步
如果设置了一个Slave,无论是第一次连接还是重连到Master,它都会发出一个SYNC命令;
当Master收到SYNC命令之后,会做两件事:
a) Master执行BGSAVE:后台写数据到磁盘(rdb快照);
b) Master同时将新收到的写入和修改数据集的命令存入缓冲区(非查询类);
当Master在后台把数据保存到快照文件完成之后,Master会把这个快照文件传送给Slave,而Slave则把内存清空后,加载该文件到内存中;
而Master也会把此前收集到缓冲区中的命令,通过Reids命令协议形式转发给Slave,Slave执行这些命令,实现和Master的同步;
Master/Slave此后会不断通过异步方式进行命令的同步,达到最终数据的同步一致;
需要注意的是Master和Slave之间一旦发生重连都会引发全量同步操作。但在2.8之后,也可能是部分同步操作。
2.8开始,当Master和Slave之间的连接断开之后,他们之间可以采用持续复制处理方式代替采用全量同步。
Master端为复制流维护一个内存缓冲区(in-memory backlog),记录最近发送的复制流命令;同时,Master和Slave之间都维护一个复制偏移量(replication offset)和当前Master服务器ID(Masterrun id)。
当网络断开,Slave尝试重连时:
a. 如果MasterID相同(即仍是断网前的Master服务器),并且从断开时到当前时刻的历史命令依然在Master的内存缓冲区中存在,则Master会将缺失的这段时间的所有命令发送给Slave执行,然后复制工作就可以继续执行了;
b. 否则,依然需要全量复制操作。