redis高可用性基础:Master-Slave

理解Master-Slave

Master-Slave 常常翻译为 主/备 ,是一种高可用性( High Availability )方案。

举个生活中的 Master-Slave 例子:

参加考试的时候,我们会准备两支钢笔,正常情况下我们只会使用一支,出问题了才会换另外一支。

所以实施 Master-Slave 是有成本的,至少会有 50% 的资源浪费(多备几支浪费会更多),可以让 Slave 承担一部分工作来充分利用资源。

Redis的Master-Slave

关于 RedisMaster-Slave ,《Replication – Redis》 有详尽描述。

需要注意的是 RedisMaster-Slave 不能保证绝对不丢数据,而是丢失一小段时间内(如:1秒钟)的数据。

下面开始 RedisMaster-Slave 实践,使用的 redis 版本为 3.0.6

创建Master结点

  • redis配置文件

    /etc/redis.conf 拷贝一份进行修改,无关的配置项已去掉,使用默认值即可。

    redis-master.conf

  • 在终端 1 启动 Master 结点

    redis-server ./redis-master.conf

  • 使用 redis-cli 连接 Master

    $ redis-cli -p 6379
    127.0.0.1:6379>
    

创建Slave结点

  • redis配置文件

    redis-master.conf 拷贝一份进行修改,主要是修改监听的端口号( 6380 )、PID文件名、DB文件名,

    最关键的是设置为 MasterSlave slaveof 127.0.0.1 6379

    redis-slave.conf

  • 在终端 2 启动 Slave 结点

    redis-server ./redis-slave.conf

  • 使用 redis-cli 连接 Slave

    $ redis-cli -p 6380
    127.0.0.1:6380>
    

演示Master写Slave读的场景

  • Master 写入

    127.0.0.1:6379> set hello world
    OK
    
  • Slave 读取

    127.0.0.1:6380> get hello
    "world"
    

演示Slave挂掉的场景

  • 关闭 Slave

    127.0.0.1:6380> shutdown
    not connected>
    

    终端 2 上的 redis-server 会自动退出,注意到它退出前进行了存盘。

  • Master 写入

    127.0.0.1:6379> set hello redis
    OK
    
  • 在终端 2 上再次启动 Slave

    redis-server ./redis-slave.conf
    

    从日志上可以看到 SlaveMaster 重新进行了数据同步。

  • Slave 上读取

    not connected> get hello
    "redis"
    127.0.0.1:6380> 
    

演示Master挂掉的场景

  • 关闭 Master

    127.0.0.1:6379> shutdown
    not connected>
    

    终端 1 上的 redis-server 会自动退出,注意到它退出前进行了存盘, 终端 2 上的 Slave 在不断尝试重连 Master

  • Master-Slave角色切换

    将运行中的原 Slave 提升为新 Master

    127.0.0.1:6380> slaveof no one
    OK
    

    修改原 Slave 的配置文件 redis-slave.conf 删除配置 #slaveof 127.0.0.1 6379

    修改原 Master 的配置文件 redis-master.conf 添加配置 slaveof 127.0.0.1 6380

  • 在新 Master 写入

    127.0.0.1:6380> set hello master-slave
    OK
    
  • 在终端 1 上再次启动原 Master

    redis-server ./redis-master.conf
    

    从日志上可以看到它现在是 Slave 角色了,反而从原 Slave 同步数据。

  • 在原 Master 上读取

    not connected> get hello
    "master-slave"
    127.0.0.1:6379>
    

总结

RedisMaster-Slave 是一种动态关系,角色( MasterSlave )会互相转换,角色转换过程中必须严格按照步骤来,操作不当可能导致数据丢失。

后面会发文介绍自动进行这种切换的工具 Redis Sentinel ,以及当 Master-Slave 发生切换后,应用程序该如何重连到新的 Master


redis