zoukankan      html  css  js  c++  java
  • Redis实战总结-Redis的高可用性

    在之前的博客《Redis实战总结-配置、持久化、复制》给出了一种Redis主从复制机制,简单地实现了Redis高可用。然后,如果Master服务器宕机,会导致整个Redis瘫痪,这种方式的高可用性较低。正常会采用多台Redis服务器构成一个集群,即使某台,或者某几台Redis宕机,Redis集群仍能正常运行,从而提高其高可用性。

    在Redis中,主要存在两种方式实现Redis集群机制:

    • Redis Sentinel集群机制:在Redis2.X版本,往往都是通过这种方式实现Redis的高可用。redis-sentinel是在master-slave机制上加入监控机制哨兵Sentinel实现的。

    • Redis Cluster集群机制:在Redis3.0版本后推出了redis-cluster集群机制。redis-cluster集群中各个节点之间是对等的,即master-master模式。

    **注意:**Redis Sentinel集群是解决HA问题的(主从同步),Redis Cluster集群是解决sharding问题的(分区),两种不重复,可以混合使用。

    下面详解这两种集群,并给出具体的演示示例。

    1. Redis Sentinel集群机制

    Redis-Sentinel是在master-slave机制上加入监控机制哨兵Sentinel实现的。Sentinel主要功能就是为Redis Master-Slave集群提供:

    • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
    • 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
    • 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

    在Sentinel集群中,一个最小的Master-Slave单元包含一个master和一个slave服务器。当master失效后,sentinel自动将slave提升为master,从而可以减少管理员的人工切换slave的操作过程。

    1.1 Redis-Sentinel集群架构图

    1.2 各个机器配置

    部署在本地机器上,保证各个端口号不一样,具体配置如下

    • Redis服务器:

      • master:127.0.0.1:6379
      • slave01:127.0.0.1:6389
      • slave02:127.0.0.1:6399
    • Sentinel服务器

      • sentinel01:127.0.0.1:26379
      • sentinel02:127.0.0.1:26389
      • sentinel03:127.0.0.1:26399

    1.3 redis.conf和sentinel.conf配置

    • redis.conf

      • master特殊配置如下:
      
      # 后台线程启动
      
      daemonize yes
      
      # 监听端口号
      
      port 6379
      
      # 访问验证密码
      
      requirepass "123456"
      • slave特殊配置如下:
      
      # 后台线程启动
      
      daemonize yes
      
      # 监听端口号,如果为slave02,端口号为6399
      
      port 6389
      
      # 主节点访问密码
      
      masterauth "123456"
      
      # 访问验证密码
      
      requirepass "123456"
      
      # 主节点服务器IP和端口号
      
      slaveof 127.0.0.1 6379
    • sentinel.conf

    # 后台线程启动
    daemonize yes
    # 监听端口号,如果为sentinel02,则端口号为26389,如果为sentinel01,则端口号为26399
    port 26379
    #1表示在sentinel集群中只要有两个节点检测到redis主节点出故障就进行切换   
    sentinel monitor mymaster 127.0.0.1 6379 1
    # master节点密码验证
    sentinel auth-pass mymaster 123456
    #如果3秒内mymaster无响应,则认为mymaster宕机了
    sentinel down-after-milliseconds mymaster 3000
    # 选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长
    sentinel parallel-syncs mymaster 1
    #如果10秒后,mysater仍没活过来,则启动failover 
    sentinel failover-timeout mymaster 10000

    注意:

    • 1.如果上述涉及的所有配置均放置在同一目录下,需保证各配置名称不同;
    • 2.在配置中,不同实例的日志输出、快照文件要求名称不能一样,具体可自行配置;
    • 3.一定要保证”sentinel myid”不相同,否则无法进行故障转移

    1.4 启动集群及启动后结果详情展示

    • 各Redis节点启动:

      redis-server redis_****.conf
    • 各Sentinel节点启动

      redis-sentinel sentinel_*****.conf
    • Redis Master节点详情展示
    •  

    Redis Slave节点效果截图展示 

    各个Sentinel节点详情展示 

    1.5 高可用性场景测试

    • Master宕机 

    • sentinel使用failover机制重新选举出master
    • Master恢复 

    • master节点恢复后,由Master变成slave
    • Slave宕机 

    • 哨兵发现6399已经宕机,等待6399的恢复(主观下线)
    • Slave重启6399节点 

    如果想详细了解sentinel机制的话,可以参考博客: 
    http://shift-alt-ctrl.iteye.com/blog/1884370

    2. Redis Cluster集群机制

    2.1 Redis-cluster介绍

    Redis-cluster是一种服务器Sharding技术,Redis3.0以后版本正式提供支持。

    Redis-cluster没有使用一致性hash,而是引入了哈希槽的概念。Redis-cluster中有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。Cluster中的每个节点负责一部分hash槽(hash slot),比如集群中存在三个节点,则可能存在的一种分配如下:

    • 节点A包含0到5500号哈希槽;
    • 节点B包含5501到11000号哈希槽;
    • 节点C包含11001 到 16384号哈希槽。

    这种集群架构很容易扩展,如果扩充一个节点D,只需要将A、B、C节点中的部分槽放置在D上;如果想移除节点A,只需要将A的slot转移到B和C节点上。由于将哈希槽从一个节点移动到另一个节点不需要停止服务,只需要通过命令直接再分配,因而上述拓展不会造成集群不可用。目前这种方式还是一种半自动的方式,需要人工介入。

    2.2 Redis-Cluster主从复制

    在Redis-Cluster中,如果某个节点宕机或者处在不可用状态时,那它负责的Hash槽也将失效,导致整个集群不可用。因而为了提供高可用性,正常会将每个节点配置成主从式结构,即一个master节点,挂在多个slave节点。如果Master节点失效时,集群便会选取一个slave节点作为master,继续提供服务,从而不会导致整个集群不可用。

    2.3 Redis-Cluster集群模拟

    2.3.1 Redis-Cluster集群准备

    • 集群部署图 

    • 集群由三个节点组成,每个节点均为主从式架构。因而共需要创建6个Redis实例,分配如下:

      • Redis01:127.0.0.1:7000
      • Redis02:127.0.0.1:7001
      • Redis03:127.0.0.1:7002
      • Redis04:127.0.0.1:7003
      • Redis05:127.0.0.1:7004
      • Redis06:127.0.0.1:7005

      对于每个实例的redis_700*.conf配置如下:

      # 监听端口号
      port 700*
      # 开启集群
      cluster-enabled yes
      # 修改集群加载配置文件,不需要手动创建,启动后默认生成,并且需要时自动更新
      cluster-config-file /Users/guweiyu/develop/redis/redis-cluster/workpid/nodes-7000.conf
      # 集群中的节点能够失联的最大时间,超过这个时间,该节点就会被认为故障
      cluster-node-timeout 15000
      # 默认为“no”,表示部分Key所在的节点不可用时,集群仍然为可达节点提供服务;如果为“yes”,表示部分key所在的节点不可用时,则整个集群停止服务。注意:实际使用中要修改为"yes"
      cluster-require-full-coverage no
    • 安装ruby,如果为Mac OS系统,直接执行即可:

      brew install ruby

    2.3.2 集群启动

    • 启动所有Redis实例,可以编写一个启动和停止所有redis实例的脚本(start.sh,stop.sh)

      redis-server redis_7000.conf
      redis-server redis_7001.conf
      redis-server redis_7002.conf
      redis-server redis_7003.conf
      redis-server redis_7004.conf
      redis-server redis_7005.conf
      
      ps -ef | grep redis-server
      echo "redis 7000-7005全部启动完成"
    • redis-cli -p 7000 shutdown
      redis-cli -p 7001 shutdown
      redis-cli -p 7002 shutdown
      redis-cli -p 7003 shutdown
      redis-cli -p 7004 shutdown
      redis-cli -p 7005 shutdown
      
      ps -ef | grep redis-server
      echo "redis-server 7000-7005节点已全部停止"
    • 1创建redis-cluster

    Redis中创建集群是通过redis-trib.rb命令实现的,redis-trib.rb位于Redis源码的src目录下,可将其直接拷贝到当前目录下。

    运行命令

    ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

    如果出现如下错误:

    /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- redis (LoadError)
        from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from ./redis-trib.rb:25:in `<main>'

    这是由于没有安装redis的第三方接口导致的。因此需要给Ruby安装client包,如下(必须加上sudo执行,否则会执行失败):

    sudo gem install redis

    再执行创建集群命令,结果如下:

    >>> Creating cluster
    >>> Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    127.0.0.1:7000
    127.0.0.1:7001
    127.0.0.1:7002
    Adding replica 127.0.0.1:7004 to 127.0.0.1:7000
    Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
    Adding replica 127.0.0.1:7003 to 127.0.0.1:7002
    >>> Trying to optimize slaves allocation for anti-affinity
    [WARNING] Some slaves are in the same host as their master
    M: aab0162a039d2f224322afe6caf2e153230f2d82 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
    M: 058204226f52757925a606b9697a8e39756bfdff 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
    M: 857075aef280cf35cd369ebc30738cd31c05e479 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
    S: 7dac141fa9510315905f505be52bba0208c391ab 127.0.0.1:7003
       replicates aab0162a039d2f224322afe6caf2e153230f2d82
    S: 65a2bc432e5930e97f0fd172eb838af9f07229b6 127.0.0.1:7004
       replicates 058204226f52757925a606b9697a8e39756bfdff
    S: 3d2a665d2e2eb28acb0a187c1a0b4bbce9ce87d2 127.0.0.1:7005
       replicates 857075aef280cf35cd369ebc30738cd31c05e479
    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join...
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: aab0162a039d2f224322afe6caf2e153230f2d82 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    S: 3d2a665d2e2eb28acb0a187c1a0b4bbce9ce87d2 127.0.0.1:7005
       slots: (0 slots) slave
       replicates 857075aef280cf35cd369ebc30738cd31c05e479
    S: 65a2bc432e5930e97f0fd172eb838af9f07229b6 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 058204226f52757925a606b9697a8e39756bfdff
    S: 7dac141fa9510315905f505be52bba0208c391ab 127.0.0.1:7003
       slots: (0 slots) slave
       replicates aab0162a039d2f224322afe6caf2e153230f2d82
    M: 857075aef280cf35cd369ebc30738cd31c05e479 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    M: 058204226f52757925a606b9697a8e39756bfdff 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.

    创建成功,16384个Hash槽分配完成,所有节点(Master和slave节点)均已加入到集群中。三个Master节点分配的Hash槽及从节点如下:

    • Master01:127.0.0.1:7000

      M: aab0162a039d2f224322afe6caf2e153230f2d82 
      slots:0-5460 (5461 slots) master
      127.0.0.1:7004 to 127.0.0.1:7000
    • Master02:127.0.0.1:7001
    • M: 058204226f52757925a606b9697a8e39756bfdff 
      slots:5461-10922 (5462 slots) master
      127.0.0.1:7005 to 127.0.0.1:7001
    • Master03:127.0.0.1:7002
    • M: 857075aef280cf35cd369ebc30738cd31c05e479 
      slots:10923-16383 (5461 slots) master
      127.0.0.1:7003 to 127.0.0.1:7002

    2.3.3 集群测试

    • 测试集群存取值

    客户端命令redis-cli连接集群需要带上”-c”, 比如redis-cli -c -p 端口号

    127.0.0.1:7000> set test1 guweiyu
    OK
    127.0.0.1:7000> set name  guweiyu
    -> Redirected to slot [5798] located at 127.0.0.1:7001
    OK
    127.0.0.1:7001> get name
    "guweiyu"
    127.0.0.1:7001> get test1
    -> Redirected to slot [4768] located at 127.0.0.1:7000
    "guweiyu"
    127.0.0.1:7000>

    测试发现”set test1 guweiyu”,直接返回OK,说明该值就是存储在7000上,执行“set name guweiyu”发生了Redirected到7001上,获取的时候,同样出现上述情况。这个是Redis Cluster去中心特性,访问集群中的任一节点,均可直接操作集群。

    • 主节点宕机测试

    • 从节点宕机

  • 相关阅读:
    sql中保留2位小数
    C# 操作字符串,在某些特定的字符后面或前面添加其它字符
    Windows Server 2008 R2中上传和下载文件
    winform中显示标题,点击打开链接
    正则表达式
    winform重绘
    js获取元素的页面坐标
    剑指offer-从上往下打印二叉树
    剑指offer-栈的压入、弹出序列
    剑指offer-包含min函数的栈
  • 原文地址:https://www.cnblogs.com/austinspark-jessylu/p/8960961.html
Copyright © 2011-2022 走看看