value中存储过多的元素-Redis大key多key拆分方案

背景

在我的项目中,会存在一个DG下拥有10w+的学生,每个学生在进入直播之前,都需要通过校验,查询是否是这个直播所关联DG下的学生;为了提高并发,我们把大纲和学生的关系存入Redis中,使用set存储,那么一个DG的key会存储过多的元素(学生ID),形成Redis大key的情况。

在阿里云 Redis 的开发规范, 对value设计有以下建议:

  • 1)【强制】:拒绝 bigkey(防止网卡流量、慢查询) string 类型控制在 10KB 以内,hash、list、set、zset 元素个数不要超过 5000。

反例:一个包含 200 万个元素的 list。

非字符串的 bigkey,不要使用 del 删除,使用 hscan、sscan、zscan 方式渐进式删除,同时要注意防止 bigkey 过期时间自动删除问题 (例如一个 200 万的 zset 设置 1 小时过期,会触发 del 操作,造成阻塞,而且该操作不会不出现在慢查询中 (latency 可查)),查找方法和删除方法

value中存储过多的元素拆分方案

类似这种场景,可以将这些元素分拆。

现在,固定一个桶(bucket)的数量,比如 5000, 每次存取的时候,先在本地计算field的hash值,模除 5000, 确定了该field落在哪个key上。

以上的DG学生场景,我们根据学生ID模除5000,确定该学生落在哪个key上;

为了方便获取大纲下所有的学生ID,那么维护一个key来存储大纲学生key的集合(学生ID模除 5000的值)

下图简要说明我们是怎么设计实现的:

  1. 我们定义每个key为一个桶,那么这个桶 bucket=学生ID模除5000
  2. 为了快速查询所有桶,把桶的序号存储在 her:sy:{syllabusId}:b key的set集合中
  3. 其中 syllabusId 为DG

不适合的场景

如果要保证 SPOP 的数据的确是集合中的一个随机元素,这个就需要一些附加的属性,或者是在key的拼接上做一些工作

相关文章

Java微服务架构选型:优雅拆分与高效整合

Java微服务架构选型:优雅拆分与高效整合在当今的软件开发领域,微服务架构已经成为一种主流趋势。它将单一庞大的应用程序划分为多个小型、自治的服务,每个服务负责特定的功能模块。对于使用Java语言的开发...

Java 9 到 Java 16 的版本演进:一次模块化革命和语言的持续进化

Java 9 到 Java 16 的版本演进:一次模块化革命和语言的持续进化在这个飞速发展的时代,Java 的发布节奏也变得越来越快,从传统的“龟速”升级到如今的“火车模式”。从 2017 年 9 月...

Java 拆分PDF页面

在操作PDF文档时,拆分PDF页面,意味着将一页的文本内容展示在多个较小些的页面上。Free Spire.PDF for Java控件支持从水平或垂直方向来将PDF页面拆分为多个页面。本文将演示相关代...

项目案例:Java多线程批量拆分List导入数据库

一、前言二、直接把list怼进Mysql三、分组把list导入Mysql中四、多线程分批导入Mysql五、小结一、前言前两天做了一个导入的功能,导入开始的时候非常慢,导入2w条数据要1分多钟,后来一点...

如何将长字符串定义拆分成多行?

在编程的过程中,我们常常会遇到需要处理长字符串的情况。当字符串特别长时,将其全部写在一行会让代码变得难以阅读和维护。那么,怎样才能把长字符串的定义拆分成多行呢?这是不少开发者都会遇到并想要解决的问题。...