Redis的四种部署方案-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

这篇文章介绍Reids最为常见的四种部署模式其实Reids和数据库的集群模式差不多可以分为 Redis单机模式部署、Redis主从模式部署、Redis哨兵模式部署、Cluster集群模式部署其他的部署方式基本都是围绕以下几种方式在进行调整到适应的生产环境最常见的还是集群模式的部署

接下来我们来主要分析和学习一下的部署方式和利弊。

约定信息
系统Linux CentOS 7.9
Redis版本Redis 7.2.2

方案一单机模式部署

编译部署

# 设置内核参数
[root@redis ~]# echo "vm.overcommit_memory=1"  >> /etc/sysctl.conf 
[root@redis ~]# echo "net.core.somaxconn=511"  >> /etc/sysctl.conf 
[root@redis ~]# sysctl # 查看生效情况

# 下载二进制包并编译
[root@redis ~]# wget http://download.redis.io/releases/redis-7.2.2.tar.gz
[root@redis ~]# tar zxf redis-7.2.2.tar.gz -C /usr/local/
[root@redis ~]# cd /usr/local/redis-7.2.2/
[root@redis redis-7.2.2]# make


# 编辑redis.conf配置文件
[root@redis redis-7.2.2]# vim redis.conf
# 绑定主机iP
bind 0.0.0.0
# 设置端口号
port 6379
# 启用后台运行
daemonize yes
# 设置redis密码
requirepass 123123

# 启动并查看监听和进程
[root@redis ~]# /usr/local/redis-7.2.2/src/redis-server /usr/local/redis-7.2.2/redis.conf 

[root@redis ~]# ps -ef | grep redis
root       878     1  0 23:24 ?        00:00:00 /sbin/dhclient -q -lf /var/lib/dhclient/dhclient--eth0.lease -pf /var/run/dhclient-eth0.pid -H redis eth0
root     12429     1  0 23:42 ?        00:00:00 /usr/local/redis-7.2.2/src/redis-server 0.0.0.0:6379
root     12505 12289  0 23:43 pts/1    00:00:00 grep --color=auto redis
[root@redis ~]# netstat -tnlp | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      12429/redis-server

# 停止
[root@redis ~]# ./redis-cli -p 6379 -a 123123 shutdown

# 客户端连接测试测试
[root@redis ~]# /usr/local/redis-7.2.2/src/redis-cli 
127.0.0.1:6379> auth 123123
OK
127.0.0.1:6379> set flag if010.com
OK
127.0.0.1:6379> get flag
"if010.com"
127.0.0.1:6379>

使用systemctl进行管理

[root@redis ~]# cp ../utils/redis_init_script /etc/init.d/redis  #不同版本可能位置不同

[root@redis ~]# vim /etc/init.d/redis
	Port           : 6379
	Config file    : /usr/local/redis/conf/redis.conf
	Log file       : /usr/local/redis/log/redis.log
	Data dir       : /usr/local/redis/data
	Executable     : /usr/local/redis/bin/redis-server  /usr/local/redis/conf/redis.conf
	Cli Executable : /usr/local/redis/bin/redis-cli


	# redis         Start up the redis server daemon
	#
	# chkconfig: 2345 55 25
     添加chkconfig 开机启动   
     ....


redis.service
	[Unit]
	Description=Redis Server
	After=network-online.target

	[Service]
	Type=forking
	PIDFile=/var/run/redis_6379.pid
	ExecStart=/etc/init.d/redis start
	ExecStop=/etc/init.d/redis stop
	ExecReload=/etc/init.d/redis reload
	PrivateTmp=true

	[Install]
	WantedBy=multi-user.target

至此单机模式就部署完成了优点嘛就是能用缺点就是故障了就无法提供服务且没有备份所以接下来介绍第二种方案—主从模式部署

单点服务器带来的问题

  • 单点故障服务不可用
  • 无法处理大量的并发数据
  • 数据丢失----大灾难
  • 开启多Redis进程
  • Redis默认单进程
  • 开启多进程导致CPU压力过大
  • 对于服务器纵向消耗服务器硬件性能CPU

方案二主从模式部署

Redis主从原理

和MySQL需要主从复制的原因一样Redis虽然读取写入的速度都特别快但是也会产生性能瓶颈特别是在读压力上为了分担压力Redis支持主从复制。Redis的主从结构一主一从一主多从或级联结构复制类型可以根据是否是全量而分为全量同步和增量同步。
下图为级联结构

级联结构

Redis主从同步的策略

主从同步刚连接的时候进行全量同步全量同步结束后开始增量同步。如果有需要slave在任何时候都可以发起全量同步其主要策略就是无论如何首先会尝试进行增量同步如果不成功则会要求slave进行全量同步之后再进行增量同步。

注意如果多个slave同时断线需要重启的时候因为只要slave启动就会和master建立连接发送SYNC请求和主机全量同步如果多个同时发送SYNC请求可能导致master IO突增而发送宕机。

全量同步

Redis全量同步一般发生在slave的初始阶段这时slave需要将master上的数据都复制一份具体步骤如下

  1. slave连接master发送SYNC命令
  2. master街道SYNC命令后执行BGSAVE命令生产RDB文件并使用缓冲区记录此后执行的所有写命令
  3. master的BGSAVE执行完成后向所有的slave发送快照文件并在发送过程中继续记录执行的写命令
  4. slave收到快照后丢弃所有的旧数据载入收到的数据
  5. master快照发送完成后就会开始向slave发送缓冲区的写命令
  6. slave完成对快照的载入并开始接受命令请求执行来自master缓冲区的写命令
  7. slave完成上面的数据初始化后就可以开始接受用户的读请求了。

大致流程如下

全量同步流程

增量复制

增量复制实际上就是在slave初始化完成后开始正常工作时master发生写操作同步到slave的过程。增量复制的过程主要是master每执行一个写命令就会向slave发送相同的写命令slave接受并执行写命令从而保持主从一致。

Redis主从同步的特点

  1. 采用异步复制
  2. 可以一主多从
  3. 主从复制对于master来说是非阻塞的也就是说slave在进行主从复制的过程中master依然可以处理请求
  4. 主从复制对于slave来说也是非阻塞的也就是说slave在进行主从复制的过程中也可以接受外界的查询请求只不过这时候返回的数据不一定是正确的。为了避免这种情况发生可以在slave的配置文件中配置在同步过程中阻止查询
  5. 每个slave可以接受来自其他slave的连接
  6. 主从复制提高了Redis服务的扩展性避免单节点问题另外也为数据备份冗余提供了一种解决方案
  7. 为了降低主redis服务器写磁盘压力带来的开销可以配置让主redis不在将数据持久化到磁盘而是通过连接让一个配置的从redis服务器及时的将相关数据持久化到磁盘不过这样会存在一个问题就是主redis服务器一旦重启因为主redis服务器数据为空这时候通过主从同步可能导致从redis服务器上的数据也被清空

部署方式

环境约定Master节点172.17.0.100、Slave1节点172.17.0.101、Slave2节点172.17.0.102

部署思路先配置好Master节点然后拷贝到Slave1节点上在Master节点的配置基础上再配置replicaofmasterauth其他节点直接拷贝Slave1节点上的配置文件即可

编译安装

编译安装好Redis环境(所有节点操作)

# 下载软件包
[root@Redis-Test1 ~]# wget http://download.redis.io/releases/redis-7.2.2.tar.gz

# 解压软件包
[root@Redis-Test1 ~]# tar zxf redis-7.2.2.tar.gz -C /usr/local/
[root@Redis-Test1 ~]# cd /usr/local/redis-7.2.2/
[root@Redis-Test1 redis-7.2.2]# ls
00-RELEASENOTES  CODE_OF_CONDUCT.md  COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  sentinel.conf  tests   utils
BUGS             CONTRIBUTING.md     deps     Makefile  README.md  runtest     runtest-moduleapi  SECURITY.md       src            TLS.md

# 编译
[root@redis-master-01 ~]# make

编辑配置文件

修改Redis的配置文件Master节点操作

[root@Redis-Test1 redis-7.2.2]# vim redis.conf

bind 0.0.0.0
port 6379
daemonize yes
pidfile /data/redis/redis.pid
logfile "/data/redis/logs/redis.log"
appendonly yes	#开启AOF持久化
requirepass 123123
dir /data/redis/

