并发下如何使用redis存储列表数据

1、问题

  今天在工作中遇到一个问题,需要查询表A,需要根据每天所处小时所在时段,返回不同的记录给前端展示,如0-2时是在昨日0到2时生成的记录,而2-4时则是在昨日2-4时生成的记录,每条记录有一个唯一的id。表A记录的数据只读不写,但会一一对应关联另外一个表B的数据,表B的数据需要读和写。

  由于表A的数据只读不写,所以会在第一次查询时,缓存进redis,这样每一天只需要进行一次IO,后续就可以只通过缓存读取。而表B的数据需要会涉及到写,且每个用户共享这些记录,所以并发会比较高。为了减少缓存穿透,并没有将表B符合条件的记录作为列表存入redis(因为存入列表,写一条记录就需要删除整个列表缓存),而是先筛选表A的记录,收集id列表,再查表B,再将表B记录的id的作为key单独存入redis。这是一个非常蠢的设计,记录单独存入redis中,也就意味着根据id循环io查单条和循环写入缓存,程序需要与数据库和redis进程频繁交互,原本为了提高查询效率的考虑,反而大大增加了查询压力,直接影响就是查询效率极低,压力测试不通过。

  由于每个时段需要展示的数据量并不多,只有几十条,于是便采用list进存入redis,但在压力测试高并发的条件下,会导致重复添加记录到redis,这样会造成两个影响,其一是冗余数据在redis中会形成大key,占用空间增大且查询减慢,其二是程序处理也会增加遍历成本且可能出错。可如果对该查询进行同步(加锁),这又会影响查询效率,达不到性能优化的目的。那么应该如何解决呢?

2、解决:redis的hash结构

redis中的另一种数据结构hash,则可以完美解决这个问题: hash可以类比成Java中的Map,在这个业务当中,可以将每条记录的id作为key,记录本身作为value,形成一个会去重的key-value列表,在高并发下,多个线程的写入,相同的key会去重,这样不会造成冗余数据

相关推荐
机建狂魔5 分钟前
Codex 接入第三方模型 API 实战:以 Mimo 为例
java·服务器·数据库·ai·ai编程·codex
山峰哥32 分钟前
数据库工程与SQL调优:从慢查询到秒级响应的实战之路
java·开发语言·数据库·sql·深度优先·启发式算法
moMo1 小时前
# 向量数据库入门:从"关键词匹配"到"语义理解"
数据库
ACP广源盛139246256731 小时前
DeepSeek‑V4‑Flash 公测@ACP#昇腾 950 国产算力组合落地,国产 PCIe 交换芯片 IX9104 有哪些硬件机会
大数据·数据库·人工智能·分布式·单片机·嵌入式硬件·microsoft
进击的女IT2 小时前
通过mysql中的Data目录恢复数据库数据
数据库·mysql
yuezhilangniao2 小时前
AI工具全家桶:从开发到运维,从数据库到产品经理-含魔塔社区简介
运维·数据库·人工智能
gb42152872 小时前
ChromaDB向量数据库的特点
数据库
nvd112 小时前
ArgoCD 双层轮询深入拆解:从 redis-app.yaml 注册到缓存重建的完整链路
redis·缓存·argocd
IvorySQL2 小时前
PostgreSQL 日报| GiST 索引扫描可见性缺陷(8 月 3 日)
数据库·人工智能·postgresql·开源
xiaoxiangsiyan2 小时前
LNMP + Redis Sentinel 高可用架构部署手册(续)
运维·网络·数据库·redis·缓存·架构·sentinel