最新要闻
- 李想:L7、L8、L9是世界上最安全的车 副驾坐的是我老婆
- 天天快报!美版《西游记》定档!阵容强大:奥斯卡影后杨紫琼饰观音、吴彦祖演美猴王
- 日本原装进口!雀巢金牌速溶黑咖啡大促 28.9元到手
- Android 14不再允许“杀后台”!一键加速App别装了
- 上汽投资成立股权投资合伙企业 出资额5亿
- 环球最资讯丨华擎Intel显卡集体降价 最多20%:RTX 3060瞬间不香了
- 【快播报】《瞬息全宇宙》七项大奖横扫奥斯卡!杨紫琼获封奥斯卡影后:亚洲首位
- 新一代Y9000P来了!联想拯救者2023生态新品发布会官宣
- 环球短讯!小红书后台删用户照片遭系统拦截?官方回应:只是清理临时缓存
- 仅隔17天 中国火箭又一次成功为海外客户发射荷鲁斯2号卫星
- 【世界时快讯】749元 一加Buds Pro 2轻享版无线耳机开售:48dB深度降噪
- 方舟里面风神翼龙怎么抓_方舟生存进化风神翼龙怎么抓 具体抓捕方法介绍
- 每日速递:豆瓣7.9分 《阿凡达:水之道》电影拿下奥斯卡最佳视效奖:实至名归
- 当前速看:iPad Pro 2024要大涨价:比MacBook Pro还贵
- 每日视讯:美佛州海滩清出近两吨死鱼:民众直呼“辣眼睛”
- 全球即时:上班一周不用充电 比油车少花70元!哪吒S用车成本秒杀燃油车
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
【环球时快讯】面试官:如何在千万级数据中查询 10W 的数据,都有什么方案?
作者:变速风声 链接:https://juejin.cn/post/7104090532015505416
前言
在开发中遇到一个业务诉求,需要在千万量级的底池数据中筛选出不超过 10W 的数据,并根据配置的权重规则进行排序、打散(如同一个类目下的商品数据不能连续出现 3 次)。
(相关资料图)
下面对该业务诉求的实现,设计思路和方案优化进行介绍,对「千万量级数据中查询 10W 量级的数据」设计了如下方案
- 多线程 + CK 翻页方案
- ES
scroll scan
深翻页方案 - ES + Hbase 组合方案
- RediSearch + RedisJSON 组合方案
初版设计方案
整体方案设计为:
- 先根据配置的「筛选规则」,从底池表中筛选出「目标数据」
- 在根据配置的「排序规则」,对「目标数据」进行排序,得到「结果数据」
技术方案如下:
- 每天运行导数任务,把现有的千万量级的底池数据(
Hive
表)导入到 Clickhouse 中,后续使用 CK 表进行数据筛选。 - 将业务配置的筛选规则和排序规则,构建为一个「筛选 + 排序」对象
SelectionQueryCondition
。 - 从 CK 底池表取「目标数据」时,开启多线程,进行分页筛选,将获取到的「目标数据」存放到
result
列表中。
//分页大小 默认 5000int pageSize = this.getPageSize();//页码数int pageCnt = totalNum / this.getPageSize() + 1;List
对目标数据 result
进行排序,得到最终的「结果数据」。
推荐一个开源免费的 Spring Boot 最全教程:
https://github.com/javastacks/spring-boot-best-practice
CK分页查询
在「初版设计方案」章节的第 3 步提到了「从 CK 底池表取目标数据时,开启多线程,进行分页筛选」。此处对 CK 分页查询进行介绍。
封装了 queryPoolSkuList
方法,负责从 CK 表中获得目标数据。该方法内部调用了 sqlSession.selectList
方法。
public List> queryPoolSkuList( Map params ) { List> resultMaps = new ArrayList<>(); QueryCondition queryCondition = parseQueryCondition(params); List> mapList = lianNuDao.queryPoolSkuList(getCkDt(),queryCondition); if (CollectionUtils.isNotEmpty(mapList)) { for (Map data : mapList) { resultMaps.add(camelKey(data)); } } return resultMaps;}// lianNuDao.queryPoolSkuList@Autowired@Qualifier("ckSqlNewSession")private SqlSession sqlSession;public List> queryPoolSkuList( String dt, QueryCondition queryCondition ) { queryCondition.setDt(dt); queryCondition.checkMultiQueryItems(); return sqlSession.selectList("LianNu.queryPoolSkuList",queryCondition);}
sqlSession.selectList
方法中调用了和 CK 交互的 queryPoolSkuList
查询方法,部分代码如下。
可以看到,在 CK 分页查询时,是通过 limit #{limitStart},#{limitEnd}
实现的分页。
limit
分页方案,在「深翻页」时会存在性能问题。初版方案上线后,在 1000W 量级的底池数据中筛选 10W 的数据,最坏耗时会达到 10s~18s 左右。
使用ES Scroll Scan 优化深翻页
对于 CK 深翻页时候的性能问题,进行了优化,使用 Elasticsearch 的 scroll scan
翻页方案进行优化。
ES的翻页方案
ES 翻页,有下面几种方案
from
+size
翻页scroll
翻页scroll scan
翻页search after
翻页
翻页方式 | 性能 | 优点 | 缺点 | 场景 |
---|---|---|---|---|
from + size | 低 | 灵活性好,实现简单 | 深度分页问题 | 数据量比较小,能容忍深度分页问题 |
scroll | 中 | 解决了深度分页问题 | 需要维护一个 scrollId (快照版本),无法反应数据的实时性;可排序,但无法跳页查询 | 查询海量数据 |
scroll scan | 中 | 基于 scroll 方案,进一步提升了海量数据查询的性能 | 无法排序,其余缺点同 scroll | 查询海量数据 |
search after | 高 | 性能最好,不存在深度分页问题,能够反映数据的实时变更 | 实现复杂,需要有一个全局唯一的字段。连续分页的实现会比较复杂,因为每一次查询都需要上次查询的结果 | 不适用于大幅度跳页查询,适用于海量数据的分页 |
对上述几种翻页方案,查询不同数目的数据,耗时数据如下表。
ES 翻页方式 | 1-10 | 49000-49010 | 99000-99010 |
---|---|---|---|
from + size | 8ms | 30ms | 117ms |
scroll | 7ms | 66ms | 36ms |
search_after | 5ms | 8ms | 7ms |
耗时数据
此处,分别使用 Elasticsearch 的 scroll scan
翻页方案、初版中的 CK 翻页方案进行数据查询,对比其耗时数据。
如上测试数据,可以发现,以十万,百万,千万量级的底池为例
- 底池量级越大,查询相同的数据量,耗时越大
- 查询结果 3W 以下时,ES 性能优;查询结果 5W 以上时,CK 多线程性能优
ES+Hbase组合查询方案
在「使用 ES Scroll Scan 优化深翻页」中,使用 Elasticsearch 的 scroll scan
翻页方案对深翻页问题进行了优化,但在实现时为单线程调用,所以最终测试耗时数据并不是特别理想,和 CK 翻页方案性能差不多。
在调研阶段发现,从底池中取出 10W 的目标数据时,一个商品包含多个字段的信息(CK 表中一行记录有 150 个字段信息),如价格、会员价、学生价、库存、好评率等。对于一行记录,当减少获取字段的个数时,查询耗时会有明显下降。如对 sku1
的商品,从之前获取价格、会员价、学生价、亲友价、库存等 100 个字段信息,缩减到只获取价格、库存这两个字段信息。
如下图所示,使用 ES 查询方案,对查询同样条数的场景(从千万级底池中筛选出 7W+ 条数据),获取的每条记录的字段个数从 32 缩减到 17,再缩减到 1个(其实是两个字段,一个是商品唯一标识 sku_id
,另一个是 ES 对每条文档记录的 doc_id
)时,查询的耗时会从 9.3s 下降到 4.2s,再下降到 2.4s。
从中可以得出如下结论
- 一次 ES 查询中,若查询字段和信息较多,
fetch
阶段的耗时,远大于query
阶段的耗时。 - 一次 ES 查询中,若查询字段和信息较多,通过减少不必要的查询字段,可以显著缩短查询耗时。
下面对结论中涉及的 query
和 fetch
查询阶段进行补充说明。
ES查询的两个阶段:query和fetch
在 ES 中,搜索一般包括两个阶段,query
和 fetch
阶段
query 阶段
- 根据查询条件,确定要取哪些文档(
doc
),筛选出文档 ID(doc_id
)
fetch 阶段
- 根据
query
阶段返回的文档 ID(doc_id
),取出具体的文档(doc
)
ES的filesystem cache
- ES 会将磁盘中的数据自动缓存到
filesystem cache
,在内存中查找,提升了速度 - 若
filesystem cache
无法容纳索引数据文件,则会基于磁盘查找,此时查询速度会明显变慢 - 若数量两过大,基于「ES 查询的的 query 和 fetch 两个阶段」,可使用 ES + HBase 架构,保证 ES 的数据量小于
filesystem cache
,保证查询速度
组合使用Hbase
在上文调研的基础上,发现「减少不必要的查询展示字段」可以明显缩短查询耗时。沿着这个优化思路,参照参考链接 ref-1,设计了一种新的查询方案
- ES 仅用于条件筛选,ES 的查询结果仅包含记录的唯一标识
sku_id
(其实还包含 ES 为每条文档记录的doc_id
) - Hbase 是列存储数据库,每列数据有一个
rowKey
。利用rowKey
筛选一条记录时,复杂度为O(1)
。(类似于从HashMap
中根据key
取value
) - 根据 ES 查询返回的唯一标识
sku_id
,作为 Hbase 查询中的rowKey
,在O(1)
复杂度下获取其他信息字段,如价格,库存等。
使用 ES + Hbase 组合查询方案,在线上进行了小规模的灰度测试。在 1000W 量级的底池数据中筛选 10W 的数据,对比 CK 翻页方案,最坏耗时从 10~18s
优化到了 3~6s
左右。
也应该看到,使用 ES + Hbase 组合查询方案,会增加系统复杂度,同时数据也需要同时存储到 ES 和 Hbase。
RediSearch+RedisJSON优化方案
RediSearch 是基于 Redis 构建的分布式全文搜索和聚合引擎,能以极快的速度在 Redis 数据集上执行复杂的搜索查询。RedisJSON 是一个 Redis 模块,在 Redis 中提供 JSON 支持。RedisJSON 可以和 RediSearch 无缝配合,实现索引和查询 JSON 文档。
根据一些参考资料,RediSearch
+ RedisJSON
可以实现极高的性能,可谓碾压其他 NoSQL 方案。在后续版本迭代中,可考虑使用该方案来进一步优化。
下面给出 RediSearch
+ RedisJSON
的部分性能数据。
RediSearch 性能数据
在同等服务器配置下索引了 560 万个文档 (5.3GB),RediSearch 构建索引的时间为 221 秒,而 Elasticsearch 为 349 秒。RediSearch 比 ES 快了 58%。
数据建立索引后,使用 32 个客户端对两个单词进行检索,RediSearch 的吞吐量达到 12.5K ops/sec
,ES 的吞吐量为 3.1K ops/sec
,RediSearch 比ES 要快 4 倍。同时,RediSearch 的延迟为 8ms,而 ES 为 10ms,RediSearch 延迟稍微低些。
对比 | Redisearch | Elasticsearch |
---|---|---|
搜索引擎 | 专用引擎 | 基于 Lucene 引擎 |
编程语言 | C 语言 | Java |
存储方案 | 内存 | 磁盘 |
协议 | Redis 序列化协议 | HTTP |
集群 | 企业版支持 | 支持 |
性能 | 简单查询高于 ES | 复杂查询时高于 RediSearch |
RedisJSON 性能数据
根据官网的性能测试报告,RedisJson + RedisSearch 可谓碾压其他 NoSQL
- 对于隔离写入(isolated writes),RedisJSON 比 MongoDB 快 5.4 倍,比 ES 快 200 倍以上
- 对于隔离读取(isolated reads),RedisJSON 比 MongoDB 快 12.7 倍,比 ES 快 500 倍以上
在混合工作负载场景中,实时更新不会影响 RedisJSON 的搜索和读取性能,而 ES 会受到影响。
- RedisJSON 支持的操作数/秒比 MongoDB 高约 50 倍,比 ES 高 7 倍/秒。
- RedisJSON 的延迟比 MongoDB 低约 90 倍,比 ES 低 23.7 倍。
此外,RedisJSON 的读取、写入和负载搜索延迟,在更高的百分位数中远比 ES 和 MongoDB 稳定。当增加写入比率时,RedisJSON 还能处理越来越高的整体吞吐量。而当写入比率增加时,ES 会降低它可以处理的整体吞吐量。
总结
本文从一个业务诉求触发,对「千万量级数据中查询 10W 量级的数据」介绍了不同的设计方案。对于「在 1000W 量级的底池数据中筛选 10W 的数据」的场景,不同方案的耗时如下
- 多线程 + CK 翻页方案,最坏耗时为 10s~18s
- 单线程 + ES
scroll scan
深翻页方案,相比 CK 方案,并未见到明显优化 - ES + Hbase 组合方案,最坏耗时优化到了 3s~6s
- RediSearch + RedisJSON 组合方案,后续会实测该方案的耗时
参考资料:
- https://juejin.cn/post/7103848212154286087
- https://www.infoq.cn/article/wymrl5h80sfawg8u7ede
- https://juejin.cn/post/7042476201574662175
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!
5.《Java开发手册(嵩山版)》最新发布,速速下载!
觉得不错,别忘了随手点赞+转发哦!
关键词:
-
【环球时快讯】面试官:如何在千万级数据中查询 10W 的数据,都有什么方案?
作者:变速风声链接:https: juejin cn post 7104090532015505416前言在开发中遇到一个业务诉求,...
来源: -
全球快资讯:Rancher 管理 Kubernetes 集群
一、Rancher简介Rancher是一个开源的企业级多集群Kubernetes管理平台,实现了Kubernetes集群在混合云+本...
来源: 【环球时快讯】面试官:如何在千万级数据中查询 10W 的数据,都有什么方案?
网络安全(中职组)-B模块:压缩包破解
全球快资讯:Rancher 管理 Kubernetes 集群
李想:L7、L8、L9是世界上最安全的车 副驾坐的是我老婆
天天快报!美版《西游记》定档!阵容强大:奥斯卡影后杨紫琼饰观音、吴彦祖演美猴王
日本原装进口!雀巢金牌速溶黑咖啡大促 28.9元到手
Android 14不再允许“杀后台”!一键加速App别装了
上汽投资成立股权投资合伙企业 出资额5亿
环球快资讯丨解惑:教你在 Arch Linux 终端上更改 WiFi 密码
教程|在矩池云使用 Stable Diffusion web UI v1.5 模型和 ControlNet 插件
【环球新要闻】应聘软件测试 HR 会问到哪些问题?收藏这一篇就够了!
Nebius Welcome Round (Div. 1 + Div. 2)
环球快讯:火山引擎 DataTester:一个 A/B 测试,将一款游戏的核心收益提升了 8%
环球最资讯丨华擎Intel显卡集体降价 最多20%:RTX 3060瞬间不香了
容声冰箱质量怎么样?容声冰箱怎么调温?
oracle是什么软件?oracle怎么创建表空间?
bios是什么意思?如何刷主板bios?
苹果手表可以连接安卓手机吗?苹果手表怎么配对新的手机?
empty来显示暂无数据简直太好用,阻止用户复制文本user-select
raw格式怎么打开?raw格式怎么转换jpg?
【快播报】《瞬息全宇宙》七项大奖横扫奥斯卡!杨紫琼获封奥斯卡影后:亚洲首位
新一代Y9000P来了!联想拯救者2023生态新品发布会官宣
环球短讯!小红书后台删用户照片遭系统拦截?官方回应:只是清理临时缓存
仅隔17天 中国火箭又一次成功为海外客户发射荷鲁斯2号卫星
【世界时快讯】749元 一加Buds Pro 2轻享版无线耳机开售:48dB深度降噪
今热点:Spring Boot 分片上传、断点续传、大文件上传、秒传,应有尽有,建议收藏!!
全球信息:Ai翻译还是挺香的
限时促销,火山引擎 ByteHouse 为企业带来一波数智升级福利!
方舟里面风神翼龙怎么抓_方舟生存进化风神翼龙怎么抓 具体抓捕方法介绍
每日速递:豆瓣7.9分 《阿凡达:水之道》电影拿下奥斯卡最佳视效奖:实至名归
当前速看:iPad Pro 2024要大涨价:比MacBook Pro还贵
每日视讯:美佛州海滩清出近两吨死鱼:民众直呼“辣眼睛”
全球即时:上班一周不用充电 比油车少花70元!哪吒S用车成本秒杀燃油车
创时速435公里纪录 CR450型动车组首台车涂装完成 顺利交付
【全球热闻】架构师日记-软件高可用实践那些事儿
使用 VS 2019 将 c# 生成 DLL 动态链接库文件
环球头条:获亚洲电影大奖最佳男主角 刘嘉玲给梁朝伟颁奖
全球信息:腾讯前端最高级别专家!T13技术大佬黄希彤被曝遭裁员
环球微头条丨老人推倒摩托案车主回应带货遭网暴:清者自清
男子称花了2999元网购iPhone 13 Pro却收到过保XR:商家已联系不到
今日播报!老人把7万养老钱埋树下找不着 掘地三尺才找回 专家不建议埋
全球热讯:NAT 穿透原理浅浅说 ---转发
前端设计模式——职责链模式
世界微速讯:郑州车辆限行违章怎么处罚_郑州机动车限行
环球快资讯:知名安全公司Acronis被攻击 黑客:他们技术渣 只是羞辱一下
踩踏式降价背后:燃油车这回真崩了
又一地方补贴了 深圳一比亚迪4S店汉EV全系限时补贴1万元
环球视讯!李想:美国人没那么懂车 特斯拉对异响控制是中下档水平
非java异构服务如何集成到SpringCLoud集群中
环球热议:全球首创双枪充电!比亚迪高端MPV腾势D9三月新增订单或再破10000台
当前讯息:我国每年废弃手机约4亿部:你的怎么处理 闲置、提炼金子还是?
焦点消息!多家科技公司被硅谷银行坑了 ChatGPT老板紧急援手:钱先用着 慢慢还
魔兽国服重开遥遥无期 暴雪釜底抽薪:全球服直营
今日报丨Zen4大翻身 AMD移动CPU之王来了:55W战平253W功耗旗舰i9
天天看热讯:读Java性能权威指南(第2版)笔记15_垃圾回收B
快讯:舒筋丸和脑络通胶囊可以一起吗_脑络通胶囊能长期吃吗
焦点简讯:新娘自己主持婚礼省下万元 仅花费160元:网友点赞 本人回应不是给别人看
Docker圣经:大白话说Docker底层原理,6W字实现Docker自由
当前热门:工作一年,我重新理解了《重构》
【QCustomPlot】版本迭代日志
游客饮料不慎掉落被大熊猫雅一捡来喝:园方回应正密切留意
微速讯:30多家车企集体降价:已经没人看得上油车了吗?
当前看点!比尔·盖茨最爱的游戏:用40多年 开启一个时代
【天天快播报】AMD:我们也可以做出RTX 4090!只是不想做而已
天天速讯:抉择!荷兰屈从美国,对华限制但有保留,瑞士顺从美国,面临中资暴减
【天天热闻】MySQL学习笔记-事务
观天下!day01-SpringBoot基本介绍
每日视讯:3-2 字符串
浙江人1年花18亿买香奈儿 网友:原来消费降级的只有我
环球观点:中国杂牌显卡蜂拥进入美国:矿卡滞销 帮帮我们!
当前快看:《生化危机4:重制版》泄露艾达王美图:脚踩恨天高 性感妖娆
48GB大容量配8000MHz高频率!芝奇推出创纪录的DDR5内存
redux crateStore connect
当前快讯:反序列化刷题
天天热门:钻石不值钱了 1/3原价就能买到!中国河南小县城颠覆神话
速读:AMD向Intel正面开炮:顶级性能 不需要高功耗!
网络安全(中职组)-B模块:Web隐藏信息获取
ARC058F
Codeforces Round #857 Div.1 1801 E F 题解
打开MASA Blazor的正确姿势6:表单验证
看点:C#中定义自己的消费队列(下)
焦点关注:什么是牙周炎及症状_什么是牙周炎
SE终于承认《Forspoken》失败:但仍有可取之处
焦点速看:前端设计模式——适配器模式
世界短讯!广西:全面实现高速服务区充电桩100%全覆盖
环球动态:鲜嫩如蛋挞 多鲜岩烧乳酪吐司1斤14.9元
世界滚动:Win10极限精简版系统Tiny10更新:加入远程桌面等实用功能
Intel中国特供i5-13490F闪电降价!这性价比 没治了
计应212小组讨论junit成果
当前简讯:女子沙漠种树16年让县城免于消失 11年前美国预言翻车
每日短讯:掀起汽车降价狂潮之后 湖北再投放5亿元消费券
全球讯息:突破142万人!《CS:GO》同时在线数达10年来最高点
【世界时快讯】ELF 文件
环球快资讯丨表数据量大优化方案设计
2.8K OLED高刷屏!华硕灵耀14 2023轻薄本图赏
女子试驾比亚迪汉撞树:碗口粗的树都弯了 A柱完好无损
环球关注:面向 DevOps 的 Kubernetes 最佳安全实践
焦点速递!9.3.3输入的符号2
明明不缺钱 为什么总有人喜欢在家收集垃圾?
大众ID.家族新能源汽车跟进降价 最高优惠4万元