通过接口从CK数据库获取详情数据,为何要等很长时间甚至会失败?
最近日常支撑用户期间,随着越来越多用户开始深度使用基于大数据底座的服务,对高达百亿的数据关注度越来越高,一个比较尖锐的问题也在浮出水面:为什么在导出详情数据的时候,要等很长时间,甚至在等了很久之后任务会失败?本文从几个角度给大家解释下定位与分析原因。
首先,我们先抛出几个定位出来的原因:
- “XX组织”作为新增的维度,在数据详情表内还未加上相关索引,导致CK数据查询XX组织数据的效率低;
- 查询到的数据,经常是万级,数据展示需要做分页;深度分页时,CK查询效率低;
- 通过接口传统分页方式,经常是突发性大流量对网络压力大,大数据查询有超时风险,可以考虑流式获取数据;
- 数据详情表关联了规则、任务等字段,列数过多且部分字段存储内容很大,是一张大宽表,即使只查询部分任务,CK列示存储仍需要解压整个行组。
接着,我们先介绍下CK是什么,以及其一些关于数据查询的限制。
CK介绍
CK数据库,全称是ClickHouse,是一款开源的列式数据库管理系统(DBMS),由俄罗斯Yandex公司开发。它专为在线分析处理(OLAP)设计,能够高效处理大规模数据分析任务。它的数据查询功能非常显著,因为采用列式存储结构,查询时只需读取相关列,显著减少I/O操作。
但它的限制点同样突出,1、仅支持批量更新/删除,不支持单行高频修改;2、单查询会占用服务器一半CPU资源,限制并发能力;3、JOIN语法特殊且性能较差,特别是大表JOIN,因此建议都是采用预聚合宽表替代多表JOIN。这些限制点,导致在数据查询期间,CK对于深度分页问题效率极低,大查询可能触发max_memory_usage限制,分布式JOIN性能较差很多数据需要预聚合处理。
数据获取过程
然后,我们梳理下用户在看板上获取数据的大概过程:1、用户触发导出请求;2、验证查询条件;3、查询条件发送到ClickHouse;4、CK执行查询(阻塞点1);5、结果排序;6、分页处理(阻塞点2);6、生成临时结果集;7、上传到OBS;8、生成下载链接;9、通知用户。
原因解析
接着,我们对分析出来的几个原因展开解析。
缺乏合适索引
在告警详情表中,“XX组织”作为新增的查询维度,因为未在ClickHouse的ORDER BY索引中显式定义,查询时触发了全表扫描,引擎需解压并扫描所有数据块,导致查询性能下降。
下一步动作:在表内,将高频查询字段(XX组织)加入ORDER BY键,减少数据扫描范围。
深度分页问题
因为看板展示详情数据的需要(支持用户分页展示详情),相关接口需要展示万级数据并实现分页,传统LIMIT offset, size
分页在ClickHouse中会转化为"先读取offset+size行,再丢弃前offset行"的操作,这都是需要物理跳过的操作。例如,在查询第100页的时候(LIMIT 10000, 100),需要物理扫描10,100行数据,而随着offset增大,查询耗时呈线性增长,最终触发CK的短连接时间限制超时。根因在于列式存储的不可跳读特性——即使只需返回100条记录,引擎仍需解压所有相关列的数据块。
下一步动作:调研相关技术手段,改用游标分页(如WHERE id > last_id ORDER BY id LIMIT 100);或结合业务需求,不做详情数据分页,不再支持分页展示,直接导出相关数据。
接口突发流量与超时
传统分页接口每次请求均需CK执行完整查询并返回固定页数据,导致两个问题:
- 流量尖峰:同时发送几十个甚至上百个的并发请求,每页1万条数据,瞬时可能传输GB级数据,突破APIG的1000MB/min限制;
- 超时风险:排序和分页操作集中在单次查询里,30秒超时阈值极易被触发。
下一步动作:调研流式获取数据方案,通过JDBC来流式获取数据,避免内存溢出,且可将大查询拆分为多个小批次避免长耗时操作,网络传输更平滑。
告警详情表大宽表
详情表关联规则、任务等字段后,形成几十列的宽表。详情数据查询经常又涉及20个左右的字段,ClickHouse的列式存储仍按行组(Granule)解压所有列。尤其是部分列(如描述、理由字段)还包含长文本,解压该行组将消耗额外CPU和内存。
下一步动作:结合业务需求,仅在详情表内关联关键字段,非运营分析关键字段需要剔除;考虑将部分字段分离到扩展表内,查询时避免全列查询,调整行组大小等。
- 点赞
- 收藏
- 关注作者
评论(0)