vlambda博客
学习文章列表

到了弃用Redis-sentinel架构的时候了

redis5.0新特性

  1. 新的流数据类型(Stream data type)

  2. 新的 Redis 模块 API:定时器、集群和字典 API(Timers, Cluster and Dictionary APIs)

  3. RDB 增加 LFU 和 LRU 信息

  4. 从 Ruby (redis-trib.rb)中将集群管理的C语言代码移植到了redis-cli 中

  5. 新的有序集合(sorted set)命令:ZPOPMIN/MAX 和阻塞变体(blocking variants)

  6. 升级 Active defragmentation 至 v2 版本

  7. 增强 HyperLogLog 的实现更好的内存统计报告许多包含子命令的命令现在都有一个 HELP 子命令

  8. 客户端频繁连接和断开连接时,性能表现更好许多

  9. 错误修复和其他方面的改进升级

  10. Jemalloc 至 5.1 版本

  11. 引入 CLIENT UNBLOCK 和 CLIENT ID

  12. 新增 LOLWUT 命令 antirez.com/news/123

  13. 在不存在需要保持向后兼容性的地方,弃用 "slave" 术语

  14. 网络层中的差异优化

  15. Lua 相关的改进

  16. 引入动态的 HZ(Dynamic HZ) 以平衡空闲 CPU 使用率和响应性

  17. 对 Redis 核心代码进行了重构并在许多方面进行了改进

服务的可用性

  1. 在集群分片的过程中,依旧可以提供部分的可用性,当集群一部分节点故障或者无法与其他节点通信,集群依旧可以运行

  2. 当集群中大部分主节点出现问题,集群将不可用

  3. 因为将哈希槽从一个节点移动到另一个节点不需要停止操作,所以添加和删除节点或更改节点持有的哈希槽的百分比都不需要停机

  4. redis cluster可以通过增加N个redis slave提高集群的可用性以及健壮性

Redis集群中节点端口

  1. 服务客户端常规tcp端口6379

  2. 大端口,为tcp端口加上10000,是一个数据端口,作为集群总线,主要用于节点与节点之间通信通道的二进制协议,它的功用还有:故障检测,配置更新,故障转移授权

Redis集群与Docker

当前的Redis集群不支持NAT网络模式以及被重新映射的IP和端口。如果使用docker部署redis,要使用 --network=host

Redis-cluster 5.0 部署篇

编译安装Redis二进制文件

 
   
   
 
  1. mkdir redisworkdir && cd $_

  2. wget http://download.redis.io/releases/redis-5.0.8.tar.gz

  3. tar xf redis-5.0.8.tar.gz

  4. cd redis-5.0.8 && make # [option]此步之后可以选择make test.比较耗时,测试成功后会遇到以下信息。

  5. #######

  6. # 124 seconds - integration/replication-psync

  7. # 108 seconds - unit/obuf-limits

  8. # 98 seconds - unit/memefficiency

  9. # 162 seconds - integration/replication

  10. #

  11. #\o/ All tests passed without errors!

  12. #

  13. #Cleanup: may take some time... OK

  14. #make[1]: Leaving directory `/root/redis-5.0.8/src'

  15. cp src/redis-cli src/redis-server /usr/local/bin/

准备Redis实例的基础配置文件
 
   
   
 
  1. cat << EOF > redis-7000.conf

  2. port 7000

  3. daemonize yes

  4. dir "/data/redis/data"

  5. dbfilename "dump-7000.rdb"

  6. logfile "redis-7000.log"

  7. cluster-enabled yes

  8. cluster-config-file nodes-7000.conf

  9. EOF

生成多实例配置文件

