redis简介与基本使用 | 青训营

210 阅读23分钟

本笔记是学习字节后端青训课程与网上学习了解所写,简单介绍redis与基本的使用流程

1. redis的简介

1.1 redis的定义

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串哈希表列表集合有序集合位图hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区

1.2 redis的功能

可以减轻数据库压力,查询内存比查询数据库效率高

1.3 应用场景

缓存系统

redis具有非常优秀的读写性能,常用作缓存cache系统,用来提高系统负载能力和响应速度。

分布式锁

redis支持setnx操作(即key不存在的情况下设置value),这种特性常用来做分布式锁的实现。

配置中心

redis提供key/value的查询、存储机制,也提供了watch机制,可以很方便的实现一个配置中心。

消息系统

redis的Pub/Sub功能用作简单的消息系统

分布式场景

redis不仅支持数据持久化,还支持集群化的协同方式,这些特性很好的支持了分布式设计的一些要求(支持扩容和高可用)。

排行榜、热搜、秒杀等

redis内置一些数据结构,可以很方便的解决各式各样的热点数据访问问题。

2. redis的安装与配置

2.1 安装

  1. 配置Linux环境
  2. 配置gcc编译环境
  3. 官网下载tar.gz包,tar -zxvf解压,进入解压目录执行make && make install image.png
  4. 默认安装路径/usr/local/bin
  5. 安装好的文件 image.png
  • redis-server  redis服务器
  • redis-cli  redis命令行客户端
  • redis-benchmark  redis性能测试工具
  • redis-check-aof aof  文件修复工具
  • redis-check-dump rdb  文件检查工具
  • redis-sentinel Redis Sentinel是一个分布式的架构,每一个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当发现某个节点无法到达的时候,会自动标识该节点。如果这个节点是主节点,那么它会和其他 Sentinel 节点“协商”,大部分节点都认为主节点无法到达的时候,它们会选举一个 Sentinel 节点来完成自动故障转移,同时会告知 Redis 的应用方。

2.2 配置

修改配置文件redis.conf 设置密码 requirepass 密码 修改daemonize no为daemonize yes 使用 yes 启用守护进程 注释掉 bind 127.0.0.1 绑定本地主机 修改 protected-mode yes 为projected-mode no

3.0 使用redis

3.1 启动redis服务

redis-server 配置文件目录 redis-cli -a 密码 -p 端口号(默认为6379)

3.2 关闭redis服务

在redis命令行内shotdown命令 远程关闭redis-cli -a 密码 -p 端口号 shotdown

3.3 redis命令行的key操作

  • keys * 获取本数据库的所有key
  • get key 获取key对应的值
  • del key 删除key-value(删除成功为1,否则为0)
  • unlink key 非阻塞删除,将key从keyspace元数据空间中删除,真正的删除在后台异步操作
  • dbsize 获取本数据库的key的数量
  • exists key 查看key是否存在(1存在,0不存在)
  • expire key seconds 设置过期时间(单位为秒)
  • ttl key 获取key剩余过期时间 返回值-1说明没有设置过期时间(即永不过期), -2 则表示过期
  • type key 返回对应value的数据类型
  • select 数据库编号 redis默认有16个数据库,编号为0-15,默认为0号
  • move key 数据库编号 移动k-v到数据库
  • flushdb 清空当前数据库
  • flushall 清空所有数据库

