Redis集群 解析+配置

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Redis集群 解析+配置

Redis集群

由于数据量的增加,单个master不一定能承但全部的写任务;所以,可以对多个复制集进行集群,水平扩展每个复制集值存储数据集中的一部分,这就是Redis集群,可以在Redis节点间共享数据;

Redis集群是一个提供在多个Redis节点间空闲数据的程序集,Redis集群支持多个Master

  • Redis集群支持多个Master,每个Master可以挂载多个Slave
  • 由于Cluster自带哨兵的故障转移机制,无需再使用哨兵
  • 客户端与Redis的节点连接不需要连接集群中的全部节点,只需要连接集群中任意节点即可
  • 槽位Slot负责分配到各个物理节点,由对应的集群哦来负责维护节点、插槽和数据之间的关系

集群分片

槽位Slot

Redis集群没有使用一致性哈希,而是使用了哈希槽的概念;Redis哈希槽有16384个槽位,当存储时使用CRC16算法值和16384取模,得到0-16383之间的一个槽位值;再根据配置的Redis数量,将0-16383的位置按区间平均映射到集群中的Redis服务器,就确定了访问的是集群中的哪台master机器了。

Redis建议最多配置1000台Redis主服务器

分片

使用Redis集群就会将存储的数据分配到多台Redis机器上,这就是分片,每个Redis实例中的数据只是整个数据集的一个分片。

为了找到给定key对应的分片,只需要对key进行CRC16算法并且取模就可以得到对应分片的位置,因为这是一种确定性哈希算法,所以必定可以找到存放数据的Redis实例。

优势

  • 可以方便进行扩容和缩容,添加和删除节点都只需要调整槽位即可
  • 方便进行数据的查找

Slot槽位映射方法

  • 哈希取余算法:将键值得到的哈希值直接对Redis服务器数量取余
  • 简单有效,但是需要规划好数据和节点数量,保证数据访问一致
  • 但是扩容缩容问题较大,如果服务器数量发生变化,就会导致映射数据访问位置变化,导致数据变化,很难维护
  • 一致性哈希算法:设计目标是为了解决分布式数据的变动和映射问题,尽量固定哈希取模的分母,要尽量少影响客户端到服务器的映射关系
  • 算法构架一致性哈希环:定义一个哈希空间,使其区间的头尾相连,使得其在逻辑上相连,即哈希算法的所有计算结果都落在一个区间内;
  • 一致性哈希算法对2^32取模,使得哈希值一定落在0到2^32-1之间
  • Redis服务器IP节点映射:将各个服务器的标识(如IP或主机名)通过哈希函数映射,落到0 - 2^32 -1 的哈希环上
  • key到服务器的落下规则:对key进行哈希计算,得到哈希值后就可以确定在哈希环上的位置,之后每次从此顺时针(服务器哈希-key哈希为正)寻找服务器,寻找到第一台服务器(服务器哈希-key哈希最小)就是要访问的服务器
  • 优点:
  • 容错性:如果一台服务器宕机,则只是这台服务器到前一台服务器之间哈希值的数据不可访问,且数据写入被放入了下一台服务器;
  • 扩展性:如果需要增加服务器,只需要将增加位置前一台服务器到增加服务器的数据从增加位置的下一台服务器转移即可
  • 缺点:
  • 数据倾斜:可能存在服务器聚集在一段空间内,使得聚集位置的顺时针第一台服务器负载较大,数据分布不均匀
  • 哈希槽

一致性哈希算法存在数据倾斜问题,而哈希槽实际上就是一个数组,在 0 - 2^14 -1 个空间内存放数据,形成了哈希槽空间;

为了解决均匀分配问题,就引入了哈希槽,使得key的哈希值取模得到的槽位直接对应一个Redis服务器,这样就只需要将槽位给Redis服务器分配就可以了;如果出现单位数据移动,因为槽位固定,所以也容易处理,只需要把对应哈希槽位的数据进行迁移即可

为什么Redis集群的哈希槽最大是16384

