在之前的文章中,我们讨论了一种基于IP范围维度的数据入库设计,并将这份包含超过60万条记录的表,分别写入了ClickHouse和Doris数据库中。
为了保证后续查询效率对比的公平性,对于存入CK和Doris的两张表,我使用了尽可能一致的表引擎、索引字段和字段类型。
同时,为了检验当前这种维表设计的可行性,我们也把之前使用同一份数据、基于Redis跳表的存储方式一并纳入关联查询的对比测试中。
本次测试旨在探究,这份维度数据分别存储在CK、Doris、Redis这三种不同的数据库中时,对于关联上游业务数据(来自Kafka)的效率表现究竟如何?
一、测试任务设计
如前文所述,这份维度数据的查询方式不能依赖于普通的JOIN关联,而只能通过WHERE条件进行“大于等于起始值,且小于等于终止值”的范围查询。
同时,考虑到该维度数据将持续更新,综合这两点,其业务查询模式必然是“来一条,查一条”。
为了清晰测试这份维度数据在三种不同数据库下的查询性能,我们设计了如下的流式任务流程,它清晰地展现了数据从源头到关联结果的完整路径。
该测试方案将部署为三个独立的任务:
- 任务1:Flink消费Kafka数据,查询Doris维表,结果写入CK。
- 任务2:Flink消费Kafka数据,查询CK维表,结果写入CK。
- 任务3:Flink消费Kafka数据,查询Redis维表,结果写入CK。
二、ClickHouse结果表设计
为了清晰对比三个任务的结果,需要设计一个字段功能强大的结果表。经过考量,决定将这张结果表创建在ClickHouse中,其结构如下:
ip:需要查询的IPv4字符串。
ip_and_address: 根据ip查询到的地理位置及运营商信息字符串。
hit_source: 当前查询所使用的数据源(Doris、CK或Redis)。
data_time: Flink获取到ip数据时记录的当前时间。
insert_time:Flink查询到地理位置和运营商数据后记录的当前时间。
time_gap:insert_time与data_time的时间差,单位为毫秒,即单条数据的查询耗时。
三、查询接口设计
- ClickHouse查询接口:毫无疑问,采用JDBC方式。这在之前的多个Flink项目案例中已被多次验证。
- Doris查询接口:目前同样采用基于MySQL协议的JDBC进行连接和查询。
- Redis查询接口:基于Jedis框架实现,并已进行了封装。
这三种接口的实现本身并不复杂,关键点在于它们在Flink分布式框架下的数据库连接管理问题。
四、 多级流量压力测试
根据经验,不同吞吐量的数据源下,流式任务的处理效率表现差异可能很大。因此,本次测试设定了多个不同流量等级的Kafka数据源,逐一观察三者在不同压力下的效率区别。
1、10条/秒流量
- Doris:平均查询耗时约10.24毫秒。
- ClickHouse:平均查询耗时约7.01毫秒。
- Redis:平均查询耗时约1.58毫秒。
2、100条/秒流量
- Doris:平均查询耗时约10.48毫秒。
- ClickHouse:平均查询耗时约6.96毫秒。
- Redis:平均查询耗时约1.57毫秒。
3、500条/秒流量
- Doris:平均查询耗时约11.33毫秒。
- ClickHouse:平均查询耗时约6.79毫秒。
- Redis:平均查询耗时约1.57毫秒。
4、 2000条/秒流量
- Doris:平均查询耗时约11.76毫秒。
- ClickHouse:平均查询耗时约7.02毫秒。
- Redis:平均查询耗时约1.59毫秒。
五、结论与选型建议
通过对上游Kafka事实数据关联三种不同数据库维表的测试,可以得出以下结论:
- 关联效率:Redis的速度最快(耗时稳定在1-2毫秒左右),且表现最稳定(耗时波动最小)。
- 次优选择:ClickHouse的关联效率次之,查询耗时基本在6-7毫秒区间,表现不如Redis稳定,存在一定波动。
- 对比结果:Doris的关联效率相对较低,查询耗时基本维持在10毫秒左右,波动性比CK稍大。
此外,还有一个值得注意的发现:当调高上游Kafka数据流量并进行长时间压测后,基于Doris的流任务在夜间出现了中断(而CK和Redis的任务运行正常)。
综合来看,在当前测试的维表关联场景下,基于Redis的方案表现最优,ClickHouse方案可作为备选,而Doris方案在此特定场景下暂不推荐。
|