Redis
Redis
安装-启动
-
gz
压缩包安装 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21# 可以直接写入脚本文件中一次执行
# 安装依赖、安装 gcc: c/c++ 编译器
yum install -y gcc tcl gcc-c++
# 指定安装位置问题: 解压的 tar 文件的放置位置就是安装路径,配置文件等全在此处
# 下载 redis gz 镜像地址 选择所需版本
https://mirrors.huaweicloud.com/redis/
# 下载 6.2.4
wget https://mirrors.huaweicloud.com/redis/redis-6.2.4.tar.gz
# 解压
tar -zxvf redis-6.2.4.tar.gz
# 进入目录
cd redis-6.2.4.tar.gz
# 编译
make
# 如果 make出错,则执行如下 (执行清理命令), 之后再次执行 make
make distclean
# 在 make 执行后再执行 make install 该操作则将 src 下的许多可执行文件复制到 /usr/local/bin 目录下,这样做可以在任意目录执行 redis 的软件命令 (例如: 启动、停止、客户端连接服务器等)
make install -
make install
make-install
执行作用 (默认的安装路径) -
前台启动
不推荐,
占用整个控制台 前台启动 ( redis-server
)-
后台启动
redis
服务 1
2# 备份 redis.conf(解压后的目录中)
cp redis.conf redis.conf.default1
2
3
4
5
6
7
8
9
10
11# 修改配置
# 允许访问的地址,默认是 127.0.0.1 会导致只能在本地访问,修改为 0.0.0.0 则可以在任意 IP 访问, 生产环境下要设置为 0.0.0.0
bind 0.0.0.0
# 守护进程,修改为 yes 后即可后台运行
daemonize yes
# 默认是yes,即开启。当配置为 no, 此时外部网络可以直接访问
protected-mode no
# 密码 设置后访问 Redis 必须输入密码
# requirepass root-
启动方式
1
2# 后台启动,
在任何目录下执行, 未修改配置文件时, 将以默认配置启动
redis-server &1
2
3
4
5
6
7
8
9# 启动 redis 服务时指定配置文件
(修改配置文件时, 在解压目录中执行)
redis-server redis.conf &
# 查看启动是否成功(获取进程 pid)
ps -ef|grep redis
# 安装 lsof
yum -y install lsof
lsof -i:6379
-
-
关闭
redis
服务 1
2
3
4
5
6
7# 1. 关闭对应进程
(数据有丢失风险) 获取进程 pid
ps -ef|grep redis
kill -9 pid
# 2. 使用 redis 命令关闭(推荐)
redis-cli shutdownredis
-命令关闭 -
redis
客户端 redis
客户端: 用来连接 redis
服务, 向 redis
服务端发送命令, 并且显示 redis
服务处理结果 redis-cli
: 是redis
自带客户端, 使用命令 redis-cli
就可以启动 redis
的客户端程序 redis-cli
:默认连接127.0.0.1:6379
的 redis
服务 redis-cli -p
指定端口号连接 redis -[p -h ip
连接指定地址 ip
主机上的指定端口的 redis
服务 -
退出
客户端
1
exit
redis
-启动-退出
-
-
如果某些命令不想被其他人使用,
则可以通过配置文件中的 rename-command
进行修改 1
2rename-command flushall ""
rename-command flushdb ""
开机自启
-
配置: 首先,新建一个系统服务文件
1
vim /etc/systemd/system/redis.service
-
填入如下内容
1
2
3
4
5
6
7
8
9
10
11[Unit]
Description=redis-server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /root/redis-6.2.4/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target -
重载系统服务
1
systemctl daemon-reload
-
可以用下面这组命令来操作
redis
1
2
3
4
5
6
7
8# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis -
开机自启
1
systemctl enable redis
-
后续连接方式
前提条件: 服务已处于启动状态 1
2
3
4
5
6
7# 当 redis 服务为启动状态时,
只需要通过如下命令进入 redis 控制台即可
# 方式一: 使用服务端配置直接启动
redis-cli
# 方式二: 可以启动指定,也可以是本机的服务
redis-cli -h 192.168.2.3 -a password
基本知识
-
测试
redis
服务的性能 1
redis-benchmark
-
查看
redis
服务是否正常运行 1
ping 如果正常 ==> pong
-
查看
redis
服务器的统计信息 1
2
3
4# 查看 redis 服务的所有统计信息
info
# 查看 redis 服务器的指定的统计信息 # CPU | # Replication | ...
info [信息段] -
redis
数据库实例 -
了解
redis
中的数据库实例只能由 redis
服务来创建和维护,开发人员不能修改和自行创建数据库实例, 默认情况下, redis
会自动创建 16
个数据库实例, 并且会给这些数据库实例进行编号, 从 0
开始, 一直到 15
,使用时通过编号来使用数据库, 可以通过配置文件, 指定 redis
自动创建的数据库个数, redis
的每一个数据库实例本身占用的存储空间是很少的, 所以也不造成存储空间的太多浪费,默认情况下, redis
客户端连接的是编号是 0
的数据库实例 -
数据库切换
1
select index
-
查看当前数据库实例中所有
key
的数量 1
dbsize
-
查看当前数据库实例中所有的
key
1
keys *
基础使用 -
清空数据库实例
1
2
3flushdb
# 慎重使用 清空所有数据库实例
flushall -
查看
redis
配置信息 1
2
3
4# 查看所有配置信息
config get *
# 查看指定字段
config get port
-
Redis 卸载
-
输入以下命令查看
reids
是否在运行,如果在运行需要将其关闭。 1
2
3ps aux | grep redis #查看
reids 是否在运行
kill -9 PID #通过杀掉reids 进程将其关闭 -
停止服务
1
redis-cli shutdown
-
删除相关目录
1
2
3rm -rf /usr/local/bin/redis-* #删除
redis 文件
ls /usr/local/bin/redis-* #查看redis 文件 -
删除解压文件
1
rm -rf redis-*
客户端界面下载
-
地址
https://github.com/uglide/RedisDesktopManager(未提供
Windows
版本, 源码. 使用需要) https://github.com/lework/RedisDesktopManager-Windows/releases`【同步上述更新免费版本下载】`
Redis 常用命令
keys 操作命令
-
keys
: 查看符合模板的所有key
,不建议在生产环境设备上使用, 是因为在一个大的数据库中使用他可能会阻塞当前服务器的服务,在生产环境中, 可以使用 scan 命令代替 keys *
匹配 0
个或者多个字符 keys ?
匹配一个字符 keys []
匹配 []
里边的 1
个字符
keys
-
判断
key
在数据库中是否存在 1
2# 如果存在返回 1,
不存在 返回 0
exists keyexists
-
移动指定
key
到指定的数据库实例 1
move key index
move
-
查看指定
key
的剩余生存时间 1
2
3
4
5ttl: time to live
# 语法
ttl key
# 如果 key 没有设置生存时间,返回 -1
# 如果 key 不存在,返回 -2 -
设置
key
的最大生存时间 1
expire key seconds[秒]
ttl
-
查看指定
key
的数据类型 1
type key
-
重命名
1
rename key newkey
-
删除指定的
key
1
2# 返回值是实际删除的 key 的数量
del key1 key2 ...del
-
persist
- 格式:
persist key
- 功能: 去除给定
key
的生存时间, 将这个 key
从 易失的
转换为持久的
- 说明: 当生存时间移除成功时,
返回: 1
,若key
不存在或 key
没有设置生存时间, 则返回 0
- 格式:
-
randomkey
- 格式:
randomkey
- 功能: 从当前数据库中随机返回
(不删除) 一个 key
- 说明: 当数据库不为空是,
返回一个 key
。当数据库为空时,返回nil
- 格式:
-
scan
hscan
:Hash
sscan
:Set
zscan
:ZSet
Redis 数据结构介绍
-
是什么
Redis
是一个 key-value
的数据库, key
一般是 string
类型,不过 value
的类型是多种多样的 -
数据类型
数据类型
数据类型操作
String
-
String
类型, 也就是字符串类型, 是 Redis
中最简单的存储类型, 其 value
是字符串,不过根据字符串的格式不同,又可以分为 3
类 String
: 普通字符串int
: 整数类型,可以做自增、自减操作float
: 浮点类型,可以做自增、自减操作
-
将
String
类型的数据设置到 redis
中 1
2# set 键 值
(key 存在则更新)
set username coder-itl -
从
redis
中获取 string
类型的数据 1
get username
-
追加字符串
1
2# 返回追加之后的字符串长度 如果 key 不存在,
则新创建一个 key 并且把 value 值设置为 value
append key value -
获取字符串数据的长度
1
strlen username
string
-
字符串数值
+1 /-1
运算1
2
3
4
5
6
7
8# 返回加 1 运算之后的数据 如果 key 不存在,
首先设置一个 key 值初始化为 0 然后进行 incr 运算
incr key
# 返回减 1 运算之后的数据 如果 key 不存在,首先设置一个 key 值初始化为 0 然后进行 incr 运算
decr key
# 必须是数值类型incr-decr
-
带偏移量的
+/-
1
2
3# 将字符串数值进行 offset 运算
incrby key offset
decrby key offsetincrby-decrby
-
子串
1
2# 获取字符串 key 中 startIndex 的字符串组成的子字符串(下标自左至右,
从 0 开始, 最后一个字符的下标是字符串长度-1, 属于 [](数学含义),而不是 ( ] )
getrange key starIndex endIndex -
覆盖
1
2# 用 value 覆盖从下标 startIndex 开始的字符串,其余位数保留或新增
setrange key startIndex value覆盖 -
设置字符串数据的同时,
设置它的最大生命周期 1
2
3
4
5
6# 存在也会设置
setex key seconds value
# key 不存在时设置,否则放弃设置
setnx key value -
批量设置
key
到 redis
数据库中 1
2
3
4
5
6
7# 批量设置
mset key1 value1 key2 value2 ...
# 批量获取
mget key1 key2 ...
# 只要一个存在则放弃
msetnxmset
List
-
Redis
中的 List
类型与 Java
中的 LinkedKist
类似,可以看作是一个双向链表结构。既可以支持正向检索和也可以支持反向检索 -
特征
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
-
分析
以 A
为起始, 如果执行 LPUSH C
,结果出现在 A
的左侧, 对 E
进行 RPUSH
出现在右侧
-
-
lpush
1
2
3
4
5
6
7# 元素在列表中的顺序或者下标由放入的顺序来决定
# 删除列表
del key
# 将一个或者多个值依次插入到列表的表头(左侧)
lpush key value1 value2 ....
# 查看列表中的数据
lrange key startIndex endIndex将一个或者多个值依次插入到列表的表头 (左侧) 分析 -
rpush
1
2# 将一个或者多个值依次插入到列表的表尾
rpush key value将一个或者多个值依次插入到列表的表尾 -
lpop
1
2# 从指定列表中移除并且返回表头元素
lpop keylpop
从指定列表中移除并且返回表头元素 -
rpop
1
2# 从指定列表中移除并且返回表尾元素
rpop key -
lindex
1
2# 获取列表中指定下标的元素
lindex keylindex
-
获取指定列表的长度
1
llen key
-
lrem
1
2
3
4
5# 根据 count 值移除指定列表中跟 value 相等的数据
lrem key count value
# count > 0 从列表的左侧移除 count 个和 value 相等的数据
# count < 0 从列表的右侧移除 count 个和 value 相等的数据
# count = 0 从列表移除 count 个和 value 相等的数据lrem
Set
-
Redis
的 Set
结构与 Java
中的 HashSet
类似,可以看作是一个 value
为 null
的 HashMap
。因为也是一个hash
表,因此具备与 HashSet
类似的特征 - 特征
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
- 特征
-
sadd
1
2
3# 将一个或者多个元素添加到指定的集合中
sadd key value
# 返回成功加入元素的个数,如果元素存在, 则会忽略 -
smembers
1
2# 获取指定集合中所有的元素
smembers key -
sismember
1
2
3
4# 判断指定元素在指定集合中是否存在
sismember key member
# 存在 返回 1
# 不存在 返回 0 -
scard
1
2# 获取指定集合的长度
scard key -
srem
1
2# 移除指定集合中一个或者多个元素
srem key memberset
-
srandmember
1
2
3
4
5
6
7
8# 随机获取指定集合中的一个元素
srandmember key
srandmember key count
# count > 0 随机获取的多个元素之间不能重复
# count < 0 随机获取的多个元素之间可能重复 -
spop
1
2# 从指定集合中随机移除一个或者多个元素
spop key [count] -
smove
1
2# 将指定集合中的指定元素移动到另一个集合中
smove source desc membersmove
-
sdiff
(差)1
2# 获取第一个集合中有,
但是其他集合中都没有的元素组成的新集合
sdiff key key -
sinter
(交)1
2# 获取所有指定集合中都有的元素组成的新集合
sinter key keysinter
-
sunion
(并)1
2# 获取所有指定集合中所有的元素组成的大集合
sunion key keysunion
-
案例练习
-
将下列数据用
Redis
的 Set
集合来存储 -
张三的好友有: 李四、王五、赵六
1
sadd zhangsan 李四 王五 赵六
-
李四的好友有: 王五、麻子、二狗
1
sadd lisi 王五 麻子 二狗
张四的好友有
-
-
利用
Set
的命令实现下列功能 -
计算张三的好友有几人
1
scard zhangsan
-
计算张三和李四有那些共同好友
集合 交集 1
2# 交集
sinter zhangsan lisi -
查询那些人是张三的还有却不是李四的好友
1
2# 差集
sdiff zhangsan lisi -
查询张三和李四的好友总共有那些人
1
2# 并集
sunion zhangsan lisi -
判断李四是否是张三的好友
1
sismember zhangsan lisi
-
判断张三是否是李四的好友
1
2# 判断李四在不在张三的列表中
sismember lisi zhangsan -
将李四从张三的好友列表中移除
1
srem zhangsan lisi
-
-
Hash
-
Hash
类型, 也叫散列,其 value
是一个无序字典,类似于 Java
中的 HashMap
结构 -
String
结构是将对象结果序列化为 JSON
字符串后存储,当需要修改对象某个字段时很不方便 对象结果序列化为 JSON
字符串后存储 -
Hash
结构可以将对象中的每个字段独立的存储,可以针对单个字段做 CRUD
-
-
hset
1
2
3
4
5
6# 将一个或者多个 field-value 对设置到哈希表中
hset key field ...
# hash 存储
hset vue:admin:userinfo name Jack
hset vue:admin:userinfo age 18hset
-
hget
1
2# 获取指定哈希表中指定 field 的值
hget key field -
hmset
1
2# 批量将多个 field-value 对设置到哈希表中
hmset key field1 field2 ... -
hmget
1
2# 批量获取多个 field-value 的值
hmget key field1 field2 ... -
hgetall
1
2# 获取指定哈希表中所有的 field 和 value
hgetall key -
hdel
1
2# 从指定哈希表中删除一个或者多个 field
hdel key field1 field2 ... -
hlen
1
2# 获取指定哈希表中所有的 field 个数
heln key -
hexists
1
2# 判断指定哈希表中是否存在某一个 field
hexists key field -
hkeys
1
2# 获取指定哈希表中所有的 field 列表
hkeys key -
hvals
1
2# 获取指定哈希表中所有的 value 列表
hvals key -
hincrby
1
2
3
4
5# 对指定哈希表中指定 field 值进行整数加法运算
hincrby key field int
# Eg:
hincrby key field 5 -
hincrbyfloat
1
2
3
4
5# 对指定哈希表中指定 field 值进行浮点数加法运算
hincrbyfloat key field float
# Eg:
hincrbyfloat stu score 5.5 -
hsetnx
1
2# 将一个 field-value 对设置到哈希表中,
当 key-filed 已经存在时, 则放弃设置, 否则 设置 filed-value
hsetnx key field
Zset
-
简介
redis
有序集合 zset
和集合 set
一样也是 string
类型元素的集合, 且不允许重复的成员 不同的是
zset
的每个元素都会关联一个分数 (分数可以重复) redis
通过分数来为集合中的成员进行从小到大的排序 -
Redis
的 SortedSet
是一个可排序的 set
集合,与 Java
中的 TreeSet
有些类似,但是底层数据结构差别很大, SortedSet
中的每一个元素都带有一个 score
属性,可以基于 score
属性对元素排序,底层的实现是一个跳表加 Hash
表 -
SortedSet
特性 - 可排序
- 元素不重复
- 查询速度快
- 因为
SortedSet
的可排序特性,经常被用来实现排行榜这样的功能
-
zadd
1
2
3
4# 将一个或者多个 member 及其 score 值加入有序集合
zadd key score member ...
# Eg: score(键名称)
zadd score 1 a 2 b 3 c ... -
zrange
1
2# 获取指定有序集合中指定区间的元素
zrange key startIndex endIndex [withscores]zadd-zrange
-
zrangebyscore
1
2
3
4# 获取指定有序集合中指定分数区间
(闭区间) 的元素
zrangebyscore key scorreStart endScore withscores
# Eg:
zrangebyscore score[有序集合名] scorreStart[起始区间] endScore[结束区间] withscoreszrangebyscore
-
zrem
1
2# 删除指定有序集合中一个或者多个元素
zrem key a b -
zcard
1
2# 获取指定有序集合中所有元素的个数
zcard key -
zcount
1
2# 获取指定有序集合中分数在指定区间内的元素的个数
zcount key 20 50 -
zrank
1
2
3
4# 获取指定有序集合中指定元素的排名
(排名从 0 开始)
zrank key member
# Eg:
zrank key a -
zscore
1
2
3
4# 获取指定有序集合中指定元素的分数
zscore key member
# Eg:
zscore key a -
zrevrank
1
2# 获取指定有序集合中指定元素的排名 逆序排名(大 -> 小)
zrevrank key member -
zdiff、zinter、zunion
:求差集、交集、并集注意: 所有的排名默认都是升序、如果要
降序
则在命令的z
后面添加 REV
即可 -
案例练习
将班级的学生的粉存入:
Jack 85
,Lucy 89
,Rose 82
,Tom 95
,Jerry 78
1
2# 添加 student_score(键名) 85 Jack(分数和键)
zadd student_score 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry存储后 -
实现如下
-
删除
Tom
同学 1
zrem student_score Tom
-
获取
Rose
同学的分数1
zscore student_score Rose
-
获取
Rose
同学的排名 1
2
3
4# 升序
(下标从 0 开始)
zrank student_score Rose
# 降序(下标从 0 开始)
zrevrank student_score Rose -
查询
80
分以下的有几个学生 1
2# 统计
zcount student_score 0 80 -
给
Jack
同学加 2
分 1
zincrby student_score 2 Jack
-
查出成绩前
3
名的同学 1
2
3
4# 升序
zrange student_score 0 2
# 倒序
zrevrange student_score 0 2排序 -
查出成绩
80
分以下的所有同学 1
2# 显示具体信息
zrangebyscore student_score 0 80
-
-
Redis 没有类似 MYSQL 中的 Table 的概念,我们该如何区分不同类型的 Key 呢?
-
例如: 需要存储用户,商品信息到
Redis
,有一个用户id
是 1
,有一个商品id
恰好也是 1
-
Key
的结构: Redis
的 key
允许有多个单词形成层级结构,多个单词之间用 :
隔开,格式如下 1
2
3项目名: 业务名: 类型:id
# 验证码: srb(项目名):core(模块):code(验证码相关) 1775297131(手机号) 7g8h(生成的验证码)
srb:core:code:1775297131 7g8h验证码存储 -
层级结构
1
2
3
4set heima:user:1 '{"id":1,"name":"Jack","age":21}'
set heima:user:2 '{"id":2,"name":"Rose","age":29}'
set heima:product:1 '{"id":1,"name":"RedMi","price":4999}'
set heima:product:2 '{"id":2,"name":"荣耀9","age":2999}' 层级结构
Redis-配置文件
-
port
配置端口,默认 6379
-
bind
指定 ip
如果配置了
port
和 bind
则客户端连接 redis
服务时, 必须指定端口和 ip
redis-cli -h 192.168.10.10 -p 6380
redis-cli -h 192.168.10.10 -p 6380 shutdown
-
日志
日志级别 -
数据库数量
数据库数量 loglevel
: 配置日志级别,开发阶段配置 debug
,上线阶段配置notice
或者 warning
logfile
: 指定日志文件,redis
在运行过程中, 会输出一些日志信息, 默认情况下, 这些日志信息会输出到控制台, 我们可以使用 logfile
配置日志文件, 使用 redis
把日志信息输出到指定文件中 database
:配置 redis
服务默认创建的数据库实例个数, 默认值是 16
logfile
-
安全配置
1
2
3requirepass: 设置访问 redis 服务时所使用的密码,
默认不使用 此参数必须在 protected-mode=yes 时才起作用
# 连接方式
redis-cli -h ip -p port -a pwd
Redis-持久化
简介
-
简介
Redis
的持久化: Redis
提供持久化策略, 在适当的时机采用适当手段把内存中的数据持久化到磁盘中, 每次 redis
服务启动时, 都可以把磁盘上的数据再次加载到内存中使用 -
RDB
策略 在指定时间间隔内,
redis
服务执行指定次数的写操作,会自动触发一次持久化操作 RDB
策略是 redis
默认的持久化策略, redis
服务开启时这种持久化策略就已经默认开启了 save <scconds> <changes>
配置持久化策略 dbfilename
配置 redis
RDB
持久化数据存储的文件 dir
:配置 redis
RDB
持久化文件所在目录 -
AOF
策略 采用操作日志来记录进行每一次写操作,
每次 redis
服务启动时, 都会重新执行一遍操作日志中的指令 效率低下,
redis
默认不开启 AOF
功能 appendonly
配置是否开启 AOF
策略 appendfilename
配置操作日志文件 -
小结
一般清空,
开启 RDB
就足够了 -
持久化的原理
持久化原理 持久化文件加载 Redis
持久化也成为钝化, 是指将内存中数据库的状态描述信息保存到磁盘中。只不过是不同的持久化技术,对数据的状态描述信息是不同的,生成的持久化文件也是不同的。但是他们的作用都是相同的: 避免数据意外丢失
通过手动方式,
或自动定时方式, 或条件自动触发方式, 将内存中数据库的状态描述信息写入到指定的持久化文件中。当系统重新启动时, 自动加载持久化文件, 并根据文件中数据库状态描述信息将数据恢复到内存中,这个数据恢复过程也称为 激活
.这个钝化与激活的过程就是 Redis
持久化的基本原理。 不过从以上分析可知,
对于 Redis
单机状态下, 无论是手动方式,还是定时方式或条件触发方式,都存在数据丢失问题: 在尚未手动 / 自动保存时发生了 Redis
宕机状况,那么从上次保存到宕机期间产生的数据就会丢失。不同的持久化方式, 其数据的丢失率也是不同的。需要注意的是, RDB
是默认的持久化方式, 但 Redis
允许 RDN
与 AOF
两种持久化技术同时开启, 此时系统会使用 AOF
方式做持久化,即 AOF
持久化技术优先级要更高。同样的道理,两种技术同时开启状态下,系统启动时若两种持久化文件同时存在,则 优先
加载AOF
持久化文件
持久化的执行
-
持久化的执行
持久化的执行有三种方式: 手动
save
命令、手动 bgsave
命令、与自动条件触发 -
查看
dump
文件位置 如果安装根目录下不存在, 在进入命令行后可通过该命令获取文件位置 config get dir
,文件内容不可以直接读取,二进制 -
手动
save
通过在
redis-cli
客户端中执行 save
命令可立即进行一次持久化保存。 save
命令在执行期间会 阻塞
redis-server
进程, 直至持久化过程完毕。而在 redis-server
进程阻塞期间, Redis
不能处理任何读写请求, 无法对外提供服务 -
手动
bgsave
命令 通过在
redis-cli
客户端中执行 bgsave
命令可立即进行一次持久化保存。不同于 save
命令的是, 正如该命令的名称一样, background save
,后台运行save
。bgsave
命令会使服务器进程 redis-server
生成一个子进程,由该子进程负责完成保存过程。在子进程保存过程中, 不会阻塞 redis-server
进程对客户端读写请求的处理 -
查看持久化时间
通过
lastsave
命令可以查看最近一次执行持久化的时间, 其返回值是一个 Unix
时间错
-
RDB-持久化
-
RDB
RDB
,是指将内存中某一时刻的数据快照
**全量 写入到指定的 rdb
文件的持久化技术。 RDB
持久化默认是开启的。当 Redis
启动时会自动读取``RDB 快照文件, 将数据从硬盘载入到内存, 以恢复 -
RDB
相关的配置在 redis.conf
文件的 SNAPSHOTTING
部分 -
RDB
的持久化过程 RDB-持久化过程流程图 对于
Redis
默认的 RDB
持久化,在进行 bgsve
持久化时, redis-server
进程会 fork
出一个 bgsave
子进程,由该子进程以 异步方式
负责完成持久化。而在持久化过程中,redis-server
进程不会阻塞,其会继续接受并处理用户的读写请求。 bgsave
子进程的详细工作原理如下: 由于子进程可以继承父进程的所有资源,
且父进程不能拒绝子进程的继承权。所以, bgsave
子进程由权读取到 redis-server
进程写入到内存中的用户数据, 是得将内存数据持久化到 dump.rdb
成为可能 bgsave
子进程在持久化时首先会将内存中的全量数据 copy
到磁盘中的一个 RDB
临时文件, copy
结束后,再将给文件 rename
为 dump.rdb
,替换掉原来的同名文件。不过,
再进行持久化过程中,如果 redis-server
进程接收到了用户写请求,则系统会将内存中发生数据修改的物理块 copy
出一个副本。等内存中的全量数据 copy
结束后,会再将副本的数据 copy
到 RDB
临时文件。这个副本的生成是由于 Linux
系统的 写时复制技术
(Copy on Write) 实现的。
AOF-持久化
-
AOF
AOF(Append Only File)
: 是指Redis
将每一次的写操作都以日志的形式记录到一个 AOF
文件中的持久化技术。当需要恢复内存数据时,将这些写操作重新执行一次,便会恢复到之前的内存数据状态。 -
AOF
基础配置 -
开启
AOF
1
2
3appendonly yes
# redis7 配置文件
https://github.com/CN-annotation-team/redis7.0-chinese-annotated/blob/7.0-cn-annotated/redis.confredis-6
redis-7
-
-
Rewrite
机制 随着使用时间的推移,
AOF
文件会越来越大。为了防止 AOF
文件由于太大而占用大量的磁盘空间, 降低性能, Redis
引入了 Rewrite
机制对 AOF
文件进行压缩 -
什么是
rewrite
所谓
Rewrite
其实就是对 AOF
文件进行重新整理。当 Rewrite
开启时, 主进程 redis-server
创建出一个子进程 bgrewriteaof
,由该子进程完成rewrite
过程。其首先对现有 aof
文件进行 rewrite
计算, 将计算结果写入到一个临时文件,写入完毕后, 再 rename
该临时文件为原 aof
文件名,覆盖原有文件。 -
rewrite
计算 - 读操作命令不写入文件
- 无效命令不写入文件
- 过期数据不写入文件
- 多条命令合并写入文件
-
开启
rewrite
-
手动开启
bgrewriteaof
-
条件自动开启
文档以及配置
-
-
-
AOF
-优化配置之同步策略appendfsync
always
:写操作命令写入aof_buf
后会立即调用 fsync()
系统函数, 将其追加到 AOF
文件。该策略效率较低,但相对比较安全, 不会丢失太多数据,最多就是刚刚执行过的写操作在尚未同步时出现宕机或重启, 将这一操作丢失 no
: 写操作命令写入aof_buf
后什么也不做, 不会调用 fsync()
函数。而将 aof_buf
中的数据同步磁盘的操作由操作系统负责。 Linux
系统默认同步周期为 30s
。效率较高,everysec
: 默认策略。写操作命令写入aof_buf
后并不会直接调用 fsync()
。而是每秒调用一次fsync()
系统函数来完成同步。该策略兼顾到了性能与安全, 是一种折中方案。
-
AOF
-持久化过程AOF
-持久化过程- Redis 接收到的写操作命令并不是直接追加到磁盘的
AOF
文件的,而是将每一条写命令按照 redis 通讯协议格式暂时添加到 AOF
缓冲区 aof_buf
- 根据设置的数据同步策略,
当同步条件满足时,再将缓冲区中的数据一次性写入磁盘的 AOF
文件,以减少磁盘 IO
次数,提高性能 - 当磁盘的
AOF
文件大小达到了 rewrite
条件时, redis-server
主进程会 fork
出一个子进程 bgrewriteaof
,由该子进程完成rewrite
过程 - 子进程
bgrewriteaof
首先对该磁盘 AOF
文件进行 rewrite
计算, 将计算结果写入到一个临时文件,全部写入完毕后, 再 rename
该临时文件为磁盘文件的原名称,覆盖源文件 - 如果在
rewrite
过程中又有写操作命令追加, 那么这写数据会暂时写入 aof_rewrite_buf
缓冲区。等将全部 rewrite
计算结果写入临时文件后, 会将 aof_rewrite_buf
缓冲区中的数据写入临时文件,然后再 rename
为磁盘文件的原名称,覆盖源文件。
- Redis 接收到的写操作命令并不是直接追加到磁盘的
-
RDB
和 AOF
的对比 RDB
的优劣势 - 优势
RDB
文件较小 - 数据恢复较快
- 劣势
- 数据安全性较差
- 写时复制会降低性能
RDB
文件可读性差
- 优势
AOF
的优劣势 - 优势
- 数据安全性高
AOF
文件可读性强
- 劣势
- 文件较大
- 写操作会影响性能
- 数据恢复较慢
- 优势
-
持久化技术的选型
- 官方推荐使用
RDB
与 AOF
混合式持久化 - 若多数据安全性要求不高,
则推荐使用纯 RDB
持久化技术 - 不推荐使用纯
AOF
持久化方式 - 若
Redis
仅用于缓存, 则无需使用任何持久化技术
- 官方推荐使用
事务
-
事务: 把一组数据库命令放在一起执行,
保证操作原子性, 要么同时成功, 要么同时失败 -
Redis
事务: 允许把一组 redis
命令放在一起, 把命令进行序列化, 然后一起执行, 保证部分原子性 -
开启事务
1
2
3
4# 用来标记一个事务的开始
multi
... -
exec
1
2# 用来执行事务队列中所有的命令
exec -
redis
的事务只能保证部分原子性 -
如果一组命令中,
有在压入事务队列过程中发生错误的命令, 则本事务中所有的命令都不执行, 就能够保证事务的原子性 1
2
3
4
5
6multi
set k1 v1
# 错误语句
seta k2 v2
set k3 v3
exec事务的原子性 -
如果一组命令中,
在压入队列过程中正常, 但是在执行事务队列命令时发生了错误, 则只会影响发生错误的命令, 不会影响其他命令的执行, 不能够保证事务的原子性 1
2
3
4
5multi
set k4 v4
# k4 不是数值型,会报错 但是语法正确
incr k4
exec未能保证原子性 -
discard
1
2
3
4
5# 清除所有已经压入队列中的命令,
并且结束整个事务
multi
set k5 v5
set k6 v6
discard -
watch
1
2
3
4
5
6# 监控某一个键,
当事务在执行过程中, 此键 的值发生变化, 则本事务放弃执行 否则 正常执行
watch key
multi
...
exec -
unwatch
1
2
3
4
5
6# 放弃监控所有键
watch key
unwatch
multi
...
exec
-
Redis
消息发布与订阅
-
简介
redis
客户端订阅频道, 消息的发布者往往在频道上发布消息, 所有订阅此频道的客户端都能够接收到消息 -
subscribe
1
2# 订阅一个或者多个频道的消息
subscribe ch1 ch2 ch3 -
publish
1
2# 将消息发布到执行频道
publish ch1 hello -
psubscribe
1
# 订阅一个或者多个频道的消息,
频道名支持通配符
Redis
-主从复制
-
简介
redis
主从复制: 主多从少、主写从读、读写分离、主写同步复制到从 -
搭建一主二从
redis
集群 -
搭建三台
redis
服务: 使用一个 redis
模拟三台 redis
服务 -
提供三分
redis
配置文件 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21redis6379.conf
redis6380.conf
redis6381.conf
# 修改如下内容
bind 127.0.0.1
port 6379 | 6380 | 6381
pidfile .var/run/redis_6379.pid | pidfile .var/run/redis_6380.pid | pidfile .var/run/redis_6381.id
logfile "6379.rdb | 6380.rdb | 6381.rdb"
dbfilename dump6379.rdb | dump6380.rdb | dump6381.rdb
# 分别使用三个 redis 配置文件,启动三个 redis 服务
redis-server redis6379.conf &
redis-server redis6380.conf &
redis-server redis6381.conf &
# 通过 redis 客户端分别连接三台 redis 服务
redis-cli -h 127.0.0.1 -p 6379
redis-cli -h 127.0.0.1 -p 6380
redis-cli -h 127.0.0.1 -p 6381
-
-
启动三台
redis
服务 -
查看三台
redis
服务器在集群中的主从角色 1
2info replication
# 默认情况下 所有的 redis 服务都是主机,即都能写和读, 但是都还没有从机 replication
-
设置主从关系: 设从不设主
1
2# 在 6380 上执行 slaveof 127.0.0.1 6379
# 在 6381 上执行 slaveof 127.0.0.1 63796380
6381
-
全量复制
1
# 一旦主从关系确定,
会自动把主库上已有的数据同步复制到从库 全量复制 -
增量复制
1
# 主库写数据会自动同步到从库
-
主写从读,
读写分离 1
# 在从机 set key value 报错
-
主机宕
( dang
)机 1
2
3# 关闭主机 6379 服务
redis-cli -h 127.0.0.1 -p 6379 shutdown主机宕机 -
查看从机角色信息
主机宕机, 从机原地待命 -
主机恢复
重启主机 恢复后的主机信息
-
-
从机宕机
从机宕机,
主机少一个从机, 其他从机不变 从机恢复,
需要重新设置主从关系 -
从机上位
(寻找新的主机) -
在从机上断开原来的主从关系
1
2# Eg: 6380
slaveof no one -
从新设置主从关系
1
slaveof 127.0.0.1 6380
-
Redis
-哨兵模式
-
搭建一个一主二从集群架构
-
提供哨兵配置文件,在
reids
安装目录下创建自定义配置文件 1
2
3
4
5
6vim redis_sentinel.conf
# 添加如下
sentinel monitor dc-redis 127.0.0.1 6379 1
# sentinel monitor dc-redis 127.0.0.1 6379 1 表示: 指定监控主机的 ip 地址 port 端口 得到哨兵的投票数(当哨兵投标数大于或者等于次数时切换主从关系) -
启动哨兵服务
1
redis-sentinel redis_sentinel.conf
启动哨兵服务 -
主机宕机
-
关闭
6379
服务 1
redis-cli -h 127.0.0.1 -p 6379 shutdown
-
从机自动变为主机
从机自动变为主机 哨兵文件变化信息 -
主机恢复
主机恢复后自动从属新的主机
-
Redis-密码
-
命令行设置密码
也可以在配置文件中修改 requirepass => vim +798 redis.conf
-
配置文件中设置密码
1
2
3
4# 密码出现位置为 901 行,
编辑起始位置
vim +901 redis.conf
# 密码修改为: redis6.4
requirepass redis6.4测试密码: redis6.4
Redis-配置文件详解
-
快速修改配置
-
redis-cli
连接后 1
2
3config get appendonly
config set appendonly yes
config rewrite
-
-
vim
匹配高亮取消 -
在命令模式下
( ESC
)关键词匹配搜索,搜索到的关键词高亮 -
在命令模式下
:/noh
,出现找不到匹配模式, 高亮将不会显示
-
-
Includes
模块 INCLUDES
关键点说明: 如果需要覆盖配置,
那么最好将 include
放置在最后一行,使用方式如图中的 35-36
行内容格式 -
network
模块 -
bind
-
protected-mode
-
port
-
tcp-backlog*
说明:
tcp-logback
是一个 TCP
连接的队列, 其主要作用用于解决高并发场景下客户端 慢连接
问题。这里设置的值就是这个队列的长度。该队列与TCP
连接的三次握手有关。不同的 Linux
内核, backlog
队列中存放的元素 (客户端连接) 类型是不同的 Linux
内核 2.2
版本之前, 该队列中存放的是已完成了 第一次握手
的所有客户端连接,其中就包含已经完成三次握手
的客户端连接。当然,此时的 backlog
队列中的连接也具有两种状态: 未完成三次握手的链接状态为 SYN_RECEIVED
,已完成三次握手的连接状态为 ESTABLISHED
,只有ESTABLISHED
状态的连接才会被 Redis
处理 Linux
内核 2.2
版本之后 TCP
系统中维护了两个队列: SYN_RECEIVED
队列与 ESTABLISHED
队列。 SYN_RECEIVED
队列中存放的是未完成三次握手的连接, ESTABLISHED
队列中存放的是已完成三次握手的连接。此时的 backlog
就是 ESTABLISHED
队列
-
查看当前
Linux
的版本内核 1
2
3
4# 方式一
uname -a
# 方式二
cat /proc/versionversion: 3.10.0
-
查看当前
Linux
内核中 somaxconn
的值 1
cat /proc/sys/net/core/somaxconn
somaxconn
TCP
中的 backlog
队列的长度在 Linux
中由内核参数 somaxconn
来决定。所以, 在 Redis
中该队列的长度由 Redis
配置文件设置与 somaxconn
来共同决定:取它们中的最小值。 生产环境下
(特别是高并发场景下), backlog
的值最好要大一些, 否则可能会影响系统性能 -
修改
/etc.sysctl.conf
文件,在文件最后添加如下内容 1
vim /etc/sysctl.conf
1
2# 添加如下内容
net.core.somaxconn=2048 -
修改过后可以重启虚拟机,
也可以通过如下命令加载,使得配置重新生效 1
sysctl -p
-
-
timeout
-
tcp-keepalive
-
-
general
模块 daemonzie
: 该配置可以控制Redis
是否采用守护进程方式, 即是否是后台启动. yes
是采用后台启动 pidfile
: 该配置用于指定Redis
运行时 pid
写入的文件, 无论是 Redis
是否采用守护进程方式, pid
都会写入到该配置的文件 loglevel
: 日志级别debug
: 可以获取到很多的信息,一般在开发和测试时使用verbose
: 可以获取到很多不太有用的信息,但不像debug
级别那么多 notice
: 可以获取到在生产中想获取到的适当多的信息,默认级别warning
: 只记录非常重要/ 关键的信息
logfile
: 指定日志文件。如果设置为空串,则强制将日志记录到标准输出设备 (显示器)。如果使用的是守护进程启动方式, 设置为空串,则意味着会将日志发送到设备 /dev/null(空设备)
databases
: 设置数据库的数量。默认数据库是0
号数据库。可以使用 select <dbid>
在每个连接的基础上选择一个不同的数据库,其中 dbid
是介于 0
和 databases
-1
之间的数字
-
security
模块: 用户设置 ACL
权限、 Redis
访问密码相关配置。该模块中最常用的就是 requirepass
属性 -
clients
模块: 该模块用于设置于客户端相关的属性,其中包含一个属性 maxclients
.maxclients
用于设置 Redis
可并发处理的客户端连接数量,默认值为 10000
.如果达到了该最大连接数,则会拒绝再来的新连接, 并返回一个异常信息: 已达到最大连接数
-
memory management
模块: 该配置可以控制最大可用内存以及线管内容移除问题 maxmemory
: 将内存使用限制设置为指定的字节数。当达到内存限制时,Redis
将根据选择的住处策略 maxmemory-policy
尝试删除符合条件的 key
-
Threaded I/O
模块: 该配置模块用于配置 Redis
对多线程 IO
模型的支持
数据类型操作总结
-
通用
通用 -
String
String
-
Hset
Hset
-
List
List
-
Set
Set
-
SortedSet
SortedSet