命令行操作详情: (http://www.redis.cn/topics/rediscli.html)

4. redis数据类型

命令不区分大小写,key严格区分大小写

获取帮助文档: help @数据类型

数据类型指的是value的类型,key一般为string

4.1 string

Redis 的字符串叫做「SDS」,也就是 Simple Dynamic String。它的结构是一个带长度信息的字节数组

struct SDS<T> {
    T capacity; // 数组容量 使用泛型表示的 
    T len; // 数组长度 使用泛型表示的 
    byte flags; // 特殊标识位,不理睬它 
    byte[] content; // 数组内容 字节数组 
}
content 里面存储了真正的字符串内容
capacity 表示所分配数组的长度
len 表示字符串的实际长度

当字符串长度小于 1M 时,扩容都是加倍现有的空间
超过 1M,扩容时一次只会多扩 1M 的空间
字符串最大长度为 512M
  1. set key value [NX|XX] [GET] [EX seconds|PX milliseconds|EXAT unix-time-seconds|PXAT unix-time-milliseconds|KEEPTTL]
  • nx 键不存在,才可以成功
  • xx 键存在才可以成功,用于更新
  • get 更新前返回key对应value,并更新为新的value
  • ex 过期时间,单位秒
  • px 设置毫秒级过期时间
  • exat 以unix时间戳设置过期时间,单位秒
  • pxat 以unix时间戳设置过期时间,单位毫秒
  • keepttl 更新值时保留过期时间,没有这个参数更新后原先的过期时间失效
  1. mset key value [key value] 批量设置key
  2. mget key [key] 批量获取值
  3. msetnx key value [key value] 批量设置key,所有都键不存在,才可以成功
  4. 当value值数字时,incr key(递增)/incrby key 数字(增加指定数字)/decr为递减
  5. getrange key start end 获取指定范围的字符串
  6. SETRANGE key offset value 用value取代从offset开始的等长的字符串
  7. strlen key 获取字符串大小
  8. append key value 追加
  9. getset先get再set 等同于set后接get参数

4.2 list

列表即一个key对应多个value,

Redis的List列表底层双向链表结构,经常用于实现堆栈和队列。双向链表结构在存储时,有一个前结点,有一个后结点。可以进行双端操作

一个列表的最大长度可放2^32-1(4294967295)个元素

  1. LPUSH/RPUSH key element [element ...] 左插和右插,key不存在则创建,存在则添加元素
  2. LRANGE key start stop 遍历列表
  3. LPOP/RPOP key [count] 从左边/右边弹出并删除count个元素
  4. lindex key index 按索引获取元素
  5. llen key 获取列表中元素个数
  6. lrem key count element 删除count个element
  7. ltrim key start stop 截取指定范围内的值后赋给key
  8. rpoplpush source destination 从右边弹出source的一个元素,左插到destination
  9. lset key index element 按索引赋值
  10. linsert key BEFORE|AFTER pivot element 在列表中pivot的前面后面插入element

4.3 hash

hash的k-v模式保持不变,但v是键值对组

  1. hset/hmset key field value [field value ...] key不存在则创建,存在则添加元素
  2. hget key field 获取值
  3. hmget key field [field ...] 获取值
  4. hgetall key 获取所有值
  5. hdel key 删除hash
  6. hlen 获取hash内的键值对的数量
  7. HEXISTS key field 判断hash内filed是否存在
  8. hkeys/hvals key 获取hash内所有的键和值
  9. hincrby/hincrbyfloat key field increment 给相应字段加increment
  10. hsetnx key field value field字段不存在赋值,存在无效

4.4 set

set为单值多value,但value不重复,会自动去重

  1. sadd key member [member ...] key不存在则创建,存在则添加元素
  2. SMEMBERS key 显示集合中所有元素
  3. srem key member [member ...] 删除集合中的元素
  4. SISMEMBER key member 判断集合中是否存在该元素
  5. scard key 获取集合内元素的个数
  6. SRANDMEMBER key [count] 随机展示集合内的几个元素
  7. SPOP key [count] 随机展示并删除集合内的几个元素
  8. smove source destination member 将soucrce中的member移到destination
  9. sdiff/sunion/sinter key1 key2 集合的差并交运算
  10. SINTERCARD numkeys key [key ...] [LIMIT limit] numskeys为参与运算的集合个数,limit为限制结果 此命令返回交集元素的个数

4.5 zset

zset(有序集合)中的成员是有序排列的,它和 set 集合的相同之处在于,集合中的每一个成员都是字符串类型,并且不允许重复;而它们最大区别是,有序集合是有序的,set 是无序的这是因为有序集合中每个成员都会关联一个 double(双精度浮点数)类型的 score (分数值),Redis 正是通过 score 实现了对集合成员的排序。

  1. zadd key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...] 添加元素
  2. ZRANGE key start stop [BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES] 获取元素
  3. ZREVRANGE key start stop [WITHSCORES] 反转获取元素
  4. ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 获取在指定区间的元素
  5. ZSCORE key member 获取元素分数
  6. ZCARD key 获取元素个数
  7. ZREM key member [member ...] 删除元素
  8. ZINCRBY key increment member 给指定元素增加分数
  9. ZCOUNT key min max 获取指定区间内元素的个数
  10. zmpop numkeys key [key ...] MIN|MAX [COUNT count] 删除元素
  11. zrank key member [WITHSCORE] 获取元素下标
  12. ZREVRank key member [WITHSCORE] 逆序获取元素下标