我们使用Redis Cluster方案,建议需要准备最少6个实例.

 
   
   
 
  1. redis-server redis-7000.conf

  2. for i in `seq 7001 7005`

  3. do

  4. sed "s/7000/$i/g" redis-7000.conf > redis-"$i".conf

  5. redis-server redis-"$i".conf

  6. done


  7. [root@qiniu redis-5.0.8]# ps -ef |grep redis-server


  8. root 32284 1 0 21:24 ? 00:00:00 redis-server *:7000 [cluster]

  9. root 32291 1 0 21:24 ? 00:00:00 redis-server *:7001 [cluster]

  10. root 32297 1 0 21:24 ? 00:00:00 redis-server *:7002 [cluster]

  11. root 32303 1 0 21:24 ? 00:00:00 redis-server *:7003 [cluster]

  12. root 32309 1 0 21:24 ? 00:00:00 redis-server *:7004 [cluster]

  13. root 32312 1 0 21:24 ? 00:00:00 redis-server *:7005 [cluster]

此时进去某一个Redis节点中会发现集群下线不可用的状态

 
   
   
 
  1. [root@qiniu redis-5.0.8]# redis-cli -p 7000

  2. 127.0.0.1:7000> set hello world

  3. (error) CLUSTERDOWN Hash slot not served

  4. 127.0.0.1:7000> cluster info

  5. cluster_state:fail

  6. cluster_slots_assigned:0

  7. cluster_slots_ok:0

  8. cluster_slots_pfail:0

  9. cluster_slots_fail:0

  10. cluster_known_nodes:1

  11. cluster_size:0

  12. cluster_current_epoch:0

  13. cluster_my_epoch:0

  14. cluster_stats_messages_sent:0

  15. cluster_stats_messages_received:0

  16. 127.0.0.1:7000> cluster nodes

  17. b1019e6e716125f14def5f35fac2c7024324a8ec :7000@17000 myself,master - 0 0 0 connected

Cluster节点主要的配置

 
   
   
 
  1. cluster-enabled yes

  2. cluster-node-timeout 15000

  3. cluster-config-file "nodes.conf"

  4. clutser-require-full-coverage yes # 当集群中出现一个节点不合理,是否就标识集群不可用,一般配置为no

meet集群节点
 
   
   
 
  1. for i in `seq 7001 7005`

  2. do

  3. redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 "$i"

  4. done

当连接到7002端口时候,就会发现redis-7002发现了7000和7001

 
   
   
 
  1. redis-cli -h 127.0.0.1 -p 7002 cluster nodes #这里会有6个节点

  2. redis-cli -h 127.0.0.1 -p 7005 cluster info # 这里的cluster_know_nodes:6

分配槽位
 
   
   
 
  1. #!/bin/sbash

  2. start=$1

  3. end=$2

  4. port=$3

  5. for slot in `seq ${start} ${end}`

  6. do

  7. echo "slot:${slot}"

  8. redis-cli -p ${port} cluster addslots ${slot}

  9. done

 
   
   
 
  1. chmod +x addslots.sh

  2. ./addslots.sh 0 5460 7000

  3. ./addslots.sh 5461 10922 7001

  4. ./addslots.sh 10923 16383 7002


  5. ...

