尽管 ClickHouse 拥有如此极致的性能,但实践生产过程中仍然面临一些困境。比如存在数据类型不支持,全量复制性能问题等方面的挑战。此外也有一些与引擎本身设计有关的性能问题:比如 FINAL 去重导致的查询性能问题等,给用户使用过程带来一些不好的体验。
全量并行复制
Materialize MySQL 引擎通过消费 BinLog 的方式来订阅 MySQL 数据。数据同步过程分为三个步骤,首先是检验源端 MySQL 参数是否符合规范,然后是全量和增量复制阶段。ClickHouse 数据同步的全量复制过程是单线程的,在数据量较大时复制时延较高。GaussDB(forMySQL) HTAP只读分析对全量复制进行了并行化处理,优化后的复制性能平均提升 8-10 倍,对实际生产实践是十分有意义的。
MVCC & Snapshot
MaterializeMySQL 引擎在 DDL 转化过程中默认增加了2个隐藏字段:_sign (-1删除,1插入/更新) 和 _version (数据版本)。下方是同一张表在 MySQL 和 ClickHouse 里的 DDL:
Create Table: CREATE TABLE `runoob_tbl` ( `runoob_id` int unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`runoob_id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 --------------------------------------------------------------- ATTACH TABLE _ UUID '14dbff59-930e-4aa8-9f20-ccfddaf78077' ( `runoob_id` UInt32, `_sign` Int8 MATERIALIZED 1, /// _sign 字段 `_version` UInt64 MATERIALIZED 1 /// _version 字段Materialize MySQL 引擎当前不提供 MySQL 数据的事务一致性视图,数据行以批量插入的方式同步到 ClickHouse 中,引擎底层使用的是 ReplacingMergeTree。如果数据发生了修改,获取最新的数据时需要指定 FINAL(类似于 GROUP BY)去重,并使用过滤器隐藏已删除的行。然而当数据规模很大时,FINAL 操作的性能往往不太理想。
为了感知事务,GaussDB(for MySQL) HTAP只读分析实现了事务一致性并提供四种隔离级别,用户可以根据具体使用场景选择不同的隔离级别。此外,GaussDB(for MySQL) HTAP只读分析还提供了快照功能,优化 FINAL带来的查询性能问题。
read_uncommitted: 不提供 MVCC 支持,可能会引入脏读 read_committed: 提供 MVCC 支持(包括SubQuery),读最新已 commit 的数据 query_snapshot: 规避 SELECT + FINAL 查询中的 Merge 开销,直接查询快照 query_raw: 不做任何优化,返回所有数据(包括已删除和更新的不同版本)FINAL 性能优化
前面提到 MaterializeMySQL 底层使用的是 ReplacingMergeTree,该引擎后台会按照一定规则执行 Merge 操作,用户想要获得最新数据则必须通过 FINAL 操作去重。除了采用 MVCC + Snapshot 机制保障查询性能外,GaussDB(for MySQL) HTAP只读分析从索引以及过滤策略等方面对ReplacingMergeTree 引擎本身的 FINAL 操作进行了优化,即使不依赖 MVCC + Snapshot 也能提供不错的查询性能。
5. GaussDB(for MySQL) HTAP只读分析兼容性及稳定性
类型支持增强
MySQL 和 ClickHouse 的基本数据类型之间都有对应的映射关系(见下表),值得一提的是 ClickHouse 将不支持的 MySQL 数据类型都转换为 String 类型存储。MySQL 不支持的 ClickHouse 类型也都被转换为 MYSQL_TYPE_STRING 类型。从下表中不难看出,ClickHouse 仍有一部分数据类型还未支持,而这部分数据类型在实际应用场景中是有可能出现的,因此 GaussDB(for MySQL) HTAP只读分析针对常用的数据类型例如 BIT 和 TIME 以及 YEAR 等做了适配,解决部分用户的刚要需求。
Unique Key 同步支持
MaterializeMySQL 引擎当前仅支持含有 Primary Key 的表同步,现实生产过程中是可能存在一些表格没有主键,但却含有 Unique Key 的,因此有必要支持这种表的数据同步。GaussDB(for MySQL) HTAP只读分析对仅含有 Unique Key (NOT NULL) 的表单独处理,使用 Unique Key 进行分区。
优雅的复制中断重连
实际应用过程中,全量数据复制的数据规模通常较大,同步时间较长,复制中断(网络,MySQL服务端宕机等)的情况是有可能发生的,ClickHouse 遇到上述情况时选择终止当前库的同步并返回错误。为了提升数据同步的稳定性,GaussDB(for MySQL) HTAP只读分析针对MaterializeMySQL 引擎设计了重连,当中断发生时清理现场并在一定时间间隔内进行重连。与全量复制中断重连不同的是,增量复制中断后不需要清理现场,这与增量复制的方式有关,增量复制基于 BinLog Event,已经增量同步成功的数据不需要重新再来一次,重新建立连接后会根据全局 GTID 找到最新的同步点开始同步。
更完备的异常处理机制