redis、memcache、mongoDB 对比

三者对比出自:https://www.cnblogs.com/457248499-qq-com/p/7392653.html

Redis相比Memcached

1.Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

2.内存使用效率对比:使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。

3.性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。

具体为什么会出现上面的结论,以下为收集到的资料:

(摘录于https://www.cnblogs.com/itxuexiwang/p/5200575.html

https://blog.csdn.net/u011489043/article/details/78922390

选择及相似出自:http://www.ituring.com.cn/article/503667

1、数据类型和操作支持不同

与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多。最为常用的数据类型主要由五种:String、Hash、List、Set和Sorted Set。

Redis相比Memcached来说,拥有更多的数据结构并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去,序列化再反序列化,这大大增加了网络IO的次数和数据体积。在Redis中,支持在服务器端的数据操作,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择

macache 单个value最大存储 1M,超过1M只能用redis,redis支持value最大1G。

2、数据存储原理不同

Redis和Memcached都是将数据存放在内存中,都是内存数据库。

不过memcached还可用于缓存其他东西,例如图片、视频等等。memcached把数据全部存在内存之中,数据不能超过内存大小,断电后会挂掉数据不可恢复;

在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。当物理内存用完时,memcached超过内存比例会抹掉前面的数据。Redis可以将一些很久没用到的value交换到磁盘。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。

3、数据持久化及备份恢复支持

memcached不支持内存数据的持久化操作,所有的数据都以in-memory的形式存储。
redis支持持久化操作。redis提供了两种不同的持久化方法来讲数据存储到硬盘里面,一种是快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里面。另一种方法叫只追加文件(append-only file, AOF),它会在执行写命令时,将被执行的写命令复制到硬盘里面。

memcached挂掉后,数据不可恢复;redis数据丢失后可以通过aof恢复,Redis支持数据的备份,即master-slave主从模式的数据备份。

1)RDB快照

Redis支持将当前数据的快照存成一个数据文件的持久化机制,即RDB快照。

2)AOF日志

AOF日志的全称是append only file,它是一个追加写入的日志文件。与一般数据库的binlog不同的是,AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令。只有那些会导致数据发生修改的命令才会追加到AOF文件。每一条修改数据的命令都生成一条日志,AOF文件会越来越大,所以Redis又提供了一个功能,叫做AOF rewrite。其功能就是重新生成一份AOF文件,新的AOF文件中一条记录的操作只会有一次,而不像一份老文件那样,可能记录了对同一个值的多次操作。

数据一致性问题

Memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。 Redis没有提供cas 命令,并不能保证这点,不过Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。

5、内存使用效率
  使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。
 

6、内存管理机制不同

内存管理机制不同的原因

对于像Redis和Memcached这种基于内存的数据库系统来说,内存管理的效率高低是影响系统性能的关键因素。传统C语言中的malloc/free函数是最常用的分配和释放内存的方法,但是这种方法存在着很大的缺陷:首先,对于开发人员来说不匹配的malloc和free容易造成内存泄露;其次频繁调用会造成大量内存碎片无法回收重新利用,降低内存利用率;最后作为系统调用,其系统开销远远大于一般函数调用。所以,为了提高内存的管理效率,高效的内存管理方案都不会直接使用malloc/free调用。Redis和Memcached均使用了自身设计的内存管理机制,但是实现方法存在很大的差异,下面将会对两者的内存管理机制分别进行介绍。

Memcached内存机制

Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。Slab Allocation机制只为存储外部数据而设计,也就是说所有的key-value数据都存储在Slab Allocation系统里,而Memcached的其它内存请求则通过普通的malloc/free来申请,因为这些请求的数量和频率决定了它们不会对整个系统的性能造成影响Slab Allocation的原理相当简单。 如图所示,它首先从操作系统申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。其中,Chunk就是用来存储key-value数据的最小单位。每个Slab Class的大小,可以在Memcached启动的时候通过制定Growth Factor来控制。假定图中Growth Factor的取值为1.25,如果第一组Chunk的大小为88个字节,第二组Chunk的大小就为112个字节,依此类推

è¿éåå¾çæè¿°

 

 

当Memcached接收到客户端发送过来的数据时首先会根据收到数据的大小选择一个最合适的Slab Class,然后通过查询Memcached保存着的该Slab Class内空闲Chunk的列表就可以找到一个可用于存储数据的Chunk。当一条数据库过期或者丢弃时,该记录所占用的Chunk就可以回收,重新添加到空闲列表中。从以上过程我们可以看出Memcached的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺点就是会导致空间浪费。因为每个Chunk都分配了特定长度的内存空间,所以变长数据无法充分利用这些空间。如图 所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就浪费掉了。Memcached主要的cache机制是LRU(最近最少使用Least Recently Used)算法+超时失效

è¿éåå¾çæè¿°

