网易首页 > 网易号 > 正文 申请入驻

千万级数据查询:CK、ES、RediSearch怎么选?

0
分享至

目录

  • 前言

  • 初版设计方案

  • CK 分页查询

  • 使用ES Scroll Scan 优化深翻页

  • ES+Hbase 组合查询方案

  • RediSearch+RedisJSON 优化方案

  • 总结

前言

在开发中遇到一个业务诉求,需要在千万量级的底池数据中筛选出不超过 10W 的数据,并根据配置的权重规则进行排序、打散(如同一个类目下的商品数据不能连续出现 3 次)。下面对该业务诉求的实现,设计思路和方案优化进行介绍。

对“千万量级数据中查询 10W 量级的数据”设计了如下方案:

  • 多线程+CK 翻页方案

  • ES scroll scan 深翻页方案

  • ES+Hbase 组合方案

  • RediSearch+RedisJSON 组合方案

初版设计方案

整体方案设计为:

  • 先根据配置的「筛选规则」,从底池表中筛选出「目标数据」

  • 在根据配置的「排序规则」,对「目标数据」进行排序,得到「结果数据」

技术方案如下:

每天运行导数任务,把现有的千万量级的底池数据(Hive 表)导入到 Clickhouse 中,后续使用 CK 表进行数据筛选。

将业务配置的筛选规则和排序规则,构建为一个「筛选 + 排序」对象 SelectionQueryCondition。

从 CK 底池表取「目标数据」时,开启多线程,进行分页筛选,将获取到的「目标数据」存放到 result 列表中。


//分页大小 默认 5000
int pageSize = this.getPageSize();
//页码数
int pageCnt = totalNum / this.getPageSize() + 1;

List> result = Lists.newArrayList();
ListList>>> futureList = new ArrayList<>(pageCnt);

//开启多线程调用
for (int i = 1; i <= pageCnt; i++) {
//将业务配置的筛选规则和排序规则 构建为 SelectionQueryCondition 对象
SelectionQueryCondition selectionQueryCondition = buildSelectionQueryCondition(selectionQueryRuleData);
selectionQueryCondition.setPageSize(pageSize);
selectionQueryCondition.setPage(i);
futureList.add(selectionQueryEventPool.submit(new QuerySelectionDataThread(selectionQueryCondition)));
}

for (Future>> future : futureList) {
//RPC 调用
List> queryRes = future.get(20, TimeUnit.SECONDS);
if (CollectionUtils.isNotEmpty(queryRes)) {
// 将目标数据存放在 result 中
result.addAll(queryRes);
}
}

④对目标数据 result 进行排序,得到最终的「结果数据」。

CK 分页查询

在「初版设计方案」章节的第 3 步提到了「从 CK 底池表取目标数据时,开启多线程,进行分页筛选」。此处对 CK 分页查询进行介绍。

①封装了 queryPoolSkuList 方法,负责从 CK 表中获得目标数据。该方法内部调用了 sqlSession.selectList 方法。


public List> queryPoolSkuList( Map params ) {
List> resultMaps = new ArrayList<>();



// 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 查询方法,部分代码如下:


select sku_pool_id,i tem_sku_id, skuPoolName, price, ... ... businessType from liannu_sku_pool_indicator_all where dt=#{dt} and"queryItem.type == 'equal'"> ${queryItem.field} = #{queryItem.value}foreach> group by sku_pool_id,item_sku_id if> group by sku_pool_id,item_sku_id,${orderBy} order by ${orderBy} ${orderAd} if> limit #{limitStart},#{limitEnd} if>select>③可以看到,在 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 翻页对上述几种翻页方案,查询不同数目的数据,耗时数据如下表:| 耗时数据此处,分别使用 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 查询的两个阶段在 ES 中,搜索一般包括两个阶段:query 阶段:根据查询条件,确定要取哪些文档(doc),筛选出文档 ID(doc_id)fetch 阶段:根据 query 阶段返回的文档 ID(doc_id),取出具体的文档(doc)| 组合使用 Hbase在上文调研的基础上,发现「减少不必要的查询展示字段」可以明显缩短查询耗时。沿着这个优化思路,设计了一种新的查询方案: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 数据集上执行复杂的搜索查询。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 延迟稍微低些。| 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~6sRediSearch+RedisJSON 组合方案,后续会实测该方案的耗时作者:变速风声 https://juejin.cn/post/7104090532015505416公 众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!------ 特别推荐 ------特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注。文章有帮助的话,点在看,转发吧!

QueryCondition queryCondition = parseQueryCondition(params);
List> mapList = lianNuDao.queryPoolSkuList(getCkDt(),queryCondition);
if (CollectionUtils.isNotEmpty(mapList)) {
for (Map data : mapList) {
resultMaps.add(camelKey(data));
}
}
return resultMaps;
}

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
大量寻呼机是如何被引爆的?黎巴嫩数千人死伤,誓言要“报复”以色列

大量寻呼机是如何被引爆的?黎巴嫩数千人死伤,誓言要“报复”以色列

都市快报橙柿互动
2024-09-18 09:55:56
乌媒:泽连斯基称乌克兰“胜利计划”90%以上已制定完成,将于下周呈现给盟友

乌媒:泽连斯基称乌克兰“胜利计划”90%以上已制定完成,将于下周呈现给盟友

