RedisTimeSeries+ClickHouse来实现时序数据的分析和实时查询

发布时间 2023-11-15 11:15:46作者: jqr0301

ClickHouse很好,在它擅长的OLAP领域。千万级别的数据的分页查询秒级呈现。由于其对资源的使用追求极致,所以相应的TPS不是很高。所有的OLAP的数据库本身TPS都不会很高,单台机器100+就可称之为优秀了。然而,高并发的读写正好是Redis所擅长的,如何将两者的优点结合起来呢?在IOT行业时序数据的存储和实时查询方面,我们做了一些探索!

业务需求
我们的业务需求:兼顾时序数据分析的同时,还能提供高并发的写入和查询。结合项目情况,调研了相关的开源实现。感觉没有一个中间件能比较好的满足我们的需求。慢慢的我们转变了思路,何不取众家之所长?

1、高并发场景

使用RedisTimeSeries中间件来实现高并发的写入和查询。由于其是基于内存的,需要结合业务场景和机器配置情况,存储一定周期的数据。比如:只存储最近一个月的时序数据。

2、OLAP场景

使用ClickHouse中间件,主要实现历史数据查询和分析。存储所有的时序数据库,可结合业务场景进行合适的分区,比如:按照天、月。

单ClickHouse架构
之前文章有分享过,我们基于ClickHouse实现了时序数据的分析和洞察。我们先将时序数据先发送到Kafka中,然后由Kafka引擎表进行ETL操作,将数据输出到ODS事实表中。方案如下:

此方案有如下两个明显的缺点:

1、数据入库延迟较大(1-5s)。

2、查询并发能力差。

我们引入RedisTimeSeries中间件来弥补ClickHouse的这两个缺点。

RedisTimeSeries+ClickHouse架构
借鉴了WAL的思想:在ClickHouse前搭建一个消息中间件Kafka,将Kafka作为WAL的对象。程序在双写的时候,先将消息写入到Kafka,待Kafka写入成功了,可以通过ACK机制确保消息已经落盘,然后再写RedisTimeSeries。整体的架构如下:

此架构能比较好的解决我们目前的需求。Reids写操作TPS单机能达到8-10万,Kafka更不用说了,号称单机百万吞吐。整个架构的TPS会轻松上5万+,能满足绝大多数的业务场景。对于实时查询场景,RedisTimeSeries能提供1000+TPS的查询能力(点查、小范围查)。ClickHouse能提供海量数据的分析查询功能。

问题和衍生
此方案也不是完美的,存在第二个环节写入失败,然后RedisTimeSeries和ClickHouse数据不一致的问题。也就是典型的一致性保证:

1、可以借助kafka事物的概念来做一致性保证。

此方案实现起来比较简单,但是整体的性能会下降很多。

2、异步补偿机制

对于第二部操作,如果写入RedisTimeSeries失败。可以考虑将失败的消息发送到额外的队列中,然后有单独的补偿线程对数据进行补录。

另外,此方案也可以衍生到MySQL数据库,比如我们想利用好B+树的特性,来支持高并发的查询排序操作。将操作RedisTimeSeries的部分修改为操作MySQL即可。MySQL的单机查询TPS和RedisTimeSeries不是一个数量级,这块需要特别注意。结合自己的业务场景,做好技术选型即可。