Clickhouse频繁更新删除问题记录

2,472 阅读4分钟

问题

问题描述

生产查询和统计操作发生严重卡顿,查询无返回,接口无响应。

问题原因

有大量的删除新增更新操作落在了ClickHouse上,导致ClickHouse无法正常处理,ClickHouse占用100%内存完全卡死。

问题排查

  1. 首先想到的是重启ClickHouse看一下能不能缓解问题,重启后,ClickHouse监听端口启动后,短时间内抢占100%内存后卡死。
  2. 重启没有解决问题,后尝试通过配置限制内存使用情况,根据网上资料和官方文档修改过User.xml和Config.xml之后,重启,问题依旧(这个应该是有配置解决的,但没有找到对应的配置,望大佬指点)
  3. 后尝试,通过Kill mutation语句解决问题,但在ClickHouse重启的时间内这条语句无法完整执行。
  4. 最后通过删除data目录下对应表内的mutation文件解决问题。重启正常后再执行kill mutation命令清理mutation表,宕机阶段的数据需要重建。好在Mysql的数据备份是完整的。

优化

基础

  1. ClickHouse有一类操作(更新,删除)被称为Mutation操作,这类操作的响应是实时的,但是实际的处理是异步的。
  2. MergerTree引擎详细分析www.cnblogs.com/traditional… ,作者真的太细了。

方向

  1. 整体的优化方向是去除更新操作,合并零散的删除和新增操作。

解题

  1. 去除更新
    使用ReplacingMergerTree解决数据幂等,把更新操作变为新增操作。
  2. 合并零散操作
    因为去掉了更新操作,具体的操作只剩下新增和删除,两个思路
    1. 创建一个操作记录表,把每次的操作和操作内容记录下来,定时把操作同一个表的相同操作聚合,按照先执行新增后执行删除的方式执行操作。把零散的新增和删除以时间段聚合成一个操作。
      需注意:这个表的操作需要和具体业务表的操作保持事务。
    2. 使用redis创建一个操作队列,先进先出,消费一方取100条操作,按顺序在内存中执行一遍,这一遍是为了过滤新增完立刻删除这种重复且频繁的操作。把执行的结果聚拢成一个单独的新增和删除语句。 两种方案也可以同时使用,这样同步会有延迟,但是对于clickhouse的mutation操作压力会有效控制,适用于单条数据频繁更新的场景。

2022-09-21

更新: 生产上已经长期运行,且没有发现明显问题的方案 后来经过阅读官方文档,和借鉴其他已经公开的方案,总结了一套合适公司项目情况的实现方案. clickhouse本身在设计上是没有想过要支持更新删除操作,我的理解它作为一个数据库,提供的更多是在大数据的下的统计分析和数据增量方案. 更新是一定要避免的.可以使用ReplaceMergerTree来解决,这样更新操作可以被替换为新增操作. 如果存在大量的新增操作,10w级以下可以考虑自行实现批插入,实现中可以考虑缓存表clickhouse.com/docs/zh/eng… 然后如果数据量超过了这个级别,可以考虑SeaTunnel的实现方案,B站可以搜到比较详细的视频教程. 删除操作,关于clickhouse的删除操作是异步执行的这个问题无需担心
clickhouse.com/docs/en/sql…
官方给了详细解释,提交突变操作后插入的数据不参与突变操作 所以我们的解决方案一定是如何聚合操作. 然后大多数情况下没有批量更新难以实现,所以我们选择把增删改的操作聚合在一起,变成增删操作. 使用kafka或者rabbitmq,按照批次阈值和时间阈值进行批量执行. 我们系统的时间阈值保持在30s,用于保证30s内数据一定完成同步.