在OLAP数据库中 , 可变数据(Mutable data)通常是不受欢迎的 。 ClickHouse也是如此 。 早期的版本中并不支持UPDATE和DELETE操作 。 在1.15版本后 , Clickhouse提供了MUTATION操作(通过ALTER TABLE语句)来实现数据的更新、删除 , 但这是一种“较重”的操作 , 它与标准SQL语法中的UPDATE、DELETE不同 , 是异步执行的 , 对于批量数据不频繁的更新或删除比较有用 。 除了MUTATION操作 , Clickhouse还可以通过CollapsingMergeTree、VersionedCollapsingMergeTree、ReplacingMergeTree结合具体业务数据结构来实现数据的更新、删除 , 这三种方式都通过INSERT语句插入最新的数据 , 新数据会“抵消”或“替换”掉老数据 , 但是“抵消”或“替换”都是发生在数据文件后台Merge时 , 也就是说 , 在Merge之前 , 新数据和老数据会同时存在 。
针对与不同的业务场景 , ClickHouse提供了不同的业务引擎来进行数据变更 。
对于离线业务 , 可以考虑增量和全量两种方案:
增量同步方案中 , 使用ReplacingMergeTree引擎 , 先用Spark将上游数据同步到Hive , 再由Spark消费Hive中的增量数据写入到ClickHouse中 。 由于只同步增量数据 , 对下游的压力较小 。 需要确保维度数据基本不变 。
全量同步方案中 , 使用MergeTree引擎 , 通过Spark将上游数据定时同步到Hive中 , truncate ClickHouse中的表 , 随后使用Spark消费Hive近几天的数据一起写入到ClickHouse中 。 由于是全量数据导入 , 对下游压力较大 , 但无需考虑维度变化的问题 。
对于实时业务 , 可以采用VersionedCollapsingMergeTree和ReplacingMergeTree两种引擎:
使用VersionedCollapsingMergeTree引擎 , 先通过Spark将上游数据一次性同步到ClickHouse中 , 在通过Kafka消费增量数据 , 实时同步到ClickHouse中 。 但因为引入了MQ , 需要保证exectly once语义 , 实时和离线数据连接点存在无法折叠现象 。
使用ReplacingMergeTree引擎替换VersionedCollapsingMergeTree引擎 , 先通过Spark将上游存量数据一次性同步到ClickHouse中 , 在通过MQ将实时数据同步到ReplacingMergeTree引擎中 , 相比VersionedCollapsingMergeTree要更简单 , 且离线和实时数据连接点不存在异常 。 但此种方案无法保重没有重复数据 。
StarRocks中的数据更新
相较于ClickHouse , StarRocks对于数据更新的操作更加简单 。
StarRocks中提供了多种模型适配了更新操作 , 明细召回操作 , 聚合操作等业务需求 。 更新模型可以按照主键进行UPDATE/DELETE操作 , 通过存储和索引的优化可以在并发更新的同时高效的查询 。 在某些电商场景中 , 订单的状态需要频繁的更新 , 每天更新的订单量可能上亿 。 通过更新模型 , 可以很好的适配实时更新的需求 。
StarRocks 1.19版本之前 , 可以使用Unique模型进行按主键的更新操作 , Unique模型使用的是Merge-on-Read策略 , 即在数据入库的时候会给每一个批次导入数据分配一个版本号 , 同一主键的数据可能有多个版本号 , 在查询的时候StarRocks会先做merge操作 , 返回一个版本号最新的数据 。
自StarRocks 1.19版本之后发布了主键模型 , 能够通过主键进行更新和删除的操作 , 更友好的支持实时/频繁更新的需求 。 相较于Unique模型中Merge-on-Read的模式 , 主键模型中使用的是Delete-and-Insert的更新策略 , 性能会有三倍左右的提升 。 对于前端的TP库通过CDC实时同步到StarRocks的场景 , 建议使用主键模型 。
集群的维护
相比于单实例的数据库 , 任何一款分布式数据库维护的成本都要成倍的增长 。 一方面是节点增多 , 发生故障的几率变高 。 对于这种情况 , 我们需要一套良好的自动failover机制 。 另一方便随着数据量的增长 , 要能做到在线弹性扩缩容 , 保证集群的稳定性与可用性 。
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
