OceanBase 4.X-2F1A 仲裁高可用方案初探

news2024/11/20 18:23:30

作者:郑增权,爱可生 DBA 团队成员,OceanBase 和 MySQL 数据库技术爱好者。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1500 字,预计阅读需要 5 分钟。

背景

对于分布式数据库来说,当多个数据副本间发生半数异常时(一半副本故障或与另一半网络隔离),可以通过集群之外的仲裁服务来参与变更决策(选主/成员组变更),进而恢复服务。OceanBase 数据库 V4.1.0 版本开始支持 仲裁服务(Arbitratrion Service)。

某客户基于节约成本的想法,欲使用 OceanBase 仲裁服务功能,架构副本类型如下:

  • 集群架构:1-1-1
  • 副本类型为:2F1A(2 个全能型副本 + 1 个仲裁服务节点)

存在的疑虑:

  • 1 个全能型副本(Leader)发生故障后租户能否正常读写?
  • 2 个全能型副本发生可恢复的故障,均触发永久下线,后续启动 OBServer 后集群能否恢复正常?

本文基于如上 2 个问题展开实验,记录相关过程和结果,为类似需求评估提供参考。

相关术语

OceanBase 数据库仲裁服务

OceanBase 数据库仲裁服务(Arbitratrion Service)是一种基于 Paxos 多副本容灾方案提出的新型高可用方案

仲裁服务独立于 OceanBase 集群部署,是一个以特殊模式启动的轻量级 observer 进程,它承载着日志流级别的仲裁成员。

仲裁成员具备如下特征:

  • 仅参与选举、成员变更投票,不参与日志同步投票。
  • 不存储日志,无 MemTable 和 SStable,资源开销极小。
  • 不能当选为主提供服务。

当半数全功能副本故障导致日志同步失败并且达到日志流降级控制时间时,仲裁服务会自动执行日志流降级流程,将故障副本从成员列表中剔除,从而恢复服务,且能做到 RPO = 0。待故障的全功能副本恢复时,仲裁服务又会执行日志流升级流程,将被降级的副本重新加入成员列表,提供更高的可用性保证。

日志流

OceanBase 数据库参考传统数据库分区表的概念,把一张表格的数据划分成不同的分区(Partition)。在 V4.0.0 版本,分区是用户创建的逻辑对象,是划分和管理表数据的一种机制。

每个分区都有其对应的数据存储对象,称之为分片(Tablet),它具备存储数据的能力,支持在机器之间迁移(transfer),是数据均衡的最小单位。

日志流是由 OceanBase 数据库自动创建和管理的实体,它代表了一批数据的集合,包括若干 Tablet 和有序的 Redo 日志流。它通过 Paxos 协议实现了多副本日志同步,保证副本间数据的一致性,实现了数据的高可用。

日志流降级

日志流 Leader 上运行的仲裁服务发现一些副本在 arbitration_timeout(默认值为 5s)内没有向 Leader 回复日志确认消息,仲裁服务将执行进一步检查,准备对日志不同步的副本进行日志流降级操作。

仲裁服务通过周期性探测,检查日志不同步的副本是否存在降级策略中所列的异常,如果存在异常,则执行日志流降级操作。

注意: 仅当故障副本(包括已降级的副本)总数等于全功能副本总数的一半时,仲裁服务才会执行日志流降级操作。例如,4F1A 部署场景下:

  • 如果只有 1 个 F 副本出现异常,仲裁服务不会执行日志流降级,因为此时 4F 的多数派 3F 依然存活,可以正常同步日志。
  • 如果有 2 个 F 副本出现异常(例如:2 个 F 副本网络中断,或者一个 F 副本 Rebuild,一个 F 副本所在 Server 宕机),仲裁服务会执行日志流降级。
  • 如果有 3 个及以上 F 副本出现异常,此时仅存活一个 F 副本和仲裁服务,不满足多数派,日志流将会无主,无法执行日志流降级。