通过NodeID设置主从关系
 
   
   
 
  1. [root@qiniu redis-5.0.8]# redis-cli -h 127.0.0.1 -p 7000 cluster nodes

  2. c28ad47247c7172faeddeebbfbbbcb7bf9f151b0 127.0.0.1:7002@17002 master - 0 1585835343000 4 connected 10923-16383

  3. 5260ee3591f0a43698d71735dd57a65efb16dd2f 127.0.0.1:7004@17004 master - 0 1585835342000 3 connected

  4. f68ef79fbed0b2faa59227037f99d09ac32295dc 127.0.0.1:7005@17005 master - 0 1585835342615 5 connected

  5. df55c705abff3cc905eefadbc5332a9a59af9597 127.0.0.1:7003@17003 master - 0 1585835343617 2 connected

  6. fb1026c49a5cccd2d18310a5bafd67433538bc78 127.0.0.1:7001@17001 master - 0 1585835341000 1 connected 5461-10922

  7. fdd63d2dddddbca505b824685f7a03e08d88558b 127.0.0.1:7000@17000 myself,master - 0 1585835342000 0 connected 0-5460

  8. redis-cli -h 127.0.0.1 -p 7003 cluster replicate fdd63d2dddddbca505b824685f7a03e08d88558b

  9. redis-cli -h 127.0.0.1 -p 7004 cluster replicate fb1026c49a5cccd2d18310a5bafd67433538bc78

  10. redis-cli -h 127.0.0.1 -p 7005 cluster replicate c28ad47247c7172faeddeebbfbbbcb7bf9f151b0


  11. [root@qiniu redis-5.0.8]# redis-cli -h 127.0.0.1 -p 7000 cluster info

  12. cluster_state:ok

  13. cluster_slots_assigned:16384

  14. cluster_slots_ok:16384

  15. cluster_slots_pfail:0

  16. cluster_slots_fail:0

  17. cluster_known_nodes:6

  18. cluster_size:3

  19. cluster_current_epoch:5

  20. cluster_my_epoch:0

  21. cluster_stats_messages_ping_sent:577

  22. cluster_stats_messages_pong_sent:558

  23. cluster_stats_messages_meet_sent:5

  24. cluster_stats_messages_sent:1140

  25. cluster_stats_messages_ping_received:558

  26. cluster_stats_messages_pong_received:582

  27. cluster_stats_messages_received:1140


  28. [root@qiniu redis-5.0.8]# redis-cli -h 127.0.0.1 -p 7000 cluster nodes

  29. c28ad47247c7172faeddeebbfbbbcb7bf9f151b0 127.0.0.1:7002@17002 master - 0 1585835417764 4 connected 10923-16383

  30. 5260ee3591f0a43698d71735dd57a65efb16dd2f 127.0.0.1:7004@17004 slave fb1026c49a5cccd2d18310a5bafd67433538bc78 0 1585835415762 3 connected

  31. f68ef79fbed0b2faa59227037f99d09ac32295dc 127.0.0.1:7005@17005 slave c28ad47247c7172faeddeebbfbbbcb7bf9f151b0 0 1585835418765 5 connected

  32. df55c705abff3cc905eefadbc5332a9a59af9597 127.0.0.1:7003@17003 slave fdd63d2dddddbca505b824685f7a03e08d88558b 0 1585835417000 2 connected

  33. fb1026c49a5cccd2d18310a5bafd67433538bc78 127.0.0.1:7001@17001 master - 0 1585835419767 1 connected 5461-10922

  34. fdd63d2dddddbca505b824685f7a03e08d88558b 127.0.0.1:7000@17000 myself,master - 0 1585835418000 0 connected 0-5460


  35. [root@qiniu redis-5.0.8]# redis-cli -h 127.0.0.1 -p 7000 cluster slots

  36. 1) 1) (integer) 10923

  37. 1) (integer) 16383

  38. 2) 1) "127.0.0.1"

  39. 1) (integer) 7002

  40. 2) "c28ad47247c7172faeddeebbfbbbcb7bf9f151b0"

  41. 3) 1) "127.0.0.1"

  42. 1) (integer) 7005

  43. 2) "f68ef79fbed0b2faa59227037f99d09ac32295dc"

  44. 2) 1) (integer) 5461

  45. 1) (integer) 10922

  46. 2) 1) "127.0.0.1"

  47. 1) (integer) 7001

  48. 2) "fb1026c49a5cccd2d18310a5bafd67433538bc78"

  49. 3) 1) "127.0.0.1"

  50. 1) (integer) 7004

  51. 2) "5260ee3591f0a43698d71735dd57a65efb16dd2f"

  52. 3) 1) (integer) 0

  53. 1) (integer) 5460

  54. 2) 1) "127.0.0.1"

  55. 1) (integer) 7000

  56. 2) "fdd63d2dddddbca505b824685f7a03e08d88558b"

  57. 3) 1) "127.0.0.1"

  58. 1) (integer) 7003

  59. 2) "df55c705abff3cc905eefadbc5332a9a59af9597"

