关于redis和Memcached的比较:
(1).数据结构:
Memcached:主要支持简单的 key-value 数据结构,类似于 Redis 里的 String;
Redis:总共有9种,常见的5种,高级的4种:
String:字符串,最基础的数据类型;
List:列表;
Hash:哈希对象;
Set:集合;
Sorted Set:有序集合,Set 的基础上加了个分值;
HyperLogLog:通常用于基数统计。使用少量固定大小的内存,来统计集合中唯一元素的数量。统计结果不是精确值,而是一个带有0.81%标准差(standard error)的近似值。所以,HyperLogLog适用于一些对于统计结果精确度要求不是特别高的场景,
例如网站的UV统计;
Geo:redis 3.2 版本的新特性。可以将用户给定的地理位置信息储存起来, 并对这些信息进行操作:获取2个位置的距离、根据
给定地理位置坐标获取指定范围内的地理位置集合;
Bitmap:位图;
Stream:主要用于消息队列,类似于 kafka,可以认为是 pub/sub 的改进版。提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
(2).数据存储:
Memcached:数据全部存在内存中,重启实例会导致数据全部丢失;
Redis:通常全部存在内存中,同时支持持久化到磁盘上;
(3).持久化:
Memcached:不支持;
Redis:AOF、RDB、混合持久化;
(4).灾难恢复:
Memcached:实例挂掉后,数据不可恢复;
Redis:实例挂掉后可以通过RDB、AOF恢复 ,但是还是会有数据丢失问题;
(5).事件处理(事件库):
Memcached:使用 Libevent 库;
Redis:自己封装了简易事件库 AeEvent;
(6).过期键删除策略:
常见的有以下三种:
定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。对内存最友好,对 CPU 时间最不友好;
惰性删除:放任键过期不管,但是每次获取键时,都检査键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。对 CPU 时间最优化,对内存最不友好;
定期删除:每隔一段时间,默认100ms,程序就对数据库进行一次检査,删除里面的过期键。至 于要删除多少过期键,以及要检査多少个数据库,则由算法决定。前两种策略的折中,对 CPU 时间和内存的友好程度较平衡;
Memcached:惰性删除
Redis:惰性删除+定期删除
(7).内存驱淘汰(驱逐)策略:
当内存空间已经用满时,服务实例将将根据配置的驱逐策略,进行相应的动作。
memcached:主要为 LRU 算法
redis:当前总共有以下8种:
noeviction:默认策略,不淘汰任何 key,直接返回错误
allkeys-lru:在所有的 key 中,使用 LRU 算法淘汰部分 key
allkeys-lfu:在所有的 key 中,使用 LFU 算法淘汰部分 key
allkeys-random:在所有的 key 中,随机淘汰部分 key
volatile-lru:在设置了过期时间的 key 中,使用 LRU 算法淘汰部分 key
volatile-lfu:在设置了过期时间的 key 中,使用 LFU 算法淘汰部分 key
volatile-random:在设置了过期时间的 key 中,随机淘汰部分 key
volatile-ttl:在设置了过期时间的 key 中,挑选 TTL(time to live,剩余时间)短的 key 淘汰
(8).性能:
首先,影响性能比较的因素有很多,网络带宽、CPU、内存等等,所以其实很多测试并不能完全说明问题,可能在这个条件下 Redis 快,而在另一个条件下是 Memcached 快;
Redis 作者 antirez 在 12 年左右在 Stack Overflow 上谈过两者的性能问题,他是这么说的:由于 Redis 只使用单核,而 Memcached 可以使用多核,所以在比较上:在处理小数据时,平均每一个核上 Redis 比 Memcached 性能更高,而在 100k 左右的大数据时, Memcached 性能要高于 Redis;
antirez 的这个说法是按“CPU 单核”维度来比较,但是我们在实际的使用中,肯定是按“实例”维度来使用,所以接下来
我们探讨下对于两者在“实例”维度的比较;
按“实例”维度进行比较时,个人认为由于 Memcached 多线程的特性,在 Redis 6.0 之前,通常情况下 Memcached 性能是要高于 Redis 的,同时实例的 CPU 核数越多,Memcached 的性能优势越大;
而在 Redis 6.0 支持 I/O 多线程后,当 Redis 关闭持久化后,两者在性能上可能会比较接近
(9).关于两者的技术选型,该如何选择?
看完上面的比较,其实不难做出选择,99%的人、场景,或者说 Redis 能支持的场景,使用 Redis 基本不会有问题;
而且就最近几年的发展来看,Redis 可谓风光无限,而 Memcached 则是已经逐渐跟不上 Redis 脚步了,这也侧面
反映了当前大家的选择都是趋向于使用 Redis;
而关于使用 Memcached 的场景,我自己了解到的一些线上真实使用场景都是对于性能有非常高的要求;
Redis 6.0 支持的 I/O 阶段多线程目前根据官方说法至少能提升性能1倍,随着 Redis 在性能上的不断优化,可能后续 Memcached 的使用场景会越来越少了