云计算百科
云计算领域专业知识百科平台

Redis知识点(二)

redis知识点(二)

1.主从复制优化

  • redis主从同步分为全量同步和增量同步。且主从同步是非阻塞的,即同步过程不会影响主服务器的正常访问。
  • 主节点重启会导致全量同步,从节点重启只会导致增量同步。

1.1全量复制过程

在这里插入图片描述

  • 主从节点建立连接,验证身份后,从节点想主节点发送PSYNC命令。
  • 主节点向从节点发送FULLRESYNC命令,包括master_replid(runID)和offset
  • 从节点保存主节点信息
  • 主节点执行BGSAVE保存RDB文件,同时记录新的记录到buffer中
  • 主节点发送RDB文件给从节点
  • 主节点将新收到buffer中的记录发送至从节点
  • 从节点删除本机的旧数据
  • 从节点加载RDB
  • 从节点同步主节点的buffer信息

​全量复制发生在下面情况

  • 从节点首次连接主节点(无master_replid/run_id)
  • 从节点的复制偏移量不在复制积压缓冲区内
  • 从节点无法连接主节点超过一定的时间

1.2增量复制过程

在这里插入图片描述

  • 在主从复制首次完成全量同步之后再次需要同步时,从服务器只要发送当前的offset位置(类似于MySQL的binlog的位置)给主服务器,然后主服务器根据相应的位置将之后的数据(包括写在缓冲区的积压数据)发送给从服务器,再次将其保存到从节点内存即可

1.3主从同步完整过程

主从同步完整过程如下:

  • slave发起连接master,验证通过后,发送PSYNC命令
  • master接收到PSYNC命令后,执行BGSAVE命令将全部数据保存至RDB文件中,并将后续发生的写操作记录至buffer中
  • master向所有slave发送RDB文件
  • master向所有slave发送后续记录在buffer中写操作
  • slave收到快照文件后丢弃所有旧数据
  • slave加载收到的RDB到内存
  • slave 执行来自master接收到的buffer写操作
  • 当slave完成全量复制后,后续master只会先发送slave_repl_offset信息
  • 以后slave比较自身和master的差异,只会进行增量复制的数据即可

1.4避免全量复制

  • 第一次全量复制不可避免,后续的全量复制可以利用小主节点(内存小),业务低峰时进行全量
  • 节点master_replid或RUN_ID不匹配:主节点重启会导致master_replid或RUN_ID变化,可能会触发全量复制,可以利用config命令动态修改配置,故障转移例如哨兵或集群选举新的主节点也不会全量复制,而从节点重启动,不会导致全量复制,只会增量复制
  • 复制挤压缓冲区不足:当主节点生成的新数据大于缓冲区大小,从节点恢复和主机节点连接后,会导致全量复制。解决方法:将repl-backlog-size调大

1.5避免复制风暴

  • 单主节点复制风暴:当主节点重启,多从节点复制;解决方法:跟换复制拓扑。级联复制。

  • 单机器多实例复制风暴。机器宕机后,大量全量复制。解决方法:主节点分散多机器
    在这里插入图片描述

1.6常见主从复制故障

  • 主从硬件和软件配置不一致

    • 主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据

    • rename-command 命令不一致,如在主节点启用flushdb,从节点禁用此命令,结果在master节点执行flushdb后,导致slave节点不同步

  • slave节点配置的master密码错误

  • redis的版本不一致,主从复制的所有节点应该使用相同的版本。

  • 如果开启了安全模式,并且没有设置bind地址和密码,会导致无法远程连接

2.redis哨兵sentinel

在这里插入图片描述

  • 客户从sentinel获取Redis信息。
  • Sentinel是一个分布式系统,即需要在多个节点上各自同时运行一个sentinel进程,Sentienl 进程通过流言协议(gossip protocols)来接收关于Master是否下线状态,并使用投票协议(Agreement Protocols)来决定是否执行自动故障转移,并选择合适的Slave作为新的Master

