解决 ClickHouse 高可用集群中 VRID 冲突问题:基于 chproxy 和 keepalived 的实践分析

Part1背景描述

近期,我们部署了两套 ClickHouse 生产集群,分别位于同城的两个数据中心。这两套集群的数据保持一致,以便在一个数据中心发生故障时,能够迅速切换应用至另一个数据中心的 ClickHouse 实例,确保服务连续性。

这两套 ClickHouse 集群采用高可用架构,由两台 ClickHouse 和三台 ZooKeeper 组成,前端通过两台服务器部署了 chproxy 与 keepalived,采用主备模式。当主节点发生异常时,VIP(虚拟 IP 地址)可以快速漂移至备份节点,继续对外提供服务。

这两套同城数据中心的 ClickHouse 集群的 chproxy + keepalived 配置基本相同,除了虚拟 IP 地址(virtual_ipaddress)和虚拟路由器 ID(virtual_router_id)不同。

keepalived.conf 配置文件内容如下:

! Configuration File for keepalivedglobal_defs {notification_email {xxxx@xxxx.com}notification_email_from xxxx@xxxx.comsmtp_server 192.168.xxx.xxxsmtp_connect_timeout 30router_id Chproxy_Router_Id
}vrrp_script chk_http_port {script "/opt/check_chprpoxy.sh"interval 40weight 20
}vrrp_instance VI_1 {state MASTER interface ens192virtual_router_id xxxpriority 110advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_http_port}virtual_ipaddress {192.168.xxx.xxx}notify_master "/opt/keepalived_notify.sh"}

chproxy和keepalived 服务启动后,virtual_ipaddress 会漂移到其中一个节点,如下所示。

图片

昨日巡检发现其中一个机房的 chproxy-keepalived 的集群 /var/log/messages  产生大量如下信息。

[root@xxx-xxx-chproxy-keepalive-xxx ~]# tail -1f /var/log/messages
Oct 16 16:38:09 localhost Keepalived_vrrp[3712]: VRRP_Instance(VI_1) Dropping received VRRP packet...
Oct 16 16:38:16 localhost Keepalived_vrrp[3712]: (VI_1): ip address associated with VRID 53 not present in MASTER advert : 192.168.xxx.xxx
Oct 16 16:38:16 localhost Keepalived_vrrp[3712]: bogus VRRP packet received on ens33 !!!
Oct 16 16:38:16 localhost Keepalived_vrrp[3712]: VRRP_Instance(VI_1) Dropping received VRRP packet...
Oct 16 16:38:17 localhost Keepalived_vrrp[3712]: (VI_1): ip address associated with VRID 53 not present in MASTER advert : 192.168.xxx.xxx
Oct 16 16:38:17 localhost Keepalived_vrrp[3712]: bogus VRRP packet received on ens33 !!!
Oct 16 16:38:17 localhost Keepalived_vrrp[3712]: VRRP_Instance(VI_1) Dropping received VRRP packet...
Oct 16 16:38:20 localhost Keepalived_vrrp[3712]: (VI_1): ip address associated with VRID 53 not present in MASTER advert : 192.168.xxx.xxx

上面的日志信息里,192.168.xxx.xxx 是 virtual_ipaddress 地址信息, VRID 53 是 该 集群 virtual_router_id 的信息。

/var/log/messages 日志文件里上述信息刷新频率很高。

Party2 分析过程

通过上面的日志,可以看到 /var/log/messages 日志里反复出现如下三段内容:

localhost Keepalived_vrrp[3712]: (VI_1): ip address associated with VRID 53 not present in MASTER advert : 192.168.4.199
localhost Keepalived_vrrp[3712]: bogus VRRP packet received on ens33 !!!
localhost Keepalived_vrrp[3712]: VRRP_Instance(VI_1) Dropping received VRRP packet...

2.1 日志信息含义

上面这些信息代表什么意思呢,我查询了相关资料,对上面的文字内容解释如下:

1) Keepalived_vrrp[3712]: (VI_1): ip address associated with VRID 53 not present in MASTER advert : 192.168.xxx.xxx

  • 这条日志表示 Keepalived 的 VRRP 实例 VI_1 收到了与 VRID 53 相关的广告包,但在这个广告包中并没有找到指定的虚拟 IP 地址 ( 192.168.xxx.xxx)。

  • 可能意味着:

    这通常是主节点发送的广告包与当前节点的配置不一致所导致的。

    • 广告包中的虚拟 IP 配置与当前节点期望的配置不匹配,可能是由于配置不一致。

    • 有其他节点错误地发送了与 VRID 53 相关的广告包,且该广告包中并未包含 192.168.xxx.xxx。

2) Keepalived_vrrp[3712]: bogus VRRP packet received on ens33 !!!:

  • 这条日志表示在网络接口 ens33 上接收到了一个“伪造的” VRRP 包。也就是说,这个 VRRP 包不符合节点对其所在集群的期望。

  • 这种情况可能是由于:

    • 网络中有其他设备错误地发送了 VRRP 广告包。

    • 主备节点之间的配置不一致,导致某个节点发送了无效或不可识别的 VRRP 广告包。

3)Keepalived_vrrp[3712]: VRRP_Instance(VI_1) Dropping received VRRP packet...:

  • 这条日志表示 Keepalived 丢弃了收到的 VRRP 包,因为它认为这些包是无效的或伪造的。

  • 由于接收到的 VRRP 包与期望不一致,因此将其丢弃以避免不正确的状态切换。

2.3 问题排查

针对以上可能存在的原因分析,目前极有可能是 网络中存在其他与 VRID 53 冲突的设备这条比较符合,那该如何排查分析原因,通过查询资料,显示可以使用 tcdump 命令来检测网络中的 VRRP 广播包,查看是否有冲突的 VRID 。

小贴士

-- tcpdump 是一个网络抓包工具,用于在指定的网络接口上捕获网络数据包并分析。tcpdump -nn 的作用是让 tcpdump 直接显示 IP 地址和端口号,避免 DNS 查询和服务名解析。 -nn 是 tcpdump 的常用选项之一,具体用法和含义如下:-n:这个选项告诉 tcpdump 不解析主机名,直接显示 IP 地址,而不是将 IP 地址解析为主机名。这样可以提高性能,因为省去了 DNS 查询的过程。
例如,显示 192.168.1.1 而不是通过 DNS 查询显示类似 server.example.com。-nn:当两个 n 连续使用时,除了不解析主机名外,还不解析端口号。这样 tcpdump 会直接显示端口号,而不是显示对应的服务名称。
例如,显示 192.168.1.1:80 而不是 192.168.1.1:http,显示 443 而不是 https。-- 实例
# 捕获所有流量
tcpdump -nn# 捕获特定接口的流量
tcpdump -nn -i ens33# 捕获特定主机的流量
tcpdump -nn host 192.168.1.100# 捕获特定端口的流量
tcpdump -nn port 80# 捕获 VRRP 流量
tcpdump -nn -i any net 224.0.0.0/8 | grep "VRRP"

此处采用 tcpdump 来捕获 VRRP 流量,通过使用 tcpdump 使用捕获 VRRP 流量的命令,得到的信息如下。

