写点什么

Redis 缓存知识大集合

作者:阿呆
  • 2023-03-08
    北京
  • 本文字数:2614 字

    阅读完需:约 9 分钟

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 冗余分配内存,可以减少扩容带来的额外的性能消耗。扩容思想:

  1. 长度小于 1M,每次扩容后:len = len * 2

  2. 长度大于 1M,每次扩容增加 1M

  3. 字符串最大长度为 512M

string 指令

# 单个键值对增删改查set key valueget key del key# 批量键值对增删改查mset key value [key value ...]mget key [key ...]# 过期:expire key secondsset key seconds value# 不存在创建,存在不更新setnx key value# 计数,当value是整数时,可以进行自增操作incr key   # 自增1 incryby key increment # 加上increment的值
复制代码

list

list 是一个双向链表,支持前后顺序便利,插入删除快,但查询慢。因而,list 可以用作异步队列,将需要延迟处理的任务放到 redis 队列中,另一个线程读取数据进行处理,但相比 kafka,由于 redis 是内存数据库,虽然有持久化策略,但依然有丢失数据的可能性,并且如果消费失败,无法再次消费,所以使用 redis 当作异步队列,能容忍数据丢失或丢失消费的场景,可以使用,否则还是直接上 kafka 吧。


list 列表的指令:

# 右进左出,队列rpush key value [value, value]  # 右边添加元素llen key  # 获取列表长度lpop key  # 左边获取元素

# 右进右出,栈rpush key value [value, value] # 右边添加元素llen key # 获取列表长度rpop key # 右边获取元素
# 遍历lindex key ind # 获取指定索引处的值lrange key start stop # 获取所有区间的值
复制代码

hash

hash 是根据散列值分布的无序字典,是数组+链表组成的二维结构,当 key 重复时,以链表存储 key 的不同 value,因此 hash 代表一个对象,可以通过不同的 key 存储不同的属性。


hash 字典指令

hset key field value  # 插入值,key表示字典名称,field相当于key, value时key的值mhset key filed value [field value ...] # 批量设置值hget key fieldhgetall keyhlen key  # 获取key的个数
# 对key的value自加操作hincrby key field increment
复制代码


set

set 相当于 python 中的字典,kv 是无序的、唯一的,因此我们可以利用其去重的功能,比如获奖,一个用户不会中奖励两次。


set 指令

# 添加sadd key member [member ...]# 查看smembers key# 获取长度acard key # 获取元素spop key [count]
复制代码


zset

zset 类似于 python 中的有序字典,通过 set 确保内部 value 的唯一,同时通过 value 进行排序。可以用来存储学生成绩,直接用来排名。

redis 淘汰策略

redis 是内存数据库,而我们机器的内存是有限的,当我们的数据量超过物理内存的限制时,就会将内存中的数据和磁盘发生频繁的交换,而在发生磁盘交换时,我们就要考虑将哪些内存中的数据置换到磁盘上,因此 redis 提供了几种数据淘汰策略,用于清理数据。

redis 淘汰策略:

  1. 默认策略:不会继续服务写请求,del 请求可以执行,可读不可写,该策略回导致业务无法继续;

  2. vilatile-lru:套题具有过期时间的 key,最少使用的淘汰;

  3. vilatile-ttl,比较即将过期的时间值(ttl),越小越早淘汰;

  4. volatile-ranndom:随机淘汰有过期时间的 key,不区分频率和过期时间;

  5. allkeys-lry:不区分过期时间,全部 key 通过使用频率淘汰;

  6. 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


发布于: 刚刚阅读数: 4
用户头像

阿呆

关注

坚守准则,认真做事。 2018-05-22 加入

职位:360资深后台开发,主要负责DevOps平台开发 技术:Python 爱好:炉石传说

评论 (1 条评论)

发布
用户头像
TODO:补充缓存击穿等方面的内容
刚刚 · 北京
回复
没有更多了
Redis缓存知识大集合_redis_阿呆_InfoQ写作社区