环境信息

  • CentOS Linux release 7.5.1804 (Core)
  • OCP 云平台:4.2.0
  • OceanBase:4.2.1.4
  • 测试租户:mysql_ob
  • 租户模式:MySQL
  • 租户规格:1.5C6G

实验过程

故障前

  1. 查看 mysql_ob 租户日志流,可以看到有 3 个日志流。
select tenant_id,ls_id from oceanbase.CDB_OB_TABLET_TO_LS where tenant_id = 1002 group by LS_ID;

  1. 查看集群普通副本节点状态。

    SELECT * FROM oceanbase.DBA_OB_SERVERS;

  2. 查看业务租户 mysql_obleader/follower 角色信息。

  • 161 节点为 leader
  • 163 节点为 follower
    select b.tenant_name,a.tenant_id,a.ls_id,a.zone,a.svr_ip,a.role from cdb_ob_table_locations  a join __all_tenant b on a.tenant_id = b.tenant_id where a.tenant_id = 1002 group by role;

  1. 查看仲裁服务节点
  • 164 节点为仲裁服务节点
    select * from DBA_OB_ARBITRATION_SERVICE;
  1. 租户 mysql_ob 为 2F1A 架构(2F:10.186.64.161/163 , 1A:10.186.64.164)。
  1. 查看仲裁节点与其他节点联通性。
  • ACTIVE: 表示仲裁服务与该节点通信正常。所有节点均通信正常才可以为租户开启仲裁服务。
  • INACTIVE: 表示仲裁服务与该节点无法通信。无法为租户开启仲裁服务,需要排查节点与仲裁服务之间的网络通信情况。
SELECT * FROM oceanbase.GV$OB_ARBITRATION_SERVICE_STATUS;

  1. 查看租户的仲裁服务状态
  • ENABLED: 表示租户已开启仲裁服务。
  • DISABLED: 表示租户已关闭仲裁服务。
  • ENABLING: 表示租户正在开启仲裁服务。
  • DISABLING: 表示租户正在关闭仲裁服务。
select TENANT_ID,TENANT_NAME,PRIMARY_ZONE,STATUS,TENANT_ROLE,SWITCHOVER_STATUS,ARBITRATION_SERVICE_STATUS from DBA_OB_TENANTS;

  1. 查看永久下线时间参数。

    show parameters like 'server_permanent_offline_time';

  2. 永久下线时间调整为 60s。

    ALTER SYSTEM SET server_permanent_offline_time='60s';
    show parameters like 'server_permanent_offline_time';

  1. 启动脚本,持续往 evan.time_table 表写入数据。

  1. 启动另一个脚本,持续 select evan.time_table 表的最新数据。

4.2 施加故障

模拟故障:kill 掉第 1 个全能型副本

业务租户 leader 节点执行。

ps -ef | grep observer | grep -v "grep"
date && kill -9 $(ps aux | grep "observer" | grep -v "grep" | awk '{print $2}') && ps -ef | grep observer | grep -v grep && date

4.3 故障后观察

  1. 查看脚本写入状态是否正常。

  1. 查看脚本 select 是否正常。

  1. 查看业务租户 leader/follower 角色信息。

  1. 确认触发日志流降级。

当故障副本(包括已降级的副本)总数等于全功能副本总数的一半时,仲裁服务才会执行日志流降级操作。

SELECT * FROM oceanbase.DBA_OB_SERVER_EVENT_HISTORY WHERE EVENT LIKE "%DEGRADE%" AND VALUE1 = 1002 AND TIMESTAMP >= '2024-05-06 15:53%' ORDER BY 1 ;

  1. 确认节点状态变成 INACTIVE

    SELECT * FROM oceanbase.DBA_OB_SERVERS;

  2. 查看仲裁节点与其他节点联通性。

无法与 161 节点联通。

SELECT * FROM oceanbase.GV$OB_ARBITRATION_SERVICE_STATUS;

  1. 确认旧 leader 161 节点触发永久下线(预期 60s 后永久下线)。
select * from __all_rootservice_event_history where event='permanent_offline' and gmt_create like '2024-05-06%' \G

  1. 查询 kill 掉第 1 个 observer 时间点前后,业务表 time_table 实际是否有数据插入失败。
select * from evan.time_table where time >= '2024-05-06 15:53:37' order by time limit 20;

施加故障

故障模拟:kill 掉第 2 个全能型副本。

  1. 业务租户 follower 节点执行。
ps -ef | grep observer | grep -v "grep"
date && kill -9 $(ps aux | grep "observer" | grep -v "grep" | awk '{print $2}') && ps -ef | grep observer | grep -v grep && date

故障后观察

  1. 查看脚本 insert 数据是否正常。

处于异常状态。

  1. 查看脚本 select 数据是否正常。

处于异常状态。

  1. 查看业务租户 leader/follower 角色信息。

无主状态,执行 SQL 超时。

select b.tenant_name,a.tenant_id,a.ls_id,a.zone,a.svr_ip,a.role from cdb_ob_table_locations  a join __all_tenant b on a.tenant_id = b.tenant_id where a.tenant_id = 1002 group by role;

  1. 确认日志流降级。
    SELECT * FROM oceanbase.DBA_OB_SERVER_EVENT_HISTORY WHERE EVENT LIKE "%DEGRADE%" AND VALUE1 = 1002 AND TIMESTAMP >= '2024-05-06 16%' ORDER BY 1 ;

  1. 确认节点状态变成 INACTIVE
    SELECT * FROM oceanbase.DBA_OB_SERVERS;

  1. 查看仲裁节点与其他节点联通性。

161 和 163 节点均无法联通。

  1. 确认节点触发永久下线(预期 60s 后永久下线)。

161 和 163 节点均被标记永久下线。

select * from __all_rootservice_event_history where event='permanent_offline' and gmt_create like '2024-05-06%' \G

  1. 查询 kill 掉第 2 个 observer 时间点前后,业务表 time_table 实际是否有数据插入失败。

租户故障期间无法查询,恢复正常后补图。

select * from evan.time_table where time >= '2024-05-06 16:04:25' order by time limit 20;

  1. 确认租户处于无主状态。
  • 查看最近 30 分钟是否有原主租约过期的情况。

161 和 163 节点均存在租约过期记录。

SELECT * FROM __all_rootservice_event_history WHERE module = 'server' AND event = 'lease_expire' AND gmt_create > usec_to_time(time_to_usec(now())-3600*1000000) ORDER BY gmt_create;

  • 在 observer 全能型副本的主机上确认日志打印信息存在 4038 错误码。

cd /home/admin/oceanbase/log && grep "ret=-4038" observer.log

修复故障

  1. 辨别启动 OBServer 节点的先后顺序。

由于此时租户已经不满足多数派,处于故障状态,我们应该先启动故障时间较晚的 OBServer 节点,再启动故障时间较早的 OBServer 节点。(通过 observer.log 最后写入的时间点做判断)

tail -1 /home/admin/oceanbase/log/observer.log

  1. 启动 163 节点。

根据上一步骤判断 163 节点 observer.log 较新。

su - admin
cd /home/admin/oceanbase
date && ./bin/observer
ps -ef | grep observer | grep -v "grep"

  1. 确认 insert 脚本状态。

16:24:56 写入数据成功。

  1. 确认 select 脚本状态。

16:24:55 读取数据成功(脚本打印时间每隔1秒打印一次,存在细微误差属正常情况)。

  1. 确认 163 节点状态变成 ACTIVE
SELECT * FROM oceanbase.DBA_OB_SERVERS;

  1. 启动 161 节点。

根据之前的步骤判断 161 节点 observer.log 较旧,后启动。

su - admin
cd /home/admin/oceanbase
date && ./bin/observer
ps -ef | grep observer | grep -v "grep"

确认 161 节点 OBServer 状态变成 ACTIVE。

SELECT * FROM oceanbase.DBA_OB_SERVERS;

  1. 确认 insert 脚本状态。

正常写入。

  1. 确认 select 脚本状态。

正常读取。

  1. 通过 oceanbase.DBA_OB_UNIT_JOBS 视图查看数据补全进度。

如果查询结果为空,则表示 Unit 迁移完成,数据补全成功。

SELECT * FROM oceanbase.DBA_OB_UNIT_JOBS WHERE JOB_TYPE = 'MIGRATE_UNIT';

  1. 查看测试表 time_tabletenant_idls_id(日志流 ID)。

    SELECT TENANT_ID, LS_ID FROM oceanbase.CDB_OB_TABLET_TO_LS WHERE TABLET_ID = (SELECT DATA_OBJECT_ID FROM oceanbase.CDB_OBJECTS WHERE OBJECT_NAME ='time_table' AND OBJECT_TYPE='TABLE');

  2. 查看测试表 time_table 对应日志流的选举记录。

lease_time:当 Root Service 累计超过 lease_time 时间没有收到过某节点的任意心跳数据包时,Root Service 认为该 observer 进程短暂断线,Root Service 会标记该节点的心跳状为 lease_expired。

SELECT * FROM DBA_OB_SERVER_EVENT_HISTORY WHERE MODULE LIKE '%ELECTION%' and TIMESTAMP >= '2024-05-06 15:53:37' AND NAME1 = 'TENANT_ID' AND VALUE1 = '1002' AND NAME2 = 'LS_ID' AND VALUE2 =1001 ORDER BY TIMESTAMP;

  1. 永久下线时间改回原值并确认生效。
ALTER SYSTEM SET server_permanent_offline_time='3600s';
show parameters like 'server_permanent_offline_time';

时间线梳理

时间线

  1. 将永久下线时间参数 server_permanent_offline_time 调成 60s
  2. 2024-05-06 15:53:39 kill 掉 161 节点全能型副本节点(leader)
  3. 2024-05-06 15:53:39 ~ 15:53:43 约持续 5s,insert 脚本未写入数据,select 脚本未读到数据
  4. leader 节点由 161 切至 163
  5. 2024-05-06 15:53:43 161节点触发日志流降级,原因:CRASHED_OR_BROKEN_NETWORK
  6. 2024-05-06 15:54:39 161 节点被标记永久下线
  7. 2024-05-06 16:04:28 kill 掉 163 节点全能型副本节点(新 leader)
  8. 2024-05-06 16:04:28 租户开始进入读写异常状态
  9. 确认两个全能型副本状态都为:INACTIVE
  10. 仲裁服务节点与 2 个异常节点联通异常
  11. 2024-05-06 16:05:35 163 节点被标记永久下线
  12. 租户处于无主状态
  13. 2024-05-06 16:22:53 启动 163 节点全能型副本节点(后被 kill,先启动)
  14. 2024-05-06 16:24:55 租户恢复正常读写
  15. 2024-05-06 16:36:29 启动 161 节点全能型副本节点
  16. 将永久下线时间参数 server_permanent_offline_time 调回3600s

小结

  1. kill 掉 1 个全能型副本节点后(leader),租户存在约5s读写异常,后续恢复正常。
  2. kill 掉 2 个全能型副本节点后,租户进入无主状态,读写状态异常。
  3. 启动 163 节点全能型副本节点,可正常加回集群,约 117s 后租户读写恢复正常。
  4. 启动 161 节点全能型副本节点后,可正常加回集群。

结论

  1. 1 个全能型副本(leader)发生故障后租户能否正常读写?

结论:租户切主期间短暂读写异常,后续恢复正常读写。

  1. 2 个全能型副本发生可恢复的故障,均触发永久下线,后续启动OBServer后集群能否恢复正常?

结论:可恢复正常。

  1. 需注意的点:极端情况下如果第二个全能型副本也发生故障且无法恢复,之后即使第一个 全能型副本恢复了,也会有数据丢失,原因是仲裁成员不存储 Redo 日志。

  2. 综上,成本敏感或预算有限且能承受可能丢失数据的情况可以选择 OceanBase 2F1A 仲裁高可用方案,若期望数据不丢失建议选择全功能型副本高可用方案。

后记

仲裁服务两个典型的应用场景在于 “自动选主提升同城自动容灾能力” 和 “降低跨城带宽提升两地三中心稳定性”,感兴趣的读者可查看《OceanBase 助力企业应对数据库转型深水区挑战》 中关于仲裁服务章节的内容。

更多技术文章,请访问:https://opensource.actionsky.com/

关于 SQLE

SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。

✨ Github:https://github.com/actiontech/sqle

📚 文档:https://actiontech.github.io/sqle-docs/

💻 官网:https://opensource.actionsky.com/sqle/

👥 微信群:请添加小助手加入 ActionOpenSource

🔗 商业支持:https://www.actionsky.com/sqle

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

10个国内免费AI绘画网站汇总【2024最新】

迎战MidJourney和Stable Diffusion:10款国产AI绘画神器,让你轻松创作出超凡艺术品!不论你是初学者还是资深艺术家,这些AI绘画平台都能帮你轻松入门。快来探索这些AI绘画网站,释放你的创意潜能! 1、AI绘画创…

Linux系统之nice命令的基本使用

Linux系统之nice命令的基本使用 一、nice命令介绍1.1 nice命令简介1.2 进程优先级介绍 二、nice命令基本语法2.1 nice命令的help帮助信息2.2 nice命令选项解释 三、nice命令的基本使用3.1 查看进程优先级3.2 使用nice启动进程3.3 提高优先级 四、注意事项 一、nice命令介绍 1.…

YCSB基准测试

1、Redis: 下载成功后,加载数据,运行 启动redis: /usr/local/redis/bin/redis-server ./bin/ycsb load redis -P workloads/workloade -p redis.hostlocalhost -p redis.port6379 -p recordcount10000 -p operationcount10000 -threads 32 ./bin/y…

Vue3-尚硅谷笔记

1. Vue3简介 2020年9月18日,Vue.js发布版3.0版本,代号:One Piece(n 经历了:4800次提交、40个RFC、600次PR、300贡献者 官方发版地址:Release v3.0.0 One Piece vuejs/core 截止2023年10月,最…

简述RocketMQ从了解到使用

概念篇 背景: 随着队列和虚拟主题使用的增加,ActiveMQ IO模块达到了一个瓶颈。我们尽力通过节流、断路器或降级来解决这个问题,但效果并不理想。于是我们尝试了流行的消息传递解决方案Kafka。不幸的是,Kafka不能满足我们的要求,其尤其表现在低延迟和高可靠性方面,详见下…

后端之路第三站(Mybatis)——入门配置

一、Mybatis是啥? 就是一个用java来操控数据库的框架语言 之前学的datagrip或者navicat这些软件里我们操作数据库,原理是我们编写完的操作语句发送到服务器传送到数据库系统,然后数据库执行完之后再发送给服务器返回给datagrip或者navicat显…

服务器数据恢复—用raid6阵列磁盘组建raid5阵列如何恢复原raid数据?

服务器存储数据恢复环境: 华为OceanStor 5800存储,该存储中有一组由10块硬盘组建的raid6磁盘阵列,供企业内部使用,服务器安装linux操作系统EXT3文件系统,划分2个lun。 服务器存储故障: 管理员发现存储中rai…

多家国产大模型提供OpenAI API服务替代方案,谷歌将推出明星网红AI聊天机器人

ChatGPT狂飙160天,世界已经不是之前的样子。 更多资源欢迎关注 1、OpenAI终止对中国提供服务 6月25日凌晨,多个用户收到OpenAI的推送邮件,信中称,自今年7月9日起,将开始阻止来自非支持国家和地区的API(应…

pythons工具——裁剪labelme的json不规则多边形标签保存成矩形图像

原图labelme标注 使用以下程序,裁剪labelme的json不规则多边形标签保存成矩形图像 import os import cv2 import math import json import numpy as np from PIL import Image, ImageDrawdef calculate_bounding_box(points):"""计算多边形的最小外…

高校心理咨询管理系统

摘 要 随着高校学生心理问题的增多,心理咨询服务在高校中的重要性日益凸显。然而,传统的心理咨询管理方式存在着诸多问题,如信息不透明、咨询师资源不足等。为了解决这些问题,本文设计并实现了一种基于Java Web的高校心理咨询管理…

Java Stream API揭秘:掌握List流操作,打造高效数据处理流程

序言 Java Stream API是Java 8中引入的一个非常重要的功能组成部分,它提供了一种声明式的处理数据集合的方法。它主要特点是基于函数式编程的理念,允许我们以更加简洁、高效的方式进行集合的处理、转换和过滤。通过Stream API,我们可以灵活地…

Animate软件为什么默认只能导出mov格式视频?

很多同学在学习Animate软件的时候,经常会有一个问题,就是制作好动画导出视频时,只能选择mov格式,而且导出文件特别大,为什么Animate软件默认只能导出mov格式的视频呢?这里简单说一下自己的看法。 首先&…

打破数据分析壁垒:SPSS复习必备(十)

Means过程 统计学上的定义和计算公式 定义:Means过程是SPSS计算各种基本描述统计量的过程,其实就是按照用户指定条件,对样本进行分组计算均数和标准差,如按性别计算各组的均数和标准差。 用户可以指定一个或多个变量作为分组变…

分布式系统:常见的陷阱和复杂性

分布式系统的复杂性是工程师和开发人员面临的重要挑战。复杂性往往会随着系统的发展而增加,因此积极主动非常重要。让我们来谈谈您可能会遇到哪些类型的复杂性以及在工作中应对它的有效策略。 分布式系统和复杂性 在开发中,分布式系统是相互连接并执行…

文华wh6均线交易策略多空波段止盈止损提示主图指标公式源码

文华wh6均线交易策略多空波段止盈止损提示主图指标公式源码&#xff1a; EMA120:EMA(C,120); RSV:(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*100; K:SMA(RSV,3,1); D:SMA(K,3,1); J:3*K-2*D; DRAWTEXT(C>EMA120&&J<0,L,多),VALIGN0; DRAWTEXT(C<EMA…

01_02_Mybatis的配置文件与基于XML的使用

1、引入日志 在这里我们引入SLF4J的日志门面&#xff0c;使用logback的具体日志实现&#xff1b;引入相关依赖&#xff1a; <!--日志的依赖--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version&g…

基于LangChain搭建个人知识库

前言 &#x1f63a;Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#xff0c;&#x1f600;&#x1f600; 一名热爱AI技术的GIS开发者&#xff1b;在上一篇文章中&#xff0c;我们学习了LLM API的申请、应用以及提示词工程&#xff1b; 在本文中&#xff0c;作者将介绍如…

观测云 VS 开源自建

观测云是一款面向全技术栈的监控观测一体化产品方案&#xff0c;具备强大而丰富的功能&#xff0c;目标是帮助最终用户提升监控观测的能力&#xff0c;化繁为简&#xff0c;轻松的构建起完整的监控观测体系。同时能够帮助整个企业的开发技术团队从统一的观测能力上获得完整的收…

机器学习辅助的乙醇浓度检测(毕设节选)

目录 1.为什么要机器学习 2. 神经网络一般组成 3.BP神经网络工作过程 4.评价指标 5.实操代码 1.为什么要用机器学习 人工分析大量的谐振模式&#xff0c;建立各种WGM的响应与未知目标之间的关系&#xff0c;是一个很大的挑战。机器学习(ML)能够自行识别全谱的全部特征。作为…

linux高级编程(进程)(1)

进程&#xff1a; 进程的含义? 进程是一个程序执行的过程&#xff0c;会去分配内存资源&#xff0c;cpu的调度 进程分类&#xff1a; 1、交互式进程 2、批处理进程 shell脚本 3、 守护进程 进程与程序的区别&#xff1a; 1&#xff09;程序是…