• Redis主从复制


    Redis主从复制

    Redis复制功能简单介绍

    1:使用异步复制。

    2:一个主服务器可以有多个从服务器。

    3:从服务器也可以有自己的从服务器。

    4:复制功能不会阻塞主服务器。

    5:可以通过复制功能来让主服务器免于执行持久化操作,由从服务器去执行持久化操作即可。

    Redis复制功能介绍

    1:Redis 使用异步复制。从 Redis2.8开始,从服务器会以每秒一次的频率向主服务器报告复制流(replication stream:的处理进度。

    2:一个主服务器可以有多个从服务器。

    3:不仅主服务器可以有从服务器,从服务器也可以有自己的从服务器,多个从服务器之间可以构成一个图状结构。

    4:复制功能不会阻塞主服务器:即使有一个或多个从服务器正在进行初次同步, 主服务器也可以继续处理命令请求。

    5:复制功能也不会阻塞从服务器:只要在 redis.conf 文件中进行了相应的设置, 即使从服务器正在进行初次同步, 服务器也可以使用旧版本的数据集来处理命令查询。

    6:在从服务器删除旧版本数据集并载入新版本数据集的那段时间内,连接请求会被阻塞。

    7:还可以配置从服务器,让它在与主服务器之间的连接断开时,向客户端发送一个错误。

    8:复制功能可以单纯地用于数据冗余(data redundancy:,也可以通过让多个从服务器处理只读命令请求来提升扩展性(scalability:: 比如说,繁重的SORT命令可以交给附属节点去运行。

    9:可以通过复制功能来让主服务器免于执行持久化操作:只要关闭主服务器的持久化功能,然后由从服务器去执行持久化操作即可。

    关闭主服务器持久化时,复制功能的数据安全

    1.当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。 否则的话,由于延迟等问题,部署的服务应该要避免自动拉起。

    2.为了帮助理解主服务器关闭持久化时自动拉起的危险性,参考一下以下会导致主从服务器数据全部丢失的例子:

    ​ a.假设节点A为主服务器,并且关闭了持久化。并且节点B和节点C从节点A复制数据

    ​ b.节点A崩溃,然后由自动拉起服务重启了节点A. 由于节点A的持久化被关闭了,所以重启之后没有任何数据

    ​ c.节点B和节点C将从节点A复制数据,但是A的数据是空的,于是就把自身保存的数据副本删除。

    结论:

    1:在关闭主服务器上的持久化,并同时开启自动拉起进程的情况下,即便使用Sentinel来实现Redis的高可用性,也是非常危险的。因为主服务器可能拉起得非常快,以至于Sentinel在配置的心跳时间间隔内没有检测到主服务器已被重启,然后还是会执行上面的数据丢失的流程。

    2:无论何时,数据安全都是极其重要的,所以应该禁止主服务器关闭持久化的同时自动拉起。

    主从复制原理:

    1:从服务器向主服务器发送 SYNC 命令。

    2:接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下来执行的所有写命令。

    3:当主服务器执行完 BGSAVE 命令时,它会向从服务器发送 RDB 文件,而从服务器则会接收并载入这个文件。

    4:主服务器将缓冲区储存的所有写命令发送给从服务器执行。

    开启主从复制(只需一条命令)

    #开启主从复制(在从库上执行)
    127.0.0.1:6379> SLAVEOF 10.0.0.51 6379
    OK
    
    #查看主从信息
    127.0.0.1:6379> INFO replication
    # Replication
    role:slave                   ##角色是从库
    master_host:10.0.0.51           ##主库IP是10.0.0.51
    master_port:6379
    master_link_status:down
    master_last_io_seconds_ago:-1
    master_sync_in_progress:0
    slave_repl_offset:1
    master_link_down_since_seconds:1540419761
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    

    Redis是怎么保证数据安全的呢?

    1:主服务器只在有至少N个从服务器的情况下,才执行写操作

    2:从Redis 2.8开始,为了保证数据的安全性,可以通过配置,让主服务器只在有至少N个当前已连接从服务器的情况下,才执行写命令。

    3:不过,因为 Redis 使用异步复制,所以主服务器发送的写数据并不一定会被从服务器接收到,因此, 数据丢失的可能性仍然是存在的。

    4:通过以下两个参数保证数据的安全:

    #执行写操作所需的至少从服务器数量
    min-slaves-to-write <number of slaves>
    #指定网络延迟的最大值
    min-slaves-max-lag <number of seconds>
    

    Redis主从实践

    实验环境

    角色 主机 IP 端口
    主库(master) db01 10.0.0.51 6379
    从库(slave01) db01 10.0.0.51 6380
    主库(slave02) db01 10.0.0.51 6381

    配置多实例

    #创建多实例目录
    [root@db01 ~]# /etc/redis/{6379,6380,6381}
    
    #编辑多实例配置文件
    [root@db01 ~]# cat /etc/redis/6379/redis.conf /etc/redis/6380/redis.conf /etc/redis/6381/redis.conf
    
    #redis 6379 配置文件
    port 6379
    daemonize yes
    pidfile /etc/redis/6379/redis.pid
    loglevel notice
    logfile /etc/redis/6379/redis.log
    dbfilename dump.rdb
    dir /etc/redis/6379
    bind 127.0.0.1 10.0.0.51
    protected-mode no
    
    #redis 6380 配置文件
    port 6380
    daemonize yes
    pidfile /etc/redis/6380/redis.pid
    loglevel notice
    logfile /etc/redis/6380/redis.log
    dbfilename dump.rdb
    dir /etc/redis/6380
    bind 127.0.0.1 10.0.0.51
    protected-mode no
    
    #redis 6381 配置文件
    port 6381
    daemonize yes
    pidfile /etc/redis/6381/redis.pid
    loglevel notice
    logfile /etc/redis/6381/redis.log
    dbfilename dump.rdb
    dir /etc/redis/6381
    bind 127.0.0.1 10.0.0.51
    protected-mode no
    
    #启动redis多实例
    [root@db01 ~]# redis-server /etc/redis/6379/redis.conf
    [root@db01 ~]# redis-server /etc/redis/6380/redis.conf
    [root@db01 ~]# redis-server /etc/redis/6381/redis.conf
    
    #查看进程
    [root@db01 ~]# ps -ef|grep redis
    root       3570      1  0 22:44 ?        00:00:00 redis-server 127.0.0.1:6379
    root       3574      1  0 22:44 ?        00:00:00 redis-server 127.0.0.1:6380
    root       3578      1  0 22:44 ?        00:00:00 redis-server 127.0.0.1:6381
    

    开启主从

    #连接从库slave01(6380:
    [root@db01 ~]# redis-cli -p 6380
    
    #开启主从
    127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
    OK
    
    #查从信息
    127.0.0.1:6380> INFO replication
    # Replication
    role:slave             ##角色变成了从库
    master_host:127.0.0.1       ##主库的ip
    master_port:6379          ##主库的端口
    master_link_status:up
    master_last_io_seconds_ago:7
    master_sync_in_progress:0
    slave_repl_offset:15
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
    #连接从库slave02(6381:
    [root@db01 ~]# redis-cli -p 6381
    
    #开启主从
    127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
    OK
    
    #查看主从信息
    127.0.0.1:6381> INFO replication
    # Replication
    role:slave            ##角色变成了从库
    master_host:127.0.0.1       ##主库的ip
    master_port:6379         ##主库的端口
    master_link_status:up
    master_last_io_seconds_ago:9
    master_sync_in_progress:0
    slave_repl_offset:225
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
    #连接master(6379:
    [root@db01 ~]# redis-cli -p 6379
    
    #在主库上查看主从复制信息
    127.0.0.1:6379> INFO replication
    
    # Replication
    role:master           ##角色master
    connected_slaves:2       ##两台slave
    slave0:ip=127.0.0.1,port=6380,state=online,offset=337,lag=1
    slave1:ip=127.0.0.1,port=6381,state=online,offset=337,lag=1
    master_repl_offset:337
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:336
    

    主从切换

    #连接master(6379:
    [root@db01 ~]# redis-cli -p 6379
    
    #关闭主库
    127.0.0.1:6379> shutdown
    
    #连接从库slave01(6380:
    [root@db01 ~]# redis-cli -p 6380
    
    #查看主从信息
    127.0.0.1:6380> INFO replication
    # Replication
    role:slave
    master_host:127.0.0.1
    master_port:6379
    master_link_status:down          ##连接主库的状态是:down
    master_last_io_seconds_ago:-1
    master_sync_in_progress:0
    slave_repl_offset:1877
    master_link_down_since_seconds:58
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
    #取消6380的主从关系
    127.0.0.1:6380> SLAVEOF no one
    OK
    127.0.0.1:6380> info replication
    # Replication
    role:master                ##此时6380的角色就变成了master
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
    #将其他从库重新指向新主(6380:
    
    #连接6381从库
    [root@db01 ~]# redis-cli -p 6381
    
    #将6381从库变成6380的从库
    127.0.0.1:6381> SLAVEOF 127.0.0.1 6380
    OK
    
    #查看主从信息
    127.0.0.1:6381> INFO replication
    # Replication
    role:slave            ##角色还是slave
    master_host:127.0.0.1
    master_port:6380        ##主库的端口已经变成了6380
    master_link_status:up
    master_last_io_seconds_ago:4
    master_sync_in_progress:0
    slave_repl_offset:1
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
  • 相关阅读:
    判断是否在可视区域
    格式化数字10000,为10,000
    把数组(含有30项分成5组)
    排序
    enzyme 学习一
    golang使用sftp连接服务器远程上传、下载文件
    golang使用ssh远程连接服务器并执行命令
    一文弄懂vlan、三层交换机、网关、DNS、子网掩码、MAC地址的含义
    golang的序列化与反序列化的几种方式
    golang命令行参数解析
  • 原文地址:https://www.cnblogs.com/longren/p/11889909.html
Copyright © 2020-2023  润新知