Redis超高并发分key实现

embedded/2025/3/14 18:44:20/

Redis扛并发的能力是非常强的,所以高并发场景下经常会使用Redis,但是Redis单分片的写入瓶颈在2w左右,读瓶颈在10w左右,如果在超高并发下即使是集群部署Redis,单分片的Redis也是有可能扛不住的,如下图所示:
在这里插入图片描述
虽然Redis做了集群部署,但是Redis的key只会存在一个分片上,此时超高并发下redis1很有可能会被打垮。那么在超高的并发如何解决某个热key带来的单分片被打垮的问题呢?下面聊聊Redis分key来解决这个问题的方案。

1、什么是Redis分key

Redis分key就是将一个热点key通过拆分成若干key,然后让这若干个key分散到Redis集群的不同节点,如下图所示:

在这里插入图片描述
将热点key拆分成3个小key,然后通过Redis的算法将这3个key分散到Redis集群的分片上(集群有多少个分片,就拆分成几个key)。这样由原先的一个key拆分成3个小key,在超高并发下由这3个key共同的来承担原先一个热点key扛的流量。

2、拆分后的key分散到集群的分片上

拆分key的思路可以很好的解决单个热点key可能打垮Redis集群中某个分片的问题,但是我们如何保证一个小key落到一个分片上呢?首先我们来回顾一下Redis集群中key落分片的原理,如下所示的Redis的集群:
在这里插入图片描述
从原理上分析key落在哪个节点上是经过了两次的映射,第一次映射是CRC16计算出来key哈希值除以16384之后得到是对应的槽,第二次映射是槽映射到redis的节点,这样可以知道key落在哪个分片上。

根据上述的原理,我们可以通过Redis的命令来获取Redis集群上的集群关系来计算key落在哪个分片上。我们现在为了保证一个key落在一个分片上,可以通过手动的方式来设置key,设置的过程如下:

(1)手写第一个key_longxia,然后自己手动根据CRC16和槽映射关系之后就知道它落到了哪个节点(假设是redis0上)如下所示
在这里插入图片描述
2)准备第二个key(如key_longxia01),假设计算之后发现也落到了redis0上,那么我们换一个key(如key_biancheng),经过计算发现其落在redis1上,如下所示:
在这里插入图片描述
(3)同样的方式,准备第三个key(如key_long),保证其可以落在redis2上即可,如下所示:
在这里插入图片描述
分key的时候,我们不要追求 key 是有规律的了,可以随便加点前缀与后缀,只要保证每个小key都分散到集群的分片上即可。

通过上述的试探我们得到了3个拆分后的小key,并且这些小key可以落到集群的节点上,整理出这些拆分后的key如下所示:
在这里插入图片描述

3、分key的工作原理

在这里插入图片描述

手动尝试出来的三个key我们写固定到代码中(或者放在配置中心上)。当业务请求过来之后,我们可以通过业务id与拆分出来的key数量取余数的方式映射出当前请求打到哪个key上(如key_longxia),然后通过这个可以经过redis的两次映射找到对应的节点,找到节点后就可以操作数据了。

结论:(1)Redis分可以的原理就是将一个热点key拆分成若干个小key后分散不集群的不同节点上(集群有几个节点就拆分成几个小key)(2)为保证key可以分散到集群节点上,采用的是手动尝试的方式来获取拆分后的小key。(3)分key的方案常用于超高并发业务场景下,如抢优惠券、实时榜单等。

http://www.ppmy.cn/embedded/172209.html

相关文章

java登神之阶之顺序表

一、了解List接口 在Java中,List接口是一个非常重要的集合框架接口,它继承自Collection接口(Collection接口继承Iterable接口)。List接口定义了一个有序集合,允许我们存储元素集合。并且可以根据元素的索引来访问集合中…

什么是设计模式

Christopher Alexander 说过:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”。尽管A l e x a n d e r所指的是城市和建筑模式,但他的思想…

在线招聘小程序:AI简历筛选与精准职位推荐服务

当AI算法遇上小程序开发:重新定义「人岗匹配」的智能招聘革命 一、传统招聘困境:求职者与企业为何总在「错过」? 在数字化浪潮下,企业HR日均需处理数百份简历,却仍有60%的岗位因匹配效率低下而空置;求职者海投简历后,近八成用户表示从未收到精准反馈。这种双向资源错配…

自动化的多线程实现

在Python中,处理线程并发主要有以下几种方式: 使用threading模块 threading模块是Python标准库中用于处理线程的模块,它提供了创建和管理线程的功能。可以通过继承threading.Thread类或直接实例化Thread类来创建线程。示例如下:…

美团AI面试面经

这里写自定义目录标题 美团AI面试面经零、基本情况一、选择题:选择语言C二、专业题:1.CSRF 攻击盗用用户身份方式。防御措施中的 token 机制原理。CSRF 攻击盗用用户身份的方式防御措施中 token 机制的原理 2.物理内存和虚拟内存。物理内存虚拟内存 3.联…

3.3.2 Proteus第一个仿真图

文章目录 文章介绍0 效果图1 新建“点灯”项目2 添加元器件3 元器件布局接线4 补充 文章介绍 本文介绍:使用Proteus仿真软件画第一个仿真图 0 效果图 1 新建“点灯”项目 修改项目名称和路径,之后一直点“下一步”直到完成 2 添加元器件 点击元…

Mahilo技术深度解析:构建下一代人机协同智能系统的开源框架

一、框架定位与技术突破 Mahilo作为2025年最受关注的多智能体协作框架,其创新性在于实现了人机协同的闭环控制与智能体自主协作的动态平衡。根据GitHub仓库数据显示,该框架在开源首周即获得3.2k星标,在医疗、金融、工业等领域的15个场景验证中,任务执行效率提升58%。 核心…

【C++】string类的相关成员函数以及string的模拟实现

文章目录 前言一、string类的常用接口1. string类对象的常见构造2.迭代器(iterator)3.string类对象的容量操作4.string类对象的修改操作5.string类非成员函数 二、string的模拟实现1.string.h文件2.string的相关成员函数的实现:3.string.cpp文…