Redis内存管理机制

Redis的内存管理主要通过源码中zmalloc.h和zmalloc.c两个文件来实现的。Redis为了方便内存的管理,在分配一块内存之后,会将这块内存的大小存入内存块的头部。

è¿éåå¾çæè¿°

如图所示,real_ptr是redis调用malloc后返回的指针。redis将内存块的大小size存入头部,size所占据的内存大小是已知的,为size_t类型的长度,然后返回ret_ptr。当需要释放内存的时候,ret_ptr被传给内存管理程序。通过ret_ptr,程序可以很容易的算出real_ptr的值,然后将real_ptr传给free释放内存。

Redis通过定义一个数组来记录所有的内存分配情况,这个数组的长度为ZMALLOC_MAX_ALLOC_STAT。数组的每一个元素代表当前程序所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这个数组为zmalloc_allocations。zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数。zmalloc.c中有一个静态变量used_memory用来记录当前分配的内存总大小。所以,总的来看,Redis采用的是包装的mallc/free,相较于Memcached的内存管理方法来说,要简单很多。
 

7、集群管理的不同

redis自身支持集群,实现主从读写分离功能,官方也提供sentinal哨兵的集群管理工具,实现主从监控,故障转移,memcached实现集群需要二次开发了

 

Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。

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

相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。最新版本的Redis已经支持了分布式存储功能。Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,具有线性可伸缩的功能。Redis Cluster的分布式存储架构,节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis Cluster将整个key的数值域分成4096个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点数就是4096。Redis Cluster使用的分布式算法也很简单:crc16( key ) % HASH_SLOTS_NUMBER。

为了保证单点故障下的数据可用性,Redis Cluster引入了Master节点和Slave节点。在Redis Cluster中,每个Master节点都会有对应的两个用于冗余的Slave节点。这样在整个集群中,任意两个节点的宕机都不会导致数据的不可用。当Master节点退出后,集群会自动选择一个Slave节点成为新的Master节点。


8、Memcache支持多核多线程,Redis单线程操作

9、性能及使用场景
  由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据时,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。

存储的内容比较大 : macache 单个value最大存储 1M,超过1M只能用redis了。

注意:纯的k-v 而且数据量特别大,并发也很大 或许使用memcache更合适

a.内存分配:memcache使用 预分配内存池的方式管理内存,更节省内存分配时间,redis使用临时申请的方式,kennel导致碎片。对比看memcache更快一点

b.memcache把所有的数据存储在物理内存里。redis有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上。对比看数据量大时,memcache更快一点

c.memcache使用非阻塞IO复用模型,redis也是使用非阻塞IO复用模型,但由于redis还提供一些非KV存储之外的排序,聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度。从这一点上,由于redis提供的功能较多,mc会更快一些。

d.memcache使用多线程,主线程监听,worker子线程接受请求,执行读写,这个过程中,可能存在锁冲突。redis使用单线程,虽无锁冲突,但难以利用多核的特性提升整体吞吐量。从这一点上,mc会快一些。

 

Memchached 还是 Redis?

该用哪一个?当我们讨论改进性能的时候,这是每次技术讨论中最常见的一个问题。每当性能需要改善时,采用缓存常常是迈出的第一步。与此同时,选择Memcached 或者 Redis 通常是第一个需要考虑的地方。哪个能给我们提供更佳的性能?它们的优点和缺点又是什么?

在设计任何缓存系统时,我们考虑如下几点:

  • 读/写速度
  • 内存使用情况
  • 磁盘 I/O 转储.
  • 伸缩性.

我写这篇教程是考虑到你已经知道了这些缓存的基础知识。

Redis & Memchached 之间的相似之处:

Memcached/Redis 两者都提供基于内存的、键-值数据存储,尽管Redis更准确的说是结构化数据存储。Redis是内存中的结构化数据存储器,用于数据库、缓存、消息代理。两者(Memcached/Redis)都属于数据管理方案中的NoSQL家族,都是基于键-值存储的。它们都在内存中保存数据,当然使它们作为缓存层特别有用。

截至今日,Memcached提供的每项主要功能及其优势,都是Redis功能和特性的子集。任何用例中可能使用Memcached的地方都可以对等的使用Redis。它们都是闪电般快速的高速缓存。Memcached提供的只是Redis拥有功能的冰山一角。Memcached是一个基于易失性内存的键-值存储器。Redis一样可以做到(跟Memcached做得一样好),但是它还是一个结构化数据服务器。

为什么选 Memcached?

当缓存相对较小和使用静态的数据时候,比如HTML代码片段,Memcached可能更为可取。Memcached内部的内存管理在最简单的用例中更为有效,因为它的元数据消耗相对更少的内存资源。

