ClickHouse集群在eBay事件监控平台的可用性和扩展性探索(4)
ClickHouse集群在eBay事件监控平台的可用性和扩展性探索

方案实现及改善
3.1 实现细节
为了在创建ClickHouse集群的时候可以支持Keeper,我们在FCHC的CRD里面引入了enableKeeper这个字段,当federated clickhouse operator在reconcile FCHC 时,如果检测到这个字段为true的话,它将会为ClickHouse server生成Keeper server启动需要的config文件,同时还可以在CRD里面override一些Keeper server特定的设置。
enableKeeper: true
keeperConfig:
coordinationSettings:
raft_logs_level: trace
keeperNodesCount: 3
tcpPort: 9181
对于那些Keeper server也需要同时启动的ClickHouse server, 额外的keeper server相关配置需要被添加进配置文件中。
<keeper_server>
<tcp_port>9181</tcp_port>
<server_id>190</server_id><
<log_storage_path>/var/lib/keeper/log</log_storage_path>
<snapshot_storage_path>/var/lib/keeper/snapshots</snapshot_storage_path>
<raft_configuration>
<server>
<id>190</id>
<hostname>host-38-0-0</hostname>
<port>9999</port>
</server>
<server>
<id>225</id>
<hostname>host-45-0-0</hostname>
<port>9999</port>
</server>
<server>
<id>470</id>
<hostname>host-94-0-0</hostname>
<port>9999</port>
</server>
</raft_configuration>
</keeper_server>
主要的ClickHouse Keeper相关配置都是位于<keeper_server> section中,具体的配置参数的意义可以参考ClickHouse Keeper.。Quorum的配置信息位于‘<keeper_server>.<raft_configuration>’中,其中描述了RAFT 集群servers的信息。Keeper根据此处的quorum server的定义彼此通信并创建一个NuRaft的一致性协调服务系统。
而对于某些没有Keeper server启动的ClickHouse replica, 它的配置就和其他任何一个依赖了第三方zk/keeper协调服务系统的server完全一样,只需要在<zookeeper>section下面配置好当前shard所使用的RAFT集群地址即可。
<zookeeper>
<node>
<host>host-38-0-0</host>
<port>9181</port>
</node>
<node>
<host>host-45-0-0</host>
<port>9181</port>
</node>
<node>
<host>host-94-0-0</host>
<port>9181</port>
</node>
</zookeeper>
3.2 测试及改进
在对keeper支持的测试过程中,遇到了许多实际的问题,而且又由于Keeper用来替换生产上已经非常稳定的ZooKeeper,功能测试和线上流量的测试都必不可少。
3.2.1 Ordinary database 创建失败
使用Keeper必须升级使用新版本ClickHouse,但是在测试过程中发现federated clickhouse operator在创建database时一直报错,创建失败。经过排查发现,在之前的版本,Ordinary类型的database是ClickHouse默认支持的数据库类型,operator当中也是显示指定数据库类型的。
而最新版本的ClickHouse,为了支持表的rename,将Atomic类型作为了默认数据库类型,并且默认deprecate掉Ordinary类型的数据库,如果需要继续支持Ordinary,需要显示在配置`
allow_deprecated_database_ordinary: “true”`中指定。
3.2.2 ClickHouse server 启动失败
实际上ClickHouse server有启动的过程,并且log显示Keeper server在不断的去和raft quorum中的其他server交互,但是一直处于timeout的状态。
查看之后发现问题出在我们使用开源的ClickHouse operator 来reconcile 当前kube cluster的CHI对象以创建出ClickHouse 集群,而默认情况下即使我们不指定readiness probe和liveness probe,operator会添加一个对ClichHouse 8123端口http检查的probes。但是ClickHouse server一直在等待连接RAFT cluster才能处于ready状态,RAFT要等server ready了才能够连接上彼此,因此陷入了一个死循环最终导致启动失败。
针对这个问题的解决方案是添加一个对config文件查看的readiness check,这样可以使得pod先处于ready状态,RAFT 集群可以先建立起来,最终启动成功。因为我们pod的rediness状态本身就是通过另外的service确认的,所以这个改动并不会影响我们的服务。
3.2.3 依次重启ClickHouse 集群节点时的
ip重用问题
在Keeper enable的集群启动之后,在集群里面做了一些常规的回归测试和故障恢复测试。依次重启对于ClickHouse升级或者应用某一项配置使其生效是一个非常常见的操作。但是在依次重启了一个Kube cluster里面的集群pod之后,会发现一个shard的pod会加入到另外一个shard的quorum中,而且这个问题几乎每次都可以复现。

