Redis 缓存知识大集合
简介
本文从以下几方面对 redis 展开:
1、redis 的特性,与其他缓存对比的优劣
2、redis 数据结构:string、hash、set、list、zset 及使用场景
3、redis 淘汰策略:lru、ttl、random 等
4、redis 数据持久化:AOF、RDB
5、redis 高级用法:bitmap、pipline、pub/sub 等等;
6、redis key 失效机制:主动删除、被动删除
7、redis 集群:主从同步、master 选举
8、缓存雪崩和缓存击穿
缓存对比
我们针对 Redis 与 Memcached 进行一个简单的对比,为何大家常用的是缓存是 redis
支持的数据类型:redis 支持 string、hash、set、list、zset 数据,而 memcached 只支持 key-value 数据结构,并可以直接存储图片。
key 的大小:memcached 最大只支持 1M,而 redis 最大支持 1G;
性能:redis 采用单核结构,memcached 采用多核,因此在单核上,由于避免了额外的上下文切换,redis 性能更高,针对更大的数据量,memcached 性能更好,但我们平常数据量也到不了那个量级;
数据持久化:memcached 不支持数据持久化,当故障时数据会丢失,redis 支持多种数据持久化的方式;
因此,redis 相比 memcached 的,支持的数据结构多、能够持久化存储数据、存储大 key,因而应用场景更为广泛,memcached 适用于场景简单,数据结构简单,小型静态数据的缓存场景,只需要直接读取,不做进一步运算和处理,如 html 代码片段。
redis 数据结构
redis 有 5 种数据结构,分别是:
string(字符串)
hash(字典)
list(列表)
set(集合)
zset(有序集合)
string
redis 中最简单的数据结构,内部是一个字符数组,string 是动态字符串,允许修改;结构上的实现类似于 python 中的 array 冗余分配内存,可以减少扩容带来的额外的性能消耗。扩容思想:
长度小于 1M,每次扩容后:len = len * 2
长度大于 1M,每次扩容增加 1M
字符串最大长度为 512M
string 指令
list
list 是一个双向链表,支持前后顺序便利,插入删除快,但查询慢。因而,list 可以用作异步队列,将需要延迟处理的任务放到 redis 队列中,另一个线程读取数据进行处理,但相比 kafka,由于 redis 是内存数据库,虽然有持久化策略,但依然有丢失数据的可能性,并且如果消费失败,无法再次消费,所以使用 redis 当作异步队列,能容忍数据丢失或丢失消费的场景,可以使用,否则还是直接上 kafka 吧。
list 列表的指令:
hash
hash 是根据散列值分布的无序字典,是数组+链表组成的二维结构,当 key 重复时,以链表存储 key 的不同 value,因此 hash 代表一个对象,可以通过不同的 key 存储不同的属性。
hash 字典指令
set
set 相当于 python 中的字典,kv 是无序的、唯一的,因此我们可以利用其去重的功能,比如获奖,一个用户不会中奖励两次。
set 指令
zset
zset 类似于 python 中的有序字典,通过 set 确保内部 value 的唯一,同时通过 value 进行排序。可以用来存储学生成绩,直接用来排名。
redis 淘汰策略
redis 是内存数据库,而我们机器的内存是有限的,当我们的数据量超过物理内存的限制时,就会将内存中的数据和磁盘发生频繁的交换,而在发生磁盘交换时,我们就要考虑将哪些内存中的数据置换到磁盘上,因此 redis 提供了几种数据淘汰策略,用于清理数据。
redis 淘汰策略:
默认策略:不会继续服务写请求,del 请求可以执行,可读不可写,该策略回导致业务无法继续;
vilatile-lru:套题具有过期时间的 key,最少使用的淘汰;
vilatile-ttl,比较即将过期的时间值(ttl),越小越早淘汰;
volatile-ranndom:随机淘汰有过期时间的 key,不区分频率和过期时间;
allkeys-lry:不区分过期时间,全部 key 通过使用频率淘汰;
allkeys-random:所有 key 随机淘汰;
redis 数据持久化
我们都知道,redis 是内存数据库,因此当机器宕机的情况下,内存中的数据都会丢失,因此 redis 为了应当对这种情况,提供了将内存数据持久化到硬盘的机制,redis 支持两种方式的持久化,分别是 RDB 快照和 AOF。
RDB 持久化:按照指定时间间隔,对数据生成时间节点的快照,是官方的默认支持方案;
AOF 持久化:redis 的完全持久化策略,将 redis 数据修改的命令:如 set、hset、del 等操作,按照 redis server 的处理顺序记录在文件中,当重启 redis 时,就能从头读取 AOF 文件中的指令重放,实现将数据恢复到关闭前状态;
优劣对比:
RDB 适合备份,全量复制的场景,数据恢复速度相比 AOF 更快,但 RDB 无法做到实时的持久化,当遇到故障时,一定会丢失数据,AOF 虽然不丢失数据,但恢复速度更慢,且 AOF 文件会比 RDB 文件更大。
redis 高级用法
可以参考:https://developer.aliyun.com/article/790572
TODO:补充这块
redis key 失效机制
由于 redis 可以针对 key 设置过期时间,因此,当超过过期时间后,key 及对应的值会被清除,如何清除失效的 key,redis 有两种机制,分别是:被动失效和主动失效
被动方式:当访问 key 时,发现 key 失效了,则删掉并告知客户端;
主动方式:随机抽取一部分 key 校验,如果失效了则直接删除淘汰,采取这种方案的原因在于:定时遍历一遍 key,耗时过久,不现实;
redis 集群
可以参考腾讯社区的文章:https://cloud.tencent.com/developer/article/1592432
缓存击穿缓存雪崩
TODO:
参考链接
1、redis 与 memcached 差异:https://support.huaweicloud.com/productdesc-dcs/RedisAndMemcachedChoose.html
2、Redis 的 5 种基本数据结构:https://bbs.huaweicloud.com/blogs/303862
3、redis 持久化原理:https://segmentfault.com/a/1190000039208726
版权声明: 本文为 InfoQ 作者【阿呆】的原创文章。
原文链接:【http://xie.infoq.cn/article/29af07751b96a2062ff77cece】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论 (1 条评论)