Redis集群使用的哈希槽算法使用了CRC16算法,CRC16得到的哈希值最大是2^16位。但是:

  • Redis的心跳包是需要包含这个哈希槽位数组的,如果是2^16大小的数组,就会使得数据大小从2kb变成8kb,而每秒Redis都要发送一些ping消息和心跳包,这样的话导致这个包的消息过大而导致浪费带宽
  • Redis的集群主节点基本上不推荐1000个,因为可能导致网络拥堵;对于1000左右的Redis集群,16384个槽位也完全够用了
  • 槽位越少,节点少的情况下,压缩比高;因为Redis主节点配置信息中哈希槽是一个bitmap,传输过程中是可以压缩的,压缩率是槽位数量除以节点数量,如果节点多或者槽位数量多,就会导致压缩率低

数据丢失

Redis集群不能保证强一致性,在特定的情况下,Redis集群可能丢失一些被系统收到的写入请求命令;

简单来说,如果集群中的master写入的数据没有来得及同步给它的slave就宕机了,那么slave会顶替master的位置,但是就没有这条未同步的数据,这样就写丢失了

集群搭建

集群环境配置

新建一些独立的Redis独立实例

1. Redis的集群配置文件存在一些不同,需要单独配置一些内容

  • cluster-enabled 集群是否打开,配置 yes
  • cluster-config-file 对应的集群配置文件 一般设置为 nodes- + 端口号 .conf
  • cluster-node-timeout 集群超时时间

2. 配置完之前内容,服务器仍然不是集群,启动后可以使用 ps -ef | grep redis 查看redis实例是否集群启动

3. 使用redis-cli为Redis服务器构建集群

redis-cli -a password -p port --cluster create --cluster-replicas 1 ip1:port1 ip2:port2 ip3:port3 ...

cluster-replicas x 表示每个master配置对应的x个slave节点,这个配置会自动进行,实际的配置需要通过后续命令查看。

输入之后,确定创建集群,之后就会开始发送消息,并等待其他节点加入集群;等待其他节点加入集群后,对应的集群配置文件会按照之前配置的文件名称生成;

可以使用info replication来显示主从信息,使用cluster node可以查看集群的基本信息,cluster info可以查看自己在集群中的信息;

集群读写

配置集群后,如果set的key的hash值计算后不属于自己的槽位范围,这时连接到的服务器会返回error(Move to)表示需要移动到对应槽位范围的服务器才能存储该键;此时非常不方便;

此时,为了避免路由失效,在连接入一个集群内的master写入时,需要加上 -c参数,表示路由到对应的服务器范围,不需要手动转移到对应槽位的服务器;此时再写入数据,就会返回重定向到槽位范围的Redis服务器,实际上就存入了真正的对应的服务器;

redis-cli -a password -p 6379 -c

注意,如果在集群中任意一个服务器上执行操作,都会被定向到可以执行该命令的服务器,如在slave上使用set命令也会被重定向到master上;

也可以使用 CLUSTER KEYSLOT key 来查看该key对应的槽位;

容错切换

  • 如果集群中的一个master宕机了,其对应的slave将会转变成为master,可以正常写入和读取
  • 如果宕机的master再次回到集群,就会重新被配置成新master的slave了
  • 集群是不能保证数据完全的一致的,因为可能在容错切换的时候丢失一定的写入请求
  • 如果希望宕机的master上线后重新变为回master,则需要进行节点从属调整,则需要在宕机节点恢复后,手动执行CLUSTER FAILOVER,使得当前执行命令的节点再次变成master

集群扩容

当需要新加入一些节点进入集群时

1. 新建一些Redis实例,将其配置为集群的设置启动;此时新节点还未加入集群

2. 将一个新节点加入集群作为master节点,需要找到一个已经在集群中的节点,使用客户端登录并携带 add-node 参数,包括自己的ip和端口以及在集群中的一个节点的ip和端口;执行完毕后,新的master暂时不会被分配槽位;

redis-cli -a password --cluster add-node myip:port clusternodeip:port

3. 重新分配哈希槽的区段,使用客户端启动

redis-cli -a password --cluster reshard clusternodeip:port

之后将会提示输入分配的多少号,一般设置为16384除以主机数量;输入完成后,还需要输入接收槽位的新主机id,使用info replication可以看到;之后输入all和yes完成默认设置即可完成槽位分配;但是这样分配的槽位不是连续的,而是从之前集群中的主节点中分出的;

