Memcached、Redis、MongoDB 的区别

Memcached、Redis、MongoDB 的区别

优缺点

Memcached

优点:

  • 可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS。适用于最大程度扛量。
  • 支持直接配置为 session handle。

缺点:

  • 只支持简单的 key/value 数据结构,不像 Redis 可以支持丰富的数据类型。
  • 无法进行持久化,数据不能备份,只能用于缓存使用,且重启后数据全部丢失。
  • 无法进行数据同步,不能将 Memcached 中的数据迁移到其他 Memcached 实例中。
  • 内存分配采用 Slab Allocation 机制管理内存,value 大小分布差异较大时会造成内存利用率降低,并引发低利用率时依然出现踢出等问题。需要用户注重value设计。

应用

  • 分布式缓存
  • 数据库前段缓存
  • 服务器间数据共享

Redis

优点:

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

缺点:

  • 只能使用单线程,性能受限于 CPU 性能,故单实例 CPU 最高才可能达到 5-6w QPS 每秒。
  • 支持简单的事务需求,但业界使用场景很少,并不成熟,既是优点也是缺点。
  • 在 string 类型上会消耗较多内存,可以使用 dict(hash表)压缩存储以降低内存耗用。
  • Memcached 和 Redis 都是 Key-Value 类型,不适合在不同数据集之间建立关系,也不适合进行查询搜索。比如 redis 的 keys pattern 这种匹配操作,对 redis 的性能是灾难。

应用

  • 热点数据的缓存

由于 Redis 访问速度块、支持的数据类型比较丰富,所以 Redis 很适合用来存储热点数据,另外结合expire,我们可以设置过期时间然后再进行缓存更新操作,这个功能最为常见,我们几乎所有的项目都有所运用。

  • 限时业务的运用

Redis 中可以使用expire命令设置一个键的生存时间,到时间后 Redis 会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。

  • 计数器相关问题

Redis 由于incrby命令可以实现原子性的递增,所以可以运用于高并发的秒杀活动、分布式序列号的生成、具体业务还体现在比如限制一个手机号发多少条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。

  • 排行榜相关问题

关系型数据库在排行榜方面查询速度普遍偏慢,所以可以借助 Redis 的 SortedSet 进行热点数据的排序。

在奶茶活动中,我们需要展示各个部门的点赞排行榜, 所以我针对每个部门做了一个 SortedSet,然后以用户的 openid 作为上面的 username,以用户的点赞数作为上面的 score,然后针对每个用户做一个 hash,通过zrangebyscore就可以按照点赞数获取排行榜,然后再根据 username 获取用户的hash信息,这个当时在实际运用中性能体验也蛮不错的。

  • 分布式锁

这个主要利用 Redis 的setnx命令进行,setnx:"set if not exists"就是如果不存在则成功设置缓存同时返回1,否则返回0 ,这个特性在俞你奔远方的后台中有所运用,因为我们服务器是集群的,定时任务可能在两台机器上都会运行,所以在定时任务中首先 通过setnx设置一个 lock,如果成功设置则执行,如果没有成功设置,则表明该定时任务已执行。 当然结合具体业务,我们可以给这个 lock 加一个过期时间,比如说30分钟执行一次的定时任务,那么这个过期时间设置为小于30分钟的一个时间 就可以,这个与定时任务的周期以及定时任务执行消耗时间相关。

当然我们可以将这个特性运用于其他需要分布式锁的场景中,结合过期时间主要是防止死锁的出现。

  • 延时操作

比如在订单生产后我们占用了库存,10分钟后去检验用户是够真正购买,如果没有购买将该单据设置无效,同时还原库存。 由于 Redis 自 2.8.0 之后版本提供 Keyspace Notifications 功能,允许客户订阅 Pub/Sub 频道,以便以某种方式接收影响 Redis 数据集的事件。 所以我们对于上面的需求就可以用以下解决方案,我们在订单生产时,设置一个 key,同时设置10分钟后过期, 我们在后台实现一个监听器,监听 key 的实效,监听到 key 失效时将后续逻辑加上。 当然我们也可以利用 rabbitmq、activemq 等消息中间件的延迟队列服务实现该需求。

  • 分页、模糊搜索

