Redis与memcached区别

Redis与memcached区别

 

 

参考:http://blog.csdn.net/tonysz126/article/details/8280696

http://blog.csdn.net/colorant/article/details/21089057

https://www.zhihu.com/question/21419897

1.   为什么需要缓存

少量的数据存储,高速读写访问。此类产品通过数据全部in-memory的方式保证高速访问,同时提供数据落地功能

2.   Redis与Memcached的区别

2.1.          数据类型存储

         Memcached只支持简单的K/V数据类型

         Redis不仅仅支持简答的K/V类型数据,同时还提供了List,Set,SortedSet,Hash等数据结构的存储

2.2.          数据的备份

         Redis可以以master-slave的方式配置服务器,Slave节点对数据进行replica备份,Slave节点也可以充当Read only的节点分担数据读取的工作

2.3.          数据的持久化

         memcached不保证存储的数据的有效性,Slab内部基于LRU也会自动淘汰旧数据。

客户端不能假设数据在服务器端的当前状态,这应该说是Memcached的Feature设定,用户不必太多关心或者自己管理数据的淘汰更新工作。Memcached也不做数据的持久化工作,但是有许多基于memcached协议的项目实现了数据的持久化,例如memcacheDB使用BerkeleyDB进行数据存储,但本质上它已经不是一个Cache Server,而只是一个兼容Memcached的协议key-valueData Store了。

         Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启时可以再次加载使用。Redis内建支持两种持久化方案,snapshot快照和AOF 增量Log方式。快照顾名思义就是隔一段时间将完整的数据Dump下来存储在文件中。AOF增量Log则是记录对数据的修改操作(实际上记录的就是每个对数据产生修改的命令本身),两种方案可以并存,也各有优缺点,具体参见 http://redis.io/topics/persistence

         Redis并不是所有的数据都一直存储在内存中,这是和Memcached相比最大的区别。Redis只会缓存所有的key信息,如果Redis发现内存的使用量超过一个阀值后,将进行swap操作,计算出哪些key需要交换到磁盘中。然后再将这些key对应的value持久化到磁盘,同时在内存中清除这些数据。

         Redis将内存中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个操作,直到子线程完成swap操作后才可以进行修改。

2.4.          数据的一致性(事务)

         Memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。

除了increment/decrement这样的原子操作命令,不存在对事务的支持

         Redis没有提供cas 命令,并不能保证这点。不过Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。

         Redis通过Multi / Watch /Exec等命令可以支持事务的概念,原子性的执行一批命令。在2.6以后的版本中由于添加了对Script脚本的支持,而脚本固有的是以transaction事务的方式执行的,并且更加易于使用

2.5.          网络IO模型

          Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache coherency和锁的问题,比如,Memcached最常用的stats 命令,实际Memcached所有操作都要对这个全局变量加锁,进行计数等工作,带来了性能损耗。

          Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和select,对于单纯只有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型实际会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞住的。

2.6.          内存管理

          Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除,原因可以参考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/

Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,Redis跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够导致swap也不会剔除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache

2.7.          集群

Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。下图给出了Memcached的分布式存储实现架构。当客户端向Memcached集群发送数据之前,首先会通过内置的分布式算法计算出该条数据的目标节点,然后数据会直接发送到该节点上存储。但客户端查询数据时,同样要计算出查询数据所在的节点,然后直接向该节点发送查询请求以获取数据。

Redis3.0之前

客户端Redis Sharding技术其主要思想是采用一致性哈希算法(consistent hashing),将key和节点name同时hashing。采用一致性哈希而不是采用简单类似哈希求模映射的主要原因是当增加或减少节点时,不会产生由于重新匹配造成的rehashing。一致性哈希只影响相邻节点key分配,影响量小。

Redis3.0

Redis Cluster中,Sharding采用slot(槽)的概念,一共分成16384个槽,这有点儿类pre sharding思路。对于每个进入Redis的键值对,根据key进行散列,分配到这16384个slot中的某一个中。使用的hash算法也比较简单,就是CRC16后16384取模。

http://doc.redisfans.com/topic/cluster-tutorial.html

3.   总结

1.Redis使用最佳方式是全部数据in-memory。

2.Redis更多场景是作为Memcached的替代者来使用。

3.当需要除key/value之外的更多数据类型支持时,使用Redis更合适。

4.当存储的数据不能被剔除时,使用Redis更合适。

猜你喜欢

转载自www.cnblogs.com/zjshd/p/8399819.html
今日推荐