五. Redis补充

redis持久化机制

Redis本身运行时数据保存在内存中,那么在关闭Redis进程或关闭服务器后数据肯定被会操作系统从内存中清掉,如果没有做持久化,在重启后,就会发生数据丢失。
Redis的持久化方式有两种,RDB(Redis DataBase)AOF(Append Only File)

RDB(Redis DataBase)

将内存中的数据进行快照,并写入dump.rdb文件当中,是某个时间点的一次全量数据备份。每次当redis重启之后,redis会先读dump.rdb文件,将数据从硬盘写入到内存中。

触发机制

RDB持久化触发机制分为:save、bgsave、自动触发
save
阻塞当前Redis服务器,执行save期间,Redis不能处理其他命令,直到RDB过程完成为止。
bgsave
Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。
自动触发:
自动触发是由我们的配置文件来完成的。在redis.conf配置文件中,里面有如下配置,我们可以去设置:
1 save:这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
默认如下配置:
表示900 秒内如果至少有 1 个 key 的值变化,则保存save 900 1#表示300 秒内如果至少有 10 个 key 的值变化,则保存save 300 10#表示60 秒内如果至少有 10000 个 key 的值变化,则保存save 60 10000
不需要持久化,那么你可以注释掉所有的 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:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。

RDB 的优势和劣势

优势
1. RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
2. 生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
3. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
劣势
RDB快照是一次全量备份,存储的是内存数据的二进制序列化形式,存储上非常紧凑。当进行快照持久化时,会开启一个子进程专门负责快照持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照持久化期间修改的数据不会被保存,可能丢失数据。

AOF(Append Only File)

AOF日志是持续增量的备份,将每一个收到的写命令都通过write函数追加到文件中,是基于写命令存储的可读的文本文件。AOF日志会在持续运行中持续增大,由于Redis重启过程需要优先加载AOF日志进行指令重放以恢复数据,恢复时间会无比漫长。所以需要定期进行AOF重写,对AOF日志进行瘦身。目前AOF是Redis持久化的主流方式。
文件重写
AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件。

触发机制

1. 每修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
2. 每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失
3. 不同no:从不同步

AOF 的优势和劣势

优势
1. AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。
2. AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。
3. AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
4. AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据
缺点
1. 对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大
2. AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的
3. 以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。

redis哨兵模式实现高可用及故障转移

官方文档:http://www.redis.cn/documentation.html
1. 实现主从,结合https://www.jianshu.com/p/712cfe40ed4c 修改每个配置文件

slaveof 192.168.213.128 6379
masterauth "redis"

# 使用 info replication验证
[root@lqy etc]# redis-cli -p 6379 -a redis info replication | head -n5
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.213.128,port=6381,state=online,offset=1912511,lag=1
slave1:ip=192.168.213.128,port=6380,state=online,offset=1912656,lag=1
[root@lqy etc]# redis-cli -p 6380 -a redis info replication | head -n5
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:192.168.213.128
master_port:6379
master_link_status:up
[root@lqy etc]# redis-cli -p 6381 -a redis info replication | head -n5
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:192.168.213.128
master_port:6379
master_link_status:up

2. 配置哨兵

#sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
cat << EOF > /usr/local/redis/etc/sentinel6379.conf
port 26379
daemonize yes
pidfile /data/redis6379/redis-sentinel.pid
logfile /data/redis6379/logs/sentinel.log
dir /data/redis6379/data/
sentinel monitor mymaster 192.168.213.128 6379 2
sentinel auth-pass mymaster redis
#哨兵检测确认主节点下线 默认30秒
sentinel down-after-milliseconds mymaster 30000
#指定了在发生主备切换时,最多可以有多少个slave同时对新的master进行同步,
sentinel parallel-syncs mymaster 1
#故障转移的超时时间
sentinel failover-timeout mymaster 180000
#默认情况下,SENTINEL SET将无法更改通知脚本
sentinel deny-scripts-reconfig yes
EOF

3. 启动sentinel&验证

./redis-sentinel /usr/local/redis/etc/sentinel6379.conf
./redis-sentinel /usr/local/redis/etc/sentinel6380.conf
./redis-sentinel /usr/local/redis/etc/sentinel6381.conf

#查看运行状态
[root@lqy etc]# redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.213.128:6379,slaves=2,sentinels=3

