概念
redis集群指由多个redis节点组合的分布式redis服务器群,redis 节点间两两通过握手通信。
特性
- 多个节点通过握手通信
- 共有16384个槽
- 每个槽都必须分派到具体节点,否则集群起不来
- 每个节点都记录了整个集群所有的槽分派情况
- 在redis键值归属的槽不属于当前切片(槽)时会发生moved错误
- moved 错误在客户端以集群模式访问时,会携带指引客户端跳转到负责当前槽的节点的信息
- 迁移过程中会发生ASK错误,ASK错误指示数据库继续查找键值
- 重新分片,在数据量不断变大时,可以重新分片。
- 集群中的每个节点可以通过主从模式构建高可用性。主节点下线后,集群会从其从节点中选择一个作为主节点,并接收原理主节点的所有槽。
- 集群中的节点通过发送和接收消息来进行通信,常见的消息包括MEET、PING、PONG、PUBLISH、FAIL五种。
设计原理
redis 集群通过切片方式实现,整个集群由16384个槽,通clusterState状态记录每个槽的使用情况,clusterState[i]=nil 表示当前槽未分派给指定节点。
节点实现数据结构:
struct clusterNode {
//创建节点的时间
mstime_t ctime;
//节点的名字,由40个十六进制字符组成
//例如68eef66df23420a5862208ef5b1a7005b806f2ff
char name[REDIS_CLUSTER_NAMELEN];
//节点标识
//使用各种不同的标识值记录节点的角色(比如主节点或者从节点),
//以及节点目前所处的状态(比如在线或者下线)。
int flags;
//节点当前的配置纪元,用于实现故障转移
uint64_t configEpoch;
//节点的IP地址
char ip[REDIS_IP_STR_LEN];
//节点的端口号
int port;
//保存连接节点所需的有关信息
clusterLink *link;
// ...
};
节点状态数据结构
typedef struct clusterState {
//指向当前节点的指针
clusterNode *myself;
//集群当前的配置纪元,用于实现故障转移
uint64_t currentEpoch;
//集群当前的状态:是在线还是下线
int state;
//集群中至少处理着一个槽的节点的数量
int size;
//集群节点名单(包括myself节点)
//字典的键为节点的名字,字典的值为节点对应的clusterNode结构
dict *nodes;
// ...
} clusterState;
命令
-
查看集群
- CLUSTER INFO 打印集群的信息
- CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
redis-cli -c -p 6379 cluster nodes redis-cli -c -p 6379 cluster info redis-trib.rb check 10.26.25.115:6379 redis-trib.rb info 10.26.25.115:6379
-
节点命令
- CLUSTER MEET <ip> <port> 添加节点
- redis-trib.rb add-node <ip> <port> 10.25.157.78:7022
- CLUSTER FORGET <node_id>
- redis-trib.rb del-node <ip> <port> <node_id>
-
设置主从节点
- CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。
-
槽命令
- CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。
- CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。
- CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
- CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
- CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。
-CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。 - CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
-
键命令
- CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
- CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
- CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。
redis集群三种方式
- 主从复制是用于实现高可用性的,
- 哨兵模式是主从模式的扩展,争强其高可用性。
- 集群是用户扩展数据库的,用于解决空间问题。
java 代码
Set<HostAndPort> hostAndPortSet = new HashSet();
hostAndPortSet.add(new HostAndPort("192.168.1.99", 9001));
hostAndPortSet.add(new HostAndPort("192.168.1.99", 9002));
hostAndPortSet.add(new HostAndPort("192.168.1.99", 9003));
JedisCluster cluster = new JedisCluster(hostAndPortSet);
cluster.set("name", "redis cluster");
String name = cluster.get("name");
System.out.println(name);
网友评论