4.6 bitmap位图

BitMap 原本的含义是用一个比特位来映射某个元素的状态。由于一个比特位只能表示 0 和 1 两种状态,所以 BitMap 能映射的状态有限,但是使用比特位的优势是能大量的节省内存空间。

在 Redis 中,可以把 Bitmaps 想象成一个以比特位为单位的数组,数组的每个单元只能存储0和1,数组的下标在 Bitmaps 中叫做偏移量。

image.png BitMap在Redis 中并不是一个新的数据类型,其底层是string 实现。

  1. setbit key offset value 设置偏移量的值,偏移量从0开始算起
  2. getbit key offset 获取偏移量的值
  3. strlen key 获取位图所占的字节
  4. bitcount key [start end [BYTE|BIT]] 统计bitmap中1的数量
  5. bitop AND|OR|XOR|NOT destkey key [key ...] 位操作

4.7 Hyperloglog

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。不会存储输入元素本身

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

核心是基数估算算法,主要表现为计算时内存的使用和数据合并的处理。最终数值存在一定误差。 误差说明:基数估计的结果是一个带有 0.81% 标准错误(standard error)的近似值。是可接受的范围。

  1. pfadd key [element [element ...]] 添加元素
  2. pfcount key [key ...] 统计hyperloglog的基数
  3. PFMERGE destkey [sourcekey [sourcekey ...]] 合并hyperloglog

4.8 GEO地理空

edis geo并不是全新的数据结构,而是基于Sorted Set来实现的。经度的范围是[-180,180],纬度的范围是[-90,90],当我们对经纬度进行编码时,先对经度和纬度分别进行GeoHash编码,然后再合并为一个编码值,做为zset的score

对于经度或纬度来说,GeoHash会将其编码为一个N为的二进制值,其实就是通过N次的分区得到的,N可以自定义。下面是具体的逻辑:

  • 第一次分区:我们把经度范围[-180,180]分为两个区间[-180,0) 和[0,180],简称为左右区间。看当前的经度值落在哪个区间中,如果在左区间,记为一次0,否则记为1,这样我们就得到一位编码值了。

  • 第二次分区:假设第一次落在了[0,180]区间内,我们再把该区间分为两个区间[0,90) 和[90,180],然后再根据落在左右区间,得到一个0或者1的编码值。

  • 重复N次之后,我们就得到了N个编码值。纬度也是一样的逻辑,可以得到N个编码值。