修改Redis的配置文件Slave节点操作

[root@Redis-Test2 redis-7.2.2]# vim redis.conf 

bind 0.0.0.0
port 6379
daemonize yes
pidfile /data/redis/redis.pid
logfile "/data/redis/logs/redis.log"
appendonly yes
requirepass 123123
dir /data/redis/

replicaof 172.17.0.100 6379	#指定要同步的master节点ip和端口
masterauth 123123	#指定master的认证口令

启动

这里要注意一下先启动Master节点然后在启动Slave节点

/usr/local/redis-7.2.2/src/redis-server /usr/local/redis-7.2.2/redis.conf

验证主从效果

从日志上分析验证

[root@Redis-Test2 logs]# tailf redis.log 
9025:S 01 Nov 2023 17:45:28.450 * Done loading RDB, keys loaded: 0, keys expired: 0.
9025:S 01 Nov 2023 17:45:28.450 * DB loaded from base file appendonly.aof.1.base.rdb: 0.001 seconds
9025:S 01 Nov 2023 17:45:28.450 * DB loaded from append only file: 0.001 seconds
9025:S 01 Nov 2023 17:45:28.450 * Opening AOF incr file appendonly.aof.1.incr.aof on server start
9025:S 01 Nov 2023 17:45:28.450 * Ready to accept connections tcp
9025:S 01 Nov 2023 17:45:28.450 * Connecting to MASTER 172.17.0.100:6379
9025:S 01 Nov 2023 17:45:28.450 * MASTER <-> REPLICA sync started
9025:S 01 Nov 2023 17:45:28.451 * Non blocking connect for SYNC fired the event.
9025:S 01 Nov 2023 17:45:28.451 * Master replied to PING, replication can continue...
9025:S 01 Nov 2023 17:45:28.451 * Partial resynchronization not possible (no cached master)
9025:S 01 Nov 2023 17:45:33.418 * Full resync from master: d9da2499f5cdb878a424e33159ec2b795ea7db17:14
9025:S 01 Nov 2023 17:45:33.419 * MASTER <-> REPLICA sync: receiving streamed RDB from master with EOF to disk
9025:S 01 Nov 2023 17:45:33.419 * MASTER <-> REPLICA sync: Flushing old data
9025:S 01 Nov 2023 17:45:33.419 * MASTER <-> REPLICA sync: Loading DB in memory
9025:S 01 Nov 2023 17:45:33.422 * Loading RDB produced by version 7.2.2
9025:S 01 Nov 2023 17:45:33.422 * RDB age 0 seconds
9025:S 01 Nov 2023 17:45:33.422 * RDB memory usage when created 0.94 Mb
9025:S 01 Nov 2023 17:45:33.422 * Done loading RDB, keys loaded: 0, keys expired: 0.
9025:S 01 Nov 2023 17:45:33.422 * MASTER <-> REPLICA sync: Finished with success
9025:S 01 Nov 2023 17:45:33.422 * Creating AOF incr file temp-appendonly.aof.incr on background rewrite
9025:S 01 Nov 2023 17:45:33.423 * Background append only file rewriting started by pid 9031
9031:C 01 Nov 2023 17:45:33.424 * Successfully created the temporary AOF base file temp-rewriteaof-bg-9031.aof
9031:C 01 Nov 2023 17:45:33.425 * Fork CoW for AOF rewrite: current 4 MB, peak 4 MB, average 4 MB
9025:S 01 Nov 2023 17:45:33.466 * Background AOF rewrite terminated with success
9025:S 01 Nov 2023 17:45:33.466 * Successfully renamed the temporary AOF base file temp-rewriteaof-bg-9031.aof into appendonly.aof.2.base.rdb
9025:S 01 Nov 2023 17:45:33.466 * Successfully renamed the temporary AOF incr file temp-appendonly.aof.incr into appendonly.aof.2.incr.aof
9025:S 01 Nov 2023 17:45:33.469 * Removing the history file appendonly.aof.1.incr.aof in the background
9025:S 01 Nov 2023 17:45:33.469 * Removing the history file appendonly.aof.1.base.rdb in the background
9025:S 01 Nov 2023 17:45:33.472 * Background AOF rewrite finished successfully

从Master节点上查看节点信息

[root@Redis-Test1 redis-7.2.2]# ./src/redis-cli 
127.0.0.1:6379> auth 123123
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.17.0.101,port=6379,state=online,offset=98,lag=1
slave1:ip=172.17.0.102,port=6379,state=online,offset=98,lag=1
master_failover_state:no-failover
master_replid:d9da2499f5cdb878a424e33159ec2b795ea7db17
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:98
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:98

方案三哨兵模式部署

Sentinel是Redis官方为集群提供的高可用解决方案。 在实际项目中可以使用sentinel去做redis自动故障转移减少人工介入的工作量另外sentinel也给客户端提供了监控消息的通知这样客户端就可根据消息类型去判断服务器的状态去做对应的适配操作

Sentinel 哨兵的作用

  • Monitoring集群监控Sentinel持续检查集群中的master、slave状态判断是否存活
  • Notification消息通知在发现某个redis实例死的情况下Sentinel能通过API通知系统管理员或其他程序脚本
  • Automatic failover故障转移如果一个master挂掉后sentinel会启动故障转移把某个slave提升为master其他的slave重新配置指向新master
  • Configuration provider配置中心对于客户端来说sentinel通知是有效可信赖的客户端会连接sentinel去请求当前master的地址一旦发生故障sentinel会提供新地址给客户端

核心功能在主从复制的基础上哨兵引入了主节点的自动故障转移

哨兵的核心

  • 哨兵至少需要 3 个实例来保证自己的健壮性
  • 哨兵 + redis 主从的部署架构是不保证数据零丢失的只能保证 redis 集群的高可用性

对于哨兵 + redis 主从这种复杂的部署架构尽量在测试环境和生产环境都进行充足的测试和演练

哨兵模式的故障迁移

  • 主观下线
    哨兵(Sentinel)节点会每秒一次的频率向建立了命令连接的实例发送PING命令如果在down-after-milliseconds毫秒内没有做出有效响应包括(PONG/ LOADING/MASTERDOWN)以外的响应哨兵就会将该实例在本结构体中的状态标记为SRI_s_DOWN主观下线
  • 客观下线
    当一个哨兵节点发现主节点处于主观下线状态是会向其他的哨兵节点发出询问该节点是不是已经主观下线了。如果超过配置参数quorum个节点认为是主观下线时该哨兵节点就会将自己维护的结构体中该主节点标记为SRIO DOWN客观下线询问命令SENTINEL is-master-down-by-addr
  • master选举
    在认为主节点客观下线的情况下哨兵节点节点间会发起一次选举命令为:SENTINEL is-master-down-by-addr只是runid这次会将自己的runid带进去 希望接受者将自己设置为主节点。如果超过半数以上的节点返回将该节点标记为leacer的情况下会有该leader对故障进行迁移

master选举规则

新主库选择哨兵在选择新主库时,先按照一定的筛选条件把不符合条件的从库去掉再按照一定的规则给剩下的从库逐个打分将得分最高的从库选为新主库

从库筛选

在选主时除了要检查从库的当前在线状态还要判断它之前的网络连接状态如果从库总是和主库断连而且断连次数超出了一定的阈值表明这个从库的网络状况并不是太好就可以把这个从库去掉了

在sentinel配置项down-after-milliseconds * 10中down-after-milliseconds 是认定主从库断连的最大连接超时时间如果在down-aftermilliseconds毫秒内主从节点都没有通过网络联系上就可以认为主从节点断连了如果发生断连的次数超过了10次就说明这个从库的网络状况不好不适合作为新主库

从库分数判断

Sentinle集群选主中分别按照三个规则依次进行三轮打分这三个规则分别是从库优先级、从库复制进度以及从库 ID 号只要在某一轮中有从库得分最高那么它就是主库了选主过程到此结束如果没有出现得分最高的从库那么就继续进行下一轮

第一轮优先级最高的从库得分高

用户可以通过slave-priority配置项给不同的从库设置不同优先级比如有两个从库它们的内存大小不一样可以手动给内存大的实例设置一个高优先级在选主时 哨兵会给优先级高的从库打高分如果有一个从库优先级最高那么它就是新主库了如果从库的优先级都一样那么哨兵开始第二轮打分

