redis集群

1.定义

由于数据量过大,单个master复制集难以承担,因需要对多个复制集进行集群,形成水平扩展,每个复制集只负责存储整个数据集的一部分,这就是redis的集群,其作用是提供在多个redis节点间共享数据的程序集。

(1)redis集群支持多个master,每个master又可以挂载多个slave

(2)由于cluster自带sebtinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能。

(3)客户端与redis的节点连接,不再需要连接集群中所有的节点,只需要任意连接集群中的一个可用节点即可

(4)槽位slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系

 2.分片

分片是什么?

使用redis集群时,我们会将存储的数据分散到多台redis机器上,这称为分片,简言之,集群中的每个redis实例都被认为是整个数据的一个分片

如何找到给定key的分片?

为了找到给定key的分片,我们对key进行CRC16(key)算法处理并通过对总分片数量取模,然后,使用确定性哈希函数,这意味着给定的key将多次始终映射到同一个分片,我们可以推断将来读取特定key的位置

优势

方便扩容、缩容和数据分派查找

redis集群_第1张图片

3.哈希槽算法

redis集群中内置了16384个哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同的节点。当需要再redis集群中放置一个key-value时,redis先对key使用CRC16算法算出一个结果然后用结果对16384求余[CRC16(key)%16384],这样每个key都会对应一个编号在0-16384之间的哈希槽,也就是映射到某个节点上。

另外两种算法:

哈希取余算法、一致性hash算法

redis集群_第2张图片

4.为什么redis集群的最大槽数是16384?

redis集群并没有使用一致性hash而是引入了哈希槽的概念。redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模决定位于的槽位,集群的每个节点负责一部分hash槽。但为什么哈希槽的数量是16384(2^14)个呢?

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

原因:正常的心跳数据包带有节点的完整配置,可以用幂等方式用旧的节点替换旧节点,以便更新旧的配置。这意味着它们包含原始节点的插槽配置,该节点使用2k的空间和16k的插槽,但是会使用8k的空间(使用65k的插槽)。同时,由于其他设计折衷,redis集群不太可能扩展到1000个以上的主节点。因此16k处于正确的范围内,以确保每个机器具有足够的插槽,做多可容纳1000个矩阵,但数量足够少,可以轻松地将插槽配置作为原始位图传播。在小型集群中,位图将难以压缩,因为当N较小时,位图将设置的slot/N位占设置位的很大百分比。

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

在消息头中最占空间的时myslots[CLUSTER_SLOTS/8]。当槽位是65535时,这块大小是:65535/8/1024=8kb。当槽位是16384时,这块大小是:16384/8/1024=2kb。因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65535,这个ping消息的消息头太大了,浪费带宽。

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

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

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

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

5.构建redis集群

(1)主机192.168.1.5,两个配置文件redis6379.conf、redis6380.conf

redis6379.conf

# bind * -::*

daemonize yes

protected-mode no

port 6379

logfile "/tmp/redis6379.log"

pidfile "/var/run/redis_6379.pid"

dir "/root/redis/my_cluster_conf/dumpdir"

dbfilename "dump6379.rdb"

appendonly yes

appendfilename "appendonly6379.aof"

requirepass "root"

masterauth "root"

cluster-enabled yes

cluster-config-file nodes-6379.conf

cluster-node-timeout 15000

redis6380.conf

# bind * -::*

daemonize yes

protected-mode no

port 6380

logfile "/tmp/redis6380.log"

pidfile "/var/run/redis_6380.pid"

dir "/root/redis/my_cluster_conf/dumpdir"

dbfilename "dump6380.rdb"

appendonly yes

appendfilename "appendonly6380.aof"

requirepass "root"

masterauth "root"

cluster-enabled yes

cluster-config-file nodes-6380.conf

cluster-node-timeout 15000

(2)主机192.168.1.6,两个配置文件redis6379.conf、redis6380.conf,与上面一样

(3)主机192.168.1.7,两个配置文件redis6379.conf、redis6380.conf,与上面一样

(4)在每个机器上启动redis

redis-server ./redis6379.conf

redis-server ./redis6380.conf

(5)创建集群

redis-cli -a root --cluster create --cluster-replicas 1 192.168.1.5:6379 192.168.1.5:6380 192.168.1.6:6379 192.168.1.6:6380 192.168.1.7:6379 192.168.1.7:6380

注意,集群至少3个master

连接集群

redis-cli -a root -c -p 6379

输入命令查看集群节点

redis集群_第3张图片

redis集群_第4张图片

(6)redis集群常用命令

cluster info

cluster nodes

redis-cli -a root --cluster check 192.168.1.6:6380

# 查看槽数是否被占用

CLUSTER COUNTKEYSINSLOT  {槽位数字}

# 计算某key的槽位

CLUSTER KEYSLOT {key}

当集群中某个master宕机了,集群中会有另外一个slave节点接替宕机master的位置和数据

你可能感兴趣的:(数据库,redis,数据库)