从上面的过程可以看出,在划分区间的过程中,我们其实是把整个空间划分成了一个一个的小方格。对经度和纬度分别做一次二分区的话,就会得到四个分区。这 4 个分区对应了 4 个方格,每个方格覆盖了一定范围内的经纬度值,分区越多,每个方格能覆盖到的地理空间就越小,也就越精准。我们把所有方格的编码值映射到一维空间时,相邻方格的 GeoHash 编码值基本也是接近的

  1. geoadd key [NX|XX] [CH] longitude latitude member [longitude latitude member ...] 添加地理位置的坐标
  2. geopos key [member [member ...]] 获取地理位置的坐标
  3. geodist key member1 member2 [M|KM|FT|MI] 计算两个位置之间的距离。
  4. GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
    • 半径以下列单位之一指定:m为米,km为千米,mi为英里,ft为英尺。

    • WITHDIST:还要返回指定中心返回物品的距离。距离以与指定为命令的半径参数的单位相同的单位返回。

    • WITHCOORD:还返回匹配项目的经度,纬度坐标。

    • WITHHASH:还以52位无符号整数的形式返回项目的原始 geohash 编码的有序集合分数。这只对低级别的黑客或调试很有用,对于普通用户来说这很有趣。

    • 该命令的默认设置是返回未排序的项目。使用以下两个选项可以调用两种不同的排序方法: ASC将返回的项目从最近的到最远的,相对于中心排序。DESC从最远到最近的相对于中心的返回项目排序

    • 默认情况下会返回所有匹配的项目。通过使用 COUNT <count> 选项,可以将结果限制为前 N 个匹配项。但是请注意,在内部,命令需要执行与匹配指定区域的项目数量成比例的努力,因此,COUNT即使只返回几个结果,使用非常小的选项查询非常大的区域也可能会很慢。另一方面,COUNT如果通常只使用第一个结果,则可以成为减少带宽使用的非常有效的方法。

  5. GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
  6. geohash key [member [member ...]] 返回一个或多个位置对象的 geohash 值。

4.9 redis流stream

Redis Stream 是 Redis 5.0 版本新增加的数据结构。

Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。

简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。

而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。

Redis Stream 的结构如下所示,它有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容:

image.png 每个 Stream 都有唯一的名称,它就是 Redis 的 key,在我们首次使用 xadd 指令追加消息时自动创建。

上图解析:

  • Consumer Group :消费组,使用 XGROUP CREATE 命令创建,一个消费组有多个消费者(Consumer)。
  • last_delivered_id :游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。
  • pending_ids :消费者(Consumer)的状态变量,作用是维护消费者的未确认的 id。 pending_ids 记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符)。

消息队列相关命令:

  • XADD  添加消息到末尾

    xadd key [NOMKSTREAM] [MAXLEN|MINID [=|~] threshold [LIMIT count]] *|id field value [field value ...]

    1. 新元素的ID必须比流中所有已有元素的ID都要大,redis会进行检测,一次命令生成一次消息ID,即一次只能添加一个消息
    2. *表示系统自动生成id ,也可以自己手动指定ID
    3. ID是由-隔开的两个数字组成的:1526919030474-55,前面是系统时间的毫秒值,后面是一个64位的整数
  • XTRIM 对流进行修剪,限制长度

    xtrim key MAXLEN|MINID [=|~] threshold [LIMIT count]

  • XDEL 删除消息

    xdel key id [id ...]

  • XLEN 获取流包含的元素数量,即消息长度

    xlen key

  • XRANGE 获取消息列表,会自动过滤已经删除的消息

    xrange key start end COUNT count

  • XREVRANGE 反向获取消息列表,ID 从大到小

    xrevrange key end start [COUNT count]

  • XREAD 以阻塞或非阻塞方式获取消息列表

    xread [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]

    1. block参数表示阻塞,0表示永远阻塞
    2. count参数表示获取消息的数量
    3. streams为固定参数,key为流的名称