当数据尺寸是动态的时候,Memcached的内存管理效率下降的很快,此时Memcached的内存会变成碎片。而且,大的数据集经常牵扯到数据序列化,总是需要更多的空间来存储。如果你使用Memcached,数据会随着重启动而丢失,重建缓存是个代价高昂的过程。

Memcached比Redis更具优势的另一个场景在伸缩性。因为Memcached是多线程的,所以你可以通过给它更多计算资源让它轻松扩展。Redis是单线程的,可以通过集群无损水平扩展。集群是一个有效的扩展方案,但是相对来说配置、操作复杂。Memcached不支持复制功能(数据从一台机器自动复制到另外一台)。

Memcached 非常适合处理高流量的网站。它可以一次性读取大量的信息,并在优秀的反应时间内返回。Redis不但能处理高流量的读,还能处理繁重的写入。

enter image description here

为什么选 Redis?

Redis有五种主要的数据结构可以选择。通过对缓存数据智能化的缓存和处理,它为应用程序开发人员打开了存在各种可能的新世界。由于其数据结构(使用多种格式存储数据:列表、数组、集合、有序集合)特性,Redis作为缓存系统提供了更多的能力和总体上更好的效率。缓存使用一种称为“数据回收”的机制,通过从内存中删除旧数据为新数据腾出空间。Memcached的数据回收机制使用了LRU(Least Recently Used-最近最少使用)算法,但回收与新数据近似大小的数据时有点随意性。

Redis允许对回收进行细粒度的控制,让你选择六种不同的回收策略。Redis同时支持惰性(被动)和主动回收,只有在需要更多空间或主动激活时才回收数据。另一方面,Memcached只支持惰性回收。

以下是redis提供的一些功能,可以用于“真实”数据存储,而不仅仅是缓存。

  • 强大的数据类型和可利用它们的强大命令支持。哈希、有序集合、列表等。
  • 默认的磁盘持久化支持
  • 使用乐观锁的事务支持 (WATCH/MULTI/EXEC)
  • 发布/订阅功能,速度极快
  • 高达512MB的键值尺寸上限(Memcached每个键值限于1MB大小)
  • Lua 脚本支持 (2.6及以上版本)
  • 内置集群支持 (3.0及以上版本)
  • 一切都极快

强大的数据类型尤为重要。它们允许Redis提供一个出色的共享队列(list),一个很棒的消息传递解决方案(pub/sub),一个存储会话信息(hashes)的好地方,还有一个引人注目的高分值追踪区域(sorted sets)。它们仅仅是简单探讨就能得到的使用样例。

结论

Redis与Memcached相比,性能和内存使用情况相当相似。除非你已经在Memcached上投入了大笔资金,否则向前推进使用Redis是显而易见的解决方案。不仅Redis是更好的选择,它还支持全新类型的用例和使用模式。

Redis可能会非常有用的一些示例应用程序:

  • 电子商务应用:大多数的电子商务应用量级比较重,Redis可以提升你的页面加载速度。你可以存储所有的配置文件到Redis,从内存中读取这些配置信息速度会非常快速。你也可以在Redis中存储完整的页面缓存,因为它的键值容量很大。你也可以存储会话信息到Redis。

  • 物联网应用:在物联网应用中,物联网设备非常频繁的发送数据到服务器,比如每秒钟数千条。在把它们存储到任何持久性存储器之前,你可以先把这些高容量的原始数据推送到Redis。

  • 实时分析:可以在Memcached上实现一个实时的分析引擎,以数据库为后盾。但是Redis非常擅长统计列表和一系列事物。在所有的Redis功能特性中,它对键值进行排序的能力超过了Memcached,还有计算一组页面的点击次数等数据,然后将这些数字汇总进入分析系统。这些数据可通过工作人员输入到更大的分析引擎,在这些应用场合选择Redis是正确的决定之一。

最后一件事:不管你选择什么,缓存系统都不是数据库。你不能光靠缓存,系统同时需要缓存和数据库。


这段是我的评论。总体上看,Redis功能特性远优于Memcached,完全是下一代产品。选择哪个使用似乎答案很明确。但是必须指出,Redis的单线程设计,同时也带来了一些重要的隐患。Redis有数据持久化功能,这个功能与Redis的单线程特性结合,就成了Redis故障的高发区域。默认的RDB持久化会阻塞线程,使得Redis对正常请求无法响应,在高流量网站上容易出现大量请求错误。这在系统中称为“涌现”,当然这是坏的一个。当然后来Redis也发展出了AOF持久化方式(默认没有打开,要手工开启),一定程度上减缓了Redis的持久化问题。Redis会fork一个子进程来单独处理持久化。可是fork功能并非无代价,它一样有消耗内存资源,影响主程序响应请求的问题。阻塞是Redis应用的噩梦,跟Node.js一样。所以出现故障的时候,可以多在这个角度上分析原因,也许能很快的解决。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值