上图中我们可以发现,在pod重启之后,zxid呈阶跃型上升,而原本同一个Quorum中的peer的 zxid还在原来的水平。经过debug发现,该pod已经加入了另外一个shard的quorum中。
由此我们发现,是一些原因共同作用导致了这种情况的发生。
在一些Kube cluster上,ip资源非常紧张。在批量删除了一些pod然后重建的过程,势必出现ip重用的问题,即原本shard0的pod的ip,在经过删除重建之后,成为了shard1的ip。
FQDN ip的resolve具有延时性,即quorum里面别的peer还在用老的ip在访问当前peer,然而老得ip已经是shard1的pod了,如果刚好shard1的pod的log_index小于shard0 leader的log_index, shard1就会更新自己的log_index并加入到shard0的quorum中。
目前来讲针对于这种情况并没有根本的解决方案,Tess team也没有固定ip的支持,因此ip重用在资源紧张的集群中是一定会发生的;而ip解析延迟只能通过annnotation尽量降低至分钟级别以内;因此只能通过阻止不同shard的peer加入到不同shard的quorum中解决,目前的方案是不同的shard的peer交互使用不同的端口,因此即使ip被重用了,因为端口不一致,shard1的pod永远加入不到shard0的quorum中。
3.2.4 某些shard的latency比较高
在ClickHouse 集群enable了Keeper之后,整体运行的很稳定。但是在region by region的依次重启集群pod之后,发现总有一到两个shard的latency相对其他的shard比较高。
经过研究发现,latency比较高的是所有的ClickHouse client都连到了同一个Keeper server上。
KeeperDispatcher::requestThread()
/// The code below do a very simple thing: batch all write (quorum) requests into vector until
/// previous write batch is not finished or max_batch size achieved. The main complexity goes from
/// the ability to process read requests without quorum (from local state). So when we are collecting
/// requests into
a batch we must check that the new request is not read request. Otherwise we have to
/// process all already accumulated write requests, wait them synchronously and only after that process
/// read request. So reads are some kind of "separator" for writes.
在ClickHouse Keeper的源代码我们可以看到,Keeper server会batch写请求,并且一次性执行以提高效率。但是当所有的client都连接到同一个server上时,几倍的读请求会将写请求batch分裂开执行,导致执行latency变高。
因此,为了使client连接到Keeper server分布均匀,在配置文件中的部分仅放置本地的Keeper server。
<zookeeper>
<node>
<host>localhost</host>
<port>9181</port>
</node>
</zookeeper>
该配置应用到ClickHouse集群中后,部分shard latency大的问题得到了解决。但是有时ClickHouse server重启会失败。
检查了CickHouse server的启动逻辑如下:
if <keeper_server> exists:
if < zookeeper> exists and connect successfully
start keeper async
else
wait for Keeper synchronously
KeeperDispatcher::initialize
if (!start_async)
{
server->waitInit();
LOG_DEBUG(log, "Quorum initialized");
}
void KeeperServer::waitInit()
{
std::unique_lock lock(initialized_mutex);
int64_t timeout = coordination_settings->startup_timeout.totalMilliseconds();
if (!initialized_cv.wait_for(lock, std::chrono::milliseconds(timeout), [&] { return initialized_flag.load(); }))
throw Exception(ErrorCodes::RAFT_ERROR, "Failed to wait RAFT initialization");
}
在上面的逻辑我们可以看到,Keeper server有一个等待初始化的过程,并且如果在一定的时间内不能完成初始化的工作,将会启动失败。而Keeper server的初始化工作包含snapshot快照的加载,以及应用log store里面的log commits到内部状态机。在log store的记录数比较大的情况下,将要花费大约2min完成初始化的工作,但默认情况下的等待初始化时间为30s,这是为什么有时候会出现启动失败的状况。
针对这种情况,可以增加startup启动的等待时间,同时在社区有另外一个相关的改善的PR,即在ClickHouse server退出的时候,打一份快照出来,这样在下一次启动的时候,只需要加载快照然后在leader server上同步缺失的log记录即可完成初始化,大大减少了等待时间。
3.3 Keeper在生产上的实践
目前对于ClickHouse支持Keeper的change已经部署到了生产上,并且新创建的集群都将Keeper作为数据同步默认的一致性协调系统。
而最初出现问题的OLAP集群也已经切换到了应用了Keeper的ClickHouse集群上,并且该集群已经成功enable了数据的读写分离。目前集群运行正常,数据写入的延迟和之前相比也更稳定。


总结与展望
为了保证Sherlock.io事件监控平台中ClickHouse集群的数据完整性和可用性,针对其读写分离方案提出被支持。对于任何非常重要的数据,如果有顾虑不想让读请求影响到数据的完整性,可以在ClickHouse集群上实施读写分离。
而对于ClickHouse 集群的横向扩展的集中式Zookeeper瓶颈问题,提出了在集群的shard水平上使用单独的基于Keeper的一致性协调系统来进行数据的同步。
目前Keeper的支持还仅限于replica数目大于等于3的集群,这是由RAFT集群的最小quorum数据决定的,但是Sherlock.io generic log也会使用ClickHouse作为后端存储,而对于log而言,2备份的可用性已经足够了,因此后面的调研方向将是在2备份情况下如何enable shard水平的Keeper。
以上是IT袋网网关于ClickHouse集群在eBay事件监控平台的可用性和扩展性探索的全文内容,IT袋网[www.itdai.com]希望对网友有所帮助!
相关阅读
-
笔记本nvidia显卡游戏最佳设置 教你n卡发挥最大性能
小编为你介绍笔记本nvidia显卡游戏最佳设置和教你n卡发挥最大性能的方法内容,接下来一起来看看吧。 众所周知,游戏和显卡可说是密不可分的,一款游戏的流畅度很大程度上取决于显卡和网
-
电脑显示cpu占用过高怎么办 电脑总是cpu占用过高怎么办
关于这方面的知识你知道吗?电脑显示cpu占用过高怎么办的电脑方面的小经验,关于电脑显示cpu占用过高怎么办 电脑总是cpu占用过高怎么办,相关内容具体如下: 不少的IT袋用户打开任务管理
-
如何切换电脑页面 怎么快速切换电脑页面
这些你了解吗?怎么快速切换电脑页面方面的经验,关于如何切换电脑页面 怎么快速切换电脑页面,一定能给您带来帮助的,一起来了解吧! 以Windows 10系统为例,快速切换电脑页面有4个步骤
-
cpu工作温度70左右正常吗 CPU温度70度正常吗详细介绍
跟大家分享CPU温度70度正常吗详细介绍的话题,关于cpu工作温度70左右正常吗 CPU温度70度正常吗详细介绍,继续往下看吧! 多数IT袋网友都会在电脑上给自己的硬件进行测量,大部分的CPU温度都