消费者组相关命令:

  • XGROUP CREATE 创建消费者组

    xgroup create key group id|$ [MKSTREAM] [ENTRIESREAD entries-read]

    1. key为队列名称,group为创建消费者组名,id|指定从哪条消息开始消费,指定从哪条消息开始消费,表示最后一条消息
    2. MKSTREAM:自动创建不存在的长度为0的stream;(默认不存在stream将报错)
    3. ENTRIESREAD:指定group的entries_read参数,启用对任意ID(不是stream第一个或者最后一个或者0-0的ID)的消费组延迟(lag)追踪,意思是设置group的entries_read来间接设置group的lag,有可能你不知道具体ID(读取该ID后的数据)但可能明确知道需要从steam的倒数第几条开始group读取(将entries_read设置为entries-added减去倒数条数即可);(group的entries_read计数表示steam的group里已经被消费者读取条目数,steam的entries-added计数表示添加到steam里的条目数,group的lag表示消费者还未取走的条目数)
  • XREADGROUP GROUP 读取消费者组中的消息

    XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] id [id ...]

    1. [COUNT count]设置获取消费消息数量;
    2. [BLOCK milliseconds]设置阻塞等待时间(ms)(通常跟>一起使用获取新消息);
    3. [ID ...]读取id之后的消息,id为0可获取已读但未确认的消息(可多次消费,不会获得未读取的消息),id为>表示读取组内未读取的消息(同组内成员会消费不同消息);
    4. 可在consumer和STREAMS之间加入noAck选项,使消费的消息不加入pending列表;
  • XACK 将消息标记为"已处理"

    xack key group id [id ...]

  • XGROUP SETID 为消费者组设置新的最后递送消息ID

    XGROUP SETID key group id|$ [ENTRIESREAD entries-read]

  • XGROUP DELCONSUMER 删除消费者

    XGROUP DELCONSUMER key group consumer

  • XGROUP DESTROY 删除消费者组

    XGROUP DESTROY key group

  • XPENDING 显示待处理消息的相关信息

    XPENDING key group [[IDLE min-idle-time] start end count [consumer]]

    1. [start end count]设置查询起始id,结束id,数量;
    2. [consumer]可以指定消费者;
    3. 返回值4行:消息id;消费者;最后消费时间距离现在经过的ms时间;消费次数;
  • XINFO GROUPS 打印消费者组的信息;

  • XINFO STREAM 打印流信息

    XINFO STREAM key [FULL [COUNT count]]

4.10 bitfied位域

BITFIELD可以将一个 Redis 字符串看作是一个由二进制位组成的数组, 并对这个数组中任意偏移进行访问

BITFIELD命令可以在一次调用中同时对多个位范围进行操作:它接受一系列待执行的操作作为参数,并返回一个数组,数组中的每个元素就是对应操作的执行结果。   命令基本语法如下:BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]

  • GET <type> <offset> -- 返回指定的二进制位范围。
  • SET <type> <offset> <value> -- 对指定的二进制位范围进行设置,并返回它的旧值。
  • INCRBY <type> <offset> <increment> -- 对指定的二进制位范围执行加法操作,并返回它的旧值。可以通过向 increment 参数传入负值来实现相应的减法操作。
  • OVERFLOW [WRAP|SAT|FAIL]
    • WRAP: 使用回绕(wrap around)方法处理有符号整数和无符号整数的溢出情况。对于无符号整数来说,回绕就像使用数值本身与能够被储存的最大无符号整数执行取模计算,这也是 C 语言的标准行为。对于有符号整数来说,上溢将导致数字重新从最小的负数开始计算,而下溢将导致数字重新从最大的正数开始计算。比如说,如果我们对一个值为 127 的 i8 整数执行加一操作,那么将得到结果 -128。
    • SAT: 使用饱和计算(saturation arithmetic)方法处理溢出,也即是说,下溢计算的结果为最小的整数值,而上溢计算的结果为最大的整数值。举个例子,如果我们对一个值为 120 的 i8 整数执行加 10 计算,那么命令的结果将为 i8 类型所能储存的最大整数值 127 。与此相反,如果一个针对 i8 值的计算造成了下溢,那么这个 i8 值将被设置为 -127 。
    • FAIL: 在这一模式下,命令将拒绝执行那些会导致上溢或者下溢情况出现的计算,并向用户返回空值表示计算未被执行。

