Redis-集群

  • 如何解决:容量不够,redis如何进行扩容? 并发写操作, redis如何分摊? 另外,主从模式,薪火相传模式,主机宕机,导致ip地址发生变化,应用程序中配置需要修改对应的主机地址、端口等信息
  • 之前通过代理主机来解决,但是redis3.0中提供了解决方案,就是无中心化集群配置
  • Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库数据分布存储在这N个节点中,每个节点存储总数据的1/N
  • Redis 集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求

主要作用

  • Redis集群支持多个Master,每个Master又可以挂载多个Slave
  • 由于集群Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能
  • 客户端与Redis的节点连接,不再需要连接集群中所有的节点,只需要任意连接集群中的一个可用节点即可
  • 槽位slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系

如何配置

  • 修改配置文件,复制多个redis

cluster-enabled yes 打开集群模式

cluster-config-file nodes-6379.conf 设定节点配置文件名

cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换

复制代码
include /home/bigdata/redis.conf
port 6379
pidfile "/var/run/redis_6379.pid"
dbfilename "dump6379.rdb"
dir "/home/bigdata/redis_cluster"
logfile "/home/bigdata/redis_cluster/redis_err_6379.log"
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
  • 将redis启动后,配置集群

    replicas 1 采用最简单的方式配置集群,一台主机,一台从机,正好三组

    redis-cli --cluster create --cluster-replicas 1
    192.168.11.101:6379
    192.168.11.101:6380
    192.168.11.101:6381
    192.168.11.101:6389
    192.168.11.101:6390
    192.168.11.101:6391

  • 集群策略连接,-c参数设置数据会自动切换到相应的写主机

查看集群信息

复制代码
cluster nodes

集群节点分配

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

slots插槽

  • 一个 Redis 集群包含 16384 个插槽(hash slot)
  • 数据库中的每个键属于这 16384 个插槽的其中一个分片,简言之,集群中的每个Redis实例都被认为是整个数据的一个分片
  • 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和

问题:CRC16算法产生的hash值有16bit,该算法可以产生2^16=65536个值。换句话说值是分布在0~65535之间,有更大的65536不用为什么只用16384就够?

(1)如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。

在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为65536时,这块的大小是: 65536÷8÷1024=8kb

在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为16384时,这块的大小是: 16384÷8÷1024=2kb

因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽。

(2)redis的集群主节点数量基本不可能超过1000个。

集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者不建议redis cluster节点数量超过1000个。 那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了。没有必要拓展到65536个。

(3)槽位越小,节点少的情况下,压缩比高,容易传输

Redis主节点的配置信息中它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。 如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

  • 集群中的每个节点负责处理一部分插槽,假设集群中有3个节点:
  • 好处:方便扩缩容和数据分派查找

在集群中录入值

  • 每次录入、查询键值,redis都会计算出该key应该送往的插槽,如果不是该客户端对应服务器的插槽,redis会报错,并告知应前往的redis实例地址和端口
  • 不在一个slot下的键值,是不能使用mget,mset等多键操作
  • 可以通过{}来定义组的概念,从而使key中{}内相同组内容的键值对放到一个slot中去

查询集群中的值

复制代码
CLUSTER GETKEYSINSLOT <slot><count>

故障恢复

  • 主节点宕机,超时15秒,从节点自动变为主节点;主节点恢复后,变成从节点
  • 配置文件参数cluster-require-full-coverage
    • yes:如果某一段插槽的主从都挂掉,那么整个集群都挂掉
    • no:如果某一段插槽的主从都挂掉,那么该插槽数据全都不能使用,也无法存储

集群的Jedis

java 复制代码
public static void main(String[] args) { 
	Set<HostAndPort>set =new HashSet<HostAndPort>();
	set.add(new HostAndPort("192.168.31.211",6379));
	JedisCluster jedisCluster=new JedisCluster(set);
	jedisCluster.set("k1", "v1");
	System.out.println(jedisCluster.get("k1"));
}

集群好处

  • 实现扩容
  • 分摊压力
  • 无中心配置,相对简单

集群不足

  • 多键操作是不被支持的
  • 多键的Redis事务是不被支持的
  • lua脚本不被支持
相关推荐
爬山算法5 小时前
Redis(60) Redis的复制延迟如何优化?
redis·bootstrap·php
DemonAvenger9 小时前
深入Redis Zset:从原理到实践,10年经验带你解锁高效排序场景
数据库·redis·性能优化
xujiangyan_12 小时前
Redis详解
数据库·redis·缓存
泽020218 小时前
Linux之环境变量
java·linux·redis
济南java开发,求内推19 小时前
Redis一个服务器部署多个节点
服务器·数据库·redis
Full Stack Developme19 小时前
Python Redis 教程
开发语言·redis·python
夜泉_ly21 小时前
Redis -持久化
数据库·redis·缓存
用户311879455921821 小时前
redis-4.0.11-1.ky10.sw_64.rpm安装教程(申威麒麟V10 64位系统详细步骤)
redis
zym大哥大1 天前
Redis-Zest
数据库·redis·缓存