前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redis集群-----切片集群(cluster)

redis集群-----切片集群(cluster)

作者头像
袁新栋-jeff.yuan
发布2022-05-05 14:56:21
9970
发布2022-05-05 14:56:21
举报

背景

上篇文章聊到了redis的哨兵机制,哨兵的作用是保证主从节点宕机或者故障的时候可以可以进行自愈,选举合适的master并且告知client。这个机制也就保证了redis集群的可用性。但是这次我们又遇到了新问题,那就是主从复制架构的情况下redis 的内存不够用了该怎么办。有人说那就不断的阔各个机器的内存,按照常理我们都知道一个人的力量是有限的。

当一个节点的内存过大,那么我们在进行同步的时候会通过RDB文件进行同步,而生成rdb文件是通过fork一个子进程进行的(下篇文章我们仔细聊下这个过程),在进行fork操作且在生成rdb文件的时候会阻塞主进程,导致redis 的性能就很慢。

所以我们得想办法,可以不再单台机器上扩容,而达到目的。那这个方案就是切片集群。

切片集群(cluster)

什么是切片集群?

就是多个集群/节点 组成的集群,存储数据的方式是分区存储,在这里为什么叫分区存储呢,就是说不通的节点/集群之间是不进行通信往来的,他们只需要存储客户端让存储的数据,也就是说他们存储的数据是不冗余的。

切片集群存储的问题?

1. 数据如何切分?

客户端会存储各种各样的数据,那怎么去将这个数据进行合理的分配到各个节点呢,其实这个我们应该想到一个知识点,那就是Java中的Hash表,他是如何存储的呢,在有限的hash slot 进行存储key,那就是通过key的hash值取模。然后会映射到对应的hash slot 如果有重复会进行新增加链表。那何尝和我们切片集群的场景不一致呢。每一个slot可以对应一个redis主从集群/redis节点。但是对与Java的hash表来讲它是可以进行一直扩容的。所以某些场景还是不符合的。所以我们得进行改进算法。

上面大概讲了下思路,接下啦看看redis cluster的官方方案:

  1. 根据redis的key适用CRC16的算法计算出一个16bit的值
  2. 将16bit的值对16384取模。得到一个0-16383之间的一个值。
  3. 在进行创建redis cluster的时候,每一个分片都会被分配到对应的slot
  4. 分配的规则是16383/n 也就是每一个分片会在16383/n个slot 上。

这个时候由于你手里的redis机器资源大小不太一样,所以你想让他存储的数据量不一样,这个时候你就可以进行手动分配这个slot。

2. 客户端如何去拿对应的数据呢?

我们通过上面的补助将数据存储到你了对应的一个redis节点/集群上,那么我们查询的时候如何拿呢?

  1. 首先客户端得必须知道数据是如何被分配到各个节点上去的。那就得知道CRC16算法,并且节点何hash slot对应的分配关系。
  2. redis 自身是有pubsub的能力的,所以会讲hash slot 和节点的映射关发送给客户端,客户端会缓存下来。
  3. 上文我们既然将了我们会进行一些扩容,那这如果扩容了那么这个hash slot的映射关系就会改变,那么我们怎么应对呢?
  4. redis cluster 的重定向方案,那就是redis在进行读数据的时候没有拿到对应的value值,会给客户端一个新的实例信息进行查找。 这个实例信息是通过redis 自己节点的数据存储的,因为我们这条请求的前提条件是key是存在的,但是hash slot 变了,就是在变的时候客户端还不知道,但是请求到redis node的时候才变了,于是redis node将这件事告诉了client,并且补救告诉他应该去哪里找。切更新了自己本地错误的映射关系缓存 返回的信息是: GET hello:key(error) MOVED 13320 172.16.19.5:6379
  5. 但是还有一种情况是,redis 在重新分配了后还在进行迁移,这个时间访问一个已经存在的key对应的机器会讲: GET hello:key(error) ASK 13320 172.16.19.5:6379 这个时候客户端会给对对应的机器请求asking 命令然后进行查询数据。

总结

  1. 我们聊了切片集群在保存大量数据方面的优势,以及基于哈希槽的数据分布机制和客户端定位键值对的方法。
  2. 在应对数据量扩容时,虽然增加内存这种纵向扩展的方法简单直接,但是会造成数据库的内存过大,导致性能变慢。
  3. Redis 切片集群提供了横向扩展的模式,也就是使用多个实例,并给每个实例配置一定数量的哈希槽,数据可以通过键的哈希值映射到哈希槽,再通过哈希槽分散保存到不同的实例上。
  4. 这样做的好处是扩展性好,不管有多少数据,切片集群都能应对。另外,集群的实例增减,或者是为了实现负载均衡而进行的数据重新分布,会导致哈希槽和实例的映射关系发生变化,客户端发送请求时,会收到命令执行报错信息。

参考

  1. https://segmentfault.com/a/1190000039995230
  2. https://time.geekbang.org/column/article/276545
  3. https://redis.io/documentation
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 切片集群(cluster)
    • 什么是切片集群?
      • 切片集群存储的问题?
        • 1. 数据如何切分?
        • 2. 客户端如何去拿对应的数据呢?
    • 总结
    • 参考
    相关产品与服务
    云数据库 Redis
    腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档