《redis》10-redis切片集群

上面的章节我们讲完了redis主从模式,但是主库和从库的数据基本上保持一致,那么就会遇到一个问题,在主库不断写入的情况下,数据越来越多,redis作为内存存储系统,数据存储在内存中,内存不能无限扩大,而且随着存储数据的不断增加,fork的子线程在做RDB文件备份的时候,速度越来越慢。

mysql也会遇到这样的问题,之前Facebook出现的问题,用户信息表随着注册的用不端增加,导致主键字段长度不够,全球10亿用户的信息难道都存储在一个数据库里?redis提出了解决方案,切片集群。

  1. 纵向扩展,随着数据的不断增加对内存进行扩容,之前的4G内存扩展到16G,之后再扩展到32G
  2. 横向扩展,数据进行分片存储在不同的redis服务实例上,原来的一台4G内存,扩展到4台4G的服务器,每个服务存储1/4的内容,这样既保证了单机的备份速度,还能保证单机宕机造成的数据丢失。

横向扩展是很多大数据量的解决方案,mysql中的分表也是这样的思想。redis在3.0之后提出了切片思想的实现方案Redis Cluster

Redis cluster 3.0之后的官方实现方案

切片集群的思想早就有了,但是redis在3.0之后才提供了官方的实现方案,之前有诸如ShardedJedis等的实现方案,各有优缺点。Redis cluster的设计思想很简单

  1. 所有的redis实例分配16384个hash slot(hash槽),跟Hash表的思想一致,但是提供了固定的2^14个槽点。
  2. 客户端操作key-value时,先对key进行crc16算法之后,获取16bit长的值,然后对16384取余,获取槽点
  3. 访问槽点所在的redis实例

redis如何分配槽点

  1. 在创建切片集群的时候,自动分配槽点,cluster create 会平均分配槽点,N个实例则每个实例16384/n个槽点。如果有的机器内存不大,有的机器内存大,带宽大,平均分配有失公平
  2. 手动分配,执行命令 cluster meet手动建立集群的时候,用 cluster addslots命令手动分配槽点,16384个槽点要分配完,否则不能正常工作

客户端如何直到槽点在哪个redis实例

  1. redis实例会把自己的槽点信息返回给客户端
  2. redis实例之间会互相告知槽点信息

redis新增或删除或者负载均衡怎么办

  1. redis集群新增实例或者删除实例,实例上的槽点要进行重新分配
  2. 负载均衡会把redis切片集群上的槽点进行重新分配。
  3. 在重新分配的时候,redis依然提供服务,如果slot13320这个槽点本来在redis实例4上,经过重新分配之后已经转移到redis实例9上面,客户端在操作slot13320的hello时,还是会访问实例4.。这个时候实例4会返回错误信息,这个信息告诉我们13320槽点已经移动到173.16.19.5这台机器上了,客户端会更新自己本地的slot信息,下次直接访问实例9
    GET hello:key
    (error) MOVED 13320 172.16.19.5:6379
  4. 重新分配的时候,如果slot13320还在转移当中,key1,key2已经从4机器上转移到5机器上。key3.key4还在4机器上。这个时候客户端执行获取key1的操作,还是会访问4机器,但是key1已经不在了,这个时候4机器返回异常

    GET hello:key
    (error) ASK 13320 172.16.19.5:6379

    告诉客户端,这个要访问5这台机器,客户端先向5机器发送ASK命令,然后再执行GET命令。但是客户端不会更新本地的slot信息,下次访问key2还是会访问4机器。

上面的内容是总结自蒋德钧老师的redis课程。

猜你喜欢

转载自blog.csdn.net/David_lou/article/details/109014230
今日推荐