首页 > 首页 > 数据库 > 非关系型数据库 > Redis > [ Redis ] 重要知识点备忘录
2024
05-29

[ Redis ] 重要知识点备忘录

Redis 所有历史版本更新信息

3.2 版本:https://raw.githubusercontent.com/antirez/redis/3.2/00-RELEASENOTES
4.0 版本:https://raw.githubusercontent.com/antirez/redis/4.0/00-RELEASENOTES
5.0 版本:https://raw.githubusercontent.com/antirez/redis/5.0/00-RELEASENOTES
6.0 版本:https://raw.githubusercontent.com/antirez/redis/6.0/00-RELEASENOTES
7.0 版本:https://raw.githubusercontent.com/antirez/redis/7.0/00-RELEASENOTES

Redis 如何确认两个节点数据迁移完成

1、输入info keyspace,分别查看源和目的节点的keys参数和expires参数的值。
2、对比源Redis和目标Redis的keys参数分别减去expires参数的差值。如果差值一致,表示数据完整,迁移正常。

PS:如果key 有设置过期时间,上面对比的值是时刻会变化的,不一定非常准确

慢查询参数详解

Redis对应提供了两个参数:slowlog-log-slower-than和slowlog-max-len,接下来我们详细介绍一下这两个参数。

slowlog-log-slower-than

slowlog-log-slower-than的作用是指定命令执行时长的阈值,执行命令的时长超过这个阈值时就会被记录下来。它的单位是微秒(1秒 = 1000毫秒 = 1000000微秒),默认是10000微秒。如果把slowlog-log-slower-than设置为0,将会记录所有命令到日志中。如果把slowlog-log-slower-than设置小于0,将会不记录任何命令到日志中。

在实际的生产环境中,需要根据Redis并发量来调整该配置。因为Redis采用单线程响应命令,如果命令执行时间在1000微秒以上,那么Redis最多可支撑OPS不到1000,所以对于高并发场景的Redis建议设置为1000微秒。

slowlog-max-len

slowlog-max-len的作用是指定慢查询日志最多存储的条数。实际上,Redis使用了一个列表存放慢查询日志,slowlog-max-len就是这个列表的最大长度。当一个新的命令满足满足慢查询条件时,被插入这个列表中。当慢查询日志列表已经达到最大长度时,最早插入的那条命令将被从列表中移出。比如,slowlog-max-len被设置为10,当有第11条命令插入时,在列表中的第1条命令先被移出,然后再把第11条命令放入列表。

记录慢查询是Redis会对长命令进行截断,不会大量占用大量内存。在实际的生产环境中,为了减缓慢查询被移出的可能和更方便地定位慢查询,建议将慢查询日志的长度调整的大一些。比如可以设置为2000以上。

如何进行配置
在Redis中有两个修改配置的方法:

1、修改Redis配置文件。比如,把slowlog-log-slower-than设置为1000,slowlog-max-len设置为2000:

slowlog-log-slower-than 1000
slowlog-max-len 1200

2、使用config set命令动态修改。比如,还是把slowlog-log-slower-than设置为1000,slowlog-max-len设置为2000:

redis-cli -h ip -p port config set slowlog-log-slower-than 1000
redis-cli -h ip -p port config set slowlog-max-len 2000

AOF持久化参数详解

默认参数:
auto-aof-rewrite-min-size 64M #设置触发aof的最小尺寸
auto-aof-rewrite-percentage 100 #达到重写的百分比

当AOF文件大于64MB时,并且AOF文件当前大小比基准大小增长了100%时会触发一次AOF重写。那么基准大小如何确定呢?起始的基准大小为Redis重启并加载完AOF文件之后,aof_buf的大小。当执行完一次AOF重写之后,基准大小相应更新为重写之后AOF文件的大小。

触发条件

  • 没有BGSAVE命令(RDB持久化)/BGREWRITEAOF命令(AOF持久化)在执行;
  • 当前AOF文件大小要大于server.aof_rewrite_min_size(默认为1MB),或者在redis.conf配置了auto-aof-rewrite-min-size大小;
  • 当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比(在配置文件设置了auto-aof-rewrite-percentage参数,不设置默认为100%)

如果前面三个条件都满足,并且当前AOF文件大小比最后一次AOF重写时的大小要大于指定的百分比,那么触发自动AOF重写。

自动触发重写计算规则
运行指令info Persistence获取具体信息
# /opt/redis/bin/redis-cli -h ip -p port info Persistence | egrep "aof_current_size|aof_base_size"
aof_current_size:53265813545
aof_base_size:7433364454

[ Redis ] 重要知识点备忘录 - 第1张  | 架构迷

AOF重写流程

 非重写流程(always/everysec)

[ Redis ] 重要知识点备忘录 - 第2张  | 架构迷

重写流程

[ Redis ] 重要知识点备忘录 - 第3张  | 架构迷

手动故障转移方法和原理

在什么情况下,需要进行手动故障转移呢?比如:我们原来master机器配置比较低,现在需要升级了,这个master对应的slave配置比较高,我们就可以,将对应配置搞得slave通过手动故障转移方式,提升成master节点。

利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。

①:slave节点会告知对应master节点,拒绝任何客户端请求;

②:master会返回当前自己数据最新的offset给slave;

③:slave会判断自己offset与master是否一致。如果不一致,需要同步master,将offset同步与master一致;

④:slave开始故障转移;master也开始故障转移;

⑤:slave标记自己为master,广播故障转移结果(对应的master及其他的master)

⑥:当slave对应master收到slave故障转移的结果后,开始处理客户端请求。

其执行流程如下图所示:

