- 持久化
- Redis 持久化 - RDB
- Redis 持久化 - AOF
- AOF 文件重写机制
- Redis 高可用
- Redis 主从复制
- 搭建主从复制环境
- 全量复制和部分复制
- Redis 哨兵 (Sentinel)
- 搭建哨兵集群环境
- Redis Cluster
- Hash 分布
- 配置集群 - 原生命令安装(了解)
- 配置集群 - 官方工具安装
Java 从 0 到架构师目录:【Java从0到架构师】学习记录
持久化参考:Redis 中两种持久化机制详解
Redis 所有的数据都是保存在内存中
- 如果进行了持久化,对数据的更新将异步或者同步的保存到磁盘上
- 持久化可以避免数据丢失,对数据进行备份,还可以还原指定时间的数据
持久化的方式
- 快照:MySQL dump、Redis RDB、Oracle dump
- 写日志:MySQL Binlog、Redis AOF
混合持久化内容的 AOF 文件:
appendonly yes # 开启aof模式 aof-use-rdb-preamble yes # 使用rdb和aof的混合模式, 高版本默认开启Redis 持久化 - RDB
触发方式:
- save(同步):如果存在老的 rdb 文件,新的文件会替换老的文件
- bgsave(异步):Redis 会调用 fork 来创建一个子进程
- 自动配置:在配置文件中配置快照触发的条件
saev 900 1 save 300 10 save 60 10000
save 900 1 表示 900s 内,执行了 1次 数据库操作则自动创建快照,以此类推
触发机制
- 全量复制
- debug reload
- shutdown
相关配置:
save 900 1 # 15分钟内有1个key进行修改 save 300 10 # 5分钟类有10个key进行修改 save 60 10000 # 1分钟内有10000个key进行修改 dbfilename dump_6379.rdb # 备份文件 dir /usr/local/redis-5.0.8/data # 备份目录 stop-writes-on-bgsave-error yes # 在出现错误的时候终止rdb备份, 默认yes rdbcompression yes # 是否进行压缩, 默认yes rdbchecksum yes # 是否进行检查sum值校验, 默认yes
RDB 方式的不足之处:耗时,耗费 IO 性能
Redis 持久化 - AOF
AOF 的三种策略:
- always:每个 redis 写命令都要同步写入硬盘,严重降低 redis 速度(慎用)
该策略不会丢失数据,但是 IO 开销很大 - everysec:每秒同步一次缓冲区的命令到硬盘(推荐,也是默认策略)
该策略和不使用持久化时的性能几乎无差别,即时系统奔溃也最多丢失 1 秒的数据 - no:由操作系统决定何时将缓冲区的命令写到硬盘(不推荐)
该策略是不可控的
AOF 方式会使得持久化的文件变的越来越大,AOF 重写机制可以在一定程度下减少磁盘占用量
客户端方式执行重写:BGREWRITEAOF
服务器配置自动重写:
appendonly yes # 是否开启aof文件模式 appendfilename "appendonly-6379.aof" # aof文件名称 appendfsync everysec # aof策略模式 dir usr/local/redis-5.0.8/data # 数据存储路径 no-appendfsync-on-rewrite yes # 在重写的时候, 不要执行aof操作 auto-aof-rewrite-percentage 100 # 自动重写的百分比 auto-aof-rewrite-min-size 64mb # 重写的大小配置 # 当AOF文件体积大于 64M,并且AOF文件的体积比上一次重写之后体积大了 100%(1倍) 时,自动触发重写Redis 高可用 Redis 主从复制
单击的问题:机器故障引起单点故障,容量达到瓶颈、QPS 达到瓶颈
QPS (Queries Per Second):每秒查询率,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,即每秒的响应请求数,也就是最大吞吐能力
主从复制:
- 一个 Master 可以有多个 Slave
- 一个 Slave 只能有一个 Master
- 数据流向是单向的,只能从 Master 流向 Slave
只有 Master 可以进行写的操作,然后将数据复制到 Slave
主从复制的作用:
- 避免单点故障
- 读写分离:Master 节点写数据,然后复制到 Slave 节点,Slave 节点读数据
(默认情况下 Slave 节点无法写数据) - 一主多从
- 多副本
配置文件:
port 6380 daemonize yes pidfile /var/run/redis-6380.pid logfile 6380.log dbfilename dump_6380.rdb dir /usr/local/redis-5.0.8/data/ # bind 192.168.52.128 # 局域网连接要指定 -h: redis-cli -h 192.168.52.128
目前情景:开启了两台 Redis 服务器,分别是 127.0.0.1:6379、127.0.0.1:6380,希望 6379 作为 Master 节点,6380 作为 Slave 节点,开启主从复制
-
方法1:客户端主动执行
# 以从服务器的身份来执行以下命令的 # 直接从6379服务端口Master进行数据复制, 自身的数据清空, 然后再从Master复制数据 slaveof 127.0.0.1 6379
info replication 可以查看当前服务器的角色是 master 还是 slave
# 脱离 slave 节点的身份, 但是数据会保留 slaveof no one
-
方法2:服务器配置自动成为 slave 节点
replicaof 192.168.52.128 6379 replica-read-only yes # 从节点只读,不能写
全量复制:
部分复制:
主从复制在高可用中的问题:
- 手动故障转移:Master 节点下线后,Slave 不会自动变成 Master
- 写能力和存储能力受限
哨兵机制集群 - 架构图:
哨兵机制架构规划:
配置开启主从节点:
# 主节点配置 redis_7000.conf port 7000 daemonize yes pidfile /var/run/redis-7000.pid logfile 7000.log dir /usr/local/redis-5.0.8/data/
# 从节点配置 redis_7001.conf port 7001 daemonize yes pidfile /var/run/redis-7001.pid logfile 7001.log dir /usr/local/redis-5.0.8/data/ replicaof 127.0.0.1 7000
# redis_7002.conf port 7002 daemonize yes pidfile /var/run/redis-7002.pid logfile 7002.log dir /usr/local/redis-5.0.8/data/ replicaof 127.0.0.1 7000
配置开启 sentinel 监控主从节点:
# sentinel_26379.conf port 26379 daemonize yes pidfile /var/run/redis-sentinel-26379.pid logfile "26379.log" dir /usr/local/redis-5.0.8/data/ # 告诉sentinel去监听地址为ip:port的一个master, 2个sential认为一个master失效才会真正失效 sentinel monitor mymaster 127.0.0.1 7000 2 # sentinel判断失效的时间 sentinel down-after-milliseconds mymaster 30000 # 最多1个slave对master进行同步 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes
# sentinel_26380.conf port 26380 daemonize yes pidfile /var/run/redis-sentinel-26380.pid logfile "26380.log" dir /usr/local/redis-5.0.8/data/ sentinel monitor mymaster 127.0.0.1 7000 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes protected-mode no
# sentinel_26381.conf port 26381 daemonize yes pidfile /var/run/redis-sentinel-26381.pid logfile "26381.log" dir /usr/local/redis-5.0.8/data/ sentinel monitor mymaster 127.0.0.1 7000 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes protected-mode no
开启主从节点,哨兵节点:
# 启动主从节点服务器 bin/redis-server conf/redis_7000.conf bin/redis-server conf/redis_7001.conf bin/redis-server conf/redis_7002.conf # 启动哨兵节点服务器 bin/redis-sentinel conf/sentinel_26379.conf bin/redis-sentinel conf/sentinel_26380.conf bin/redis-sentinel conf/sentinel_26381.conf
通过查看日志可以看到监控信息:
然后进行一些操作,例如结束某个 redis-server:
redis-cli -p 7000 shutdown
然后查看主从节点信息:
# 在 redis-cli 执行以下操作可以查看主从节点信息 info replication
通过哨兵机制,实现了服务端高可用和客户端高可用
Redis Cluster为什么需要使用集群?
- 并发量:如果需要的并发量是 100w/s,单个服务的性能是 11w/s,那么就需要 10 个服务器集群同时提供服务
- 数据量:如果需要存储更多的数据量,可以考虑使用 Redis 集群,集群中的每个服务器都存放一部分数据。如果一个服务存放的数据量是 200G,那么要存储 1T 的数据就需要 5 台服务器进行集群操作。
- 网络流量:单台服务器的网卡流量是固定的,比如一个服务器的网卡是 1G,需要达到 10G 的网络流量速度,可以使用 10 台服务器集群。
数据分布:对于大量数据,想要存储到不同的节点,是需要按照某种规则的
- 顺序分区:确定好所有的数据,把数据按照顺序放到不同的服务节点中,均匀分配
特点:1. 数据容易倾斜 2. 键值分布和业务相关 3. 支持批量操作 4. 可以顺序访问
- Hash 分区:确定好服务节点数量,根据每个数据的 key 计算对应的 hash 值(数字),对 hash 值进行取模操作(模的值为服务节点数量),根据取模结果把数据存放到对应的服务节点
特点:1. 数据分散度高 2. 键值分布业务无关 3. 支持批量操作 4. 无法顺序访问
节点取余扩容:
一致性 Hash:
虚拟槽分配:
集群规划图:
集群配置:
port 7000 # 设置是否以守护进程开启 daemonize yes dir /usr/local/redis-5.0.8/data dbfilename dump_7000.dbf logfile 7000.log # 是否开启集群模式 cluster-enabled yes # 集群节点的单独配置 cluster-config-file node_7000.conf cluster-node-timeout 15000 # 设置什么情况下集群对外提供服务, yes表示集群节点都正常才对外提供服务 cluster-require-full-coverage no bind 192.168.52.129 protected-mode no
快速根据已有文件替换字符并输出新文件:
sed 's/7000/7001/g' redis_7000.conf > redis_7001.conf #sed 命令 替换字符串 写入新文件
启动集群:
bin/redis-server conf/redis_7000.conf bin/redis-server conf/redis_7001.conf bin/redis-server conf/redis_7002.conf bin/redis-server conf/redis_7003.conf bin/redis-server conf/redis_7004.conf bin/redis-server conf/redis_7005.conf # 查看服务状态 ps -ef |grep redis netstat -ntlp # 查看集群状态,没有绑定ip可以不写-h(默认连接127.0.0.1) bin/redis-cli -h 192.168.52.129 -p 7000 cluster info # 以集群模式连接客户端(-c) bin/redis-cli -c -h 192.168.52.129 -p 7000 cluster info # 查看集群状态 cluster nodes # 查看集群中的节点
节点通信:
# 或者以集群模式连接客户端后,直接执行 cluster meet ip port 命令 bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7001 bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7002 bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7003 bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7004 bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7005 # 查看集群信息 bin/redis-cli -p 7000 cluster info
分配 slot 卡槽:
# 1 编写分配卡槽脚本 addslots.sh
# $1 代表第一个参数
start=$1
end=$2
port=$3
for slot in `seq ${start} ${end}`
do
./redis-cli -h 192.168.52.129 -p ${port} cluster addslots ${slot}
done
# 2 执行脚本
sh addslots.sh 0 5460 7000
sh addslots.sh 5461 10922 7001
sh addslots.sh 10923 16383 7002
配置从节点:
# 这里需要配置一个node节点的id信息 # a0502ceb7461f9b2ec99d440904cf4768a297c22 redis-cli -h 192.168.52.129 -p 7003 cluster replicate node1_id # 50caaf79a5145b511eec6680ffa3355e4dbc9e73 redis-cli -h 192.168.52.129 -p 7004 cluster replicate node2_id # 45713493b59ed5ed3cca4397fa13148cf6666efc redis-cli -h 192.168.52.129 -p 7005 cluster replicate node3_id配置集群 - 官方工具安装
# 同时杀死所有 redis-server 进程
ps -ef | grep redis | grep -v grep | awk '{print $2}' | xargs kill -9
# 清除上次配置的集群信息: 删除配置集群生成的日志
# 我配置的日志目录是 data, 因此进入 data 后执行 rm -rf *
使用官方工具安装,只需要执行集群配置和启动集群的步骤,可以省略节点通信、分配 slot 卡槽,配置从节点的步骤。
集群配置、启动集群参考上面,下面直接进行安装:
# 通过命令进行安装 # --cluster-replicas 1 表示主从比例1:1, 即 一主一从 # --cluster-replicas 2 表示主从比例1:2, 即 一主两从 bin/redis-cli --cluster create 192.168.52.129:7000 192.168.52.129:7001 192.168.52.129:7002 192.168.52.129:7003 192.168.52.129:7004 192.168.52.129:7005 --cluster-replicas 1



