浅析Memcached, Redis, MongoDB三者的区别

Redis

是一个开源(BSD许可)的,内存中的数据结构存储系统,它能够用做数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不一样级别的 磁盘持久化(persistence), 并经过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。html

Redis的优势:

  1. 支持多种数据结构,如 string(字符串)、 list(双向链表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基数估算)。
  2. 支持持久化操做,能够进行aof及rdb数据持久化到磁盘,从而进行数据备份或数据恢复等操做,较好的防止数据丢失的手段。
  3. 支持经过Replication进行数据复制,经过master-slave机制,能够实时进行数据的同步复制,支持多级复制和增量复制,master-slave机制是Redis进行HA的重要手段。
  4. 单线程请求,全部命令串行执行,并发状况下不须要考虑数据一致性问题。
  5. 支持pub/sub消息订阅机制,能够用来进行消息订阅与通知。
  6. 支持简单的事务需求,但业界使用场景不多,并不成熟。

Redis的局限性:

  1. Redis只能使用单线程,性能受限于CPU性能,故单实例CPU最高才可能达到5-6wQPS每秒(取决于数据结构,数据大小以及服务器硬件性能,平常环境中QPS高峰大约在1-2w左右)。
    支持简单的事务需求,但业界使用场景不多,并不成熟,既是优势也是缺点。
  2. Redis在string类型上会消耗较多内存,可使用dict(hash表)压缩存储以下降内存耗用。
  3. Mc和Redis都是Key-Value类型,不适合在不一样数据集之间创建关系,也不适合进行查询搜索。好比redis的keys pattern这种匹配操做,对redis的性能是灾难。

upload successfulupload successfulgit

Memcached

是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它经过在内存中缓存数据和对象来减小读取数据库的次数,从而提升动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,可是客户端能够用任何语言来编写,并经过memcached协议与守护进程通讯。github

Memcached的优势:

  1. Memcached能够利用多核优点,单实例吞吐量极高,能够达到几十万QPS(取决于key、value的字节大小以及服务器硬件性能,平常环境中QPS高峰大约在4-6w左右)。适用于最大程度扛量。
  2. 支持直接配置为session handle。

Memcached的局限性:

  1. 只支持简单的key/value数据结构,不像Redis能够支持丰富的数据类型。
  2. 没法进行持久化,数据不能备份,只能用于缓存使用,且重启后数据所有丢失。
  3. 没法进行数据同步,不能将MC中的数据迁移到其余MC实例中。
  4. Memcached内存分配采用Slab Allocation机制管理内存,value大小分布差别较大时会形成内存利用率下降,并引起低利用率时依然出现踢出等问题。须要用户注重value设计。

upload successfulupload successfulweb

MongoDB

是一个基于分布式文件存储的数据库,文档型的非关系型数据库,与上面二者不一样。redis

先解释一下文档的数据库,便可以存放xml、json、bson类型系那个的数据。算法

这些数据具有自述性(self-describing),呈现分层的树状数据结构。redis能够用hash存放简单关系型数据。数据库

MongoDB存放json格式数据。json

适合场景:事件记录、内容管理或者博客平台,好比评论系统。缓存

upload successfulupload successful服务器

Redis与Memcached的比较

一、数据类型支持不一样

与Memcached仅支持简单的key-value结构的数据记录不一样,Redis支持的数据类型要丰富得多。最为经常使用的数据类型主要由五种:String、Hash、List、Set和Sorted Set。Redis内部使用一个redisObject对象来表示全部的key和value。

二、内存管理机制不一样

在Redis中,并非全部的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。

当物理内存用完时,Redis能够将一些好久没用到的value交换到磁盘。Redis只会缓存全部的key的信息,若是Redis发现内存的使用量超过了某一个阀值,将触发swap的操做,Redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value须要swap到磁盘。而后再将这些key对应的value持久化到磁盘中,同时在内存中清除。

这种特性使得Redis能够保持超过其机器自己内存大小的数据。固然,机器自己的内存必需要可以保持全部的key,毕竟这些数据是不会进行swap操做的。同时因为Redis将内存中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操做的子线程会共享这部份内存,因此若是更新须要swap的数据,Redis将阻塞这个操做,直到子线程完成swap操做后才能够进行修改。

当从Redis中读取数据的时候,若是读取的key对应的value不在内存中,那么Redis就须要从swap文件中加载相应数据,而后再返回给请求方。 这里就存在一个I/O线程池的问题。在默认的状况下,Redis会出现阻塞,即完成全部的swap文件加载后才会相应。这种策略在客户端的数量较小,进行批量操做的时候比较合适。可是若是将Redis应用在一个大型的网站应用程序中,这显然是没法知足大并发的状况的。因此Redis运行咱们设置I/O线程池的大小,对须要从swap文件中加载相应数据的读取请求进行并发操做,减小阻塞的时间。

三、数据持久化支持

Redis虽然是基于内存的存储系统,可是它自己是支持内存数据的持久化的,并且提供两种主要的持久化策略:RDB快照和AOF日志。而memcached是不支持数据持久化操做的。

四、集群管理的不一样

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

Memcached自己并不支持分布式

,所以只能在客户端经过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。

结论

  • 没有必要过多的关心性能,由于两者的性能都已经足够高了。
    因为Redis只使用单核,而Memcached可使用多核,因此在比较上,平均每个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,可是比起Memcached,仍是稍有逊色。说了这么多,结论是,不管你使用哪个,每秒处理请求的次数都不会成为瓶颈。(好比瓶颈可能会在网卡)
  • 若是要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而若是Redis采用hash结构来作key-value存储,因为其组合式的压缩,其内存利用率会高于Memcached。固然,这和你的应用场景和数据特性有关。
  • 若是你对数据持久化和数据同步有所要求,那么推荐你选择Redis,由于这两个特性Memcached都不具有。即便你只是但愿在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。
  • 固然,最后还得说到你的具体应用需求。Redis相比Memcached来讲,拥有更多的数据结构和并支持更丰富的数据操做,一般在Memcached里,你须要将数据拿到客户端来进行相似的修改再set回去。这大大增长了网络IO的次数和数据体积。在Redis中,这些复杂的操做一般和通常的GET/SET同样高效。因此,若是你须要缓存可以支持更复杂的结构和操做,那么Redis会是不错的选择。