[root@xxx-xxx-chproxy-keepalive-xxx ~]# tcpdump -nn -i any net 224.0.0.0/8
-- 得到的信息如下
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
16:33:07.480496 IP 192.168.xxx.63 > 224.0.0.18: VRRPv2, Advertisement, vrid 184, prio 102, authtype none, intvl 1s, length 20
16:33:07.519685 IP 192.168.xxx.35 > 224.0.0.18: VRRPv2, Advertisement, vrid 76, prio 100, authtype simple, intvl 1s, length 20
16:33:07.538291 IP 192.168.xxx.116 > 224.0.0.18: VRRPv2, Advertisement, vrid 118, prio 100, authtype simple, intvl 1s, length 20
16:33:07.545689 IP 192.168.xxx.10 > 224.0.0.18: VRRPv2, Advertisement, vrid 181, prio 102, authtype none, intvl 1s, length 20
...... 省略其它信息-- 解释如下
此处以 16:33:07.480496 IP 192.168.xxx.63 > 224.0.0.18: VRRPv2, Advertisement, vrid 184, prio 102, authtype none, intvl 1s, length 20 为例来进行解释1) 16:33:07.480496: 时间戳,表示捕获到此数据包的时间2) IP 192.168.xxx.63 > 224.0.0.18:192.168.xxx.63:源 IP 地址,这个数据包是从 IP 地址 192.168.xxx.63 发送的。224.0.0.18:目标 IP 地址,这是一个组播地址,专用于 VRRP 的多播。224.0.0.18 被所有 VRRP 参与设备用于接收 VRRP 广告包。3) VRRPv2, Advertisement:表示该数据包是一个 VRRP 第 2 版(VRRPv2)的广告包(Advertisement)。VRRP 广告包由主节点发送,用于告知备节点主节点的状态,以便实现高可用。4) vrid 184:vrid 表示 VRRP 实例的虚拟路由器 ID。这是一个唯一的标识符,用于标识特定的 VRRP 组。在这一行中,vrid 的值是 184。不同的 VRID 对应不同的虚拟路由器,可以让多组 VRRP 实例在同一网络中运行而不会互相干扰。5) prio 102:prio 表示 VRRP 广告包中的优先级。优先级越高,表示该节点越有可能成为主节点(MASTER)。在这一行中,优先级 (priority) 是 102。通常,主节点会配置一个较高的优先级,以确保自己能够保持主节点地位。6) authtype none / authtype simple:authtype 表示 VRRP 包的认证类型:none:没有认证。simple:使用简单的明文密码认证。在 VRRP 中,认证可以用来防止未经授权的节点加入 VRRP 组。7) intvl 1s:intvl 表示 VRRP 广告包的发送时间间隔,这里是 1 秒。这意味着该节点每隔 1 秒发送一个广告包,以告知其他节点其状态。通常情况下,VRRP 主节点会周期性发送广告包,以确保备节点知道主节点的健康状况。8)length 20:length 表示数据包的长度(单位为字节)。在这一行中,VRRP 广告包的长度是 20 字节。

图片

通过上面的命令可以查看到当前都有些哪些 IP及其对应的 vrid,由于信息太多,显然不利于查找当前 chproxy-keepalived 集群的  vrid 53 是否有冲突,我们可以使用 grep 进行过滤,如下所示。

[root@xxx-xxx-chproxy-keepalive-xxx ~]# tcpdump -nn -i any net 224.0.0.0/8 | grep "vrid 53"
-- 得到的信息如下
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
13:40:27.104788 IP 192.168.xxx.51 > 224.0.0.18: VRRPv2, Advertisement, vrid 53, prio 102, authtype simple, intvl 1s, length 20
13:40:28.105340 IP 192.168.xxx.51 > 224.0.0.18: VRRPv2, Advertisement, vrid 53, prio 102, authtype simple, intvl 1s, length 20
13:40:29.106068 IP 192.168.xxx.51 > 224.0.0.18: VRRPv2, Advertisement, vrid 53, prio 102, authtype simple, intvl 1s, length 2013:40:30.106548 IP 192.168.xxx.51 > 224.0.0.18: VRRPv2, Advertisement, vrid 53, prio 102, authtype simple, intvl 1s, length 20

图片

通过上述命令信息,可以看到当前 chproxy-keepalived 集群的 vrid 已经被其它环境在使用,和当前这套集群有冲突。

2.4 解决办法

根据上面的分析,我们已经找到了问题根源,接下来就是如何调整,我将这套 chproxy-keepalived 主备节点的

vrid 进行调整,并通过 tcpdump -nn -i any net 224.0.0.0/8 | grep "vrid xxx", 查找哪个 vrid 未被占用,如下所示:

[root@xxx-xxx-chproxy-keepalive-xxx ~]# tcpdump -nn -i any net 224.0.0.0/8 | grep "vrid 59"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes

图片

比如,测试发现 vrid 59 没有被占用,于是我将 vrid 59 分别修改写入到  /etc/keepalived/keepalived.conf 文件,如下所示:

-- MASTER 节点 信息如下! Configuration File for keepalivedglobal_defs {notification_email {xxx@xxx.com}notification_email_from xxx@xxx.comsmtp_server 192.168.xxx.xxxsmtp_connect_timeout 30router_id Chproxy_Router_Id
}vrrp_script chk_http_port {script "/opt/check_chprpoxy.sh"interval 40weight 20
}vrrp_instance VI_1 {state MASTER interface ens33virtual_router_id 59priority 110advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_http_port}virtual_ipaddress {192.168.xxx.xxx}notify_master "/opt/keepalived_notify.sh"}-- BACKUP 节点信息如下
! Configuration File for keepalivedglobal_defs {notification_email {xxx@xxx.com}notification_email_from xxx@xxx.comsmtp_server 192.168.xxx.xxxsmtp_connect_timeout 30router_id Chproxy_Router_Id
}vrrp_script chk_http_port {script "/opt/check_chprpoxy.sh"interval 40weight 20
}vrrp_instance VI_1 {state BACKUP interface ens33virtual_router_id 59 priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_http_port}virtual_ipaddress {192.168.xxx.xxx}notify_master "/opt/keepalived_notify.sh"}

为了减少对应用的影响,我首先通过 ip addr 命令查看当前 VIP 漂移到哪个节点。当发现 VIP 位于 MASTER 节点时,我选择对 BACKUP 节点的 keepalived 服务进行重启。

# systemctl restart keepalived

重启后,再次检查 /var/log/messages,确认未再出现 VRID 被占用的相关信息。

随后,我们与应用团队协商,选择在业务低峰期对 MASTER 节点的 keepalived 也进行了重启,确认未再观察到 VRID 冲突的问题。

图片

三、总结

这次问题的根源在于 VRID 冲突,导致主备节点的 VRRP 包不匹配。通过使用 tcpdump 工具排查问题并调整配置,我们成功解决了该问题。这一过程再次证明了配置一致性和唯一性的重要性,以及 tcpdump 在网络排查中的有效性。在高可用架构的设计和实现中,保持配置的唯一性是至关重要的,这不仅能够避免集群间的资源冲突,还能保证系统在故障时的可靠性和可用性。

对于类似的高可用集群环境,严格遵循配置管理规范、保证参数的唯一性和正确性是避免故障的关键。此次排查和解决的过程也突显了掌握网络抓包工具的重要性,这些工具在复杂网络环境下的故障分析中发挥着不可或缺的作用。通过这些手段,我们不仅解决了当前的问题,也为未来可能遇到的类似问题积累了宝贵的经验,从而进一步提升了系统的稳定性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/464218.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案

在数字化转型的浪潮中,企业对于数据传输的需求日益增加,特别是在不同网络环境之间的文件共享和传输。为了满足这一需求,FileLink数据跨网摆渡系统应运而生,为企业提供了一种安全、高效的数据传输解决方案。 安全第一,保…

力扣排序350题 两个元组的交集2

题目: 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两 数组的交集。返回结果中每个元素出现的次数,应与元素在两个 数组中都出现的次数一致(如果出现次数不一致,则考虑取 较小值)。可以不考虑输出…

Python酷库之旅-第三方库Pandas(193)

目录 一、用法精讲 896、pandas.Index.isna方法 896-1、语法 896-2、参数 896-3、功能 896-4、返回值 896-5、说明 896-6、用法 896-6-1、数据准备 896-6-2、代码示例 896-6-3、结果输出 897、pandas.Index.notna方法 897-1、语法 897-2、参数 897-3、功能 897…

使用Mac如何才能提高OCR与翻译的效率

OCR与截图大家都不陌生,或许有的朋友对于这两项功能用到的不多,但是如果经常会用到的话,那你就该看看了 iOCR,快捷键唤出翻译窗口,不论是截图翻译、划词翻译、输入翻译、剪切板翻译,统统快捷键完成&#x…

《欢乐饭米粒儿9》第五期:用笑声诠释生活,让爱成为日常

在忙碌的生活节奏中,我们总是在寻找那份能够触动心灵深处的温暖与欢笑。由鲜博士独家冠名播出的独创小品剧《欢乐饭米粒儿》第九季作为一档家庭喜剧节目,正是这样一股清流,它以轻松幽默的方式,将家的温暖、爱的传递和生活的真谛娓…

基于人脸识别PCA算法matlab实现及详细步骤讲解