第二轮和旧主库同步程度最接近的从库得分高

这个规则的依据是如果选择和旧主库同步最接近的那个从库作为主库那么这个新主库上就有最新的数据

如何判断从库和旧主库间的同步进度呢

主从库同步时有个命令传播的过程。在这个过程中主库会用master_repl_offset记录当前的最新写操作在 repl_backlog_buffer中的位置而从库会用slave_repl_offset这个值记录当前的复制进度

此时我们想要找的从库它的slave_repl_offset需要最接近master_repl_offset如果在所有从库中有从库的slave_repl_offset最接近master_repl_offset那么它的得分就最高可以作为新主库但并不是取slave_repl_offsetmaster_repl_offset做对比而是不同从库的slave_repl_offset进行对比的因为这个时候master已经挂掉了无法获取master_repl_offset所以在实际的选主代码中哨兵在这一步是通过比较不同从库的slave_repl_offset找出最大slave_repl_offset的从库也就是选择salve_repl_offset最大的那个从库

master_repl_offset机制master_repl_offset是单调增加的它的值可以大于repl_backlog_size。Redis会用一个名为repl_backlog_idx的值记录在环形缓冲区中的最新写入位置
举个例子例如写入len的数据那么 master_repl_offset += len > repl_backlog_idx += len但是如果repl_backlog_idx等于repl_backlog_size时repl_backlog_idx会被置为0表示从环形缓冲区开始位置继续写入

第三轮ID 号小的从库得分高

每个实例都会有一个 ID这个 ID 就类似于这里的从库的编号目前Redis在选主库时有一个默认的规定在优先级和复制进度都相同的情况下ID 号最小的从库得分最高会被选为新主库Redis server启动时会生成一个40字节长的随机字符串作为runID具体算法用的是 SHA-1算法

部署方式

环境约定Master节点172.17.0.100、Slave1节点172.17.0.101、Slave2节点172.17.0.102

部署思路先配置好主从模式的环境然后再修改sentinel.conf配置文件最后启动即可

编译安装

编译安装好Redis环境(所有节点操作)

# 下载软件包
[root@Redis-Test1 ~]# wget http://download.redis.io/releases/redis-7.2.2.tar.gz

# 解压软件包
[root@Redis-Test1 ~]# tar zxf redis-7.2.2.tar.gz -C /usr/local/
[root@Redis-Test1 ~]# cd /usr/local/redis-7.2.2/
[root@Redis-Test1 redis-7.2.2]# ls
00-RELEASENOTES  CODE_OF_CONDUCT.md  COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  sentinel.conf  tests   utils
BUGS             CONTRIBUTING.md     deps     Makefile  README.md  runtest     runtest-moduleapi  SECURITY.md       src            TLS.md

# 编译
[root@redis-master-01 ~]# make

编辑redis配置文件

修改Redis的配置文件Master节点操作

[root@Redis-Test1 redis-7.2.2]# vim redis.conf

bind 0.0.0.0
port 6379
daemonize yes
pidfile /data/redis/redis.pid
logfile "/data/redis/logs/redis.log"
appendonly yes	#开启AOF持久化
requirepass 123123
dir /data/redis/

修改Redis的配置文件Slave节点操作

[root@Redis-Test2 redis-7.2.2]# vim redis.conf 

bind 0.0.0.0
port 6379
daemonize yes
pidfile /data/redis/redis.pid
logfile "/data/redis/logs/redis.log"
appendonly yes
requirepass 123123
dir /data/redis/

replicaof 172.17.0.100 6379	#指定要同步的master节点ip和端口
masterauth 123123	#指定master的认证口令

启动Redis服务

这里要注意一下先启动Master节点然后在启动Slave节点

/usr/local/redis-7.2.2/src/redis-server /usr/local/redis-7.2.2/redis.conf

到此结束主从环境的配置接下来配置哨兵环节


配置Sentinel配置文件

修改Redis哨兵模式的配置文件所有节点操作

[root@Redis-Test1 redis-7.2.2]# vim sentinel.conf 

bind 0.0.0.0
port 26379
daemonize yes   #哨兵的启动模式yes是后台启动
pidfile /data/redis/redis-sentinel.pid  #哨兵的pid文件存放位置
logfile "/data/redis/logs/redis-sentinel.log" #哨兵的日志文件存放位置
dir /data            #哨兵进程的工作目录默认就是/tmp

#哨兵监听的master数据库mymaster是为主数据库起的名称可以随便起个名字后面是master的ip和端口
# 最后面的1表示选举个数含义是需要多少个哨兵认为master挂了才认定master挂掉这里我设置为1是因为我只有一个哨兵如果你配置了多个哨兵建议配置2以上数字。
sentinel monitor mymaster 172.17.0.100 6379 1	
sentinel auth-pass mymaster 123123								#配置master的登陆密码mymaster是你配置的master名称
sentinel down-after-milliseconds mymaster 30000					#30秒内master无响应则认为master挂掉
acllog-max-len 128												#保持默认即可

#master重新选举之后其它节点能同时并行进行数据同步的台数有多少台
#显然该值越大则所有slave能同步完成的速度越快但如果此时刚好有人访问slave数据可能造成读取失败最保守的值建议设为1
#即同一时间只能有一台进行数据同步这样其它slave还能继续提供服务但是所有的slave数据同步完成就会显得缓慢。
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000		#故障转移超时时间指在该时间内如果故障转移没有成功则会再发起一次故障转移
sentinel deny-scripts-reconfig yes				#保持默认即可
SENTINEL resolve-hostnames no					#保持默认即可
SENTINEL announce-hostnames no					#保持默认即可

启动哨兵服务

先启master的哨兵再启slave的哨兵

/usr/local/redis-7.2.2/src/redis-sentinel /usr/local/redis-7.2.2/sentinel.conf

查看相关信息

[root@Redis-Test3 redis-7.2.2]# ./src/redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.100:6379,slaves=2,sentinels=1

验证故障转移

关闭Master节点观察日志和sentinel信息

12697:X 01 Nov 2023 19:45:57.990 # +monitor master mymaster 172.17.0.100 6379 quorum 1
12697:X 01 Nov 2023 19:47:10.430 # +sdown master mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:10.430 # +odown master mymaster 172.17.0.100 6379 #quorum 1/1
12697:X 01 Nov 2023 19:47:10.430 # +new-epoch 1
12697:X 01 Nov 2023 19:47:10.430 # +try-failover master mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:10.434 * Sentinel new configuration saved on disk
12697:X 01 Nov 2023 19:47:10.434 # +vote-for-leader 02f863db4ebd9962c4557bcad9ec78afd2b86613 1
12697:X 01 Nov 2023 19:47:10.434 # +elected-leader master mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:10.434 # +failover-state-select-slave master mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:10.517 # +selected-slave slave 172.17.0.102:6379 172.17.0.102 6379 @ mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:10.517 * +failover-state-send-slaveof-noone slave 172.17.0.102:6379 172.17.0.102 6379 @ mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:10.690 * +failover-state-wait-promotion slave 172.17.0.102:6379 172.17.0.102 6379 @ mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:11.607 * Sentinel new configuration saved on disk
12697:X 01 Nov 2023 19:47:11.607 # +promoted-slave slave 172.17.0.102:6379 172.17.0.102 6379 @ mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:11.607 # +failover-state-reconf-slaves master mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:11.703 * +slave-reconf-sent slave 172.17.0.101:6379 172.17.0.101 6379 @ mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:12.814 * +slave-reconf-inprog slave 172.17.0.101:6379 172.17.0.101 6379 @ mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:12.814 * +slave-reconf-done slave 172.17.0.101:6379 172.17.0.101 6379 @ mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:12.866 # +failover-end master mymaster 172.17.0.100 6379
12697:X 01 Nov 2023 19:47:12.866 # +switch-master mymaster 172.17.0.100 6379 172.17.0.102 6379
12697:X 01 Nov 2023 19:47:12.867 * +slave slave 172.17.0.101:6379 172.17.0.101 6379 @ mymaster 172.17.0.102 6379
12697:X 01 Nov 2023 19:47:12.867 * +slave slave 172.17.0.100:6379 172.17.0.100 6379 @ mymaster 172.17.0.102 6379
12697:X 01 Nov 2023 19:47:12.871 * Sentinel new configuration saved on disk
12697:X 01 Nov 2023 19:47:42.911 # +sdown slave 172.17.0.100:6379 172.17.0.100 6379 @ mymaster 172.17.0.102 6379
[root@Redis-Test3 redis-7.2.2]# ./src/redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.102:6379,slaves=2,sentinels=1


