高并发读多写少场景下的高效键查询与顺序统计的方案思路

之前在某平台看到一篇有意思的场景——对于高并发读多写少场景下,如何进行高效键查询与统计早于其创建时间且没有被删除的数量(只需要先入先出,不需要从中间删元素)

在高并发、读多写少的场景下,业务需求通常聚焦在以下两点:

  1. 高效查询键对应的值 —— 需要能够快速定位特定键的存储值。
  2. 统计该键前有多少个未被删除的键值对 —— 需要知道当前键在整个数据序列中的相对顺序,同时剔除已删除的无效数据。

传统的数据库索引或简单的哈希存储难以同时满足这两个需求,尤其是在高并发环境下,如何在不影响查询效率的前提下维持顺序统计成为关键挑战。

核心挑战

  1. 高并发读请求的优化 —— 需要降低锁争用,确保查询高效。
  2. 如何在键查询的同时,快速获取其顺序统计值 —— 需要维护高效的数据结构来支撑有序查询和统计。
  3. 处理删除操作对顺序统计的影响 —— 不能简单地用固定索引,而要考虑动态变化的删除情况。

方案一:map+有序数组

方案一可能是最直观的,就是将两种业务需求通过两个数据结构分别进行解决,一种以空间换时间的典型思路

但方案一存在的问题,不仅仅只是占用了更多的空间,而更在于

  1. 数据一致性难以保障
    • 写入时,需要同时写入map和有序数组,只要其中一个失败都会导致数据一致性失效
  2. 性能瓶颈
    • 计算前置键值对数量需要遍历,性能较差
    • 写时要同时写两个地方,性能较差,还会影响读取
    • 写入时需要同时获取多个锁,处理不好会造成死锁

方案二:跳表

方案二引入了跳表,跳表的优势在于既能以比较快的速度快速查询到值,而且也具有有序性

  1. 空间开销较大

    每个节点需要维护多个层级指针,需要额外储存层级、计数信息

  2. 并发控制相对复杂

    • 节点更新涉及多个层级的指针修改,需要保证原子性
    • 如果使用粗粒度锁会严重影响并发性能,如果使用细粒度锁,可能会出现死锁
    • 在调整索引层级时,需要处理复杂的并发场景
  3. 计算前置节点数量仍需要O(log n)的遍历操作,并可能在最坏情况下发生退化

方案三:双Map+自增ID

这个方案的核心思想是通过两个映射表和一个自增ID来实现所需的所有功能。这种设计利用了FIFO的特性,巧妙地用自增ID来表示元素的插入顺序,从而避免了复杂的数据结构。

数据结构设计
  1. 主数据映射表
    • 用途:储存实际键值对(并发安全)
    • 键:用户提供的键
    • 值:包含实际值和对应自增id
  2. ID键映射表
    • 用途:储存自增ID到键的映射关系,提供快速顺序查询能力(并发安全)
    • 键:分配该键的自增ID
    • 值:用户提供的键
  3. 自增ID管理
    • 当前最大ID:记录已分配的最大ID值
    • 队首ID:记录当前未被删除的最小ID值
    • 特点:使用原子操作确保线程安全
操作原理

写入

  1. 获取新自增ID
  2. 将键值和自增ID存入主数据映射表
  3. 将ID、键对应关系存入ID键映射表

当需要查询某个键对应的值时:

  1. 直接从主数据映射表中获取数据

当需要知道某个键之前有多少个元素时:

  1. 从主数据映射表中获取目标键的ID
  2. 获取当前队首ID(最小未删除ID)
  3. 两者相减即可得到前面的元素数量

删除操作由于是FIFO队列,只需要删除队首元素:通过原子操作增加队首ID,无需立即从映射表中删除数据,可以通过后台任务定期清理已删除的数据,不影响其他操作的执行

有意思的是这个设计与mysql索引有些类似,主数据映射表就是主键索引,ID键映射表就是二级索引

方案四:redis zset

如果将创建时间作为redis zset的score,那么就能很好满足该场景下的需求

zrank查询对应的值的时候就会返回这个值的排序下标(整个 zset 排序下标从 0 开始), 默认 timestamp 升序, zrank 返回的值减 1 就知道前面有多少个是先于它了.

redis zset其实依然hash表加跳表

性能分析

优势

  • zset跳表提供了O(log(N))的查询性能
  • redis单线程避免了并发控制的复杂性
  • 支持丰富的排序和范围查询操作
  • 方便实现分布式拓展

缺点

  • 内存占用较高
  • 原子性需要通过MULTI/EXEC实现
  • 获取有效键数量需要多次操作
  • 受Redis单实例内存限制

方案五:分布式

分布式是考虑到极大访问量的场景所应用的方案

kafka+elasticsearch

写入时流转kafka随后写入es,采用es倒排索引作为键快速查询,es聚合功能作为计数统计

分片+本地缓存

通过一致性hash定位分片,然后统计每个分片中本地缓存的目标数量,最后进行合并

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15020.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于python多线程多进程爬虫的maa作业站技能使用分析

基于python多线程多进程爬虫的maa作业站技能使用分析 技能使用分析 多线程(8核) import json import multiprocessing import requests from multiprocessing.dummy import Pooldef maa(st):url "https://prts.maa.plus/copilot/get/"m …

npm无法加载文件 因为此系统禁止运行脚本

安装nodejs后遇到问题: 在项目里【node -v】可以打印出来,【npm -v】打印不出来,显示npm无法加载文件 因为此系统禁止运行脚本。 但是在winr,cmd里【node -v】,【npm -v】都也可打印出来。 解决方法: cmd里可以打印出…

2.9寒假作业

web:[SWPUCTF 2022 新生赛]ez_ez_php(revenge) 打开环境,进行代码审计 下面有提示访问游戏flag.php,尝试看看 提示了正确的flag,还有要使用为协议,之前也了解过,关于执行包含文件例如include可使用为协议绕…

【Matlab优化算法-第13期】基于多目标优化算法的水库流量调度

一、前言 水库流量优化是水资源管理中的一个重要环节,通过合理调度水库流量,可以有效平衡防洪、发电和水资源利用等多方面的需求。本文将介绍一个水库流量优化模型,包括其约束条件、目标函数以及应用场景。 二、模型概述 水库流量优化模型…

Mybatis

入门 配置SQL提示 JDBC介绍 JDBC:(Java DataBase Connectivity),就是使用Java语言操作关系型数据库的一套API 本质 sun公司官方定义的一套操作所有关系型数据库的规范,即接口 各个数据库厂商去实现这套接口,提供数据库驱动jar包 我们可以使…

Deepseek的MLA技术原理介绍

DeepSeek的MLA(Multi-head Latent Attention)技术是一种创新的注意力机制,旨在优化Transformer模型的计算效率和内存使用,同时保持模型性能。以下是MLA技术的详细原理和特点: 1. 核心思想 MLA技术通过低秩联合压缩技术,将多个注意力头的键(Key)和值(Value)映射到一…

使用 SDKMAN! 在 Mac(包括 ARM 架构的 M1/M2 芯片)上安装 Java 8

文章目录 1. 安装 SDKMAN!2. 查找可用的 Java 8 版本3. 安装 Java 84. 验证安装5. 切换 Java 版本(可选)6. 解决 ARM 架构兼容性问题总结 可以使用 SDKMAN! 在 Mac(包括 ARM 架构的 M1/M2 芯片)上安装 Java 8。SDKMAN! 是一个强大…

HAL库外设宝典:基于CubeMX的STM32开发手册(持续更新)

目录 前言 GPIO(通用输入输出引脚) 推挽输出模式 浮空输入和上拉输入模式 GPIO其他模式以及内部电路原理 输出驱动器 输入驱动器 中断 外部中断(EXTI) 深入中断(内部机制及原理) 外部中断/事件控…

Windows 本地部署大模型 OpenWebUI+Ollama

安装Ollama Ollama官方网址:https://ollama.com 下载运行大模型 在Ollama官网中查看需要下载的大模型 https://ollama.com/library 复制图片中的链接 打开cmd,运行此命令(此过程会时间会很久) 下载Miniconda Miniconda作用是…

【大模型】Ubuntu下安装ollama,DeepSseek-R1:32b的本地部署和运行

1 ollama 的安装与设置 ollama官网链接:https://ollama.com/ 在左上角的【Models】中展示了ollama支持的模型在正中间的【Download】中课可以下载支持平台中的安装包。   其安装和模型路径配置操作流程如下: ollama的安装 这里选择命令安装curl -fsSL …

Ollama实现deepseek本地部署

Ollama实现deepseek本地部署 1.Ollama下载与安装2.ollama获取模型并部署2.1 使用ollama pull2.2 通过ollama create 创建自定义模型2.3 本地运行 3.使用streamlit实现网页版RAG部署3.1 加载相关包3.2 文档上传、加载与切块3.3 初始化向量存储3.4 初始化向量存储3.5 加载模型&am…

Django开发入门 – 0.Django基本介绍

Django开发入门 – 0.Django基本介绍 A Brief Introduction to django By JacksonML 1. Django简介 1) 什么是Django? 依据其官网的一段解释: Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. …

苍穹外卖-新增菜品(阿里云OSS文件上传mybatis主键返回批量保存口味表数据)

新增菜品 2.1 需求分析与设计 2.1.1 产品原型 后台系统中可以管理菜品信息,通过 新增功能来添加一个新的菜品,在添加菜品时需要选择当前菜品所属的菜品分类,并且需要上传菜品图片。 新增菜品原型: 当填写完表单信息, 点击&quo…

只需两步,使用ollama即可在本地部署DeepSeek等常见的AI大模型

只需两步,使用ollama即可在本地部署DeepSeek等常见的AI大模型 1.下载ollama,进入ollama官网即可将ollama下载到本地,之后按照提示安装ollama。 https://ollama.com/download/windows 2.安装大模型 进入ollama官网模型页面,找到所需的模型及版…

java基础语法中阶

一、面向对象 补充快捷键:alt鼠标左键,实现同时多行选中相同位置的内容。 1.类与对象 2.封装 3.构造方法 altinsert添加构造方法 4.内存分布 对象 类型 this关键字的使用 成员变量与局部变量 %s是占位符 ,ctrlaltv-补全对象 for循环的快速生成方…

DeepSeek 评价开源框架存在幻觉么?

DeepSeek 横空出世 2025 年,DeepSeek 以「价格屠夫」姿态将 API 成本降至新低(输入 0.1 元/百万 tokens,输出 2 元/百万 tokens9)霸榜了 AI 热搜。 AI 生成内容中最让人关注的就是回答内容是否存在 “幻觉”,我们不希望…

【大模型】硅基流动对接DeepSeek使用详解

目录 一、前言 二、硅基流动介绍 2.1 硅基流动平台介绍 2.1.1 平台是做什么的 2.2 主要特点与功能 2.2.1 适用场景 三、硅基流动快速使用 3.1 账户注册 3.2 token获取 3.2.1 获取token技巧 四、Cherry-Studio对接DeepSeek 4.1 获取 Cherry-Studio 4.2 Cherry-Stud…

DeepSeek之Win10系统部署教程

一、下载并安装Ollama 1、为什么要安装Ollama的呢? Ollama 是一个用于本地部署和管理大型语言模型(LLM)的工具,支持多种模型格式和框架。 它可以帮助用户轻松下载、配置和运行模型,同时提供统一的接口和依赖管理。 …

DeepSeek-r1和O1、O3mini谁更强?

DeepSeek-r1和O1、O3mini谁更强&#xff1f; 题目&#xff1a;编写一个 js 程序&#xff0c;显示一个球在旋转的六边形内弹跳。球应该受到重力和摩擦力的影响&#xff0c;并且必须逼真地从旋转的墙壁上弹起 DeepSeek-r1 <!DOCTYPE html> <html> <body> &l…

我用AI做数据分析之数据清洗

我用AI做数据分析之数据清洗 AI与数据分析的融合效果怎样&#xff1f; 这里描述自己在使用AI进行数据分析&#xff08;数据清洗&#xff09;过程中的几个小故事&#xff1a; 1. 变量名的翻译 有一个项目是某医生自己收集的数据&#xff0c;变量名使用的是中文&#xff0c;分…