2.1sentinel中的三个定时任务

  • 每10秒每个sentinel对master和slave执行info——发现slave节点,确认主从关系

  • 每2秒每个sentinel通过master节点的channel交换信息(pub/sub)

    ——通过sentinel__:hello频道交互;交互对节点的“看法”和自身信息

  • 每1秒每个sentinel对其他sentinel和redis执行ping

2.2搭建哨兵系统

  • 哨兵的前提是实现了主从复制,包括master和slave在内的所有节点的 masterauth 和requirepassslave 密码都必须相同
  • 所有主节点的 redis.conf 中关健配置

#在所有主从节点执行
#基于包安装
yum -y install redis
apt -y install redis redis-sentinel

#所有节点的masterauth和requirepass必须相同
[root@centos8 ~]#vim /etc/redis.conf
bind 0.0.0.0
masterauth "123456"
requirepass "123456"

#在所有从节点执行
[root@centos8 ~]#echo "replicaof 10.0.0.8 6379" >> /etc/redis.conf

#在所有主从节点执行
[root@centos8 ~]#systemctl enable –now redis

  • 查看主节点状态

#redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface
may not
127.0.0.1:6379> INFO replication

# Replication
role:master
connected_slaves:2
slave0:ip=10.0.0.28,port=6379,state=online,offset=112,lag=1
slave1:ip=10.0.0.18,port=6379,state=online,offset=112,lag=0

  • 配置slave1

>REPLICAOF 10.0.0.8 6379
ok
>CONFIG SET masterauth "123456"
ok
>INFO replication
role:slave
master_host:10.0.0.8
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:140
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8fdca730a2ae48fb9c8b7e739dcd2efcc76794f3
master_replid2:0000000000000000000000000000000000000000

  • 配置slave2

>REPLICAOF 10.0.0.8 6379
OK
>CONFIG SET masterauth "123456"
ok
>INFO replication
role:slave
master_host:10.0.0.8
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:182
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8fdca730a2ae48fb9c8b7e739dcd2efcc76794f3
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:168

  • 编辑哨兵配置

    • Sentinel实际上是一个特殊的redis服务器,有些redis指令支持,但很多指令并不支持.默认监听在26379/tcp端口.
    • 哨兵服务可以和Redis服务器分开部署在不同主机,但为了节约成本一般会部署在一起
    • 所有redis节点使用相同的以下示例的配置文件

    cp redis-7.0.5/sentinel.conf /apps/redis/etc/sentinel.conf
    chown redis.redis /apps/redis/etc/sentinel.conf

    #编译安装修改配置文件
    protected-mode no #包安装时默认为yes,此处要修改为no
    port 26379
    daemonize no
    pidfile "/apps/redis/run/redis-sentinel.pid"
    logfile "/apps/redis/log/redis-sentinel.log"
    dir "/tmp"
    sentinel monitor mymaster 10.0.0.102 6379 2
    #mymaster是集群的名称,此行指定当前mymaster集群中master服务器的地址和端口
    #2为法定人数限制(quorum),即有几个sentinel认为master down了就进行故障转移,一般此值是所有sentinel节点(一般总数是>=3的 奇数,如:3,5,7等)的一半以上的整数值,比如,总数是3,即3/2=1.5,取整为2,是master的ODOWN客观下线的依据

    #mymaster集群中master的密码,注意此行要在上面行的下面,注意:要求这组redis主从复制所有节点的密
    码是一样的
    sentinel down-after-milliseconds mymaster 3000
    #判断mymaster集群中所有节点的主观下线(SDOWN)的时间,单位:毫秒,建议3000
    acllog-max-len 128
    sentinel deny-scripts-reconfig yes
    sentinel resolve-hostnames no
    sentinel announce-hostnames no

    #包安装修改配置文件
    vim /etc/redis-sentinel.conf
    bind 0.0.0.0
    port 26379
    daemonize yes
    pidfile "redis-sentinel.pid"
    logfile "sentinel_26379.log"
    dir "/tmp" #工作目录
    sentinel monitor mymaster 10.0.0.8 6379 2
    sentinel auth-pass mymaster 123456
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    #发生故障转移后,可以同时向新master同步数据的slave的数量,数字越小总同步时间越长,但可以减轻新master的负载压力
    sentinel failover-timeout mymaster 180000
    #所有slaves指向新的master所需的超时时间,单位:毫秒
    sentinel deny-scripts-reconfig yes #禁止修改脚本
    logfile /var/log/redis/sentinel.log

  • 三个哨兵服务器配置

