背景
设备管理、产品管理,包含了很多更新场景,比如:设备上下线引起的设备状态信息。尤其是IoT设备接入模块,我们一般采用OLTP型数据库来实现,比如:MySQL、PostgreSQL等。OLTP型数据库提供了高并发的查询及更新能力,尤其在点范围操作场景。在OLTP更新场景下,一般采用分库分表的方式进行扩展。而在OLAP场景,我们需要数据要融合,便于分析统计,这就是一个冲突点。一般来说,我们会通过CDC技术,将OLTP数据库中的设备信息,实时同步到OLAP数据库中。IOT平台的主数据管理,就面临一个问题,我是基于接入侧的OLTP型数据库还是OLAP数据库来做主数据管理。最近想了很多,今天就和大家分享下,如何基于OLAP数据库来实现主数据管理。
整体方案
通过CDC技术,将IoT Hub的设备信息,同步到数据中台。相应的台账管理人员,登录数据中台,进行设备台账信息补充。数据中台提供基于资产目录进行资产划拨。可以针对不同目录,设置不同的数据访问权限。类似SaaS中组织的概念。
基于ClickHouse实现
1)基于Flink CDC实时同步
如果数据库使用的是MySQL、PG这些,Flink CDC天生支持同步。同步到ClickHouse的时候,不能通过kafka引擎表来入库,因为这样整体延迟很大。我们需要直接使用JDBC进行ClickHouse数据库的操作,将整体延迟控制在1秒左右。有些场景涉及流程依赖,实时性要求很高,可以通过通过缓存的方式来进行数据缓存,提供实时查询的功能。如果使用的不是MySQL、PG这些数据库,目前国产化需求旺盛,比如使用的是人大金仓、达梦这样的数据库。可以从业务侧,通过增加同步消息队列来实现,落盘整体延迟在1秒左右。Redis中数据为实时,这样一来是比较完善的方案,详情示例如下:
2)创建ReplacingMergeTree引擎表
SQL
CREATE TABLE device
(
`id` Int64,
`product_key` String,
`name` String,
...
)
ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/{layer}-{shard}/device','{replica}',version)
PARTITION BY intHash64(id) % 10
ORDER BY (id,product_key,device_key)
SETTINGS
index_granularity = 30,
vertical_merge_algorithm_min_rows_to_activate = 1,
vertical_merge_algorithm_min_columns_to_activate = 1;
vertical_merge_algorithm_min_rows_to_activate
和 vertical_merge_algorithm_min_columns_to_activate
设置为1是为了让 MergeTree 使用 Vertical 算法进行 merge。Horizontal算法是所有列都会被读出参与merge。ClickHouse对于更新支持不好,我们借助ReplacingMergeTree引擎,将更新操作转变为insert into ...select ...操作。期待新版本的轻量级的更新操作,目前23版本已经支撑轻量级的删除操作。
3)数据检索
由于ClickHouse Merge是在后端不定期进行,无法灵活控制。对于数据查询,有如下几种方式来保证数据一致性。
环境信息:虚拟机8C 16G、操作系统centos7.5、普通磁盘、clickhouse版本23.3。
1、使用final字段
对于频繁更新或者查询的场景不适用。使用final字段,查询的时候如果未merge,则触发merge,新版本做了优化,但是在较频繁操作的场景不建议使用。在1000万设备信息,执行如下SQL进行数据检索的时候,性能差强人意。
SQL
SELECT
id,
product_key,
device_key,
version AS version,
device.version AS device_name,
...
FROM device FINAL
limit 20
触发merge时,整体耗时在5-6秒,合并后性能较高,整体耗时<1s。
2、使用group by配合argMax(...,version)
SQL
SELECT
id,
product_key,
device_key,
max(device.version) AS version,
argMax(name,device.version) AS device_name,
...
FROM device
GROUP BY
id,
product_key,
device_key
limit 20
执行耗时在4-5s,相对比较慢一些。
3、这种方法比较巧妙,暂时不贴SQL了
整体性能有3-5倍的提升,1.5秒左右。有兴趣的可以一起探讨下,记得给文章点赞!
总结
千万级数据量,查询在1.5秒左右,如果是物理机器,应该能控制在1秒内,整体满足业务需求。通过此场景,我们初步做到了TP和AP场景融合,未来结合ClickHouse轻量级的更新,是一件值得期待的事情!