环球网资讯
2024-09-17 17:30:14
教育之痛?北大教授:看到北京快递员中硕士学士比例,我吓傻了

教育之痛?北大教授:看到北京快递员中硕士学士比例,我吓傻了

教育人看世界
2024-09-16 15:18:59
《凡人歌》结局震碎三观:欠债66万的谢美蓝开着70万保时捷去离婚

《凡人歌》结局震碎三观:欠债66万的谢美蓝开着70万保时捷去离婚

娱乐故事
2024-09-15 14:11:41
中产"返贫三件套",占两样就危险了,快来看看你占了几样

中产"返贫三件套",占两样就危险了,快来看看你占了几样

庞明说楼市
2024-09-17 19:55:31
女教师担心老公出去野,劝家中保姆帮忙:帮帮姐,一次给500

女教师担心老公出去野,劝家中保姆帮忙:帮帮姐,一次给500

苏大强专栏
2024-07-10 20:56:36
欧冠首日积分榜:六支球队同积3分,拜仁净胜7球领跑

欧冠首日积分榜:六支球队同积3分,拜仁净胜7球领跑

懂球帝
2024-09-18 05:33:30
我国“上将”军衔每个月薪资多少,待遇怎样?没有你想的那么夸张

我国“上将”军衔每个月薪资多少,待遇怎样?没有你想的那么夸张

世界就是这么精彩
2024-09-08 16:45:29
全网寻人!!在南翔古猗园,勇救95岁落水老人的上海模子,你在哪里?!

全网寻人!!在南翔古猗园,勇救95岁落水老人的上海模子,你在哪里?!

创作者_GRCQ
2024-09-17 19:11:49
痛心!天津大友谊是如何走到今天这个地步的?

痛心!天津大友谊是如何走到今天这个地步的?

弄堂房子
2024-09-17 20:40:33
为了劝说埃及离开中国歼-10战机,美国背弃了以色列,送13亿美元

为了劝说埃及离开中国歼-10战机,美国背弃了以色列,送13亿美元

青年的背包
2024-09-17 15:04:41
曝56岁谢广坤的小娇妻是名校毕业,曾是他资助的大学生!

曝56岁谢广坤的小娇妻是名校毕业,曾是他资助的大学生!

东城一倩
2024-09-17 14:03:09
越闹越大!曾志伟拒绝回应月饼事件,扔话筒离场,工厂注册仅一年

越闹越大!曾志伟拒绝回应月饼事件,扔话筒离场,工厂注册仅一年

奇思妙想草叶君
2024-09-16 23:26:09
何超琼刘嘉玲出席中秋晚宴,戴千万珠宝亮相,何超盈的脸又变了

何超琼刘嘉玲出席中秋晚宴,戴千万珠宝亮相,何超盈的脸又变了

素素娱乐
2024-09-18 09:07:56
脸都不要了!人见人欺!亚冠“鱼腩”主帅赛前看低中超冠军!

脸都不要了!人见人欺!亚冠“鱼腩”主帅赛前看低中超冠军!

室内设计师阿喇
2024-09-18 09:10:36
现实中如果一个连长的父亲是军长,会让全连知道吗?全军都得知道

现实中如果一个连长的父亲是军长,会让全连知道吗?全军都得知道

奇特短尾矮袋鼠
2024-08-10 12:22:12
真空的杨幂,土气的张小斐,阿那亚这一夜,女星审美差距,出来了

真空的杨幂,土气的张小斐,阿那亚这一夜,女星审美差距,出来了

娱乐圈笔娱君
2024-09-14 13:59:17
日本专家担忧:中日一旦开战,日本对上中国火箭军,能坚持多久?

日本专家担忧:中日一旦开战,日本对上中国火箭军,能坚持多久?

日风的故事屋
2024-09-14 21:09:30
泰山队谢场闹乌龙,球迷让瓦科挥舞旗帜,后者直接扛着旗帜走了

泰山队谢场闹乌龙,球迷让瓦科挥舞旗帜,后者直接扛着旗帜走了

直播吧
2024-09-17 21:35:13
削骨打胎骂老婆,骗粉丝卖假货,小杨哥好运到头,三只羊面临倒闭

削骨打胎骂老婆,骗粉丝卖假货,小杨哥好运到头,三只羊面临倒闭

室内设计师阿喇
2024-09-17 23:13:06
2024-09-18 12:28:49
Java精选
Java精选
一场永远也演不完的戏
1550文章数 3855关注度
往期回顾 全部

科技要闻

小鹏用实际行动证明,李想说得没错

头条要闻

"老虎"杜玉波被查 近期还多次公开露面

头条要闻

"老虎"杜玉波被查 近期还多次公开露面

体育要闻

78天5连胜!欧冠疯狂9-2 刷爆69年纪录

娱乐要闻

中秋晚会删于适节目,吴京新片受影响

财经要闻

许家印,又有新消息!

汽车要闻

埃安RT实车曝光 高配车型将配备高阶智驾系统

态度原创

艺术
旅游
健康
教育
公开课

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

旅游要闻

游客吐槽被困武功山数小时挨冻,景区回应

炉甘石洗剂,凭啥成了止痒全能王?

教育要闻

七中、十六中名额分配深度剖析

公开课

改变人生的10件小事

无障碍浏览 进入关怀版