人脸识别 % FaceRec.m % PCA 人脸识别修订版,识别率88% % calc xmean,sigma and its eigen decomposition allsamples[];%所有训练图像 for i1:40 for j1:5 aimread(strcat(e:\ORL\s,num2str(i),\,num2str(j),.jpg)); % imshow(a); ba(1:112*92…

C#的Event事件示例小白级剖析

1、委托Delegate 首先说一下delegate委托,委托是将方法作为参数进行传递。 // 定义了一个委托类型public delegate void MyDelegate(int num);// 定义了一个啥也不干的委托实例public MyDelegate m_delegate _ > {};// 定义了一个和委托相同格式的方法public …

Android 使用ninja加速编译的方法

ninja的简介 随着Android版本的更迭,makefile体系逐渐增多,导致make单编模块的时间越来越长,每次都需要半个小时甚至更长时间,其原因为每次make都会重新加载所有mk文件,再生成ninja编译,此完整过程十分耗时…

VSCode 1.82之后的vscode server离线安装

概述 因为今天在公司开发项目的时候,需要离线配置vscode远程开发环境, 根据参考链接1配置了一遍,不管怎么重启,VSCODE都还是提示下载vscode server,后面在官方issue上找到了解决方案 解决方案 修改Remote SSH的配置…

什么是 OpenTelemetry?

OpenTelemetry 定义 OpenTelemetry (OTel) 是一个开源可观测性框架,允许开发团队以单一、统一的格式生成、处理和传输遥测数据(telemetry data)。它由云原生计算基金会 (CNCF) 开发,旨在提供标准化协议和工具,用于收集…

缓存、注解、分页

一.缓存 作用:应用查询上,内存中的块区域。 缓存查询结果,减少与数据库的交互,从而提高运行效率。 1.SqlSession 缓存 1. 又称为一级缓存,mybatis自动开启。 2. 作用范围:同一…

AI打造超写实虚拟人物:是科技奇迹还是伦理挑战?

内容概要 在这个科技飞速发展的时代,超写实虚拟人物仿佛从科幻小说中走进了我们的日常生活。它们以生动的形象和细腻的动作,不仅在影视、广告和游戏中吸引了无数目光,更让我们对AI技术的未来充满了期待和疑惑。这些数字化身在逼真的外貌下&a…

CODESYS可视化星三角降压启动程序控制电气动画图

#一个用CODESYS可视化做的星三角降压启动程序控制电气动画图# 前言: 关于星三角降压启动控制,作为电气行业入门的必备知识点,涉及到电机本身特性导致的电压,电流(转矩),功率和转速等一系列的关系和变化,以及星型和三角形的绕组方式。本篇我们使用CODESYS结合程序和可视…

物联网赋能的人工智能图像检测系统

一、引言 在数字化时代,物联网(IoT)技术已经成为我们生活中不可或缺的一部分,极大地优化了我们的交通出行和医疗服务。物联网的核心优势在于其卓越的连接能力,它能够构建和连接庞大的资源数据库,为智能化图…

软件架构演变:从单体架构到LLM链式调用

0 前言 软件架构——我们数字世界的蓝图——自20世纪中叶计算机时代诞生以来,已经发生了巨大演变。 20世纪60年代和70年代早期,以大型主机和单体软件为主导。而今天,数字领域已完全不同,运行在由云计算、API连接、AI算法、微服务…

Claude 3.5 Sonnet模型新增了PDF支持功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

【每日一题】LeetCode - 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例 示…

基于 Canal + Elasticsearch 的业务操作日志解决方案

一、问题来源 在日常的业务系统中,操作日志是不可或缺的一部分。它能帮助我们追踪用户的操作行为,记录关键数据的变更,甚至在必要时支持操作回滚。最近,我们接到客户的需求,希望在系统中实现一个业务操作日志管理的功能…

Python并发编程库:Asyncio的异步编程实战

Python并发编程库:Asyncio的异步编程实战 在现代应用中,并发和高效的I/O处理是影响系统性能的关键因素之一。Python的asyncio库是专为异步编程设计的模块,提供了一种更加高效、易读的并发编程方式,适用于处理大量的I/O密集型任务…

【Vue项目1】第一篇

Vue项目1学习第一篇 01. 环境配置介绍和项目搭建02. Router路由配置引入03. ElementPlus引入和按需加载04. layout布局和菜单aside组件创建05. aside样式问题和treeMenu组件拆分06. treeMenu组件递归实现 01. 环境配置介绍和项目搭建 (1)安装node.js …