当被设置的二进制位范围值为整数时,用户可以在类型参数的前面添加 i 来表示有符号整数, u 来表示无符号整数。 比如说,我们可以使用 u8 来表示 8 位长的无符号整数,也可以使用 i16 来表示 16 位长的有符号整数。

命令最大支持 64 位长的有符号整数以及 63 位长的无符号整数,其中无符号整数的 63 位长度限制是由于 Redis 协议目前还无法返回 64 位长的无符号整数而导致的。

在二进制位范围命令中,用户有两种方法来设置偏移量:如果用户给定的是一个没有任何前缀的数字,那么这个数字指示的就是字符串以零为开始(zero-base)的偏移量。

如果用户给定的是一个带有 # 前缀的偏移量,那么命令将使用这个偏移量与被设置的数字类型的位长度相乘,从而计算出真正的偏移量。例如:There are two ways in order to specify offsets in the bitfield command.

BITFIELD mystring SET i8 #0 100 SET i8 #1 200

命令会把 mystring 里面,第一个 i8 长度的二进制位的值设置为100 并把第二个 i8 长度的二进制位的值设置为 200 。当我们把一个字符串键当成数组来使用,并且数组中储存的都是同等长度的整数时,使用 # 前缀可以让我们免去手动计算被设置二进制位所在位置的麻烦。

5. redis持久化

Redis之所以快,一个最重要的原因在于它是直接将数据存储在内存,并直接从内存中读取数据的,因此一个绝对不容忽视的问题便是,一旦Redis服务器宕机,内存中的数据将会完全丢失。 ​

好在Redis官方为我们提供了两种持久化的机制,RDB和AOF

5.1 redis的RDB持久化

5.1.1 RDB是什么

RDB是Redis的一种数据持久化到磁盘的策略,是一种以内存快照形式保存Redis数据的方式。所谓快照,就是把某一时刻的状态以文件的形式进行全量备份到磁盘,这个快照文件就称为RDB文件,其中RDB是Redis DataBase的缩写。RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

image.png

5.1.2 RDB的触发

5.1.2.1 自动触发

自动触发是由我们的配置文件来完成的。在redis.conf配置文件中,里面有如下配置,我们可以去设置:

  1. save: 这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save [ ...]”。表示m秒内数据集存在n次修改时,自动触发bgsave。

    默认如下配置:

    save 3600 1 300 100 60 10000
    

    不需要持久化,那么你可以注释掉所有的 save 行或者save ""来停用保存功能。

  2. stop-writes-on-bgsave-error : 默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了

  3. rdbcompression ; 默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。

  4. rdbchecksum : 默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

  5. dbfilename : 设置快照的文件名,默认是 dump.rdb

  6. dir: 设置快照文件的存放路径,这个配置项一定是个目录(已存在),而不能是文件名。

5.1.2.2 手动触发

save触发方式

该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。具体流程如下:

image.png

执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取。

bgsave触发方式

执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下: image.png 具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

5.1.2.3 其他触发

  1. 如果从节点执行全量复制操作,主节点自动执行BGSAVE生成RDB文件并发送给从节点。
  2. 执行debug reload命令重新加载Redis时,也会自动触发save操作。
  3. 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行BGSAVE。
  4. 执行flashdb与falshall时也会触发RDB,但保存的rdb文件内数据为空(即保存删除那刻的数据)

5.1.3 RDB恢复数据与rdb文件修复

  1. 关闭redis服务

  2. 修改配置文件,将appendonly 设置成no,redis启动时会把dir目录(rdb文件保存路径)下的dump.rdb 中的数据恢复。由于新生成的rdb文件会覆盖旧的,应对rdb文件进行备份

  3. 重启redis服务