• Redis Cluster 分布式集群(上)


    Redis Cluster 介绍

    • Redis 集群是一个可以在多个Redis节点之间进行数据共享的设施(installation);
    • Redis 集群不支持那些需要同时处理多个键的 Redis 命令,因为执行这些命令需要在多个Redis节点之间移动数据,并且在高负载的情况下,这些命令将降低 Redis 集群的性能,并导致不可预测的行为;
    • Redis 集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求;
    • Redis 集群有将数据自动切分(split)到多个节点的能力

    Redis Cluster 特点

    # 高性能:
    - 在多分片节点中,将 16384 个槽位,均匀分布到多个分片节点中
    - 存数据时,将 KEY 做 CRC16(KEY),然后与 16384 进行取模,得出槽位值( 0 - 16384 之间 )
    - 根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
    - 如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储
    - 客户端与 Redis 节点直连,不需要中间 Proxy 层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
    - Redis Cluster 解决了 Redis 资源利用率的问题
    
    # 高可用
    - 在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现 Slaveof 功能,同时当主节点 Down,实现类似于 Sentinel 的自动 Failover 的功能 
    

    槽(Slot)的概念

    • 在集群中,会把所有节点分为 16384 个槽位
    • 槽位的序号是 0 - 16383,序号不重要,数量才重要
    • 每一个槽位分配到数据的概率是一样

    Redis 故障转移

    在集群里面,节点会对其他节点进行下线检测,当一个主节点下线时,集群里面的其他主节点负责对下线主节点进行故障移(到从节点);换句话说,集群的节点集成了下线检测和故障转移等类似 Sentinel 的功能

    Redis Cluster 搭建(手动)

    环境准备

    节点 IP 端口
    节点① 172.16.1.121 6379,6380
    节点② 172.16.1.122 6379,6380
    节点③ 172.16.1.123 6379,6380

    搭建 Redis 多实例

    # 删除以前的 Redis 数据
    [root@dbtest01 ~]# rm -rf /service/redis/*
    
    # 创建多实例目录
    [root@dbtest01 ~]# mkdir /service/redis/{6379,6380}
    [root@dbtest02 ~]# mkdir /service/redis/{6379,6380}
    [root@dbtest03 ~]# mkdir /service/redis/{6379,6380}
    
    # 配置所有 Redis
    [root@dbtest01 ~]# vim /service/redis/6379/redis.conf
    bind 172.16.1.121 127.0.0.1
    port 6379
    daemonize yes
    pidfile /service/redis/6379/redis.pid
    loglevel notice
    logfile /service/redis/6379/redis.log
    dbfilename dump.rdb
    dir /service/redis/6379
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    
    [root@dbtest01 ~]# vim /service/redis/6380/redis.conf
    bind 172.16.1.121 127.0.0.1
    port 6380
    daemonize yes
    pidfile /service/redis/6380/redis.pid
    loglevel notice
    logfile /service/redis/6380/redis.log
    dbfilename dump.rdb
    dir /service/redis/6380
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    

    启动 Redis 多实例

    [root@dbtest01 ~]# redis-server /service/redis/6379/redis.conf 
    [root@dbtest01 ~]# redis-server /service/redis/6380/redis.conf
    [root@dbtest02 ~]# redis-server /service/redis/6379/redis.conf 
    [root@dbtest02 ~]# redis-server /service/redis/6380/redis.conf
    [root@dbtest03 ~]# redis-server /service/redis/6379/redis.conf 
    [root@dbtest03 ~]# redis-server /service/redis/6380/redis.conf
    

    关联所有节点

    登录所有节点

    [root@dbtest01 ~]# redis-cli -h 172.16.1.121 -p 6379
    [root@dbtest01 ~]# redis-cli -h 172.16.1.121 -p 6380
    [root@dbtest02 ~]# redis-cli -h 172.16.1.122 -p 6379
    [root@dbtest02 ~]# redis-cli -h 172.16.1.122 -p 6380
    [root@dbtest03 ~]# redis-cli -h 172.16.1.123 -p 6379
    [root@dbtest03 ~]# redis-cli -h 172.16.1.123 -p 6380
    

    查看集群节点

    # 查看集群节点,每一各节点只能看到自己
    172.16.1.121:6379> CLUSTER NODES
    28faba09f4c0ec8cdb90d92e09636796427b7143 :6379 myself,master - 0 0 0 connected
    

    关联所有节点

    # 关联节点
    172.16.1.121:6379> CLUSTER MEET 172.16.1.121 6380
    OK
    172.16.1.121:6379> CLUSTER MEET 172.16.1.122 6379
    OK
    172.16.1.121:6379> CLUSTER MEET 172.16.1.122 6380
    OK
    172.16.1.121:6379> CLUSTER MEET 172.16.1.123 6379
    OK
    172.16.1.121:6379> CLUSTER MEET 172.16.1.123 6380
    OK
    
    # 查看集群状态,所有节点
    172.16.1.121:6379> CLUSTER NODES
    aee9f4e6e09a452fd44bca7639be442b5138f141 172.16.1.122:6380 master - 0 1596687131655 4 connected
    777412c8d6554e3390e1083bf1f55002be08cf62 172.16.1.121:6380 master - 0 1596687131352 2 connected
    ef18ab5bab6d8bc06917a0cf2dc9bffa8b431087 172.16.1.122:6379 master - 0 1596687132362 3 connected
    f2747c92813ea06b25c3e9c8d5232b46b3cf9d3d 172.16.1.123:6379 master - 0 1596687131856 0 connected
    25f735f08ac62b2f758c1e2c21e178cc46279087 172.16.1.123:6380 master - 0 1596687131251 5 connected
    28faba09f4c0ec8cdb90d92e09636796427b7143 172.16.1.121:6379 myself,master - 0 0 1 connected
    

    平均分配槽位

    # 查看集群状态
    172.16.1.121:6379> CLUSTER INFO
    cluster_state:fail
    cluster_slots_assigned:0
    cluster_slots_ok:0
    cluster_slots_pfail:0
    cluster_slots_fail:0
    cluster_known_nodes:6
    cluster_size:0
    cluster_current_epoch:5
    cluster_my_epoch:1
    cluster_stats_messages_sent:1168
    cluster_stats_messages_received:1168
    
    # 槽位规划
    dbtest01:     5462 个槽位  (0-5461)
    dbtest02:     5461 个槽位  (5462-10922)
    dbtest03:     5461 个槽位  (10923-16383)
    
    # 分配槽位
    [root@dbtest01 ~]# redis-cli -p 6379 -h 172.16.1.121 CLUSTER ADDSLOTS {0..5461}
    OK
    [root@dbtest02 ~]# redis-cli -p 6379 -h 172.16.1.122 CLUSTER ADDSLOTS {5462..10922}
    OK
    [root@dbtest02 ~]# redis-cli -p 6379 -h 172.16.1.123 CLUSTER ADDSLOTS {10923..16383}
    

    插入数据,测试集群

    # 插入一条数据
    172.16.1.121:6379> set k1 v1
    (error) MOVED 12706 172.16.1.123:6379
    # 报错,该 KEY 的值只能插入到 12706 这个槽位
    
    [root@dbtest03 ~]# redis-cli -h 172.16.1.123
    172.16.1.123:6379> set k1 v1
    OK
    
    # 自动切换将数据添加到指定槽位
    [root@dbtest03 ~]# redis-cli -h 172.16.1.123
    172.16.1.123:6379> set k2 v2
    (error) MOVED 449 172.16.1.121:6379
    172.16.1.123:6379> quit
    [root@dbtest03 ~]# redis-cli -c -h 172.16.1.123
    172.16.1.123:6379> set k2 v2
    -> Redirected to slot [449] located at 172.16.1.121:6379
    OK
    
    # 脚本插入数据测试
    [root@dbtest03 ~]# vim data.sh 
    #!/bin/bash
    for i in {1..1000};do
        redis-cli -c -p 6379 -h 172.16.1.121 set k${i} v${i}
    done
    
    # 查看数据分配
    172.16.1.121:6379> DBSIZE
    (integer) 341
    172.16.1.122:6379> DBSIZE
    (integer) 332
    172.16.1.123:6379> DBSIZE
    (integer) 327
    

    添加副本节点

    给每一个分配了槽位的 Redis 实例,添加一个高可用从库,即集群中的副本节点 。

    查看节点

    # 查看所有节点,每一个都是 master
    172.16.1.121:6379> CLUSTER NODES
    5a7f0cf95e1850b5b5ae81d873c4c76fd366d604 172.16.1.121:6380 master - 0 1596763193422 4 connected
    5eb9e5356534ff4acda736d13f0dc9fc3d40049b 172.16.1.122:6379 master - 0 1596763192412 5 connected 5462-10922
    50878ef6a4d8141c8dbca3e2bf7c84ed48a73ee2 172.16.1.123:6380 master - 0 1596763192512 3 connected
    acc3a4d0e6e43fc74630c1f0714865fdcbdaf677 172.16.1.123:6379 master - 0 1596763191908 0 connected 10923-16383
    2325be6f1f9c1c9f57d5a033fc05e0d798ea823a 172.16.1.121:6379 myself,master - 0 0 1 connected 0-5461
    381b54584572e8013becdae2eeaff48bf6eb5450 172.16.1.122:6380 master - 0 1596763193925 2 connected
    

    配置主从

    # dbtest01 的 6380 做 dbtest02 的 6379 的从库
    172.16.1.121:6380> CLUSTER REPLICATE 5eb9e5356534ff4acda736d13f0dc9fc3d40049b
    OK
    
    # dbtest02 的 6380 做 dbtest03 的 6379 的从库
    172.16.1.122:6380> CLUSTER REPLICATE acc3a4d0e6e43fc74630c1f0714865fdcbdaf677
    OK
    
    ## dbtest03 的 6380 做 dbtest01 的 6379 的从库
    172.16.1.123:6380> CLUSTER REPLICATE 2325be6f1f9c1c9f57d5a033fc05e0d798ea823a
    OK
    

    再次查看节点信息

    172.16.1.121:6379> CLUSTER NODES
    5a7f0cf95e1850b5b5ae81d873c4c76fd366d604 172.16.1.121:6380 slave 5eb9e5356534ff4acda736d13f0dc9fc3d40049b 0 1596763362696 5 connected
    5eb9e5356534ff4acda736d13f0dc9fc3d40049b 172.16.1.122:6379 master - 0 1596763363202 5 connected 5462-10922
    50878ef6a4d8141c8dbca3e2bf7c84ed48a73ee2 172.16.1.123:6380 slave 2325be6f1f9c1c9f57d5a033fc05e0d798ea823a 0 1596763362192 3 connected
    acc3a4d0e6e43fc74630c1f0714865fdcbdaf677 172.16.1.123:6379 master - 0 1596763363203 0 connected 10923-16383
    2325be6f1f9c1c9f57d5a033fc05e0d798ea823a 172.16.1.121:6379 myself,master - 0 0 1 connected 0-5461
    381b54584572e8013becdae2eeaff48bf6eb5450 172.16.1.122:6380 slave acc3a4d0e6e43fc74630c1f0714865fdcbdaf677 0 1596763364211 2 connected
    

    故障测试

    # 停掉一台节点,dbtest03:6379 的主库宕机,dbtest01:6380 的从库(副本)应该变成主库
    [root@dbtest03 ~]# reboot
    
    # 到另一台机器查看集群状态,发现集群是正常的
    172.16.1.121:6379> CLUSTER INFO
    cluster_state:ok
    cluster_slots_assigned:16384
    cluster_slots_ok:16384
    cluster_slots_pfail:0
    cluster_slots_fail:0
    cluster_known_nodes:6
    cluster_size:3
    cluster_current_epoch:6
    cluster_my_epoch:1
    cluster_stats_messages_sent:327031
    cluster_stats_messages_received:326973
    
    # 查看节点信息,副本被提升为主库
    172.16.1.121:6379> CLUSTER NODES
    5a7f0cf95e1850b5b5ae81d873c4c76fd366d604 172.16.1.121:6380 slave 5eb9e5356534ff4acda736d13f0dc9fc3d40049b 0 1596763771309 5 connected
    5eb9e5356534ff4acda736d13f0dc9fc3d40049b 172.16.1.122:6379 master - 0 1596763771310 5 connected 5462-10922
    50878ef6a4d8141c8dbca3e2bf7c84ed48a73ee2 172.16.1.123:6380 slave,fail 2325be6f1f9c1c9f57d5a033fc05e0d798ea823a 1596763736458 1596763734245 3 disconnected
    acc3a4d0e6e43fc74630c1f0714865fdcbdaf677 172.16.1.123:6379 master,fail - 1596763736458 1596763735246 0 disconnected
    2325be6f1f9c1c9f57d5a033fc05e0d798ea823a 172.16.1.121:6379 myself,master - 0 0 1 connected 0-5461
    381b54584572e8013becdae2eeaff48bf6eb5450 172.16.1.122:6380 master - 0 1596763772319 6 connected 10923-16383
    

    恢复节点

    # 修复机器
    [root@dbtest03 ~]# redis-server /service/redis/6379/redis.conf 
    [root@dbtest03 ~]# redis-server /service/redis/6380/redis.conf
    
    # 再次查看节点信息
    172.16.1.121:6379> CLUSTER NODES
    5a7f0cf95e1850b5b5ae81d873c4c76fd366d604 172.16.1.121:6380 slave 5eb9e5356534ff4acda736d13f0dc9fc3d40049b 0 1596764061287 5 connected
    5eb9e5356534ff4acda736d13f0dc9fc3d40049b 172.16.1.122:6379 master - 0 1596764060781 5 connected 5462-10922
    50878ef6a4d8141c8dbca3e2bf7c84ed48a73ee2 172.16.1.123:6380 slave 2325be6f1f9c1c9f57d5a033fc05e0d798ea823a 0 1596764059770 3 connected
    acc3a4d0e6e43fc74630c1f0714865fdcbdaf677 172.16.1.123:6379 slave 381b54584572e8013becdae2eeaff48bf6eb5450 0 1596764062094 6 connected
    2325be6f1f9c1c9f57d5a033fc05e0d798ea823a 172.16.1.121:6379 myself,master - 0 0 1 connected 0-5461
    381b54584572e8013becdae2eeaff48bf6eb5450 172.16.1.122:6380 master - 0 1596764061789 6 connected 10923-16383
    
    # 原主节点修复后变为从节点
    # 原主节点若想恢复为主节点,需要执行命令
    172.16.1.123:6379> CLUSTER FAILOVER
    # 即可恢复初始分布式集群状态
    
  • 相关阅读:
    jmeter 5压测https接口报错javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake的解决方法
    压测部署在k8s的服务时,出现{"message":"An unexpected error occurred"}错误的可能原因
    用jmeter测试post接口body带中文参数报错,同样的body粘贴到postman里正常-----解决方法
    hive删除分区表以及修复分区表
    查看Hive表信息及占用空间
    jmeter测试的get接口中有特殊字符时的处理
    面试题-给你一个扫码支付的二维码,如何写测试用例?
    零碎的 软件测试面试题
    linux常见问题
    自动化面试常问问题
  • 原文地址:https://www.cnblogs.com/zzzwqh/p/13455201.html
Copyright © 2020-2023  润新知