[转载] redis 学习 - 分布式redis集群搭建介绍
参考链接
Redis Cluster
官方介绍文档: https://redis.io/topics/cluster-spec
redis cluster 是 redis 官方在 3.0 版本推出的一套分布式存储方案. 完全去中心化, 由多个节点组成, 所有节点彼此互联, redis 客户端可以直接链接任何一个节点获取集群中的键值对, 不需要中间代理. 如果该节点不存在用户指定的键值对, 其内部会自动把客户端重定向到键值对所在的节点.
redis 集群是一个网状结构, 每个节点都通过 TCP 与其他节点连接. 在一个有 N 个节点的集群中, 每个节点都有 N-1 个流出的 TCP 连接, 和 N-1 个流入的连接, 这些 TCP 连接会永久保持. 如下图所示:
redis cluster 功能
数据分区
redis 集群会将用户数据分散保存至各个节点中, 突破单机 redis 内存最大存储容量.
集群引入了哈希槽 slot 概念. 其搭建完成后会生成 16384 个哈希槽 slot, 同时会根据节点的数量大致均等的将 16384 个哈希槽映射到不同的节点上. 当用户存储 k-v 时, 集群会先对 key 进行 CRC16 校验然后对 16384 取模来决定 k-v 存放在哪个槽, 从而实现自动分割数据到不同的节点上.
数据冗余
redis 集群支持主从复制和故障恢复. 集群使用了主从复制模型, 每个主节点 master 应至少有一个从节点 slave. 假设某个主节点发生故障, 其所有子节点会广播一个数据包给集群里的其他主节点来请求选票, 一旦某个从节点收到了大多数主节点的回应, 那么它就赢得了选举, 被推选为主节点, 负责处理之前旧主节点负责的哈希槽.
搭建 Redis 集群
依据 redis cluster 内部故障转移实现原理, redis 集群至少需要 3 个树节点, 而每个主节点至少要有一个从节点, 因此搭建一个集群至少要包含 6 个节点, 并且分别部署在不同的机器上.
目前 Redis Cluster 的搭建有两种方式:
手动方式搭建,即手动执行 cluster 命令,一步步完成搭建流程。
自动方式搭建,即使用官方提供的集群管理工具快速搭建。
手动方式搭建
节点列表
接下来需要分别修改每个节点的配置文件。下面贴的是节点 A 的配置文件中启用或修改的一些必要参数。其他节点参照修改,注意把涉及端口的地方修改成各自节点预先规划的即可。
bind 192.168.83.128 # 设置当前节点主机地址
port 7001 # 设置客户端连接监听端口
pidfile /var/run/redis_7001.pid # 设置 Redis 实例 pid 文件
daemonize yes # 以守护进程运行 Redis 实例
cluster-enabled yes # 启用集群模式
cluster-node-timeout 15000 # 设置当前节点连接超时毫秒数
cluster-config-file nodes-7001.conf # 设置当前节点集群配置文件路径
完成上述工作就可以通过命令启动待搭建集群中的 6 个节点了。最后通过ps -ef|grep redis命令确认各个节点服务是否已经正常运行。
[root@localhost bin]# ps -ef|grep redis
root 5613 1 0 04:25 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7001 [cluster]
root 5650 1 0 04:26 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7002 [cluster]
root 5661 1 0 04:26 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7003 [cluster]
root 5672 1 0 04:27 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:8001 [cluster]
root 5681 1 0 04:27 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:8002 [cluster]
root 5690 1 0 04:27 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:8003 [cluster]
root 5731 1311 0 04:28 pts/0 00:00:00 grep --color=auto redis
节点握手
虽然上面 6 个节点都启用了群集支持,但默认情况下它们是不相互信任或者说没有联系的。节点握手就是在各个节点之间创建链接(每个节点与其他节点相连),形成一个完整的网格,即集群。
节点握手的命令如下:
cluster meet ip port
我们的创建的 6 个节点可以通过 redis-cli 连接到 A 节点执行如下五组命令完成握手
cluster meet 127.0.0.1 7002
cluster meet 127.0.0.1 7003
cluster meet 127.0.0.1 8001
cluster meet 127.0.0.1 8002
cluster meet 127.0.0.1 8003
分配槽位
此时 Redis 集群还并没有处于上线状态,可以在任意一节点上执行 cluster info 命令来查看目前集群的运行状态。
[root@localhost ~]# /usr/local/bin/redis-cli -p 7001 cluster info
cluster_state:fail
......
上面输出cluster_state:fail表示当前集群处于下线状态。因为只有给集群中所有主节点分配好槽位(即哈希槽slot,本文第一小节有提及)集群才能上线。
分配槽位的命令如下:
cluster addslots slot [slot ...]
根据预先规划,这一步需要使用 cluster addslots 命令手动将 16384 个哈希槽大致均等分配给主节点 A、B、C。
/usr/local/bin/redis-cli -p 7001 cluster addslots {0..5461}
/usr/local/bin/redis-cli -p 7002 cluster addslots {5462..10922}
/usr/local/bin/redis-cli -p 7003 cluster addslots {10923..16383}
上面三组命令执行完毕,可以再次查看目前集群的一些运行参数。
[root@localhost ~]# /usr/local/bin/redis-cli -p 7001 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:5
cluster_my_epoch:4
cluster_stats_messages_ping_sent:11413
cluster_stats_messages_pong_sent:10509
cluster_stats_messages_meet_sent:11
cluster_stats_messages_sent:21933
cluster_stats_messages_ping_received:10509
cluster_stats_messages_pong_received:10535
cluster_stats_messages_received:21044
主从复制
Redis 集群成功上线,不过还没有给主节点指定从节点,此时如果有一个节点故障,那么整个集群也就挂了,也就无法实现高可用。集群中需要使用 cluster replicate
命令手动给从节点配置主节点。集群复制命令如下:
cluster replicate node-id
集群中各个节点的 node-id 可以用cluster nodes命令查看