Redis 的 set 集合中提供了一个zrangebylex方法,语法如下:

ZRANGEBYLEX key min max [LIMIT offset count]

通过ZRANGEBYLEX zset - + LIMIT 0 10 可以进行分页数据查询,其中- +表示获取全部数据

zrangebylex key min max 这个就可以返回字典区间的数据,利用这个特性可以进行模糊查询功能,这个也是目前我在 Redis 中发现的唯一一个支持对存储内容进行模糊查询的特性。

  • 点赞、好友等相互关系的存储

Redis set 对外提供的功能与 list 类似是一个列表的功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,并且 set 提供了判断某个成员是否在一个 set 集合内的重要接口,这个也是 list 所不能提供的。 又或者在微博应用中,每个用户关注的人存在一个集合中,就很容易实现求两个人的共同好友功能。

  • 队列

由于 Redis 有 list push 和 list pop 这样的命令,所以能够很方便的执行队列操作。

MongoDB

优点:

  • 更高的写负载,拥有更高的插入速度。
  • 处理很大的规模的单表,当数据表太大的时候可以很容易的分割表。
  • 高可用性,设置 M-S 不仅方便而且很快,还可以快速、安全及自动化的实现节点(数据中心)故障转移。
  • 快速的查询,支持二维空间索引,比如管道,因此可以快速及精确的从指定位置获取数据。在启动后会将数据库中的数据以文件映射的方式加载到内存中。如果内存资源相当丰富的话,这将极大地提高数据库的查询速度。
  • 非结构化数据的爆发增长,增加列在有些情况下可能锁定整个数据库,或者增加负载从而导致性能下降,由于弱数据结构模式,添加一个新字段不会对旧表格有任何影响,整个过程会非常快速。

缺点:

  • 不支持事务。
  • 占用空间过大 。
  • 没有成熟的维护工具。

应用

  • 网站数据

Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

  • 缓存

由于性能很高,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo 搭建的持久化缓存层可以避免下层的数据源过载。

  • 大尺寸、低价值的数据

使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。

  • 高伸缩性的场景

Mongo 非常适合由数十或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置支持。

  • 用于对象及JSON 数据的存储

Mongo 的BSON 数据格式非常适合文档化格式的存储及查询。

对比

性能:总的来讲:Memcached 和 Redis 差不多,要高于 MongoDB。

便利性

  • Memcached 数据结构单一。
  • Redis 丰富一些,数据操作方面,Redis 更好一些,较少的网络 IO 次数。
  • MongoDB 支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。

存储空间

  • Memcached 可以修改最大可用内存,采用 LRU 算法。
  • Redis 在 2.0 版本后增加了自己的 VM 特性,突破物理内存的限制;可以对 key-value 设置过期时间。
  • MongoDB 适合大数据量的存储,依赖操作系统 VM 做内存管理,吃内存也比较厉害,不要和别的服务在一起。

可用性

  • Memcached 本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的 hash 或者环状的算法,解决单点故障引起的抖动问题。
  • Redis 依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,所以单点问题比较复杂;不支持自动 sharding,需要依赖程序设定一致 hash 机制。一种替代方案是,不用 redis 本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡。
  • MongoDB 支持 master-slave,replicaset(内部采用 paxos 选举算法,自动故障恢复),auto sharding 机制,对客户端屏蔽了故障转移和切分机制。

可靠性

  • Memcached 不支持快照、AOF,通常用在做缓存,提升性能。
  • Redis 支持快照、AOF,依赖快照进行持久化,aof 增强了可靠性的同时,对性能有所影响。
  • MongoDB 从1.8版本开始采用 binlog 方式支持持久化的可靠性。

一致性

  • Memcached 在并发场景下,用 cas 保证一致性。
  • Redis 事务支持比较弱,只能保证事务中的每个操作连续执行。
  • MongoDB 不支持事务。

数据分析:MongoDB 内置了数据分析的功能(mapreduce),其他两者不支持。

应用场景

  • Memcached:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能。
  • Redis:数据量较小的更新操作和运算上。
  • MongoDB:主要解决海量数据的访问效率问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值