[ Redis ] 重要知识点备忘录 - 第4张  | 架构迷

这种failover命令可以指定三种模式:

1:缺省:默认的流程。如上图中1~6步

2:force:省略了对offset的一致性校验步骤

用于当主节点宕机且无法自动完成故障转移情况。从节点接到cluster failover force请求时,从节点直接发起选举,不再跟主节点确认复制偏移量(从节点复制延迟的数据会丢失),当从节点选举成功后替换为新的主节点并广播集群配置。

3:takeover:直接执行第五步,忽略数据一致性、忽略master状态和其他master的意见。

用于集群内超过一半以上主节点故障的场景,因为从节点无法收到半数以上主节点投票,所以无法完成选举过程。可以执行cluster failover takeover强制转移,接到命令的从节点不再进行选举流程而是直接更新本地配置纪元并替换主节点。

takeover故障转移由于没有通 过领导者选举发起故障转移,会导致配置纪元存在冲突的可能。当冲突发生时,集群会以nodeId字典序更大的一方配置为准。因此要小心集群分区后,手动执行takeover导致的集群冲突问题。

redis cluster 集群如何让多个 key 落到一个slot 槽里面 ?

对于类似mset,mget这样的多个key的原生批量操作命令,redis集群只支持所有key落在同一slot的情况,如果有多个key一定要用mset命令在redis集群上操作,则可以在key的前面加上{XX},这样参数数据分片hash计算的只会是大括号里的值,这样能确保不同的key能落到同一slot里去,示例如下:

mset {user1}:1:name zhangsan {user1}:1:age 18

假设name和age计算的hash slot值不一样,但是这条命令在集群下执行,redis只会用大括号里的 user1 做hash slot计算,所以算出来的slot值肯定相同,最后都能落在同一slot。

Redis 数据淘汰策略

在Redis中,处理内存满载的情况是通过配置特定的淘汰策略来实现的。根据Redis官方文档的介绍(Redis Eviction Policies),当达到maxmemory限制时,Redis的行为是通过maxmemory-policy配置指令来设定的。通过在配置文件中设置maxmemory-policy来选择适合业务需求的淘汰策略。

maxmemory-policy noeviction // 默认策略,不淘汰数据,只允许读操作,不允许写操作

以下是官方提供的8种淘汰策略的说明,这8种策略可分为「不进行数据淘汰」和「进行数据淘汰」两类策略。

1、不进行数据淘汰的策略

noeviction(Redis3.0之后,默认的内存淘汰策略) :它表示当运行内存超过最大设置内存时,不淘汰任何数据,这时如果有新的数据写入,会报错通知禁止写入,不淘汰任何数据,但是如果没用数据写入的话,只是单纯的查询或者删除操作的话,还是可以正常工作。

2、进行数据淘汰的策略

针对「进行数据淘汰」这一类策略,又可以细分为「在设置了过期时间的数据中进行淘汰」和「在所有数据范围内进行淘汰」这两类策略。

a)在设置了过期时间的数据中进行淘汰:

  • volatile-random:随机淘汰设置了过期时间的任意键值;
  • volatile-ttl:优先淘汰更早过期的键值。淘汰即将过期的键,即选择生存时间(TTL)最短的键优先删除。
  • volatile-lru(Redis3.0 之前,默认的内存淘汰策略):淘汰所有设置了过期时间的键值中,最久未使用的键值;
  • volatile-lfu(Redis 4.0 后新增的内存淘汰策略):淘汰所有设置了过期时间的键值中,最少使用的键值;利用LFU计数器跟踪键的访问频次,较少访问的键更可能被选中淘汰。

b)在所有数据范围内进行淘汰:

  • allkeys-random:随机淘汰任意键值;对所有键进行随机选择并删除,不考虑访问频率或过期时间。
  • allkeys-lru:淘汰整个键值中最久未使用的键值;不区分键是否设置过期时间;适用于希望在整体数据集层面维持热点数据的场景。
  • allkeys-lfu(Redis 4.0 后新增的内存淘汰策略):淘汰整个键值中最少使用的键值。同样利用LFU计数器,但决策范围扩大至整个数据集。

3、Redis淘汰流程

Redis的淘汰流程是一个精心设计的过程,旨在高效地管理内存使用。以下是详细的淘汰流程:

初始化淘汰池:Redis维护一个淘汰池,默认大小为16。这个池子采用末尾淘汰制,即最不适合保留的数据会被放置在池子的末尾。

内存检查:每次执行指令前,Redis会自旋检查当前可用内存是否足够执行该指令。

内存不足时的处理:

如果内存不足以执行指令,Redis会从淘汰池的尾部选择一个最合适的候选数据进行淘汰。

取样过程:为了提高效率,Redis不会检查所有数据,而是通过配置maxmemory-samples参数来随机选取一定数量的样本数据。

选择淘汰数据:在这些样本数据中,根据配置的淘汰算法(如LRU或LFU),找到最应该被淘汰的数据。

比较与替换:将找到的最适合淘汰的数据与淘汰池中的数据进行比较,如果它比淘汰池中的任何数据更适合淘汰,则将其放入淘汰池。

排序:淘汰池中的数据会根据适合淘汰的程度进行排序,最应该淘汰的数据被放置在池子的尾部。

淘汰数据:最终,被选为淘汰的数据会被从Redis中删除,并且从淘汰池中移除。

淘汰池的设计意义在于它提高了数据淘汰的精准度。由于淘汰池中只保留了每次取样后最适合淘汰的16个数据,这确保了Redis在内存紧张时能够高效、精确地释放空间。

最后编辑:
作者:摘星怪
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。