ClickhouseAlter操作造成zk连接丢失的问题分析
背景
业务方数据在出现错误后需要重跑数据,由于业务方没有使用MergeTree的折叠表,需要删除旧的数据后,再重新跑数据写入新的正确的数据。
之前这种模式一直运转的比较好,没有出现过问题,不过近期发现,对该表发起Alter语句时,出现了ZK Connection Loss的错误,但是对其他的表发起Alter语句没有出现相同的错误。
本文主要分析一下定位问题的过程以及确定问题所在,也希望大家就该问题进行讨论提供更好的解决方案。 问题现象分析问题描述
Clickhouse版本:20.9.3.45
表结构: CREATE TABLE default.business_table ( createTime DateTime, appid int , totalCount bigint ) ENGINE = ReplicatedMergeTree("/clickhouse/tables/{shard}/business_table", "{replica}");
Alter语句以及响应的报错信息: alter table default.business_table delete where toYYYYMMDDHH(createTime) =2022012020 and appid=1; ERROR 999 (00000): Code: 999, e.displayText() = Coordination::Exception: Connection loss (version 20.9.3.45 (official build))问题定位
首先查看了一下clickhouse的错误日志,错误日志中有相关的堆栈信息 2022.02.10 11:17:51.706169 [ 34045 ] {} executeQuery: Code: 999, e.displayText() = Coordination::Exception: Connection loss (version 20.9.3.45 (official build)) (from 12 7.0.0.1:48554) (in query: alter table yylive_indicator.player_firstaccess_core_indicator_percentile delete where formatDateTime(_date_,"%Y%m%d%H")="2022012020" and time_type="1h "), Stack trace (when copying this message, always include the lines below): 0. Poco::Exception::Exception(std::__1::basic_string, std::__1::allocator > const&, int) @ 0x18e1b360 in /usr/bin/clickhouse 1. DB::Exception::Exception(std::__1::basic_string, std::__1::allocator > const&, int) @ 0xe736dad in /usr/bin/clickhouse 2. Coordination::Exception::Exception(Coordination::Error) @ 0x16887dad in /usr/bin/clickhouse 3. ? @ 0x168991b0 in /usr/bin/clickhouse 4. DB::EphemeralLocksInAllPartitions::EphemeralLocksInAllPartitions(std::__1::basic_string, std::__1::allocator > const&, std::__1::basic _string, std::__1::allocator > const&, std::__1::basic_string, std::__1::allocator > const&, zkut il::ZooKeeper&) @ 0x161dca16 in /usr/bin/clickhouse 5. DB::StorageReplicatedMergeTree::EphemeralLocksInAllPartitions(DB::MutationCommands const&, DB::Context const&) @ 0x1609c636 in /usr/bin/clickhouse 6. DB::InterpreterAlterQuery::execute() @ 0x15ab5126 in /usr/bin/clickhouse
再查看了一下zk的错误日志 2022-02-10 11:17:51,680 [myid:90] - WARN [NIOWorkerThread-30:NIOServerCnxn@373] - Close of session 0x5a02260902470005 java.io.IOException: Len error 1190892 at org.apache.zookeeper.server.NIOServerCnxn.readLength(NIOServerCnxn.java:541) at org.apache.zookeeper.server.NIOServerCnxn.doIO(NIOServerCnxn.java:332) at org.apache.zookeeper.server.NIOServerCnxnFactory$IOWorkRequest.doWork(NIOServerCnxnFactory.java:522) at org.apache.zookeeper.server.WorkerService$ScheduledWorkRequest.run(WorkerService.java:154) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
然后大致对比了一下系统的表的大小,目前出问题的表是最大的。 mysql> select count() from system.parts where table="business_table" and active =1 ; +---------+ | count() | +---------+ | 8108 | +---------+ 1 row in set (0.04 sec)
从上面可以看出表的数据分片很多。
分析ZK的日志发现,ZK认为客户端发送的消息格式不正确,从而主动断开了clickhouse的连接。从clickhouse的异常日志有可以看出正在执行zk操作时出现了连接断开的错误。
现在我们从代码层面去看看问题的根因,当clickhouse执行alter操作时,如果对应的mutation如果涉及到分片数据的变更时,就需要对分片进行锁定,而分片的锁定操作是在对应的分片对应的zk子目录下面创建一个临时节点,如下面代码所示: EphemeralLocksInAllPartitions::EphemeralLocksInAllPartitions( const String & block_numbers_path, const String & path_prefix, const String & temp_path, zkutil::ZooKeeper & zookeeper_) : zookeeper(&zookeeper_) { std::vector holders; while (true) { ...... Coordination::Requests lock_ops; // 这里没有 for (size_t i = 0; i < partitions.size(); ++i) { String partition_path_prefix = block_numbers_path + "/" + partitions[i] + "/" + path_prefix; lock_ops.push_back(zkutil::makeCreateRequest( partition_path_prefix, holders[i], zkutil::CreateMode::EphemeralSequential)); } lock_ops.push_back(zkutil::makeCheckRequest(block_numbers_path, partitions_stat.version)); Coordination::Responses lock_responses; // 问题出在这里 Coordination::Error rc = zookeeper->tryMulti(lock_ops, lock_responses); if (rc == Coordination::Error::ZBADVERSION) { LOG_TRACE(&Poco::Logger::get("EphemeralLocksInAllPartitions"), "Someone has inserted a block in a new partition while we were creating locks. Retry."); continue; } else if (rc != Coordination::Error::ZOK) throw Coordination::Exception(rc);
clickhouse在zk的访问中,采用了大量批量操作,在上面的分片锁定操作中,它针对所有影响到的分片的锁定批量一次性提交命令到zk中,而zk的传输使用了jute,jute缺省最大的包大小为1M,具体细节可以参考一下关于zookeeper写入数据超过1M大小的踩坑记。
这里clickhouse的问题在于它没有做分包,而是对所有影响的分片合并请求后,批量向zk发起请求,从而造成了超过zk最大的传输包大小,从而造成连接断开。
为什么这里需要一次性的批量提交呢?具体的原因有朋友了解的可以分享一下,我理解可能clickhouse需要做类似事务级别的保证。 问题解决
知道了问题的根因首先考虑到增加zk的jute缺省的最大包大小,zookeeper本身,我们可以在配置上实现。但是我们查看了一下clickhouse的zk配置相关参数,能够调整的主要是ip、port和会话时长,没有看到jute大小的控制参数,所以这条路基本上行不通,经过只修改zk的参数重启后,测试也发现不能成功。
控制Alter DELETE影响的数据范围,从原来的Alter语句来看我们已经制定了时间的范围,但是看起来Clickhouse不会主动根据条件来做分区裁剪。查看源码也发现没有这块逻辑,但是从最新的clickhouse的文档中,我们可以看到Delete语句支持分区操作。 ALTER TABLE [db.]table DELETE [IN PARTITION partition_id] WHERE filter_expr
但是这个语法在20.9.3.45版本中并没有得到支持,所以最后我们对clickhouse做了升级到21.X.X.X,并让业务方采用DELETE IN PARTITION,问题暂时得到解决。如果读者有更好的解决方案,希望留言探讨
Linux基础知识Linux基本认知容量大小bit(位)Byte(字节,8位)KB(210,千字节)MB(兆字节)GB(吉字节)TBGbit(吉比特)自动补全命令或文件(夹)TAB复用之前的命令上下
苹果硬件不如国产机?这是国产机编织的谎言,是对苹果的误解最近这几年,估计很多人都听过苹果硬件落后,不如国产机等这样的说法。甚至华为余承东曾经直接这样他们在硬件方面已经难与我们竞争,苹果目前缺乏产品硬件创新。而事实上,许多人也喜欢拿苹果的
PC市场迎来新变化荣耀正成为行业新星据第三方权威调研机构报告显示,截至2021年11月份,在中国轻薄本市场,联想华硕戴尔惠普等传统PC厂商市场份额出现较大波动以荣耀华为为首的新兴品牌,其市场份额合计超过20,正在不断
哥伦比亚大学教授大公司的法律套利圣诞购物季来临时,不管你是否拥有相关信仰,在每年这个时候几乎都无法抗拒购物和送礼的诱惑。不过最大的送礼者其实是非生命体我指的可不是人工智能,而是以常规企业形式存在的法人。各企业发放
全链条的未来教育变革随着网络技术人工智能等信息技术的迅速发展,人类社会正在发生巨大变化。生活方式变了,社会需求变了,知识传播渠道变了,我们的教育如何发展,这是教育人必须认真面对深入思考的问题。变革是教
被人说成疯子的投资家,他要建立300年屹立不倒的企业帝国孙正义何许人也,他是软银集团的总裁。他收购了ARM,投资过雅虎,阿里巴巴,还涉足了电力行业,被人评为鲁莽的投资家。他有着建立300年企业帝国的梦想,人们会觉得他是疯子。那他到底是个
因为科技导致的内卷和躺平虎年有娱正文我直接说核心观点吧,不然没人愿意看。科技上不去,我们就会在原有的阶级疯狂竞争,这就是我们说的内卷,等一定的阶级固化,我们发现无论如何竞争也很难,进行阶级跨越,大部分能力
小米12发布这么久了体验参数究竟怎样基本参数发布会时间2021年12月28日。上市日期2021年12月31日。机身材质黑色蓝色紫色金属中框,玻璃后壳原野绿金属中框,素皮后壳机身颜色紫色蓝色黑色原野绿指纹识别屏幕指纹识
新年好物选什么?首选华为智选720全效空气净化器2春节将至,各大厂商开始纷纷推出新年好物,为新年的年货做好充足的准备。这一次华为智选也没有落下,在华为智选720全效空气净化器的基础上全面升级的华为智选720全效空气净化器2也赶在新
iPhone15或全面采用自研基带,真的能够解决苹果的信号问题吗?尽管说,iPhone代表了手机行业非常高的水准,但是每一个iPhone用户都有一个苦衷,那就是iPhone的信号问题。在火车上电梯里,往往身边朋友的安卓手机都好好的,而自己的iPh
为什么有的手机要砍掉8128GB版本?内行人说出其中缘由观察今年手机行业的朋友应该发现了,有部分手机取消了128GB版本,起步就是256GB,促使手机厂商做出这一决定的原因是什么?难道128GB版本已经不够用了吗?还是大部分用户已经抛弃