#停6379端口验证
[root@lqy etc]# /etc/init.d/redis stop 6379
Stopping ...
Redis stopped
[root@lqy etc]# redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.213.128:6380,slaves=2,sentinels=3
#查看主节点被切换到6380
Redis cluster
# 集群节点配置文件
cat << EOF >  /usr/local/redis/etc/redis7001.conf
daemonize yes
port 7001
pidfile /data/redis-cluster/7001/redis.pid
bind 127.0.0.1 192.168.213.128
cluster-enabled yes
cluster-config-file nodes7001.conf
cluster-node-timeout 5000
appendonly yes
EOF
# 拷贝配置文件修改对应参数
echo 'redis7002.conf redis7003.conf redis7004.conf redis7005.conf redis7006.conf' | xargs -n 1 cp redis7001.conf

# 创建目录
mkdir -p  /data/redis700{1..6}

# 启动各节点redis
/etc/init.d/redis start 7001
···
/etc/init.d/redis start 7006

# 创建redis cluster
redis-cli --cluster create 192.168.213.128:7001 192.168.213.128:7002 192.168.213.128:7003 192.168.213.128:7004 192.168.213.128:7005 192.168.213.128:7006 --cluster-replicas 1

#查看cluster状态
[root@lqy data]# redis-cli -p 7002 cluster nodes
9dfee5dc0f8e8b5561a7ad2c12fde4c217390ada 127.0.0.1:7006@17006 slave dbc18d4c7e5ac26d862cf0897fbec253554c347b 0 1617876570507 1 connected
dbc18d4c7e5ac26d862cf0897fbec253554c347b 127.0.0.1:7001@17001 master - 0 1617876570003 1 connected 0-5460
a9f11034b60bfc03156f0988017abb2cbee1a8e0 127.0.0.1:7004@17004 slave 5e5acf9b8b56b9d9d7c795bb853324d43fa27369 0 1617876571011 2 connected
5e5acf9b8b56b9d9d7c795bb853324d43fa27369 127.0.0.1:7002@17002 myself,master - 0 1617876570000 2 connected 5461-10922
2cb617b46b22513ad72550dfad482a1eec9f160e 127.0.0.1:7005@17005 slave 7946a3412560d169ff2d2f0d6e24e38fcea524c2 0 1617876569000 3 connected
7946a3412560d169ff2d2f0d6e24e38fcea524c2 127.0.0.1:7003@17003 master - 0 1617876569499 3 connected 10923-16383

