内容简介:Redis 集群是 Redis 提供的分布式数据库方案,集群通过**分片(sharding)**来进行数据提供,并提供复制和故障转移功能。学习记录以下几点:1.复制三份配置 redis.conf,
Redis 集群是 Redis 提供的分布式数据库方案,集群通过**分片(sharding)**来进行数据提供,并提供复制和故障转移功能。
学习记录以下几点:
- 节点
- 槽指派
- 命令执行
- 重新分片
- 转向
- 故障转移
- 消息
首先先看如何以集群模式启动Redis
1.复制三份配置 redis.conf, 修改端口号 port 和 node.conf
#可选操作,该项设置后台方式运行, daemonize yes port 7000 cluster-enabled yes cluster-config-file nodes0.conf cluster-node-timeout 5000 appendonly yes 复制代码
记住三份文件要在不同文件夹下(例如/7001/redis.conf、/7002/redis.conf···)
**node.conf **虽然此配置的名字叫"集群配置文件",但是此配置文件不能人工编辑,它是集群节点自动维护的文件,主要用于记录集群中有哪些节点、他们的状态以及一些持久化参数等,方便在重启时恢复这些状态。通常是在收到请求之后这个文件就会被更新。
配置文件结构:
Redis/ ├── 7000 | ├── redis.conf | ├── nodes0.conf ├── 7001 | ├── redis.conf | ├── nodes1.conf ├── 7002 | ├── redis.conf | ├── nodes2.conf 复制代码
2.依次通过redis-server根据具体配置启动
# redis-server /7000/redis.conf 复制代码
如果遇到以下错误:
Sorry, the cluster configuration file nodes.conf is already used by a different Redis Cluster node. Please make sure that different nodes use different cluster configuration files. 复制代码
请确认node.conf文件名是否修改正确
我是以前台方式启动的,所以能看到打印以下打印信息:
10992:M 10 Apr 13:48:38.266 * No cluster configuration found, I'm f745788c4c24711a11c8ad516ead9a485e5b1dbb 复制代码
此时表示 redis 已经以集群模式启动了
节点
一个Redis集群通常有多个节点(Node)组成,在刚开始的时候,每个节点都是互相独立的,它们都处于一个只包含自己的集群当中,要组件一个真正可工作的集群,我们必须将各个独立的节点连接起来,构成一个包含多个节点的集群。
连接各个节点的工作可以使用 CLUSTER MEET 命令,可以让 node 节点与 io 和 port 所指定的节点进行握手 # CLUSTER MEET <ip> <port> 复制代码
测试,用三个独立的节点(本地打开7000、7001、7002三个端口)
# redis-cli -c -p 7000 27.0.0.1:7000> CLUSTER NODES f745788c4c24711a11c8ad516ead9a485e5b1dbb :7000@17000 myself,master - 0 0 0 connected 可以看出,现在集群只包含700自己一个节点 复制代码
开始节点之间的连接:
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7001 OK 127.0.0.1:7000> CLUSTER NODES 2a1035a6642f8f1020c279c8a69ce66ff7eb564b 127.0.0.1:7001@17001 master - 0 1523341290344 1 connected f745788c4c24711a11c8ad516ead9a485e5b1dbb 127.0.0.1:7000@17000 myself,master - 0 0 0 connected 127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7002 OK 127.0.0.1:7000> CLUSTER NODES 3110ed887330d428e1b544932dc22b1fcbd3fa45 127.0.0.1:7002@17002 master - 0 1523341327519 2 connected 2a1035a6642f8f1020c279c8a69ce66ff7eb564b 127.0.0.1:7001@17001 master - 0 1523341328553 1 connected f745788c4c24711a11c8ad516ead9a485e5b1dbb 127.0.0.1:7000@17000 myself,master - 0 1523341327000 0 connected 复制代码
通过 CLUSTER NODES 可以看出,现在集群中包含了三个节点。
集群数据结构
clusterNode结构保存了一个节点的当前状态,比如节点的创建时间节点的名字、节点当前的配置纪元节点的IP地址和端口号等等。
结构如下定义:
struct clusterNdoe { //创建节点的时间 mstime_t ctime; //节点的名字 char name[REDIS_CLUSTER_NAMELEN]; //节点标识 int flags; //节点当前的配置纪元,用来实现故障转移 uint64_t configEpoch; //节点的IP地址 char ip[REDIS_IP_STR_LEN]; //节点的端口号 int port; //保存连接节点所需的有关信息 clusterLink *link; ··· } 复制代码
每个节点都保存着一个clusterState结构,这个结构在当前节点描述集群当前所处的状态,例如集群是在线还是下线,集群包含多少个节点,集群当前的配置纪元等。
typedef struct clusterState { // 指向当前节点的指针 clusterNode *myself; //集群当前的配置纪元,用于实现故障转移 uint64_t currentEpoch; //集群当前的状态:在线OR下线 int state; //集群节点名单(包括自己) dict *nodes; ··· } 复制代码
槽指派
Redis 集群通过分片的方式来保存数据库中的键值对:集群的整个数据库被分为 16384 个槽(slot),数据库中的每个键都属于这 16384 个槽的其中一个,集群中的每个节点可以处理 0 个或最多 16384 个槽。
当数据库中的 16384 全部槽都有节点在处理时,表示集群处于上线状态;否则,处于下线状态。
通过CLUSTER_INFO进行集群状态查看
127.0.0.1:7000> cluster info # state显示是fail,因为没有处理槽 cluster_state:fail cluster_slots_assigned:0 cluster_slots_ok:0 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 cluster_size:0 cluster_current_epoch:2 cluster_my_epoch:0 cluster_stats_messages_ping_sent:1261 cluster_stats_messages_pong_sent:1350 cluster_stats_messages_meet_sent:2 cluster_stats_messages_sent:2613 cluster_stats_messages_ping_received:1350 cluster_stats_messages_pong_received:1263 cluster_stats_messages_received:2613 复制代码
使用 redis-trib.rb 创建集群并分配槽
在节点中通过 CLUSTER ADDSLOTS [slot ...]
# 将0-5000槽指派给7000负责 127.0.0.1:7000>CLUSTER ADDSLOTS 0 1 2 3 ... 5000 复制代码
大雾!!!一个一个将槽位打出来不现实,所以使用redis-trib.rb帮助我们进行简单集群配置,但redis-trib.rb是由 ruby 语言编写的所以需要安装ruby环境。
发现绕来绕去,REDIS的集群安装还需要RUBY环境和使用gem安装redis接口。
给大伙一个安装传送门
注意:Mac 通过 Homebrew 没有 src 目录,gem install redis后找不到redis-trib.rb,被折磨很久后,直接去 GITHUB下载这个文件
# redis-trib.rb create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 >>> Creating cluster >>> Performing hash slots allocation on 3 nodes... Using 3 masters: 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 M: f745788c4c24711a11c8ad516ead9a485e5b1dbb 127.0.0.1:7000 slots:0-5460 (5461 slots) master M: 2a1035a6642f8f1020c279c8a69ce66ff7eb564b 127.0.0.1:7001 slots:5461-10922 (5462 slots) master M: 3110ed887330d428e1b544932dc22b1fcbd3fa45 127.0.0.1:7002 slots:10923-16383 (5461 slots) master 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: f745788c4c24711a11c8ad516ead9a485e5b1dbb 127.0.0.1:7000 slots:0-5460 (5461 slots) master M: 2a1035a6642f8f1020c279c8a69ce66ff7eb564b 127.0.0.1:7001 slots:5461-10922 (5462 slots) master M: 3110ed887330d428e1b544932dc22b1fcbd3fa45 127.0.0.1:7002 slots:10923-16383 (5461 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. 复制代码
踩坑:之前通过 CLUSTER MEET,让各个节点进行握手,所以使用 redis-trib.rb 会报下面这个错误
[ERR] Node 127.0.0.1:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0. 复制代码
解决方法:在每个节点查询nodes编号后,使用 CLUSTER FOTGET 命令
$ cluster forget 3110ed887330d428e1b544932dc22b1fcbd3fa45 # 接着重新输入命令 $ redis-trib.rb create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 复制代码
查看槽分派情况
使用 CLUSTER SLOTS 查询
127.0.0.1:7000> CLUSTER SLOTS 1) 1) (integer) 10923 2) (integer) 16383 3) 1) "127.0.0.1" 2) (integer) 7002 3) "3110ed887330d428e1b544932dc22b1fcbd3fa45" 2) 1) (integer) 5461 2) (integer) 10922 3) 1) "127.0.0.1" 2) (integer) 7001 3) "2a1035a6642f8f1020c279c8a69ce66ff7eb564b" 3) 1) (integer) 0 //起始槽编号 2) (integer) 5460 //结束槽编号 3) 1) "127.0.0.1" //IP 2) (integer) 7000 //PORT 3) "f745788c4c24711a11c8ad516ead9a485e5b1dbb" //NODE编号 复制代码
从上图可以看出,每个节点负责处理自己对应的槽。
一个节点除了会将自己负责处理的槽记录在 clusterNode 结构的 slots 属性和 numslot s属性之外,还会将自己的 slots 数组通过消息发送给集群中的其他节点,以此来告知其他节点自己目前负责处理哪些槽。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 操作系统学习笔记-11:内存分配(一):连续分配
- 操作系统学习笔记-12:内存分配(二):非连续分配
- PHPKafka 1.1.1 发布,支持消费者分区分配策略之粘性分配等功能
- Go:内存管理分配
- 多机任务分配机制
- Allocations分析内存分配
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。