Redis集群

简介:

容量不够时,redis如何进行扩容。 –建立服务器集群,分担写入压力。 并发写操作,redis如何分摊。

主从模式的从机继承,导致ip地址发生变化,应用程序中配置需要修改对应的主机地址、端口等信息。

redis3.0中提供了 无中心化集群。

无中心化集群简介

任何一台服务器都可以作为集群的入口,之间可以互相联通。

Redis集群是对Redis的水平扩容,即启动N个节点。整个数据库分布存储在这N个节点,每个节点存储总数据的 1/N。

Redis集群通过分区来提供一定程度的可用性:及时集群中有一部分节点失效或者失去通讯,也能继续进行服务。

集群搭建示例

制作6个示例并启动

在配置文件追加以下内容

cluster-enabled yes // 开启集群
cluster-config-file [filename] // 设置集群文件名称
cluster-node-timeout [time] // 设置超时时间

然后启动6个服务器

集群配置:

新版本redis不需要再装ruby环境。ruby环境配置在redis目录src文件夹中的redis-trib.rb中。 需要在该目录中执行集群配置的命令

// --cluster create 创建一个集群
// cluster-replicas 集群配置方式,1为最简单的方式
// 随后输入不同的节点[ip:port]加入集群
redis-cli --cluster create --cluster-replicas 1 192.168.199.129:6379 192.168.199.129:6380 192.168.199.129:6381 192.168.199.129:6389 192.168.199.129:6390 192.168.199.129:6391

执行后会自动分配主机和从机,输入yes后接受分配,当看到如下图片,说明集群配置成功

image-20240902144759411

测试:

用集群方式开启redis客户端,连接集群。

// -c 采用集群策略连接,设置数据会自动切换到相应的写主机
redis -c -p [port]

用 cluster nodes查看集群信息

image-20240902145144990

能看到节点的分析情况,一主一从的模式,共有三组。

Cluster自动分配:

一个集群至少要有三个主节点。 –cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。 分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。

Slots:

在集群创建成功信息中,可以看到日志包含:

image-20240902145640621

一个Redis集群包含16384个slot (0-16383),数据库中的每个键都属于这16384个slot中的其中一个。

集群使用公式 CRC16(key) % 16384 来计算键key数据哪个槽 其中 CRC16(key) 语句用于计算键 key的CRC16校验和。

集群中的每个节点是插槽的一部分,在cluster node插槽信息中可以看到。

在集群中录入值:

由于redis集群是无中心化集群,任何一个主机都可以作为集群的入口

image-20240902154547693

图中k1的slot为12706,由对应的主机完成写操作。

在集群中使用mset操作会报错,不能计算多个key的hash slot。 image-20240902154723152

如果需要添加多个key-value,需要用组的形式,格式例:

// 向数据库中加入多个值,根据{}中的值计算slot
mset name{user} lucy age{user} 20
image-20240902160451740

查询集群中的值

// 计算key的插槽值
cluster keyslot [key]
// 计算该插槽中的key数量。(在对应的主机只能看它具有的插槽)
cluster countkeysinslot [slot] [count]
// 会返回count个在slot中的key。
cluster getkeysinslot [slot] [count]

故障恢复:

如果主机下线,从节点能否自动升为主节点?(可以)

image-20240902165636533

如果主机再上线,还会成为主机吗?(不会,会成为从机)

image-20240902165756369

如果集群中某一节点(插槽段)的主机和从机都下线后,Redis集群还能继续运行吗?(不一定)

// 如果该配置属性为yes,则集群整个都会下线
// 如果为no,集群中该插槽数据全都无法访问,新数据也无法存储。
cluster-require-full-coverage [yes/no]

集群Jedis开发

Jedis可以针对集群进行操作(创建集群Jedis对象而不是Jedis对象)

// 创建对象
HostAndPort hostAndPort = new HostAndPort([host],[port]);
JedisCluster jedisCluster = new JedisCluster(hostAndPort);

// 进行操作
jedisCluster.set("b1","value1");

String value = jedisCluster.get("b1");
sout("value: "+value);

jedisCluster.close();

总结:

Redis集群实现了扩容,分摊IO压力,且无中心配置相对简单,每个主机都可以作为集群的入口。

Redis集群也有不足,多键操作不被支持,需要分组来进行操作。 多键的Redis事务是不被支持。lua脚本也不被支持。

上一篇
下一篇