4. 将新主节点的从节点加入集群,需要输入指令

redis-cli -a password --cluster add-node myip:port newmasterip:port --cluster-slave --cluster-master-id newmasterid

集群缩容

如果需要删除一些主节点和其从节点

1. 先清除从节点,使用命令

redis-cli -a password --cluster del-node slaveip:port

2. 清空主节点的槽号,并归还给集群中其他主节点

redis-cli -a password --cluster reshard masterip:port

根据提示,清除该主节点自己的全部槽号,并且输入接收槽号的节点;再选择由哪个节点通知接收槽号的节点,设置为需要删除的主节点即可;

3. 此时,如果把主节点的全部槽位交给其余主节点后,自己将会变成一个从节点,这时就可以删除了

redis-cli -a password --cluster del-node masterip:port masterid

操作之后,需要删除的主从机器都被删除出集群

其他

  • 不再同一个槽位之下,多键操作是无法使用的;必须要使用 {} 定义一个组的概念,才能使得key中{}内相同内容的键值放到一个slot槽位中;

所以,在使用多键操作时,需要指定一个组作为映射槽位的基准,使得同一个组的键映射到同一个槽位,如下就可以正常取数据

mset k1{k} v1 k2{k} v2 k3{k} v3
mget k1{z} k2{z} k3{z}
  • CRC16的使用,在Redis源码中的cluster.c中的keyHashSlot函数计算的,其中会先检测是否有大括号形成的组,然后对键值进行CRC16计算
  • 其他命令
  • cluster-require-full-coverage 参数设置的是是否只要Redis集群完整时才向外提供服务(即如果至少一个主机和其全部从机都宕机时,任务集群已经不完整,无法提供完整的数据访问了),默认值为yes(不完整就不提供服务)
  • CLUSTER COUNTKEYSINSLOT slotnum 可以查看某一个槽位是否存在至少一个键值
  • CLUSTER KEYSLOT key 查看某个键在哪个槽位上


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
63 0
|
2天前
|
弹性计算 网络协议 Ubuntu
如何在阿里云国际版Linux云服务器中自定义配置DNS
如何在阿里云国际版Linux云服务器中自定义配置DNS
|
1天前
|
消息中间件 NoSQL Kafka
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
10 0
|
1天前
|
SQL 分布式计算 大数据
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
9 0
|
1天前
|
SQL 分布式计算 算法
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(二)
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(二)
10 0
|
4天前
|
NoSQL Ubuntu Linux
redis的基本安装配置启动使用
redis的基本安装配置启动使用
15 0
|
7天前
|
缓存 NoSQL 数据处理
原生php实现redis缓存配置和使用方法
通过上述步骤,你可以在PHP项目中配置并使用Redis作为高性能的缓存解决方案。合理利用Redis的各种数据结构和特性,可以有效提升应用的响应速度和数据处理效率。记得在实际应用中根据具体需求选择合适的缓存策略,如设置合理的过期时间,以避免内存过度消耗。
15 0
|
15天前
|
存储 缓存 NoSQL
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
31 0
|
2月前
|
持续交付 jenkins Devops
WPF与DevOps的完美邂逅:从Jenkins配置到自动化部署,全流程解析持续集成与持续交付的最佳实践
【8月更文挑战第31天】WPF与DevOps的结合开启了软件生命周期管理的新篇章。通过Jenkins等CI/CD工具,实现从代码提交到自动构建、测试及部署的全流程自动化。本文详细介绍了如何配置Jenkins来管理WPF项目的构建任务,确保每次代码提交都能触发自动化流程,提升开发效率和代码质量。这一方法不仅简化了开发流程,还加强了团队协作,是WPF开发者拥抱DevOps文化的理想指南。
53 1
|
2月前
|
Java 微服务 Spring
Spring Cloud全解析:配置中心之解决configserver单点问题
但是如果该configserver挂掉了,那就无法获取最新的配置了,微服务就出现了configserver的单点问题,那么如何避免configserver单点呢?

推荐镜像

更多