[root@Redis-Test3 redis-7.2.2]# ./src/redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.17.0.101,port=6379,state=online,offset=55358,lag=0
master_failover_state:no-failover
master_replid:1bc5d3796192e6c518baa423a3d24573a0360abd
master_replid2:0963bdef90dddf0294c0972160a9476e40345768
master_repl_offset:55358
second_repl_offset:8434
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:55358

关于切换不成功常见的问题

无法切换有几种情况

  1. redis保护模式开启了
  2. 选举个数多了或者少了
  3. 端口没有放开
  4. master密码和从密码不一致
  5. master节点的redis.conf没有添加masterauth

方案四集群模式部署

集群即Redis Cluster是Redis 3.0开始引入的分布式存储方案集群由多个节点(Node)组成Redis的数据分布在这些节点中集群中的节点分为主节点和从节点:只有主节点负责读写请求和集群信息的维护从节点只进行主节点数据和状态信息的复制

Redis-Cluster集群的作用

  • 数据分区 数据分区(或称数据分片)是集群最核心的功能集群将数据分散到多个节点一方面突破了Redis单机内存大小的限制存储容量大大增加另一方面每个主节点都可以对外提供读服务和写服务大大提高了集群的响应能力Redis单机内存大小受限问题在介绍持久化和主从复制时都有提及例如如果单机内存太大bgsave和bgrewriteaof 的保存操作可能导致主进程阻塞主从环境下主机切换时可能导致从节点长时间无法提供服务全量复制阶段主节点的复制缓冲区可能溢出
  • 高可用 集群支持主从复制和主节点的自动故障转移与哨兵类似当任一节点发生故障时集群仍然可以对外提供服务

Redis集群的数据分片

Redis集群引入了哈希槽的概念Redis集群有16384个哈希槽编号0-16383)集群的每个节点负责部分哈希槽每个Key通过CRc16校验后对16384取余来决定放置哪个哈希槽通过这个值去找到对应的插槽所对应的节点然后直接自动跳转到这个对应的节点上进行存取操作

以3个节点组成的集群为例:
节点A包含0到5460号哈希槽
节点B包含5461到10922号哈希槽
节点C包含10923到16383号哈希槽

Redis集群的主从复制模型

集群中具有A、B、C三个节点如果节点B失败了整个集群就会因缺少5461-10922这个范围的槽而不可以用为每个节点添加一个从节点A1、B1、C1整个集群便有三个Master节点和三个slave 节点组成在节点B失败后集群选举一位为主节点继续服务但是要注意的是当B和B1都失败后集群将不可用

Redis Cluster的工作原理

在哨兵sentinel机制中可以解决redis高可用问题即当master故障后可以自动将slave提升为master从而可以保证redis服务的正常使用但是无法解决redis单机写入的瓶颈问题即单机redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素

部署方式

环境约定

  • Master节点172.17.0.101、172.17.0.103、172.17.0.105
  • Slave节点172.17.0.102、172.17.0.104、172.17.0.106

部署思路安装部署好所有节点的redis服务并启动然后使用自动部署集群工具设定集群

编译安装

# 下载软件包
[root@redis-master-01 ~]# wget http://download.redis.io/releases/redis-7.2.2.tar.gz

# 解压软件包
[root@redis-master-01 ~]# tar zxf redis-7.2.2.tar.gz -C /usr/local/
[root@redis-master-01 ~]# cd /usr/local/redis-7.2.2/
[root@redis-master-01 redis-7.2.2]# ls
00-RELEASENOTES  CODE_OF_CONDUCT.md  COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  sentinel.conf  tests   utils
BUGS             CONTRIBUTING.md     deps     Makefile  README.md  runtest     runtest-moduleapi  SECURITY.md       src            TLS.md

# 编译
[root@redis-master-01 ~]# make

编辑配置文件

# 编辑配置文件
vim /usr/local/redis-7.2.2/redis.conf
# 监听端口
port 6379

# IP不限制习惯改成0了必须避免后面出现麻烦如果是外网必须!
bind 0.0.0.0

# 设置Redis实例pid文件
pidfile /data/redis/redis.pid

# 后台模式必须
daemonize yes
# 仅追加
appendonly yes
appendfsync always

# 集群开启必须
cluster-enabled yes

# 节点信息可选因为系统会默认
cluster-config-file nodes.conf

# 设置当前节点连接超时毫秒数
cluster-node-timeout 15000

# 数据存放目录
dir /data/redis/

# 认证密码
requirepass 123123

# 设置客户端连接时的超时时间单位为秒
timeout 60

# 日志等级debugrevbosenotice和warning
loglevel notice
# 配置log文件地址默认使用标准输出
logfile "/data/redis/logs/redis.log"

# 设置数据库的个数默认使用的数据库是0
databases 16

# 设置redis进行数据库镜像的频率
save 900 1 300 10 60 10000

# 镜像备份文件的文件名
dbfilename dump.rdb

启动Redis

