• Redis—听说你速度跟甲斗一样快?——主从复制


    前言

    现如今,Redis变得越来越流行,在很多业务场景都使用到了Redis。那么在一些高并发、大流量的业务场景里,Redis是如何高效、稳定地提供服务呢?

    现在假设你有一台Redis来对外提供服务,架构如下

    在这里插入图片描述

    Redis负责缓存后端数据库的数据以及用户的写数据,由于Redis的数据都是运行在内存中,所以大大提高了业务的性能

    刚开始你的业务流量不算很大,随着时间的推移,你的Redis里的数据越来越多,突然有一天,你的Redis宕机了,这时前端所有的流量都会打到后端的数据库上,这会导致你的数据库压力剧增,严重的话还对压垮数据库

    这时你该怎么办,可能你想的是重启Redis不就行了,但是Redis的数据都是在内存中的,重启之后就什么都没了;这时你可能想到文章上篇介绍到的数据持久化机制,通过将内存中的数据持久化到磁盘里,避免了Redis因某些故障导致的数据丢失

    但是在恢复数据这段时间里,你的业务很有可能还是会收到影响,有没有更好的方法呢?

    一台Redis宕机,只能通过恢复数据来解决,那我们是不是可以部署多个Redis,然后让它们保持数据同步,这样当其中一台Redis宕机时,我们再重新挑选一台Redis继续提供服务就好了

    这个方法就是下面我要将的Redis第一个架构——主从复制

    主从复制

    • 在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复和负载均衡等需求。Redis也是如此,它为我们提供了复制功能,实现了相同数据的多个Redis副本。复制功能是高可用Redis 的基础,后面章节的哨兵和集群都是在复制的基础上实现高可用的
    • 优点:保障数据安全,实现高可用
    • 缺点:
      • 主节点出现问题,不能提供服务。需要人工修改配置
      • 主节点的写能力有限
      • 单机节点存储能力有限

    数据同步方式

    • 全量同步

    一般发生再slave初始化阶段,这时slave需要将master上的所有数据都复制一份

    步骤如下:

    1.从服务器连接主服务器,发送PSYNC命令
    2.主服务器收到PSYNC命令之后开始执行BGSAVE命令生成RDB快照,在生成过程中使用缓冲区来记录此后执行的所有写命令
    3.主服务器执行完BGSAVE后,向从服务器发送快照文件,并在发送期间继续记录被执行的写命令
    4.从服务器收到快照文件后丢弃所有旧数据,载入收到的快照
    5.主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令
    6.从服务器载入快照后,开始接收命令请求,并执行来自主服务器缓冲区的写命令
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 增量同步

    slave初始化后开始正常工作时主服务器将发生的写操作同步到从服务器的过程

    增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令

    • 同步策略

    主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave在任何时候都可 以发起全量同步

    redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步

    增量同步其实是以全量同步为基础(得到复制ID),
    用复制积压缓冲区中的缓存命令做命令重放的增量同步逻辑,
    不过受制于复制积压缓冲区的容量,它可容忍的范围是有限的。
    这与持久化机制的AOF混合持久化如出一辙,也与mysql中主从复制的Binlog思路不谋而合
    
    • 1
    • 2
    • 3
    • 4

    部署

    在这里插入图片描述

    • master配置
    vim /etc/redis/redis.conf
    bind 0.0.0.0
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize yes
    supervised systemd
    pidfile "/var/run/redis.pid"
    loglevel notice
    logfile "/var/log/redis/redis.log"
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename "dump.rdb"
    dir "/var/lib/redis"
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • slave1配置
    vim /etc/redis/redis.conf
    bind 0.0.0.0
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize yes
    supervised systemd
    pidfile "/var/run/redis.pid"
    loglevel notice
    logfile "/var/log/redis/redis.log"
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename "dump.rdb"
    dir "/var/lib/redis"
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    appendonly no
    appendfilename "appendonly.aof"
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    lua-time-limit 5000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events ""
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    aof-rewrite-incremental-fsync yes
    slaveof 192.168.149.128 6379
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • slave2配置
    vim /etc/redis/redis.conf
    bind 0.0.0.0
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize yes
    supervised systemd
    pidfile "/var/run/redis.pid"
    loglevel notice
    logfile "/var/log/redis/redis.log"
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename "dump.rdb"
    dir "/var/lib/redis"
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    appendonly no
    appendfilename "appendonly.aof"
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    lua-time-limit 5000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events ""
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    aof-rewrite-incremental-fsync yes
    slaveof 192.168.149.128 6379
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    
    ## 默认yes,开启之后保护你的redis实例,只能本地使用,外网不允许连接和操作
    protected-mode no
    
    ## 是否以守护进程方式启动
    daemonize yes
    
    ## no:开机不会自启动;systemed:开机自启动
    supervised systemd
    
    ## RDB持久化配置
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes ## 当启用了RDB且最后一次后台保存数据失败,Redis是否停止接
    收数据
    rdbcompression yes ## 对于存储到磁盘中的快照,可以设置是否进行压缩存储
    rdbchecksum yes ## 在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验
    
    ## salve配置,指定哪台服务器是master
    slaveof 192.168.149.128 6379
    
    ## 默认redis使用的是rdb方式持久化
    appendonly no
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 启动则完成主从复制架构的部署
    systemctl start redis-server
    
    • 1
    • 验证

    可以看到master下有两台slave,分别是192.168.149.129、192.168.149.130

    [root@master ~]# redis-cli  -p 6379
    127.0.0.1:6379> info Replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=192.168.149.129,port=6379,state=online,offset=169,lag=0
    slave1:ip=192.168.149.130,port=6379,state=online,offset=169,lag=0
    master_repl_offset:169
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:168
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    我们随便登上一台slave的Redis查看一下

    #slave1
    [root@slave1 ~]# redis-cli -p 6379
    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:192.168.149.128
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:1
    master_sync_in_progress:0
    slave_repl_offset:267
    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
    
    #salve2
    [root@slave2 ~]# redis-cli -p 6379
    127.0.0.1:6379> info Replication
    # Replication
    role:slave
    master_host:192.168.149.128
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:3
    master_sync_in_progress:0
    slave_repl_offset:379
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 测试

    现在master上写入,看slave有没有同步数据

    
    # master操作
    192.168.149.128:6379> set name python
    OK
    192.168.149.128:6379> get name
    "python"
    
    # slave同步数据
    192.168.149.129:6379> get name
    "python"
    
    192.168.149.130:6379> get name
    "python""
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ps:slave只能读数据,不能写数据

    192.168.149.129:6379> set name1 java
    (error) READONLY You can't write against a read only slave.
    
    • 1
    • 2
  • 相关阅读:
    JD-怎样获取别人家店铺商品的API接口呢??
    Java岗吃透这份pdf,拿下阿里、腾讯等大厂offer
    11月4日绿健简报,星期五,农历十月十一
    仓储业如何减低成本
    【excel技巧】单元格内的公式如何隐藏?
    Vision Transformer(ViT)论文解读与代码实践(Pytorch)
    掌握未来技术趋势,Python编程引领人工智能时代
    c 按位运算
    CentOS7中原生Python2.7.5和Python3共存
    Matlab2022b软件如何切换中/英文界面?
  • 原文地址:https://blog.csdn.net/s_alted/article/details/126400817