sentinel monitor mymaster 10.0.0.8 6379 2 #修改此行
sentinel auth-pass mymaster 123456 #增加此行
sentinel down-after-milliseconds mymaster 3000 #修改此行
#注意此行自动生成必须唯一,一般不需要修改,如果相同则修改此值需重启redis和sentinel服务
sentinel myid 50547f34ed71fd48c197924969937e738a39975b

  • 启动哨兵服务

[root@redis-master ~]systemctl enable –now redis-sentinel.service
[root@redis-slave1 ~]systemctl enable –now redis-sentinel.service
[root@redis-slave2 ~]systemctl enable –now redis-sentinel.service

  • 查看当前sentinel状态

    在sentinel状态中尤其是最后一行,涉及到masterIP是多少,有几个slave,有几个sentinels,必须是符合全部服务器数量

#redis-cli -p 26379
127.0.0.1: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=10.0.0.8:6379,slaves=2,sentinels=3 #两个slave,三个sentinel服务器,如果sentinels值不符合,检查myid可能冲突

2.3sentinel运维

vim /etc/redis.conf
replica-priority 10 #指定优先级,值越小sentinel会优先将之选为新的master,默认值为100,如果为0,表示只当从节点

#或者动态修改
127.0.0.1:6379> CONFIG GET replica-priority
1) "replica-priority"
2) "100"
127.0.0.1:6379> CONFIG SET replica-priority 99
OK
127.0.0.1:6379> CONFIG GET replica-priority
1) "replica-priority"
2) "99"

2.4应用程序连接sentinel

  • Java连接

#jedis/pom.xml 配置连接redis
<properties>
<redis
hosts>localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383
,localhost:6384,localhost:6385</redishosts>
<sentinelhosts>localhost:26379,localhost:26380,localhost:26381</sentinelhosts>
<clusterhosts>localhost:7379,localhost:7380,localhost:7381,localhost:7382,localhost:7383
,localhost:7384,localhost:7385</clusterhosts>
<github.global.server>github</github.global.server>
</properties>

  • python连接

apt -y install python3-redis
cat sentinel_test.py
#!/usr/bin/python3
import redis
from redis.sentinel import Sentinel

#连接到哨兵服务(主机也可以使用域名)
sentinel = sentinel([('10.0.0.8',26379),
('10.0.0.18',26379),
('10.0.0.28',26379)],
socket_timeout=0.5)

redis_auth_pass = '123456'

#mymaster是配置哨兵模式的redis集群名称,此为默认值
#获取主服务器地址
master = sentinel.discover_master('mymaster')
print(master)

#获取从服务器地址
slave = sentinel.discover_slaves('mymaster')
print(master)

#获取主服务器进行写入
master = sentinel.master_for('mymaster', socket_timeout=0.5,
password=redis_auth_pass, db=0)
w_ret = master.set('name', 'wang')
#输出:True

#获取从服务器进行读取(默认是round-roubin)
slave = sentinel.slave_for('mymaster', socket_timeout=0.5,
password=redis_auth_pass, db=0)
r_ret = slave.get('name')
print(r_ret)
#输出:wang

#给权限
chmod +x sentinel_test.py

#运行脚本
./sentinel_test.py

赞(0)
未经允许不得转载:网硕互联帮助中心 » Redis知识点(二)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!