以上就完成了三主三从的Redis集群配置

redis cluster测试

通过go-redis简单地测试

 
   
   
 
  1. package main


  2. import (

  3. "fmt"

  4. "github.com/go-redis/redis"

  5. "strconv"

  6. )


  7. func main() {

  8. //redis cluster

  9. rdb := redis.NewClusterClient(&redis.ClusterOptions{

  10. Addrs: []string{"192.168.99.128:7000", "192.168.99.129:7001", "192.168.99.130:7002", "192.168.99.130:7003", "192.168.99.129:7004", "192.168.99.128:7005"},

  11. Password: "passwd!s",

  12. MaxRetries: 4,

  13. })

  14. for i := 0; i < 1000; i++ {

  15. key := "test" + strconv.Itoa(i)

  16. err := rdb.Set(key, "set key from golang", 0).Err()

  17. //rdb.Process()

  18. if err != nil {

  19. panic(err)

  20. }

  21. }

  22. fmt.Println("insert data done.")

  23. for i := 500; i < 1000; i++ {

  24. keys := "test" + strconv.Itoa(i)

  25. fmt.Println("keys: ", rdb.ClusterKeySlot(keys))

  26. }

  27. }

官方方式部署redis-cluster

在Redis 5.0 之后可以通过Redis-cli实现集群的部署与安装

 
   
   
 
  1. # 首先我们需要提前准备好这些redis实例

  2. [root@qiniu ~]# redis-cli --cluster create 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 --cluster-replicas 1

  3. >>> Performing hash slots allocation on 6 nodes...

  4. Master[0] -> Slots 0 - 5460

  5. Master[1] -> Slots 5461 - 10922

  6. Master[2] -> Slots 10923 - 16383

  7. Adding replica 127.0.0.1:7004 to 127.0.0.1:7000

  8. Adding replica 127.0.0.1:7005 to 127.0.0.1:7001

  9. Adding replica 127.0.0.1:7003 to 127.0.0.1:7002

  10. >>> Trying to optimize slaves allocation for anti-affinity

  11. [WARNING] Some slaves are in the same host as their master

  12. M: ab3f9f295905d3ff113c0cfebc3000ae8d0eb717 127.0.0.1:7000

  13. slots:[0-5460] (5461 slots) master

  14. M: a22ca7f0c97d86a47897694a8e1f48a29702ae72 127.0.0.1:7001

  15. slots:[5461-10922] (5462 slots) master

  16. M: 5f08b2ea3c26ae39843b0bf964bac5a8596e8cda 127.0.0.1:7002

  17. slots:[10923-16383] (5461 slots) master

  18. S: 3712bc46f0fcc14ef4fa8044ad319eee1ddc56c9 127.0.0.1:7003

  19. replicates 5f08b2ea3c26ae39843b0bf964bac5a8596e8cda

  20. S: a34cf5c793e3e606f6fe0c2834d9660cd4b7dcf0 127.0.0.1:7004

  21. replicates ab3f9f295905d3ff113c0cfebc3000ae8d0eb717

  22. S: 88ecb048427276a287504e124ef78dd5b7a6e183 127.0.0.1:7005

  23. replicates a22ca7f0c97d86a47897694a8e1f48a29702ae72

  24. Can I set the above configuration? (type 'yes' to accept): yes

  25. >>> Nodes configuration updated

  26. >>> Assign a different config epoch to each node

  27. >>> Sending CLUSTER MEET messages to join the cluster

  28. Waiting for the cluster to join

  29. ...

  30. >>> Performing Cluster Check (using node 127.0.0.1:7000)

  31. M: ab3f9f295905d3ff113c0cfebc3000ae8d0eb717 127.0.0.1:7000

  32. slots:[0-5460] (5461 slots) master

  33. 1 additional replica(s)

  34. S: 88ecb048427276a287504e124ef78dd5b7a6e183 127.0.0.1:7005

  35. slots: (0 slots) slave

  36. replicates a22ca7f0c97d86a47897694a8e1f48a29702ae72

  37. S: a34cf5c793e3e606f6fe0c2834d9660cd4b7dcf0 127.0.0.1:7004

  38. slots: (0 slots) slave

  39. replicates ab3f9f295905d3ff113c0cfebc3000ae8d0eb717

  40. S: 3712bc46f0fcc14ef4fa8044ad319eee1ddc56c9 127.0.0.1:7003

  41. slots: (0 slots) slave

  42. replicates 5f08b2ea3c26ae39843b0bf964bac5a8596e8cda

  43. M: 5f08b2ea3c26ae39843b0bf964bac5a8596e8cda 127.0.0.1:7002

  44. slots:[10923-16383] (5461 slots) master

  45. 1 additional replica(s)

  46. M: a22ca7f0c97d86a47897694a8e1f48a29702ae72 127.0.0.1:7001

  47. slots:[5461-10922] (5462 slots) master

  48. 1 additional replica(s)

  49. [OK] All nodes agree about slots configuration.

  50. >>> Check for open slots...

  51. >>> Check slots coverage...

  52. [OK] All 16384 slots covered.

  53. [root@qiniu ~]# redis-cli -c -p 7000

  54. 127.0.0.1:7000> cluster info

  55. cluster_state:ok

  56. cluster_slots_assigned:16384

  57. cluster_slots_ok:16384

  58. cluster_slots_pfail:0

  59. cluster_slots_fail:0

  60. cluster_known_nodes:6

  61. cluster_size:3

  62. cluster_current_epoch:6

  63. cluster_my_epoch:1

  64. cluster_stats_messages_ping_sent:68

  65. cluster_stats_messages_pong_sent:69

  66. cluster_stats_messages_sent:137

  67. cluster_stats_messages_ping_received:64

  68. cluster_stats_messages_pong_received:68

  69. cluster_stats_messages_meet_received:5

  70. cluster_stats_messages_received:137

  71. 127.0.0.1:7000> cluster nodes

  72. 88ecb048427276a287504e124ef78dd5b7a6e183 127.0.0.1:7005@17005 slave a22ca7f0c97d86a47897694a8e1f48a29702ae72 0 1585820315000 6 connected

  73. a34cf5c793e3e606f6fe0c2834d9660cd4b7dcf0 127.0.0.1:7004@17004 slave ab3f9f295905d3ff113c0cfebc3000ae8d0eb717 0 1585820312475 5 connected

  74. 3712bc46f0fcc14ef4fa8044ad319eee1ddc56c9 127.0.0.1:7003@17003 slave 5f08b2ea3c26ae39843b0bf964bac5a8596e8cda 0 1585820316484 4 connected

  75. 5f08b2ea3c26ae39843b0bf964bac5a8596e8cda 127.0.0.1:7002@17002 master - 0 1585820315000 3 connected 10923-16383

  76. a22ca7f0c97d86a47897694a8e1f48a29702ae72 127.0.0.1:7001@17001 master - 0 1585820315481 2 connected 5461-10922

  77. ab3f9f295905d3ff113c0cfebc3000ae8d0eb717 127.0.0.1:7000@17000 myself,master - 0 1585820314000 1 connected 0-5460

  78. 127.0.0.1:7000>

  79. 127.0.0.1:7000> set hello redis

  80. OK

  81. 127.0.0.1:7000> exit

  82. [root@qiniu ~]# redis-cli -c -p 7001

  83. 127.0.0.1:7001> get hello

  84. -> Redirected to slot [866] located at 127.0.0.1:7000

  85. "redis"

  86. 127.0.0.1:7000>