# 启动Redis
[root@redis-master-01 redis-7.2.2]# /usr/local/redis-7.2.2/src/redis-server /usr/local/redis-7.2.2/redis.conf 
[root@redis-master-01 ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1083/sshd   
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      10980/redis-server  
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      10980/redis-server

验证服务

Redis登录验证

验证没有问题后其余的节点也是这么配置即可~

自动搭建集群

Redis 3.0 版本之后官方发布了一个集群管理工具 redis-trib.rb集成在 Redis 源码包的src目录下。其封装了 Redis 提供的集群命令使用简单、便捷。不过 redis-trib.rb 是 Redis 作者使用 Ruby 语言开发的故使用该工具之前还需要先在机器上安装 Ruby 环境。后面作者可能意识到这个问题Redis 5.0 版本开始便把这个工具集成到 redis-cli 中以–cluster参数提供使用其中create命令可以用来创建集群。如果您安装的 Redis 是 3.x 和 4.x 的版本可以使用 redis-trib.rb 搭建不过之前需要安装 Ruby 环境。先使用 yum 安装 Ruby 环境以及其他依赖项

yum -y install ruby ruby-devel rubygems rpm-build

查看ruby版本

ruby -v

确认没有问题之后我们就可以创建集群了

./redis-cli -a 123123 --cluster create 172.17.0.101:6379 172.17.0.103:6379 172.17.0.105:6379 172.17.0.102:6379 172.17.0.104:6379 172.17.0.106:6379 --cluster-replicas 1

注意主节点在前从节点在后。其中–cluster-replicas参数用来指定一个主节点带有的从节点个数如上–cluster-replicas 1即表示 1 个主节点有 1 个从节点

创建集群结果输出

至此Redis集群搭建完毕

我们可以查看一下节点信息用一下命令或者可查看redis任意一个目录下的 nodes.conf配置文件

[root@redis-master-01 ~]# cat /data/redis/nodes.conf
5f2ce841ecf51d58be0120f7132e1abff2f3b8bc 172.17.0.102:6379@16379,,tls-port=0,shard-id=327de171b1a685bf6f4741253bb8dc7c3134b7b4 slave 78f722a1b410336219fafbe1813fdb5456d9cf0a 0 1698661133000 3 connected
25115e9cb55c0981f16165f19ade5b9de5c6ce87 172.17.0.103:6379@16379,,tls-port=0,shard-id=19c2b46d9a0d0038ae1b57f6c7c4449eb6647c6f master - 0 1698661133000 2 connected 5461-10922
f7cf16beffbb991aa1a2de43b6738289904d683b 172.17.0.104:6379@16379,,tls-port=0,shard-id=8d019b1cdda30d0ad959a197c7cf6308016d1999 slave 278629f1ab3f5d1fcfdbb1274d3000d03be102a7 0 1698661131000 1 connected
2ab90783a1275af9e1fbcee0d3207bea36953e89 172.17.0.106:6379@16379,,tls-port=0,shard-id=19c2b46d9a0d0038ae1b57f6c7c4449eb6647c6f slave 25115e9cb55c0981f16165f19ade5b9de5c6ce87 1698661126915 1698661124000 2 disconnected
278629f1ab3f5d1fcfdbb1274d3000d03be102a7 172.17.0.101:6379@16379,,tls-port=0,shard-id=8d019b1cdda30d0ad959a197c7cf6308016d1999 myself,master - 0 1698661124000 1 connected 0-5460
78f722a1b410336219fafbe1813fdb5456d9cf0a 172.17.0.105:6379@16379,,tls-port=0,shard-id=327de171b1a685bf6f4741253bb8dc7c3134b7b4 master - 0 1698661133000 3 connected 10923-16383
vars currentEpoch 6 lastVoteEpoch 0

或者

[root@redis-master-01 ~]# /usr/local/redis-7.2.2/src/redis-cli -c -h 172.17.0.101 -a 123123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
172.17.0.101:6379> cluster nodes
5f2ce841ecf51d58be0120f7132e1abff2f3b8bc 172.17.0.102:6379@16379 slave 78f722a1b410336219fafbe1813fdb5456d9cf0a 0 1698661185010 3 connected
25115e9cb55c0981f16165f19ade5b9de5c6ce87 172.17.0.103:6379@16379 master - 0 1698661182000 2 connected 5461-10922
f7cf16beffbb991aa1a2de43b6738289904d683b 172.17.0.104:6379@16379 slave 278629f1ab3f5d1fcfdbb1274d3000d03be102a7 0 1698661184000 1 connected
2ab90783a1275af9e1fbcee0d3207bea36953e89 172.17.0.106:6379@16379 slave 25115e9cb55c0981f16165f19ade5b9de5c6ce87 0 1698661185000 2 connected
278629f1ab3f5d1fcfdbb1274d3000d03be102a7 172.17.0.101:6379@16379 myself,master - 0 1698661180000 1 connected 0-5460
78f722a1b410336219fafbe1813fdb5456d9cf0a 172.17.0.105:6379@16379 master - 0 1698661184008 3 connected 10923-16383

集群信息

注意

链接时候务必选择集群模式链接如果你链接失败可以重新看上面配置文件部分或者往下看

由于自动生成的nodes.conf文件里面会默认生成带有内网IP所以你如果是要使用外网链接就去把每一个Redis目录下的 /data/redis/nodes.conf配置文件里面IP为内网的改成外网并且16379端口也要被允许访问注意防火墙问题然后再重启所有Redis不用再重新创建集群

Another Redis 可视化工具连接测试

附录Redis配置参数介绍

基础配置

bind

默认配置bind 127.0.0.1如果没用通过bind命令明确绑定ipredis可以监听到请求过来的所有网络接口
bind后面拼接1个或多个ip地址那么该redis实例只能监听到来自这几个ip的请求

# 举例
bind 192.168.1.100 10.0.0.1
bind 127.0.0.1 ::1
# redis默认配置的是只允许本机访问bind 127.0.0.1
# 如果需要redis允许其他ip访问那么注释掉默认配置即可#bind 127.0.0.1

port

默认配置port 6379port用来配置redis接受连接的端口即监听端口

protected-mode

默认配置protected-mode yesprotected mode是一个安全保护层用来避免redis实例暴漏在互联网被访问或者利用如果开启保护模式并且没有通过bind绑定外部的ip地址并且没有通过requirepass配置密码那么该redis实例只能接受本地127.0.0.1回环地址的连接如果想运行其他主机访问那么可以将保护模式关闭protected-mode no

daemonize

默认配置daemonize noredis默认不是以守护进程的方式后台运行如果想后台运行开启配置daemonize yes

supervised

默认配置supervised no是否Supervised模式运行Redis

pidfile

默认值pidfile /var/run/redis_6379.pid如果配置指定了pid 文件Redis就用该配置的pid文件写入退出的时候移除对应的pid文件。如果Redis是以非守护进程模式的运行又没有配置指定的pid文件那么不会创建pid文件。如果Redis是守护进程的模式即使没有配置指定的pid文件会默认使用 /var/run/redis.pid文件

loglevel

默认配置loglevel notice指定Server的日志级别有以下四种级别

  • debug包含许多具体信息开发/测试环境下很方便
  • verbose包含许多不常用的信息但没有debug级别那么混乱
  • notice适中的信息很适合生产环境
  • warning只记录重要或者非常的信息

logfile

默认值logfile “”指定log文件名。配置成空串的话可以强制Redis在标准输出记录日志。如果使用标准输出进行日志记录且是以守护进程的模式运行日志会在/dev/null中。

syslog-enabled

默认配置syslog-enabled no想让日志记录到系统日志设置syslog-enabled成yes

syslog-ident

默认配置syslog-ident redis指定syslog的身份

syslog-facility

默认配置syslog-facility local0指定syslog工具facility,一定要是USER或者在LOCAL0 - LOCAL7之间

databases

默认配置databases 16设置数据库的数量。默认的数据库号是DB 0

always-show-logo

默认配置always-show-logo yesRedis会在启动的时候如果标准输出日志是TTY则会在开始记录标准输出日志的时候展示一个ASCII字符组成的Redis Logo也就是说通常只在交互的会话中会展示该Logo

持久化配置配置

RDB

save

默认配置save 900 1 300 10 60 10000rdb保存数据,如果时间秒数seconds和写的次数都配置了那么一旦达到了配置条件Redis会将DB保存到硬盘

以默认配置举例达到了以下条件会触发写磁盘
900秒内15分钟且数据库中至少有1个key被改变。
300秒内5分钟且数据库中至少有10个key被改变。
60秒内1分钟且数据库中只有一个10000个key被改变。

可以通过添加一个带空串的save指令来让配置的save选择失效比如save ""

stop-writes-on-bgsave-error

默认配置stop-writes-on-bgsave-error yes在开启了RDB快照后如果最近的一次RDB快照在后台生成失败的话Redis默认会拒绝所有的写请求。这么做的目的是为了让用户注意到后台持久化可能出现了问题。否则用户可能一直无法注意到问题进而可能导致灾难级别的事情发生。如果bgsave正常Redis会自动的继续处理写请求。如果已经为Redis实例和持久化配置了合适的监控手段且希望Redis在非理想情况下比如硬盘问题权限问题等等仍继续提供服务可以将此项配置为no

rdbcompression

默认配置rdbcompression yes想要在生成rdb文件的时候使用LZF压缩String对象将该配置保持默认为yes几乎不会出现意外状况可以将该配置设置为no来节省CPU开销但是那些原本可以被压缩的key和value会让数据集更大

dbchecksum

默认配置rdbchecksum yes从5.0版本开始RDB文件的末尾会默认放置一个CRC64的校验码这会让文件的格式更加容易检验验证代价是生成和加载RDB文件的性能会损失10%左右你可以把该配置关闭以求更佳的性能没有开启校验码配置的RDB文件会将校验码设置为0加载该文件的程序就会跳过校验过程

dbfilename

默认配置dbfilename dump.rdb配置rdb文件的名称

dir

默认配置dir ./工作目录存储rdb文件的目录数据库会使用该配置放置rdb文件文件的名字使用上面的dbfilename指定的文件名AOF文件的存储位置也会使用这个配置项但要注意是配置一个目录而不是文件名

AOF

appendonly

Redis默认使用异步方式转储数据到硬盘但在Redis处理出现问题或者设备断电的意外期间可能丢失相应的写操作取决于save配置的时间点AOF文件是Redis提供的另外一种提供更好的持久性的持久化模式例如如果使用默认的数据传输策略根据之后提供的配置Redis在发生意外情况下比如设备断电或者Redis本身的进程出现了一些问题的情况下操作系统正常运行Redis可以仅仅丢失1秒钟的写操作AOF和RDB的持久化策略可以同时启用如果打开了AOFRedis启动时会加载AOF

常见配置
appendonly yes	#开启AOF
appendfilename "appendonly.aof"	#AOF 的文件名

appendfsync

默认配置appendfsync everysec函数fsync()会告诉操作系统立即把数据写到磁盘上而不是等输出缓冲区有更多的数据时才进行有些OS会马上把数据刷到硬盘有些OS只保证尽快进行刷盘操作

Redis 支持三种模式

  • no不fsync让操作系统来决定什么时候进行刷盘最不会影响Server响应
  • always每写入aof文件就进行fsync影响Server响应但是数据更安全
  • everysec默认模式每秒进行fsync最稳健的形式在响应速度和数据安全方面最稳妥的选择选择no让OS选择写入时机这样有更好的性能表现又或者使用always可以会让响应变慢一些但是数据的安全性会更高如果不确定选哪种的话那就用everysec吧

no-appendfsync-on-rewrite

默认配置no-appendfsync-on-rewrite no当AOF fsync策略是always或者everysec会启动一个后台进程后台进行保存或者AOF文件的后台重写该进程会在磁盘上频繁的I/O在一些Linux配置下Redis的fsync() 调用可能会阻塞太久需要注意的是目前还没有相应的优化策略极端情况下在不同线程进行的fsync可能阻塞同步的write(2)调用为了减缓上面提到的问题可以在主线程调用BGSAVE或者BGREWRITEAOF命名避免fsync()在主线程上调用这意味着当其他的子节点在保存的时候Redis的持久化就和appendfsync no策略一样这意味着在实际中的最糟糕的场景下在默认的Linux配置下有可能丢失超过30s时间粒度的log如果应用不能忍受延迟问题将选项配置为yes否则保持为no这样在持久化的角度上是最安全的选择。

auto-aof-rewtire-percentage、auto-aof-rewrite-min-size

默认配置auto-aof-rewtire-percentage 100 、 auto-aof-rewrite-min-size 64mb 自动重写aof文件Redis支持调用BGREWRITEAOF命名并在AOF文件达到特定的百分比的时候自动重写AOF文件一般是这么工作的Redis会记录最近一次重写后的AOF文件大小如果启动后没有重写过则记录启动时的AOF文件大小基础的文件大小和当前的文件大小进行比较如果当前的大小比配置的百分比大则触发重写操作。同时也应该配置一个触发重写的最小文件大小这么做可以避免当AOF文件达到了配置的百分比但是AOF文件还是很小的情况触发重写操作配置百分比为0意味着关闭自动重写AOF的特性。

aof-load-truncated

默认值aof-load-truncated yes当AOF文件的数据加载到内存的时候AOF文件可能在Redis启动的时候在末尾被截断这可能在跑Redis进程的系统崩溃的情况下出现特别是当一个ext4文件系统挂载的时候没有使用data=ordered选项但是在Redis进程自己崩溃或者中止但是操作系统还正常运行时这种情况就不会发生,当Redis发现AOF在末尾被截断的时候Redis可以主动退出进程或者尽可能的加载更多的数据目前的默认行为并正常启动如果aof-load-truncated设置成yesRedis加载被截断的AOF文件redis启动并将相关的信息写到log中通知用户有这一现象发生。如果设置成noRedis错误充电并拒绝启动当该配置设置为no的时候就要求用户在重启服务前使用redis-check-aof来修复AOF文件。

注意如果AOF文件的中间位置出现了问题Redis仍会错误退出。这个配置选项只在Redis想从AOF文件中读取更多数据但是实在没有新的可以读取的情况下才有作用。

aof-use-rdb-preamble

默认配置aof-use-rdb-preamble yes当重写AOF文件的时候Redis也可以在AOF文件在开头应用RDB文件来更快的重写和恢复。当该配置选项开启AOF文件的重写组成由这两部分组成[RDB file][AOF tail]Redis加载AOF文件的时候发现AOF文件里由"REDIS"字符串打头Redis就会加载预先的RDB文件接着在尾部加载AOF文件。

生产常见配置

安全配置

requirepass

配置格式requirepass password要求客户端先使用命令AUTH进行认证才能处理其他命令

rename-command

配置格式rename-command CONFIG abcdef命令重命名可以在环境中重命名那些比较危险的命令比如把CONFIG命令重命名成一个不好猜的名字这样内部的功能还可以使用且可以避免大部分的客户端使用

客户端配置

maxclients

默认配置maxclients 10000设置可以同时连接客户端的最大数量一旦达到该限制数Redis会拒绝所有的新连接并返回错误信息max number of clients reached

内存管理

maxmemory

配置格式maxmemory设置限定的最大内存使用当内存使用达到限制Redis会根据配置的淘汰策略见maxmemory-policy移除键值对如果根据淘汰策略Redis不能移除键值对Redis会拒绝那些申请更大内存的命令比如SETLPUSH等等但是仍可以处理读请求比如GET等该选项对那些使用Redis进行LRULFU缓存系统或者硬性限制内存很友好使用noeviction策略如果为实例配置了maxmemory且该实例配置了子节点那么已使用内存的大小就需要加上为副本配置的输出缓冲区的大小。这样因为网络问题/重新同步不会一直触发键的淘汰行为。相反的副本缓冲区中充满了对键的删除或淘汰的情况可能触发更多key被淘汰以此类推直到库完全被清空。简单说就是如果为实例配置了副本那么建议设置一个较低的maxmemory值这样系统中就有更多的内存空间留给副本缓冲区如果淘汰策略是‘noeviction’那上面说的就没有必要

maxmemory-policy

默认配置maxmemory-policy noeviction在内存使用达到maxmemory后Redis如何选择键值对进行淘汰。有以下几种

  1. volatile-lru使用LRU算法在设置了过期时间的key中选择
  2. allkeys-lru使用LRU算法在所有的key中选择
  3. volatile-lfu使用LFU算法在设置了过期时间key中选择
  4. allkeys-lfu使用LFU算法在所有的key中选择
  5. volatile-random在设置了过期时间的key中随机选择
  6. allkeys-random在所有key中随机选择
  7. volatile-ttl在设置了过期时间的key中选择过期时间最近的key
  8. noeviction不淘汰key对任何写操作使用额外内存返回错误

LRU 代表最近最少使用
LFU 代码最近最不常使用
LRULFU和volatile-ttl均由近似的随机算法实现
不管采用了以上的哪种策略对于新的写请求如果没有合适的key可以淘汰Redis均会响应一个error

[post cid=“625” cover=“https://resource.if010.com/redis_maxmemory_policy_banner.jpg” size=“”/]

maxmemory-samples

默认配置maxmemory-samples 5LRU、LFU 以及最小TTL的实现都不是精确的而是比较粗略的近似算法为了节省内存为了速度或者精确度可以进行相应的配置。默认Redis会检查5个key在其中选择最近最少使用的也可以直接在下面的配置项中配置 Redis 选择的样本数量,默认配置的值5已经可以有一个很完美的结果,10的话可能会让选择策略更像真正意义上的LRU算法但是需要更多CPU资源3的话会更快但是不够精确

replica-ignore-maxmemory

默认配置replica-ignore-maxmemory yes从Redis 5.0之后副本默认会忽略为其配置的maxmemory选项除非因为故障转移failover或者选择将其晋升为主节点也就是说key的淘汰只会由主节点执行副本对应的是主节点发送对应的删除命令给副本作为key的淘汰方式这个行为模式保证了主副节点的一致性但是如果副本是可写的或者你想要你的副本有不同的内存配置而且你也很确认到达副本的写操作能保证幂等性idempotenet那你可以修改这个默认值但是最好保证你理解了这么做的原因

提示因为副本默认没有maxmemory和淘汰策略副本实际的内存占用可能比maxmemeory配置的值大可能因为副本缓冲区或者某些数据结构占用了额外的内存等等原因。所以确保对副本有合适的监控手段保证在主节点达到配置的maxmemory设置之前副本有足够的内存保证不会出现真正的out-of-memory条件

主从配置

replicaof

配置格式replicaof masterip masterport主从复制使用replicaof来让一个Redis实例复制另一个Redis实例Redis复制是异步进行的但是可以通过配置让Redis主节点拒绝写请求配置会给定一个值主节点至少需要和大于该值的从节点个数成功连接如果 Redis 从节点和主节点意外断连了很少的一段时间从节点可以向主节点进行增量复制复制会自动进行且不需要人为介入

masterauth

配置格式masterauth master-password如果主节点配置了密码使用了"requirepass"配置项从节点需要进行密码认证才能进行复制同步的过程否则主节点会直接拒绝从节点的复制请求

replica-serve-stale-data

默认配置replica-serve-stale-data yes当复制过程与主节点失去连接或者当复制正在进行时复制可以有两种行为模式

  • 如果replica-serve-stale-data设置为’yes’默认设置从节点仍可以处理客户端请求但该从节点的数据很可能和主节点不同步如果这是与主节点进行的第一次同步从节点的数据也可能是空数据集
  • 如果replica-serve-stale-data设置成’no’从节点会对除了INFO、replicaOF、AUTH、PING、SHUTDOWN、REPLCONF、ROLE、CONFIG、SUBSCRIBE、UNSUBSCRIBE、PSUBSCRIBE、PUNSUBSCRIBE、PUBLISH、PUBSUB、COMMAND、POST、HOSTand LATENCY这些命令之外的请求均返回"SYNC with master in process"

replica-read-only

默认配置replica-read-only yes可以配置从节点是否可以处理写请求。针对从节点开启写权限来存储时效低的ephemeral数据可能是一种有效的方式因为写入到从节点的数据很可能随着重新同步而被删除但是开启该配置也会导致一些问题。从Redis 2.6开始从节点默认是仅可读的

repl-diskless-sync

默认配置repl-diskless-sync no同步复制策略硬盘或者套接字不使用硬盘的复制策略目前还在实验阶段新建立连接和重连的副本不会根据数据情况进行恢复传输只会进行全量复制主节点会传输在从节点之间传输RDB文件

传输行为有两种方式
硬盘备份Redis主节点创建一个子进程来向硬盘写RDB文件之后由父进程持续的文件传给副本
不使用硬盘Redis主节点建立一个进程直接向副本的网络套接字写RDB文件不涉及到硬盘

对于方式1在生成RDB文件时多个副本会进行入队并在当前子进程完成RDB文件时立即为副本进行RDB传输而对于方式2一旦传输开始新来的副本传输请求会入队且只在当前的传输断开后才建立新的传输连接如果使用方式2主节点会等待一段时间根据具体的配置等待是为了可以在开始传输前可以有期望的副本同步请求到达这样可以使用并行传输提高效率对于配置是比较慢的硬盘而网络很快带宽大的情况下使用方式2进行副本同步会更适合

repl-diskless-sync-delay

默认配置repl-diskless-sync-delay 5如果diskless sync是开启的话就需要配置一个延迟的秒数这样可以服务更多通过socket传输RDB文件的副本这个配置很重要因为一旦传输开始就不能为新来的副本传输服务只能入队等待下一次RDB传输所以该配置一个延迟的值就是为了让更多的副本请求到达延迟配置的单位是秒默认是 5 秒不想要该延迟的话可以配置为 0 秒传输就会立即开始

repl-ping-replica-period

默认配置repl-ping-replica-period 10副本会根据配置好的时间间隔interval向主节点发送PING命令可以通过repl_ping_replica_period配置修改时间间隔默认为10秒

repl-timeout

默认配置repl-timeout 60配置副本进行超时处理在副本的角度在同步过程中批量进行I/O传输从副本s的角度主节点超时了从主节点的角度副本超时了需要重视的一点是确保该选项的配置比repl-ping-replica-period配置的值更高否则每次主从之间的网络比较拥挤时就容易被判定为超时

repl-disable-tcp-nodelay

默认配置repl-disable-tcp-nodelay no同步过后在副本套接字上关闭TCP_NODELAY如果选择了’yes’Redis会使用很小的TCP包占用很低的带宽来想副本发送数据但是这么做到达副本的数据会有一些延迟使用默认的配置值且是Linux内核该延迟最多可能40毫秒如果选择’no’副本的数据延迟会更低但是占用的带宽会更多一些默认会为了低延迟进行优化但是在比较拥挤网络情况下或者是主节点和副本之间的网络情况比较复杂比如中间有很多路由跳转的情况下把选项设置为’yes’应该会比较适合

repl-backlog-size

默认配置repl-backlog-size 1mb配置副本的缓冲区backlog大小该缓冲区用来在副本断开连接后暂存副本数据这样做是因为副本重新连接后不一定要重新进行全量复制很多时候增量复制同步仅同步断连期间副本可能丢失的数据完全足够了配置的缓冲区越大副本可以承受的断连时间可以更长至少有一个副本连接时缓冲区才会进行分配

repl-backlog-ttl

默认配置repl-backlog-ttl 3600主节点如果一段时间没有副本连接上面提到的缓冲区会被释放可以通过配置一个指定的时间来释放缓冲区如果主节点在这个时间内还没有与新的副本建立连接需要注意的是副本不会因为超时释放缓冲区因为副本可能会被晋升promot为主节点需要保持对其他副本进行增量复制的能力因此他们总是积累缓冲区配置为’0’意味着不释放缓冲区

replica-priority

默认配置replica-priority 100副本的优先级是一个整型数字可以由Redis的INFO命令显示优先级的作用在于当主节点无法提供服务后Redis哨兵会使用到优先级进行选举副本晋升为主节点值越低代表该副本晋升成为主节点的优先级越高比如说有三个副本优先级的值分别为10、100、25Redis哨兵会选择最低的那个即优先级配置为10的那个但是一个特殊的配置值’0’意味着该副本不可能充当主节点的角色故优先级配置为0的副本永远不会被Redis哨兵选择晋升。默认的优先级配置是100

min-replicas-to-write 、 min-replicas-max-lag

主节点可以根据目前连接的延迟慢于M秒的副本数量选择是否拒绝写请求数量N的副本需要是"online"的状态延迟的秒数The lag落后 in secondsM计算方式是根据上一次副本发送ping命令到主节点的时间计算通常每秒都会发送ping命令这个选项不保证N个副本会接受写请求但是如果没有足够的副本可用则会限制那些丢失写请求的暴露窗口至特定的秒数比如要求至少有三个延迟小等于10秒的副本可以这么配置

# 配置设置为 0 会关闭该功能。
# 默认的 min-replicas-to-write 被设置为 0功能关闭
# min-replicas-max-lag 设置为 10.
min-replicas-to-write 3
min-replicas-max-lag 10

replica-announce-ip 、 replica-announce-port

主节点应该有多种方式来列举出依附与它的副本的信息ip和port比如"INFO replication"就可以提供这些信息它也会被其他的功能使用比如Redis哨兵就会使用该命令列举副本实例还有一种方式是在主节点运行"ROLE"命令来获取这些信息

副本获取监听的IP和地址分别通过以下的方式

  • IPIP地址在副本和主节点建立的socket连接中自动被检测到
  • Port端口信息会在副本进行复制的TCP握手中交流传递端口也是副本用来监听连接的一部分

如果使用了端口转发或者NATNetwork Address Translation实际连接到副本很可能通过的是不同的IP和端口对。下面的两个配置选项用来让副本上报特定的IP和端口集合给它连接的主节点之后主节点使用"INFO"或者"ROLE"命令都可以输出这些上报的值

# 如果只想上报ip或端口其中一个就没有必要两个都使用
replica-announce-ip 1.1.1.1
replica-announce-port 6379

集群配置

cluster-enabled

默认配置cluster-enabled yes是否打开集群模式

cluster-config-file

默认配置cluster-config-file nodes-6379.conf设定节点配置文件名

cluster-node-timeout

默认配置cluster-node-timeout 15000设定节点失联时间超过该时间毫秒集群自动进行主从切换

cluster-require-full-coverage

默认配置cluster-require-full-coverage yes如果某一段插槽的主从都挂掉而cluster-require-full-coverage为yes那么 整个集群都挂掉反之cluster-require-full-coverage配置为no那么该插槽数据全都不能使用也无法存储

其他配置

CLUSTER DOCKER/NAT support

在某些部署情况中Redis集群节点可能会出现地址发现失败原因是地址是NAT-ted或者端口转发一个典型的场景就是 Docker 或者其他容器为了让 Redis 集群在这种环境下正常工作就需要个静态的配置文件来让集群节点知晓他们的公共地址下面选项就有这个作用

cluster-announce-ip
cluster-announce-port
cluster-announce-bus-port

SLOW LOG慢日志

默认配置slowlog-log-slower-than 10000 、slowlog-max-len 128Redis的慢日志用来记录那些执行了超过特定时间的查询行为。这里的执行时间不包括I/O操作比如和客户端的通信发送回复的时间等等而应该只是执行了这个命令本身需要的时间就是说执行这个命令期间线程会阻塞且不会同时响应其他的请求慢日志有两个属性可以配置一个用来告诉Redis执行时间的定义什么样的执行时间才要被记录另一个用来配置慢日志的长度记录一个新的命令队列中的最旧的命令会被移除要注意的是配置的时间单位为微秒所以1000000相当于1秒如果配置的是负值慢日志则不起作用如果是0的话慢日志则会记录每个命令长度的配置没有任何限制但是主要内存的消耗可以使用慢日志的SLOWLOG RESET来回收内存

LATENCY MONITOR延迟监控

默认配置latency-monitor-threshold 0Redis的延迟监控系统会在Redis运行期间以不同的操作对象为样本收集和Redis实例相关的延迟行为用户可以通过LETENCY命令打印相关的图形信息和获取相关的报告延迟监控系统只会收集那些执行时间超过了我们通过latency-monitor-threshold配置的值的操作当latency-monitor-threshold的值设置为0的时候延迟监控系统就会关闭默认情况下延迟监控是关闭的因为大多数情况下可能没有延迟相关的问题而且收集数据对性能表现是有影响的虽然影响很小但是在系统高负载运行情况下还是不能忽视的延迟监控系统可以在运行期间使用CONFIG SET latency-monitor-threshold milliseconds开启

LAZY FREEING懒释放

Redis有两个可以删除key的原语primitive其中一种是调用DEL阻塞地删除对象。也就是说Redis Server需要通过同步的方式确认回收了所有和刚才删除的key相关的内存后才能处理接下来的命令。如果要删除的key很小执行DEL命令的时间也很短和其他时间复杂度为O(1)或O(log_N)的命令差不多。但是如果要删除的key涉及到一个存储着百万级别元素的集合Redis Server就可能因此阻塞一段时间甚至到秒的级别
由于同步的处理方式可能带来的问题Redis提供了非阻塞的删除原语比如UNLINK以及异步的选项比如FLUSHALL和FLUSHDB命名为的就是在后台回收内存这些命名会在固定时间执行in constant time另外的线程会在后台以尽可能快的速度释放这些对象

DEL、UNLINK和带有ASYNC选项的FLUSHALL和FLUSHDB命名都可以由用户控制这取决于应用层面是否理解且合适的使用相应的命令来达到目的但是还是有一些情况要注意Redis有时会因为其他操作的副作用导致触发key 的删除或者刷新整个数据库特别是在用户调用了对象删除的以下场景

  • 在淘汰策略下因为配置了maxmemory和maxmemory policy为了在不超过配置的内存限制下腾出空间给新来的数据
  • 因为过期时间的配置当一个key配置了expire时间且时间到了那它必须从内存中移除。命名在已经存在的key上进行数据的存储操作的副作用。比如RENAME命名在替换的时候需要删除原本的key的内容。类似的带有STORE选项的SUNIONSTORE或者SORT命名可能会删除已存在的key。SET命令本身为了用新的值替换会将要操作的key的旧值先删除掉。在REPLICATION期间当副本执行了全量同步复制副本的整个数据库会被清空然后加载传输来的RDB文件。

上面的场景在默认情况下都是以阻塞的方式删除对象比如调用DEL的时候。你在本配置项中为每个场景进行配置这样就可以像 UNLINK 被调用时以非阻塞的方式释放内存

lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
lazyfree-lazy-flush no

附录关于哨兵的常规命令

常用命令

PING
返回 PONG。

SENTINEL masters
列出所有被监视的主服务器以及这些主服务器的当前状态。

SENTINEL slaves
列出给定主服务器的所有从服务器以及这些从服务器的当前状态。

SENTINEL get-master-addr-by-name
返回给定名字的主服务器的 IP 地址和端口号。 如果这个主服务器正在执行故障转移操作 或者针对这个主服务器的故障转移操作已经完成 那么这个命令返回新的主服务器的 IP 地址和端口号。

SENTINEL reset
重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清除主服务器目前的所有状态 包括正在执行中的故障转移 并移除目前已经发现和关联的 主服务器的所有从服务器和 Sentinel 。

SENTINEL failover
当主服务器失效时 在不询问其他 Sentinel 意见的情况下 强制开始一次自动故障迁移 不过发起故障转移的 Sentinel 会向其他 Sentinel 发送一个新的配置其他 Sentinel 会根据这个配置进行相应的更新。

ACL>=6.2
此命令管理Sentinel访问控制列表。有关更多信息请参阅ACL文档页面和Sentinel访问控制列表验证。

AUTH>=5.0.1
对客户端连接进行身份验证。有关更多信息请参阅AUTH命令和配置带有身份验证的Sentinel实例部分。

CLIENT
此命令管理客户端连接。有关详细信息请参阅其子命令页面。

COMMAND>=6.2
此命令返回有关命令的信息。有关详细信息请参阅COMMAND命令及其各种子命令。

HELLO>=6
切换连接的协议。有关详细信息请参阅HELLO命令。

INFO
返回有关Sentinel服务器的信息和统计信息。有关更多信息请参阅INFO命令。

ROLE
此命令返回字符串“sentinel”和受监控主机的列表。

SHUTDOWN
关闭Sentinel实例。

其他命令

SENTINEL CONFIG GETname>=6.2
获取全局SENTINEL配置参数的当前值。指定的名称可以是通配符类似于Redis CONFIG GET命令。

SENTINEL CONFIG SETnamevalue>=6.2
设置全局SENTINEL配置参数的值。

SENTINEL CKQUORUMmaster name
检查当前SENTINEL配置是否能够达到故障转移主机所需的仲裁以及授权故障转移所需的多数仲裁。该命令应在监控系统中使用以检查Sentinel部署是否正常。

SENTINEL FLUSHCONFIG
强制SENTINEL在磁盘上重写其配置包括当前的SENTINEL状态。通常情况下每当状态发生变化时Sentinel都会重写配置在重新启动时保留在磁盘上的状态子集的上下文中。但是有时配置文件可能会因为操作错误、磁盘故障、包升级脚本或配置管理器而丢失。在这些情况下强制Sentinel重写配置文件的方法很方便。即使以前的配置文件完全丢失此命令也能工作。

SENTINEL FAILOVERmaster name
强制进行故障切换就好像无法访问主机一样并且不要求与其他SENTINEL达成一致但是将发布新版本的配置以便其他Sentinels更新其配置。
1.不会与其他Sentinel进行协商
2.转移完成后会通知其他Sentinel节点根据转移结果进行更新

SENTINEL GET-MASTER-ADDR-BY-NAMEMASTER NAME
返回具有该名称的主机的ip和端口号。如果此主机的故障转移正在进行或已成功终止它将返回升级的复制副本的地址和端口。

SENTINEL INFO-CACHE>=3.2
从主控和副本返回缓存的INFO输出。

SENTINEL IS-MASTER-DOWN-BY-ADDR
检查ip:port指定的主机是否从当前SENTINEL的角度关闭。此命令主要用于内部使用。

  1. 为*时Sentinel节点直接交换对主节点下线的判断
  2. 为运行ID时Sentinel节点希望其他Sentinel节点投票自己成为领导者Sentinel(运行ID为Sentinel的运行ID)
  3. 返回值由以下3个参数构成

返回参数说明
down_state 0代表Redis主节点仍在线 1代表Redis主节点已下线
leader_runid *不同意做为领导者运行Sentinel ID该运行ID代表的Sentinel同意
leader_epoch 领导者

SENTINEL MASTERMASTER name
显示指定主机的状态和信息。

SENTINEL MASTERS
显示受监控主机及其状态的列表。

SENTINEL MONITOR
启动SENTINEL的监控。

SENTINEL MYID>=6.2
返回SENTINEL实例的ID。

SENTINEL PENDING-SCRIPTS
此命令返回有关挂起脚本的信息。

SENTINEL REMOVE
停止哨兵的监控。

SENTINEL REPLICASmaster name>=5.0
显示此master的副本列表及其状态。老版本可以用SENTINEL SENTINELS master name

SENTINEL SENTINELSmaster name
显示此master的SENTINEL实例及其状态的列表。

SENTINEL SET
设置SENTINEL的监控配置。

SENTINEL SIMULATE-FAILURE选举后崩溃|晋升后崩溃|帮助>=3.2
此命令模拟不同的SENTINEL崩溃场景。

SENTINEL RESETpattern
此命令将重置具有匹配名称的所有主机。模式参数是glob样式的模式。重置过程会清除主机中以前的任何状态包括正在进行的故障转移并删除已发现并与主机关联的每个复制副本和哨兵。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis

“Redis的四种部署方案-CSDN博客” 的相关文章