ClickHouse使用(十 一)
文章目录
一、使用replaceingMergeTree引擎,实现更新
场景:在日志收集服务中心,保存用户信息表,经常需要根据日志信息更新用户的信息,在更新过程中,clickhouse:在数据量超过200万时,会经常出现
too many parts …
二、原理分析
clickHosue 更新主要实现方式为,分区替换,当出现修改语句时,clickhouse 选择新建一个分区,将数据完整拷贝一份,在merge动作发生时,废除老数据,激活新数据,实现更新效果;
(1)更新效果为异步
(2)更新动作频发,会导致新增多个新的数据备份,在数据量逐渐增大后,导致错误发生。
二、解决办法
(1)评估数据量
通过增加分区个数的方式,减小单个分区数据量,使得更新操作,操作的数据量减小,在数据量小于200万(没压缩前大约2G)内,可以正常运行,多余200万,随时可能引发错误,在错误发生后,会导致,写入持续失败
(1)使用ReplaceingMergeTree引擎,实现更新
ReplaceingMergeTree 引擎 可以按照排序字段自动清除重复数据,执行时机由clickhouse 自己控制
(1)建立ReplaceingMergeTree 引擎 表
(2)将更新语句 转换成,查询+内存内更新+批量插入的方式
(3)首先执行查询语句,根据更新条件精准查询出要更新的数据(笔者根据主键查询)。提示,此操作的并发数不易过多,clickhouse建议qps 控制在 100以内,笔者使用单线程
(4)将查询出来的数据转换成json结构
(5)将要更新数据组织称json结构
(6)循环要更新的数据,更新对应的查询出来的历史数据
(7)组织插入语句,批量插入clickHouse
(8)主动执行optimize table table_name final ,来触发按照排序键去重的操作,完成更新
(2)例子
例子:
– heaven_eye_event_log.users_production definition
CREATE TABLE heaven_eye_event_log.users_production
(
`id` Int64,
`first_id` String,
`second_id` String,
`project` String DEFAULT '',
`$city` String DEFAULT '',
`$province` String DEFAULT '',
`miniapp_pinzustate` Decimal(18,3) DEFAULT -999999999,
`$country` String DEFAULT '',
`userId` String DEFAULT '',
`$first_visit_time` String DEFAULT '',
`$first_browser_charset` String DEFAULT '',
`$first_search_keyword` String DEFAULT '',
`$first_browser_language` String DEFAULT '',
`$first_traffic_source_type` String DEFAULT '',
`$first_referrer_host` String DEFAULT '',
`$first_referrer` String DEFAULT '',
`timematters_usertype` String DEFAULT '',
`$utm_source` String DEFAULT '',
`$utm_medium` String DEFAULT '',
`$utm_campaign` String DEFAULT '',
`$utm_term` String DEFAULT '',
`$utm_content` String DEFAULT '',
`insert_date` DateTime DEFAULT now()
)
ENGINE = ReplacingMergeTree(insert_date)
PRIMARY KEY id
ORDER BY id
SETTINGS index_granularity = 8192;
三、ClickHouse副本同步及分布式DDL的原理
副本同步原理,通过监听zk的消息实现
node1 写入数据后,推送操作日志到zk,node2监听到后,就知道了node1写入了数据,从zk下载操作日志,并在node1下载数据副本