# 验证高可用
[root@lqy etc]# redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (dbc18d4c...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (7946a341...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7002 (5e5acf9b...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
[root@localhost etc]# /etc/init.d/redis stop 7004
Stopping ...
Redis stopped
[root@lqy etc]# redis-cli --cluster info 127.0.0.1:7001
Could not connect to Redis at 127.0.0.1:7004: Connection refused
127.0.0.1:7001 (dbc18d4c...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (7946a341...) -> 0 keys | 5461 slots | 0 slaves.
127.0.0.1:7002 (5e5acf9b...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.

# 增删cluster节点
# 新增目录及配置文件,修改对应参数
mkdir /data/redis700{7,8} ;echo 'redis7007.conf redis7008.conf' | xargs -n 1 cp redis7001.conf
# 启动服务,查看集群状态显示为孤儿节点
[root@lqy etc]# /etc/init.d/redis start 7007
Starting Redis server...
[root@lqy etc]# /etc/init.d/redis start 7008
Starting Redis server...
[root@lqy etc]# redis-cli -p 7007 cluster nodes
af36ead42afe611e908fd742b412d43f8ed851c4 :7007@17007 myself,master - 0 0 0 connected
[root@lqy etc]# redis-cli -p 7008 cluster nodes
4d7a81040ef0f592caa2487a683c3b3ea87b6af3 :7008@17008 myself,master - 0 0 0 connected

# 添加新节点到集群
[root@lqy etc]# redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7001
>>> Adding node 127.0.0.1:7007 to cluster 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: dbc18d4c7e5ac26d862cf0897fbec253554c347b 127.0.0.1:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 7946a3412560d169ff2d2f0d6e24e38fcea524c2 127.0.0.1:7003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 5e5acf9b8b56b9d9d7c795bb853324d43fa27369 127.0.0.1:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 9dfee5dc0f8e8b5561a7ad2c12fde4c217390ada 127.0.0.1:7006
   slots: (0 slots) slave
   replicates dbc18d4c7e5ac26d862cf0897fbec253554c347b
S: 2cb617b46b22513ad72550dfad482a1eec9f160e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 7946a3412560d169ff2d2f0d6e24e38fcea524c2
S: a9f11034b60bfc03156f0988017abb2cbee1a8e0 127.0.0.1:7004
   slots: (0 slots) slave
   replicates 5e5acf9b8b56b9d9d7c795bb853324d43fa27369
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 127.0.0.1:7007 to make it join the cluster.
[OK] New node added correctly.
# 查看状态
[root@lqy etc]#  redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (dbc18d4c...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (7946a341...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7002 (5e5acf9b...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:7007 (af36ead4...) -> 0 keys | 0 slots | 0 slaves.
[OK] 0 keys in 4 masters.
0.00 keys per slot on average.
# 为新加节点分配slots
# 注:重新分配槽位需要清空数据,需要做好数据备份再还原
[root@lqy etc]# redis-cli --cluster reshard 127.0.0.1:7001
···
How many slots do you want to move (from 1 to 16384)?4096 #新分配多少个槽位
=16384/master个数
What is the receiving node ID? af36ead42afe611e908fd742b412d43f8ed851c4 #新的
master的ID
···
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: all #将哪些源主机的槽位分配给新的节点,all是自动在所有的redis node选择划
分,如果是从redis cluster删除某个主机可以使用此方式将指定主机上的槽位全部移动到别的redis主机
...
Do you want to proceed with the proposed reshard plan (yes/no)? yes #确认分配
···

# 查看重新分配结果
[root@lqy etc]#  redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (dbc18d4c...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7003 (7946a341...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7002 (5e5acf9b...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7007 (af36ead4...) -> 0 keys | 4096 slots | 0 slaves.
[OK] 0 keys in 4 masters.
0.00 keys per slot on average.

# 为新加master添加slave
[root@lqy etc]# redis-cli --cluster add-node 127.0.0.1:7008 127.0.0.1:7001 --cluster-slave --cluster-master-id af36ead42afe611e908fd742b412d43f8ed851c4

# 验证
[root@lqy etc]#  redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (dbc18d4c...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7003 (7946a341...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7002 (5e5acf9b...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7007 (af36ead4...) -> 0 keys | 4096 slots | 1 slaves.

# 缩容
# 将待删除节点的slots分配给其他节点
redis-cli --cluster reshard 127.0.0.1:7001
# 验证slots也全部迁移走
[root@lqy etc]#  redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (dbc18d4c...) -> 0 keys | 3641 slots | 1 slaves.
127.0.0.1:7003 (7946a341...) -> 0 keys | 9102 slots | 2 slaves.
127.0.0.1:7002 (5e5acf9b...) -> 0 keys | 3641 slots | 1 slaves.
127.0.0.1:7007 (af36ead4...) -> 0 keys | 0 slots | 0 slaves.
[OK] 0 keys in 4 masters.
0.00 keys per slot on average.

[root@lqy etc]# redis-cli --cluster reshard 127.0.0.1:7001
How many slots do you want to move (from 1 to 16384)? 4096 分别给其它master节点
What is the receiving node ID? dbc18d4c7e5ac26d862cf0897fbec253554c347b  #master
127.0.0.1:7001
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: af36ead42afe611e908fd742b412d43f8ed851c4 #输入要删除127.0.0.1:7007节点ID
Source node #2: done
# 验证cluster状态
[root@lqy etc]# redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (72414c45...) -> 0 keys | 8192 slots | 2 slaves.
127.0.0.1:7007 (0a94e34a...) -> 0 keys | 0 slots | 0 slaves.
127.0.0.1:7002 (ccd7e8f5...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7003 (356b00a7...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 0 keys in 4 masters.
0.00 keys per slot on average.

#删除节点
[root@lqy etc]#redis-cli --cluster del-node 127.0.0.1:7007 af36ead42afe611e908fd742b412d43f8ed851c4
[root@lqy etc]# redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (72414c45...) -> 0 keys | 8192 slots | 2 slaves.
127.0.0.1:7002 (ccd7e8f5...) -> 0 keys | 4096 slots | 1 slaves.
127.0.0.1:7003 (356b00a7...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 0 keys in 4 masters.
0.00 keys per slot on average.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值