Redis 和 Memcached 区别_使用场景对比,教你如何选择?(超详细)
在互联网公司中,缓存是经常被用到的一个技术栈。而提到缓存数据库,最常见的就是 Redis 和 Memcached 了,其中,Redis 是被使用最多的。那么,Redis 和 Memcached 的区别是什么呢,各自都有什么优势,在技术选型上,应该选哪个更好一些?
对比
数据结构
Redis 和 Memcached 都是基于 key-value
模式,但是 Redis 支持的数据结构更加丰富,除了比较常见的 5 种数据结构,如 String、List、Hash、Set、Zset,在 Redis 后续的版本迭代中,还同时支持更多的数据结构,如 BitMap 位图、HyperLogLog(简称 HLL)、GEO、Stream 等。而 Memcache 仅支持简单的字符串存储,需要自己手动处理复杂对象。
总结:Redis 支持的数据结构更加丰富,而 Memcache 仅支持简单的字符串存储。
Key 的 Value 限制
Redis 的 Value 最大可以有 1G,而 Memcached 最大为 1M 。
持久化存储
Redis 支持数据持久化,可将每一次写入操作(数据的增加、删除、修改)记录到磁盘文件(AOF文件)中。
Memcached 不支持数据的持久化存储。
总结:Redis 相比 Memcache 在数据存储方面更加可靠。
数据迁移
Redis 支持数据迁移,可通过 RDB 快照恢复,或者 AOF 文件回放的方式,将数据备份并迁移到新的 Redis 实例上。
Memcached 不支持数据迁移。
快照备份
Redis 支持快照备份,Redis 的快照会定期生成,因此不能保证数据 100% 不丢失。Redis 会 fork 一个子进程用于生成快照,当数据较多时,可能产生Redis服务短暂中断。
Memcached 不支持数据的快照备份。
内存管理机制
和 Memcached 不同的是,在 Redis 中,并不是所有的数据都一直存在内存中的,当 Redis 发现物理内存即将用尽时,Redis 可以将那些很久没有被访问到的 value
数据(冷数据) 持久化到磁盘上。当然,key
还是会存在内存中。正是这种机制,让 Redis 能够存储超过机器内存大小的数据量。
再来说 Memcached,它默认使用的 Slab Allocation 机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块,来存储相应长度的 key-value
数据,以此解决内存碎片的问题。
从内存利用率来说,仅使用简单的 key-value
存储的话,Memcached 的内存利用率更高。而如果 Redis 使用 Hash 结构来做 key-value
存储的话,由于它组合式的压缩特性,其内存利用率会高于 Memcached。
数据一致性
Redis 是单线程的,所有操作都是串行执行,能够有效的保证数据的原子性,无需担心数据一致性问题。
Memcache 需要使用 cas
命令来保证数据一致性。
TIP: CAS(Check and Set) 是一个确保并发一致性的机制,本质上是通过乐观锁来实现的,原理是通过版本号(version)进行操作对比,版本号一致则执行操作,否则,放弃执行该操作。
IO
Redis 选用的 I/O 多路复用模型,虽然单线程不用考虑锁等问题,但是还要执行 kv 数据之外的一些排序、聚合功能,复杂度比较高。Memcache 也选用非阻塞的 I/O 多路复用模型,但是速度更快一些。
线程角度
Memcahce 为多线程模型,主线程负责监听,多个工作子线程(worker)执行读写,可能会出现锁竞争问题。Redis 是单线程的,虽然不用考虑锁竞争带来的性能损耗,但是也无法充分利用多核 CPU 来提高整体的吞吐量,只能选择开多个 Redis 进程来解决。
集群方面
Redis 和 Memcached 都支持集群部署。Redis 天然支持高可用集群,支持主从(master-slave)复制,而 Memcache 需要自己实现类似一致性 Hash 的负载均衡算法才能解决集群的问题,扩展性比较低。
多数据库
Redis 单机和主备支持多个数据库,默认 256 个 DB。Proxy 集群和Cluster 集群只支持一个数据库,为 DB0。
Memcached 不支持多数据库。
Lua 脚本支持
Redis 支持 Lua 脚本,而 Memcached 不支持。
技术选型如何抉择?
听起来好像 Redis 功能更多一些,那是不是选 Redis 就完事了呢?
非也,任何技术选型都要结合具体的业务场景来,Memcache 相比 Redis 在内存、线程、IO 角度性能更好,可以有效利用 CPU 硬件资源,但是弊端是支持的数据类型和功能都较为薄弱,且扩展性也不是很友好。
总结:如果公司业务仅要求缓存一些简单的字符串,对持久化、备份、数据迁移、脚本支持等功能没有要求,且并发很高,对吞吐量要求非常严格,可以考虑使用 Memcached ,否则大部分场景下选择 Redis。