Redis部署
一、Redis安装部署
1. 源码包下载
wget http://download.redis.io/releases/redis-6.0.6.tar.gz
安装依赖包
yum -y install gcc tcl
解压安装
tar -xf redis-6.0.6.tar.gz -C /usr/local
2.修改配置文件
mkdir /etc/redis
cd redis-6.0.6
cp /usr/local/redis-6.0.6/redis.conf /etc/redis/6379.conf
配置文件中的设置
设置监听地址
vi /etc/redis/6379.conf
# bind 127.0.0.1 192.168.195.128
bind 参数若都注释掉,则会监听服务器上的所有 ip
可以指定一个或者多个,打开注释。
注意此配置项可能在 71 行左右。默认是 bind 127.0.0.1
检查并测试
手动使用命令指定配置文件启动服务
/usr/local/bin/redis-server /etc/redis/6379.conf
这种方式执行,默认 Redis 服务侯会在前台运行。
设置使用守护进程方式运行服务
vim /etc/redis/6379.conf
daemonize yes # 守护进程的方式启动服务
指定端口访问
redis-cli -p 6379
手动停止服务
redis-cli -p 6379 shutdown
二、持久化存储
1. RDB
什么情况下会触发 RDB
第一种情况,主动执行 save 命令(同步,阻塞 ,就是save 命令执行完毕后才能执行后续的其他命令操作)
阻塞
保存 RDB 文件的策略
每次创建新的文件,并且替换原来旧文件(假如存在旧的文件)
第二种情况,主动执行 bgsave 命令 (异步,非阻塞 )
文件策略和 save 相同
第三种情况,自动触发
自动触发,就是通过对 Redis 的配置文件重相关选项的修改,当达到某个配置好的条件后,自动生成 RDB 文件
,其内部使用的是 bgsave 命令。
关于 RDB 文件的配置信息
默认文件名
dbfilename dump.rdb
默认文件保存位置
dir ./
假如 bgsave 执行中发生错误,是否停止写入,默认是 yes , 表示假如出错,就停止写入。
stop-writes-on-bgsave-error yes
是否使用压缩|
rdbcompression yes
是否进行数据的校验
rdbchecksum yes
2. AOF
什么是 AOF
AOF 文件保存了 Redis 的数据库状态, 而文件里面包含的都是符合 Redis 通讯协议格式的命令文本。
AOF 保存的模式
Redis 目前支持三种 AOF 保存模式,它们分别是:
AOF_FSYNC_NO
:不保存。
AOF_FSYNC_EVERYSEC
:每一秒钟保存一次。(生产中一般选这种)
AOF_FSYNC_ALWAYS
:每执行一个命令保存一次
不保存
在这种模式下, SAVE 只会在以下任意一种情况中被执行:
Redis 被关闭
AOF 功能被关闭
系统的写缓存被刷新(可能是缓存已经被写满,或者定期保存操作被执行)
这三种情况下的 SAVE 操作都会引起 Redis 主进程阻塞。
每执行一个命令保存一次
在这种模式下,每次执行完一个命令之后, WRITE 和 SAVE 都会被执行。
另外,因为 SAVE 是由 Redis 主进程执行的,所以在 SAVE 执行期间,主进程会被阻塞,不能接受命令请求。
三种 AOF 模式的操作特性可以总结如下:
模式 | WRITE 是否阻塞? | SAVE 是否阻塞? | 停机时丢失的数据量 |
---|---|---|---|
AOF_FSYNC_NO | 阻塞 | 阻塞 | 操作系统最后一次对 AOF 文件触发 SAVE 操作之后的数据。 |
AOF_FSYNC_EVERYSEC | 阻塞 | 不阻塞 | 一般情况下不超过 2 秒钟的数据。 |
AOF_FSYNC_ALWAYS | 阻塞 | 阻塞 | 最多只丢失一个命令的数据。 |
AOF_FSYNC_NO 阻塞 阻塞 操作系统最后一次对 AOF 文件触发 SAVE 操作之后的数据。
AOF 的重写机制
为什么需要重写机制
AOF 文件通过同步 Redis 服务器所执行的命令, 从而实现了数据库状态的记录, 但是, 这种同步方式会造成一个问题: 随着运行时间的流逝, AOF 文件会变得越来越大。
对同一个键的状态的多次不同操作,而最终得到一个结果。比如对列表的添加删除元素。
被频繁操作的键。比如累加
重新机制是如何实现的
实际上, AOF 重写并不需要对原有的 AOF 文件进行任何写入和读取, 它针对的是数据库中键的当前值,也就是源数据从目前的内存中获取。
考虑这样一个情况, 如果服务器对键 list 执行了以下四条命令:
RPUSH list 1 2 3 4 // [1, 2, 3, 4]
RPOP list // [1, 2, 3]
LPOP list // [2, 3]
LPUSH list 1 // [1, 2, 3]
那么当前列表键 list 在数据库中的值就为 [1, 2, 3] 。
如果我们要保存这个列表的当前状态, 并且尽量减少所使用的命令数, 那么最简单的方式不是去 AOF 文件上分析前面执行的四条命令, 而是直接读取 list 键在数据库的当前值, 然后用一条 RPUSH 1 2 3 命令来代替前面的四条命令。
除了列表之外,集合、字符串、有序集、哈希表等键也可以用类似的方法来保存状态。
根据键的类型, 使用适当的写入命令来重现键的当前值, 这就是 AOF 重写的实现原理。
基本步骤
for 遍历所有数据库:
if 如果数据库为空:
那么跳过这个数据库
else:
写入 SELECT 命令,用于切换数据库
for 选择一个库后,遍历这个库的所有键
if 如果键带有过期时间,并且已经过期,那么跳过这个键
if 根据数据的类型,进行相关操作。
AOF 重写的实现方式
方式 | 区别 |
---|---|
bgrewriteaof 命令 | 不需要重启服务,不便于统一管理 |
配置文件实现 | 需要重启服务,便于进行统一管理 |
bgrewriteaof
配置文件实现
触发条件,必须同时满足如下条件
aof_current_size 和 aof_base_size 可以通过命令 info persistence 查看到
重写流程图
注意:无论是RDB还是AOF都是先写入一个临时文件,然后通过 rename 完成文件的替换工作。
配置示例
// 要想使用 AOF 的全部功能,需要设置为 yes
appendonly yes
// AOF 文件名,路径才看之前的 `dir` 配置项
appendfilename "appendonly.aof"
// 平常普通的 AOF 的策略
appendfsync everysec
// 当执行 AOF 重写时,是否继续执行平常普通的 AOF 操作。
// 这里设置文件 yes , 表示不执行
// 因为假如,同时执行,两种操作都会对磁盘 I/O 进行访问,造成
// I/O 访问量过大,产生性能衰减
no-appendfsync-on-rewrite yes
// AOF 文件容量的增长率
auto-aof-rewrite-percentage 100
// AOF 文件的最低容量,就是当前文件的大小大于此值时,就会进行重写。当然这只是其中一个条件。
auto-aof-rewrite-min-size 64mb
键值对数据,观察 AOF 文件
这里在命令行中设置,以便立刻生效
[root@ela1 ~]# redis-cli
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
OK
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"
进行简单的数据添加操作
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> set hello python
OK
127.0.0.1:6379> set hello redis
OK
127.0.0.1:6379> incr nums
(integer) 1
127.0.0.1:6379> incr nums
(integer) 2
127.0.0.1:6379> incr nums
(integer) 3
127.0.0.1:6379> incr nums
(integer) 4
127.0.0.1:6379> rpush li a
(integer) 1
127.0.0.1:6379> rpush li b
(integer) 2
127.0.0.1:6379> rpush li b
(integer) 3
127.0.0.1:6379> rpush li c
(integer) 4
127.0.0.1:6379> exit
查看 AOF 文件
[root@ela1 ~]# head appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
SET
$5
hello
主动触发
先备份一份目前的 AOF 文件
[root@s1 ~]# cp /appendonly.aof{,.bak}
执行命令 bgrewriteaof
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
最后对比两个文件的内容的不同之处。
3. RDB 和 AOF 区别
Redis主从复制+哨兵模式
一、主从复制原理
主从复制特点
二、主从配置
1. 命令方式
只需要在从服务器上执行如下命令即可
slaveof 主服务器的IP 端口号
slaveof 命令是异步的,不阻塞。
并且此时,从服务器现有的数据会先被清空,之后再同步主服务器的数据。
停止一台从服务器的复制操作,在此台服务器上执行如下命令
slaveof no one
2. 配置文件方式
修改配置文件
假如主服务器 IP 是: 192.168.195.128
端口是: 6379
# slaveof <masterip> <masterport>
slaveof 172.16.153.178 6379
// 配置此服务器只提供读取操作
slave-read-only yes
之后重启从主机的 Redis 服务
查看主从信息
127.0.0.1:6379> info replication
三、主从 + Sentinel 哨兵模式
1. 哨兵模式
Redis Sentinel是Redis官方的高可用性解决方案。
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将主从复制组合中的其中一个从服务器升级为新的主服务器, 并让其他从服务器指向新的主服务器; 当客户端试图连接失效的主服务器时, Sentinel也会向客户端返回新主服务器的地址, 使得新主服务器代替失效服务器。
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。
虽然 Redis 为 Sentinel 生成一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器。
此种模式下,客户端要访问的 服务 IP 不是主节点,而是 sentiner 服务器的 IP。
架构图
Redis Sentinel 故障转移
架构的扩展应用
2. 配置主从+哨兵模式
(1)快速生成主节点的配置文件
编译全新文件 /etc/redis/redis-6380.conf, 添加如下内容
port 6379
daemonize yes
protected-mode no
pidfile /var/run/redis-6379.pid
logfile /var/log/redis-6379.log
dir /redis/data/
假如是多个主机实现的,就需要更改为 protected-mode yes,
并且添加 bind 0.0.0.0
(2)快速生成从节点的配置文件
[root@ela1 ~]# sed 's/6379/6380/g' /etc/redis/redis-6379.conf > /etc/redis/redis-6380.conf
[root@ela1 ~]# sed 's/6379/6381/g' /etc/redis/redis-6379.conf > /etc/redis/redis-6381.conf
查看配置文件内容,检验配置结果
[root@ela1 ~]# cat /etc/redis/redis-6381.conf
port 6381
daemonize yes
pidfile /var/run/redis-6381.pid
logfile /var/log/redis-6381.log
dir /redis/data/
[root@ela1 ~]# cat /etc/redis/redis-6380.conf
port 6380
daemonize yes
pidfile /var/run/redis-6380.pid
logfile /var/log/redis-6380.log
dir /redis/data/
[root@ela1 ~]#
(3)配置主从关系
[root@ela1 ~]# echo "slaveof 192.168.195.129 6379" >> /etc/redis/redis-6380.conf
[root@ela1 ~]# echo "slaveof 192.168.195.129 6379" >> /etc/redis/redis-6381.conf
(4)启动服务,并验证进程
[root@ela1 ~]# /usr/local/bin/redis-server /etc/redis/redis-6379.conf
[root@ela1 ~]# /usr/local/bin/redis-server /etc/redis/redis-6380.conf
[root@ela1 ~]# /usr/local/bin/redis-server /etc/redis/redis-6381.conf
[root@ela1 ~]# ps -ef |grep redis
(5)查看主从复制信息
3. 配置 sentinel哨兵模式
(1)获取程序
Sentinel 程序可以在编译后的 src 文档中发现, 它是一个命名为 redis-sentinel 的程序。
运行一个 Sentinel 所需的最少配置如下所示:
Redis 源码中包含了一个名为 sentinel.conf 的文件, 这个文件是一个带有详细注释的 Sentinel 配置文件示例。
运行一个 Sentinel 所需的最少配置如下所示:
// 监控一个 Redis 服务器
// 名称为 mymaster ,IP 为 127.0.0.1 端口为 6380
// 最后的 2 是指最少有 2 给 Sentinel 实例同意一台 redis 服务器宕机,才会认为 客观下线。
// sentinel monitor 自定义的主节点名称 主节点的 IP 主节点端口 票数
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 3000
// 180 秒后开始故障自动装换
sentinel failover-timeout mymaster 5000
sentinel parallel-syncs mymaster 1
各个选项的功能如下:
down-after-milliseconds 选项指定了 Sentinel 认为服务器已经断线所需的毫秒数。
如果服务器在给定的毫秒数之内, 没有返回 Sentinel 发送的 PING 命令的回复, 或者返回一个错误, 那么 Sentinel 将这个服务器标记为主观下线(subjectively down,简称 SDOWN )。
不过只有一个 Sentinel 将服务器标记为主观下线并不一定会引起服务器的自动故障迁移: 只有在足够数量的 Sentinel 都将一个服务器标记为主观下线之后, 服务器才会被标记为客观下线(objectively down, 简称 ODOWN ), 这时自动故障迁移才会执行。
将服务器标记为客观下线所需的 Sentinel 数量由对主服务器的配置决定。
parallel-syncs 选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长。
最终配置文件
sentinel-26379.conf
daemonize yes
port 26379
dir "/tmp"
logfile "26379.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel failover-timeout mymaster 5000
sentinel parallel-syncs mymaster 1
(2)哨兵的领导者选举
票数和领导者选举有关系
领导者选举的事件发生,必须满足下面的条件
max(票数, (哨兵的个数 / 2) + 1 ) 个哨兵参加选举
才可以选举出领导者,从而完成故障转移。
比如有 5 个哨兵, 配置的票数是 4
max(4, (5 / 2) + 1)
max(4, 3.5)
4 最大
结果就是需要 4 个哨兵参与选举才可以。
(3)获取并修改配置文件
快速创建三个 sentinel 配置文件
进入到 Redis 源码的目录下,执行如下命令
修改监听端口
之后在每个 sentinel 配置文件中添加守护进程方式运行,
并修改dir 配置项的目录,
daemonize yes
dir /redis/data/
logfile "sentinel-${port}.log"
最后别忘了修改监控的主服务器的 IP 和端口正确的 6379
(4)启动服务并验证
启动服务的语法:
shell> redis-sentinel sentinel的配置文件
[root@ela1 redis-6.0.6]# redis-sentinel /etc/redis/sentinel-26379.conf
可以使用以下命令查看哨兵的信息
[root@ela1 ~]# redis-cli -p 27001 info
4. 故障演练
停止 Master 节点的服务
[root@ela1 ~]# redis-cli -p 6379 shutdown
不断的刷新其中一个 Sentinel 节点的信息,观察最后一行信息的变化
[root@ela1 ~]# redis-cli -p 26379 info
master0:name=mymaster,status=ok,address=127.0.0.1:6380,slaves=2,sentinels=3
Redis集群
一、Redis集群介绍
1. Redis 集群的优势
自动分割数据到不同的节点上。
整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
2. 特点
主从复制
实现了高可用
数据分片存储
3. 架构
集群节点的 meet 过程如下图:
指派槽
客户端和槽
二、Redis集群部署
1. 基础环境
准备两台虚拟机:
一台启动三个 Redis 实例作为 主节点
另一台启动三个 Redis 实例作为 从节点
架构
2. 部署
(1)编辑集群配置文件
编译配置文件 /etc/redis/cluster-redis-7001.conf, 添加如下内容:
bind 0.0.0.0
port 7001
daemonize yes
# 允许任何地址不使用密码访问我
protected-mode no
dir "/tmp"
logfile "cluster-7001.log"
dbfilename "cluster-dump-7001.log"
cluster-enabled yes
cluster-config-file cluster-redis-7001.conf
# 不需要集群的全部节点完好才提供服务
cluster-require-full-coverage no
(2)创建其他集群的配置文件
[root@ela1 redis]# sed 's/7001/7002/g' cluster-redis-7001.conf > cluster-redis-7002.conf
[root@ela1 redis]# sed 's/7001/7003/g' cluster-redis-7001.conf > cluster-redis-7003.conf
[root@ela1 redis]# sed 's/7001/7011/g' cluster-redis-7001.conf > cluster-redis-7011.conf
[root@ela1 redis]# sed 's/7001/7012/g' cluster-redis-7001.conf > cluster-redis-7012.conf
[root@ela1 redis]# sed 's/7001/7013/g' cluster-redis-7001.conf > cluster-redis-7013.conf
拷贝从节点的配置文件到另外一台主机上
需要保证另一台主机上有目录 /etc/redis/, 因为这里计划把所有的配置文件放在此目录下
[root@ela1 redis]# scp -r cluster-redis-701* 192.168.195.128:/etc/redis/
(3)启动主、从节点的服务进程
启动主节点
[root@ela1 redis]# /usr/local/bin/redis-server /etc/redis/cluster-redis-7001.conf
[root@ela1 redis]# /usr/local/bin/redis-server /etc/redis/cluster-redis-7002.conf
[root@ela1 redis]# /usr/local/bin/redis-server /etc/redis/cluster-redis-7003.conf
启动从节点
[root@ela2 ~]# /usr/local/bin/redis-server /etc/redis/cluster-redis-7011.conf
[root@ela2 ~]# /usr/local/bin/redis-server /etc/redis/cluster-redis-7012.conf
[root@ela2 ~]# /usr/local/bin/redis-server /etc/redis/cluster-redis-7013.conf
进程检查
ps -ef | grep redis-server
3. 创建集群
(1)创建
redis-cli --cluster create 192.168.195.129:7001 192.168.195.129:7002 192.168.195.129:7003 192.168.195.128:7011 192.168.195.128:7012 192.168.195.128:7013 --cluster-replicas 1
(2)观察集群信息
观察集群的数据槽
redis-cli -p 7001 cluster slots
查看集群信息
[root@ela1 redis]# redis-cli -p 7001 cluster info
查看某一个集群节点信息
4. 测试
192.168.195.129机器:
192.168.195.128机器: