高并发读多写少场景下的高效键查询与顺序统计的方案思路
之前在某平台看到一篇有意思的场景——对于高并发读多写少场景下,如何进行高效键查询与统计早于其创建时间且没有被删除的数量(只需要先入先出,不需要从中间删元素)
在高并发、读多写少的场景下,业务需求通常聚焦在以下两点:
- 高效查询键对应的值 —— 需要能够快速定位特定键的存储值。
- 统计该键前有多少个未被删除的键值对 —— 需要知道当前键在整个数据序列中的相对顺序,同时剔除已删除的无效数据。
传统的数据库索引或简单的哈希存储难以同时满足这两个需求,尤其是在高并发环境下,如何在不影响查询效率的前提下维持顺序统计成为关键挑战。
核心挑战
- 高并发读请求的优化 —— 需要降低锁争用,确保查询高效。
- 如何在键查询的同时,快速获取其顺序统计值 —— 需要维护高效的数据结构来支撑有序查询和统计。
- 处理删除操作对顺序统计的影响 —— 不能简单地用固定索引,而要考虑动态变化的删除情况。
方案一:map+有序数组
方案一可能是最直观的,就是将两种业务需求通过两个数据结构分别进行解决,一种以空间换时间的典型思路
但方案一存在的问题,不仅仅只是占用了更多的空间,而更在于
- 数据一致性难以保障
- 写入时,需要同时写入map和有序数组,只要其中一个失败都会导致数据一致性失效
- 性能瓶颈
- 计算前置键值对数量需要遍历,性能较差
- 写时要同时写两个地方,性能较差,还会影响读取
- 写入时需要同时获取多个锁,处理不好会造成死锁
方案二:跳表
方案二引入了跳表,跳表的优势在于既能以比较快的速度快速查询到值,而且也具有有序性
但
-
空间开销较大
每个节点需要维护多个层级指针,需要额外储存层级、计数信息
-
并发控制相对复杂
- 节点更新涉及多个层级的指针修改,需要保证原子性
- 如果使用粗粒度锁会严重影响并发性能,如果使用细粒度锁,可能会出现死锁
- 在调整索引层级时,需要处理复杂的并发场景
-
计算前置节点数量仍需要O(log n)的遍历操作,并可能在最坏情况下发生退化
方案三:双Map+自增ID
这个方案的核心思想是通过两个映射表和一个自增ID来实现所需的所有功能。这种设计利用了FIFO的特性,巧妙地用自增ID来表示元素的插入顺序,从而避免了复杂的数据结构。
数据结构设计
- 主数据映射表
- 用途:储存实际键值对(并发安全)
- 键:用户提供的键
- 值:包含实际值和对应自增id
- ID键映射表
- 用途:储存自增ID到键的映射关系,提供快速顺序查询能力(并发安全)
- 键:分配该键的自增ID
- 值:用户提供的键
- 自增ID管理
- 当前最大ID:记录已分配的最大ID值
- 队首ID:记录当前未被删除的最小ID值
- 特点:使用原子操作确保线程安全
操作原理
写入
- 获取新自增ID
- 将键值和自增ID存入主数据映射表
- 将ID、键对应关系存入ID键映射表
当需要查询某个键对应的值时:
- 直接从主数据映射表中获取数据
当需要知道某个键之前有多少个元素时:
- 从主数据映射表中获取目标键的ID
- 获取当前队首ID(最小未删除ID)
- 两者相减即可得到前面的元素数量
删除操作由于是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定位分片,然后统计每个分片中本地缓存的目标数量,最后进行合并
相关文章:
高并发读多写少场景下的高效键查询与顺序统计的方案思路
之前在某平台看到一篇有意思的场景——对于高并发读多写少场景下,如何进行高效键查询与统计早于其创建时间且没有被删除的数量(只需要先入先出,不需要从中间删元素) 在高并发、读多写少的场景下,业务需求通常聚焦在以…...
Android Studio 配置 Gerrit Code Review
很多大厂(华为、荣耀)的大型项目都有gerrit代码审查流程,那么我们如何实现不手动敲命令行,就在Android Studio中像平常开发一样,只需要用鼠标点点点,就能将代码推送到gerrit审查仓呢,现在就来跟…...
html为<td>添加标注文本
样式说明: /*为td添加相对定位点*/ .td_text {position: relative; }/*为p添加绝对坐标(相对于父元素中的定位点)*/ .td_text p {position: absolute;top: 80%;font-size: 8px; }参考资料:...
(done) openMP学习 (Day10: Tasks 原语)
url: https://dazuozcy.github.io/posts/introdution-to-openmp-intel/#19-%E6%8A%80%E8%83%BD%E8%AE%AD%E7%BB%83%E9%93%BE%E8%A1%A8%E5%92%8Copenmp 本章节内容仅提供引入,关于 task 更详细的细节请看 openMP 手册或者源材料 Day9 介绍了一个优化链表遍历的粗糙方…...
力扣-字符串-28 找出字符串中第一个匹配项的下标
思路 kmp算法的练习,实际上来说在构建next数组和使用next数组都用到了前一位字符串的最长相等前后缀 代码 class Solution { public:void getNext(int *next, string s){int j 0;next[0] 0;for(int i 1; i < s.size(); i){while(j > 0 && s[j] …...
linux 基础知识点之工作队列workqueue
多年前就了解了workqueue着玩意,但理解上就并不是很很深刻,今天重新梳理一下,本文重点的是哪个些现成的demo代码,都是可以直接拿来用的,这就是写这文章的目的和作用,就是为了备份后续工作用到的时候&#x…...
C++蓝桥杯基础篇(二)
片头 嗨!小伙伴们,今天我们将学习C蓝桥杯基础篇(二),继续练习相关习题,准备好了吗?咱们开始咯~ 第1题 简单计算器输入两个数,以及一个运算符 ,-,*ÿ…...
【Android—OpenCV实战】实现霍夫圆检测针对沙盘交通灯信号检测
文章目录 Android OpenCV实战:霍夫圆检测实现沙盘交通灯智能识别🌟 引言:当计算机视觉遇见智慧交通🔍 霍夫圆检测原理剖析🔍 数学之美:参数空间转换🔍 关键参数解析 🛠 Android实现全…...
WPS如何接入DeepSeek(通过JS宏调用)
WPS如何接入DeepSeek 一、文本扩写二、校对三、翻译 本文介绍如何通过 WPS JS宏调用 DeepSeek 大模型,实现自动化文本扩写、校对和翻译等功能。 一、文本扩写 1、随便打开一个word文档,点击工具栏“工具”。 2、点击“开发工具”。 3、点击“查看代码”…...
图论——环检测
环检测以及拓扑排序 前言复习模版环检测-DFS版本环检测- BFS版本 前言 我觉得学习这些之前,一定要对图的数据结构和抽象模型有概念,并且图构建的代码模版应该手到擒来,不然还是挺折磨的,不是这差一点就是那差一点,写道力扣卡卡的非常烦人. 复习模版 我觉得单拿出来再说这个模…...
Chapter2:C#基本数据类型
参考书籍:《C#边做边学》; 2.C#基本数据类型 2.1 变量与常量 变量是程序运行过程中用于存放数据的存储单元,变量的值的程序运行过程中可以改变; 变量定义: 定义变量时,必须给每个变量起名,通过…...
kafka服务端之控制器
文章目录 概述控制器的选举与故障恢复控制器的选举故障恢复 优雅关闭分区leader的选举 概述 在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controler),它负责管理整个集群中所有分区和副本的状态。…...
Unity笔试常考
线程同步的几种方式 1.信号量pv操作 2.互斥加锁 3.条件变量 五层网络协议指的是哪五层 1.应用层 2.运输层 3.网络层 4.链路层 5.物理层 TCP和UDP区别 tcp 面向连接,保证发送顺序,速度慢,必须在线,三次握手,4次挥手…...
移植BOA服务器到GEC2440开发板
所需软件:boa-0.94.13.tar.tar(下载:http://www.boa.org/boa-0.94.13.tar.gz) 步骤: 设置好交叉编译工具链。 1、解压下载好的压缩包(tar xzvf boa-0.94.13.tar.tar),并进入解压后的目录(cd boa-0.94.13),再进行如下操作: 先进入到src目录(下面操作都是在该目录下进行…...
WPS如何接入DeepSeek(通过第三方工具)
WPS如何接入DeepSeek 一、下载并安装OfficeAI插件二、配置OfficeAI插件三、使用DeepSeek功能 本文介绍如何通过 WPS 的第三方工具调用 DeepSeek 大模型,实现自动化文本扩写、校对和翻译等功能。 一、下载并安装OfficeAI插件 1、访问OfficeAI插件下载地址ÿ…...
【安当产品应用案例100集】037-强化OpenVPN安全防线的卓越之选——安当ASP身份认证系统
在当前数字化时代,网络安全已成为企业发展的重要组成部分。对于使用OpenVPN的企业而言,确保远程访问的安全性尤为重要。安当ASP身份认证系统凭借其强大的功能和便捷的集成方式,为OpenVPN的二次登录认证提供了理想的解决方案,特别是…...
Windows Docker笔记-制作、加载镜像
引言 在文章《Windows Docker笔记-在容器中运行项目》中,已经在容器中运行了项目。而且在这个容器中,已经调试好了项目运行的环境。 使用docker,就是为了在项目发布到生产环境时,不用再去安装项目运行的环境,直接丢给…...
leetcode_26删除有序数组中的重复项
1. 题意 给定一个重复数组,删除其中的重复项目。 2. 题解 双指针 一个指针指向有序不重复数组的最后一个数,另外一个数遍历整个数组,若两个指针对应用的数不相同,有序数组的指针右移,将数填入。 代码一 class Sol…...
速递丨DeepSeek刚刚成立香港子公司,或因考虑香港上市和招募全球AI人才
图片来源:DeepSeek 根据彭博社和财联社报道,DeepSeek 2月5日在香港成立了两家公司——DeepSeek Limited 和 DeepSeek (HK) Limited。 香港中文大学莊太量教授表示,DeepSeek进军香港将推动该市的金融科技发展。如果DeepSeek考虑在香港上市&a…...
笔灵ai写作技术浅析(六):智能改写与续写
笔灵AI写作中的智能改写和续写技术是其核心功能之一,旨在帮助用户生成高质量、多样化的文本内容。 一、智能改写技术 1. 基本原理 智能改写的目标是在保持原文语义不变的前提下,对文本进行重新表述,生成语法正确、语义连贯且风格多样的新文本。其核心思想是通过语义理解和…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
