转:https://www.jianshu.com/p/c723cb3d0483
save命令会阻塞当前redis服务,已经废弃。bgsave命令只有在fork子线程的时候阻塞。
触发RDB的操作:
手动执行bgsave命令;
使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave;
如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点;
默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave;
配置
#设置目录
config set dir {newDir}
#设置RDB文件名
config set dbfilename {newFileName}
#采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远远小于内存大小,默认开启
config set rdbcompression{yes|no}
RDB特点:
RDB压缩的二进制文件,适用于备份,全量复制等场景。
Redis加载RDB恢复数据远远快于AOF的方式。
RDB方式数据没办法做到实时持久化/秒级持久化。
AOF以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的,类似数据库binlog形式。
开启AOF功能需要设置配置:appendonly yes,默认不开启。
AOF文件名通过appendfilename配置设置,默认文件名是appendonly.aof。
系统调用write和fsync说明:
•write操作会触发延迟写(delayed write)机制。Linux在内核提供页缓冲区用来提高硬盘IO性能。
write操作在写入系统缓冲区后直接返回。同步硬盘操作依赖于系统调度机制,
例如:缓冲区页空间写满或达到特定时间周期。同步文件之前,如果此时系统故障宕机,缓冲区内数据将丢失。
•fsync针对单个文件操作(比如AOF文件),做强制硬盘同步,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化。
使用everysec策略进行AOF的sync时,当系统硬盘资源繁忙时可能会阻塞主线程。
1)everysec配置最多可能丢失2秒数据,不是1秒。
2)如果系统fsync缓慢,将会导致Redis主线程阻塞影响效率。
3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。
重写达到压缩的原因:
1)进程内已经超时的数据不再写入文件。
2)旧的AOF文件含有无效命令,如del key1等。重写使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令。
3)多条写命令可以合并为一个,如:lpush list a、lpushlist b、lpush list c可以转化为:lpush list a b c。
为了防止单条命令过大造成客户端缓冲区溢出,对于list、set、hash、zset等类型操作,以64个元素为界拆分为多条。
触发时机:
手动触发:直接调用bgrewriteaof命令。
自动触发:根据auto-aof-rewrite-min-size(默认64M)和auto-aof-rewrite-percentage参数确定自动触发时机。
自动触发时机=[(aof_current_size>auto-aof-rewrite-min-size)
&& ((aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewrite-percentage)]
4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。
注意:
虽然fork创建的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。
例如对于10GB的Redis进程,需要复制大约20MB的内存页表,因此fork操作耗时跟进程总内存量息息相关,
线上建议每个Redis实例内存控制在10GB以内。
或者降低fork操作的频率,如适度放宽AOF自动触发时机,避免不必要的全量复制等。
建立主从关系
1)在配置文件中加入slaveof{masterHost}{masterPort}随Redis启动生效。
2)在redis-server启动命令后加入--slaveof{masterHost}{masterPort}生效。
3)直接使用命令:slaveof{masterHost}{masterPort}生效。
断开主从:从节点执行slaveof no one命令断开与主节点的复制关系。
#主节点6379复制状态信息:
127.0.0.1:6379>info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6379,state=online,offset=43,lag=0
....
#从节点6380复制状态信息:
127.0.0.1:6380>info replication
#Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
...
切主操作流程如下:
1)断开与旧主节点复制关系。2)与新主节点建立复制关系。3)删除从节点当前所有数据。4)对新主节点进行复制操作。切主后从节点会清空之前所有的数据,线上人工操作时小心slaveof在错误的节点上执行或者指向错误的主节点。
默认情况下,从节点使用slave-read-only=yes配置为只读模式。
repl-disable-tcp-node-lay参数
•当关闭时,主节点产生的命令数据无论大小都会及时地发送给从节点,这样主从之间延迟会变小,但增加了网络带宽的消耗。适用于主从之间的网络环境良好的场景,如同机架或同机房部署。 默认关闭
•当开启时,主节点会合并较小的TCP数据包从而节省带宽。默认发送时间间隔取决于Linux的内核,一般默认为40毫秒。这种配置节省了带宽但增大主从之间的延迟。适用于主从网络环境复杂或带宽紧张的场景,如跨机房部署。
主从之间通过长链接彼此发送心跳命令。
主节点默认每隔10秒对从节点发送ping命令,判断从节点的存活性和连接状态。可通过参数repl-ping-slave-period控制发送频率。
从节点在主线程中每隔1秒发送replconf ack{offset}命令,给主节点上报自身当前的复制偏移量。
主节点根据replconf命令判断从节点超时时间,体现在info replication统计中的lag信息中,lag表示与从节点最后一次通信延迟的秒数,正常延迟应该在0和1之间。如果超过repl-timeout配置的值(默认60秒),则判定从节点下线并断开复制客户端连接。
用于主节点出现宕机时从节点提供故障转移支持。当应用写命令并发量较高且需要持久化时,可以只在从节点上开启AOF,这样既保证数据安全性同时也避免了持久化对主节点的性能干扰。
注意主节点宕机后,先断开主从复制关系,再重启主节点。
一主多从结构(又称为星形拓扑结构)使得应用端可以利用多个从节点实现读写分离(见图6-5)。对于读占比较大的场景,可以把读命令发送到从节点来分担主节点压力。
但是对于写并发量较高的场景,多个从节点会导致主节点写命令的多次发送从而过度消耗网络带宽,同时也加重了主节点的负载影响服务稳定性。可下面采用树形结构
#主
127.0.0.1:6379> info replication
# Replication
role:master
...
master_repl_offset:1055130
#从
127.0.0.1:6379> info replication
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=1055214,lag=1
...
•主节点复制积压缓冲区。
复制积压缓冲区是保存在主节点上的一个固定长度的队列,默认大小为1MB,当主节点有连接的从节点(slave)时被创建,这时主节点(master)响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓冲区。
127.0.0.1:6379> info replication
# Replication
role:master...repl_backlog_active:1 // 开启复制缓冲区
repl_backlog_size:1048576 // 缓冲区最大长度
repl_backlog_first_byte_offset:7479 // 起始偏移量,计算当前缓冲区可用范围
repl_backlog_histlen:1048576 // 已保存数据的有效长度。
•主节点运行id。
每个Redis节点启动后都会动态分配一个40位的十六进制字符串作为运行ID。运行ID的主要作用是用来唯一识别Redis节点,比如从节点保存主节点的运行ID识别自己正在复制的是哪个主节点。需要注意的是Redis关闭再启动后,运行ID会随之改变。
如果只使用ip+port的方式识别主节点,那么主节点重启变更了整体数据集(如替换RDB/AOF文件),从节点再基于偏移量复制数据将是不安全的。
# redis-cli -p 6379 info server | grep run_id
run_id:545f7c76183d0798a327591395b030000ee6def9
•psync命令
全量复制非常耗时费力,它的时间开销主要包括:
•主节点bgsave时间。
•RDB文件网络传输时间。
•从节点清空数据时间。
•从节点加载RDB的时间。
•可能的AOF重写时间。
部分复制
主从数据延迟:可以通过监控主从偏移量,超过一定阀值报警,并迁移到其他延迟小的从节点。
读到过期数据:
过期的key删除策略主要有两种:惰性删除(读取key之前检查是否过期)和定时删除(内部定时任务会循环采样一定数量的键,当发现采样的键过期时执行del命令)。
由于从节点不能主动删除key,过期key由主节点删除后同步到从节点,因此从节点可能读到过期数据。
redis3.2之后版本支持从节点读取数据之前会检查键的过期时间来决定是否返回数据。
避免全量复制:
第一次建立复制(无法避免)
节点运行ID不匹配(手动提升从节点为主节点或者采用支持自动故障转移的哨兵或集群方案)
复制积压缓冲区不足(保证repl_backlog_size>net_break_time*write_size_per_minute,从而避免因复制积压缓冲区不足造成的全量复制)
规避复制风暴:
原文:https://www.cnblogs.com/jvStarBlog/p/12189850.html