Redis中的主从复制与Sentinel

主从复制

  • 定义

    • 一个Redis服务可以有多个该服务的复制品,这个Redis服务成为master,其他复制品成为slaves。
    • master会一直将自己的数据更新同步给slaves,保持主从同步。
    • master可以执行读写命令,主要负责写,slave只能执行读命令。
  • 作用:分担了redis读的压力(高并发)

  • 原理:从服务器执行客户端发送的读命令,比如GET、LRANGE、SMEMMBERS、HGET、ZRANGE等等,客户端可以连接slaves执行读请求,来降低master的读压力。

两种实现方式

  1. 命令行实现

    • Linux命令行实现

      redis-server --slaveof <master-ip> <master-port>
      
      # 从服务端6300端口作为6379的从
      redis-server --port 6300 --slaveof 127.0.0.1 6379
      # 从客户端
      redis-cli -p 6300
      127.0.0.1:6300> keys * 
      # 发现是复制了原6379端口的redis中数据
      127.0.0.1:6300> set mykey 123
      (error) READONLY You can't write against a read only slave.
      # 从服务器只能读数据,不能写数据
      
    • Redis命令行实现

      > slaveof IP PORT
      > slaveof no one
      
      # 服务端启动
      redis-server --port 6301
      # 客户端连接
      $ redis-cli -p 6301
      127.0.0.1:6301> keys *
      1) "myset"
      2) "mylist"
      127.0.0.1:6301> set mykey 123
      OK
      # 切换为从
      127.0.0.1:6301> slaveof 127.0.0.1 6379
      OK
      127.0.0.1:6301> set newkey 456
      (error) READONLY You can't write against a read only slave.
      127.0.0.1:6301> keys *
      1) "myset"
      2) "mylist" 
      # 再切换为主
      127.0.0.1:6301> slaveof no one
      OK
      127.0.0.1:6301> set name hello
      OK
      
  2. 修改配置文件

  • 每个redis服务,都有1个对应的配置文件

    # 两个redis服务
    1、6379 -> /etc/redis/redis.conf
    2、6300 -> /code/redis_6300.conf
    # 修改配置文件
    vim redis_6300.conf
    slaveof 127.0.0.1 6379
    port 6300
    # 启动redis服务
    redis-server redis_6300.conf
    # 客户端连接测试
    redis-cli -p 6300
    127.0.0.1:6300> hset user:1 username haha
    (error) READONLY You can't write against a read only slave.
    
  • 问题总结:master挂了怎么办?

    • 一个Master可以有多个Slaves。Slave下线,只是读请求的处理性能下降;Master下线,写请求无法执行。
    • 其中一台Slave使用SLAVEOF no one命令成为Master,其他Slaves执行SLAVEOF命令指向这个新的Master,从它这里同步数据
    • 注:以上过程是手动的,如果想要实现自动,这就需要Sentinel哨兵,实现故障转移Failover操作
    # 1、启动端口6400redis,设置为6379的slave
    redis-server --port 6400
    redis-cli -p 6400
    redis>slaveof 127.0.0.1 6379
    # 2、启动端口6401redis,设置为6379的slave
    redis-server --port 6401
    redis-cli -p 6401
    redis>slaveof 127.0.0.1 6379
    # 3、关闭6379redis
    sudo /etc/init.d/redis-server stop
    # 4、把6400redis设置为master
    redis-cli -p 6401
    redis>slaveof no one
    # 5、把6401的redis设置为6400redis的salve
    redis-cli -p 6401
    redis>slaveof 127.0.0.1 6400
    

高可用方案 - Sentinel

  • 主从复制 + 哨兵

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HtKGajWf-1582036395958)(img/主从复制+Sentinel.jpg)]

  • Redis之哨兵
    • Sentinel会不断检查Master和Slaves是否正常,自动切换主从。
    • 每一个Sentinel可以监控任意多个Master和该Master下的Slaves。
  1. 环境搭建

    # 共3台redis的服务器,如果是不同机器端口号可以是一样的
    # 1、启动6379的redis服务器
    sudo /etc/init.d/redis-server start
    # 2、启动6380的redis服务器,设置为6379的从
    $ redis-server --port 6380
    $ redis-cli -p 6380
    127.0.0.1:6380> slaveof 127.0.0.1 6379
    # 3、启动6381的redis服务器,设置为6379的从
    $ redis-server --port 6381
    $ redis-cli -p 6381
    127.0.0.1:6381> slaveof 127.0.0.1 6379
    
  2. 安装并搭建sentinel哨兵

    # 1、安装redis-sentinel
    sudo apt install redis-sentinel
    # 验证: 
    sudo /etc/init.d/redis-sentinel stop
    # 2、新建配置文件sentinel.conf
    port 26379
    sentinel monitor tedu 127.0.0.1 6379 1
    # 3、启动sentinel
    方式一: redis-sentinel sentinel.conf
    方式二: redis-server sentinel.conf --sentinel
    #4、将master的redis服务终止,查看从是否会提升为主
    sudo /etc/init.d/redis-server stop
    # 发现提升6381为master,6380为从
    # 在6381上设置新值,6380查看
    127.0.0.1:6381> set name haha
    # 启动6379,观察日志,发现变为了6381的从
    # 主从+哨兵基本就够用了
    
  • sentinel.conf解释

    # sentinel监听端口,默认是26379,可以修改
    port 26379
    # 告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效
    sentinel monitor <master-name> <ip> <redis-port> <quorum>
    
  • python获取master

    from redis.sentinel import Sentinel
    
    #生成哨兵连接
    sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
    #初始化master连接
    master = sentinel.master_for('haha', socket_timeout=0.1, db=1)
    slave = sentinel.slave_for('haha',socket_timeout=0.1, db=1)
    #使用redis相关命令
    master.set('mymaster', 'yes')
    print(slave.get('mymaster'))
    

ut=0.1, db=1)
slave = sentinel.slave_for(‘haha’,socket_timeout=0.1, db=1)
#使用redis相关命令
master.set(‘mymaster’, ‘yes’)
print(slave.get(‘mymaster’))
```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值