混沌工程:是谁背着我偷偷写 Bug 🤸

前言

GreptimeDB 支持以单机和分布式的形式进行部署,但紧随而来一个尖锐的问题:我们对投入生产的这套复杂系统有多少信心?

在 0.3 到 0.4 的迭代过程中,我们引入了混沌工程(Chaos engineering)来提高系统的健壮性。

混沌工程是怎么实施的

我们选择了 Chaos Mesh 作为故障注入工具。我们在 Pod 中运行一个测试程序(Testcase),该程序通过定义 CR(Custom Resource)为 DB 集群中特定的 Pod 注入故障;并在转移故障后,对 DB 集群的可用性和数据完整性进行验证。 下面是一个示例,向 greptimedb-cluster 命名空间中名为 greptimedb-datanode-1 的 Pod 注入一个 Pod Kill 的故障。

yaml 复制代码
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  namespace: greptimedb-cluster
spec:
  action: pod-kill
  mode: one
  selector:
    filedSelectors:
      'metadata.name': 'greptimedb-datanode-1'

为了便于调试测试程序,测试程序在开发环境中,可以直接运行在主机上,并通过 Kubectl 的端口转发访问 K8s 中的 DB 服务。

一些探索和经验

1. 从最小场景开始

测试覆盖不高时,可能会有一些"负负得正"的情况,让整套系统看起来"正常"运行(实际上即使覆盖率较高,也依然可能存在这些问题)。所以我们可以从最小场景开始测试,这个阶段你需要非常清晰地知道系统的预期行为,并通过查看系统日志,判断系统的行为是否真的符合预期,以便发现问题后及时补相应的集成测试。

例如,我们需要验证系统是否能容忍 Datanode 节点被 Kill,并触发 Region Failover 流程(即将 Region 迁移到其他可用节点)。我们可以通过构建一个最小场景(少量表,少量数据)来进行验证,通常当故障被注入到故障真正发生会有一定的时间间隔,此时我们需要一些方法去判断系统是否真实发生故障了。

通常有几种做法:通过调用 Kube API 观察 ReplicatSet 的 Pod 副本数量少于预期;亦或是通过对目标节点进行读写来感知------在观测到故障前不间断的发起一些(少量的)将会路由到目标节点的读写操作,当客户端会返回故障时,即可视为目标节点不可用。随后等待集群恢复(例如调用 Kube API 等待 ReplicatSet 的 Pod 副本数量回到预期),我们就可以开始验证服务可用性和数据的完整性。

2. 尽可能贴近真实的场景

GreptimeDB 可以将数据保存在 AWS S3 或者阿里云 OSS 等等这样的廉价对象存储上。S3 这类存储相比本地存储来说,在测试中还是有不少差异的,主要体现在对 S3 访问的延迟上。**应尽早地贴近真实场景,即测试使用 S3 存储的 DB 集群。**我们在开发测试程序的时候,也要将被测试 DB 集群的数据存储在靠近开发环境的 S3 中。

3. 梳理思路 + 补充集成测试

在开始混沌测试前,尽可能地把思路梳理清晰,在集成测试中把将要测试到链路进行覆盖。混沌测试还是有不少额外工作量的,前期把测试做到位能节省不少时间。当然混沌测试和集成测试也可以说是相辅相成的,有些问题只有你真的在混沌测试中遇到了,才会打破你之前的一些判断:"哇*,原来这个不是我想的小概率事件🤣"。

4. 关注偶发的问题

任何偶然发生的问题都要深究,对于小概率发生的问题其实需要大量的重试,并通过日志精准地定位问题。

5. 构建可复用故障

构建一个混沌测试需要投入不少精力:通常注入一个故障,其中会涉及到多个步骤,例如注入故障,观察到故障发生,等待服务完全恢复等。通过对这些步骤进行抽象,我们可以做到实现注入一个故障,测试多个不同的场景。

在混沌工程中发现的 Bugs

我们在混沌工程中发现的 Bugs 主要集中在以下几类:

  • Trait 的不同实现,行为不一致;
  • 字段或接口冗余;
  • 多个 Bug 叠加,负负得正;
  • 未使用别名造成的歧义;
  • Corner Case 中数据与缓存不一致;
  • 迭代过程中多人协作造成的一些遗漏。

我们还很意外地发现了一个上游的 Bug,OpenDAL FsBackend 的异步写入在 sync_all 之前未调用 flush,导致其有潜在丢失数据的风险。我们在 0.4 版本中及时反馈并修复了这个 Bug,可以通过下面链接详细了解:

关于 Greptime:

Greptime 格睿科技致力于为智能汽车、物联网及可观测等产生大量时序数据的领域提供实时、高效的数据存储和分析服务,帮助客户挖掘数据的深层价值。目前主要有以下三款产品:

  • GreptimeDB 是一款用 Rust 语言编写的时序数据库,具有分布式、开源、云原生和兼容性强等特点,帮助企业实时读写、处理和分析时序数据的同时降低长期存储成本。

  • GreptimeCloud 可以为用户提供全托管的 DBaaS 服务,能够与可观测性、物联网等领域高度结合。

  • GreptimeAI 是为 LLM 应用量身定制的可观测性解决方案。

  • 车云一体解决方案是一款深入车企实际业务场景的时序数据库解决方案,解决了企业车辆数据呈几何倍数增长后的实际业务痛点。

GreptimeCloud 和 GreptimeAI 已正式公测,欢迎关注公众号或官网了解最新动态!对企业版 GreptimDB 感兴趣也欢迎联系小助手(微信搜索 greptime 添加小助手)。

官网:greptime.cn/

GitHub: github.com/GreptimeTea...

文档:docs.greptime.cn/

Twitter: twitter.com/Greptime

Slack: www.greptime.com/slack

LinkedIn: www.linkedin.com/company/gre...

相关推荐
MonkeyKing_sunyuhua11 分钟前
ubuntu22.04 docker-compose安装postgresql数据库
数据库·docker·postgresql
天郁青11 分钟前
数据库交互的本地项目:后台管理系统
数据库·交互
马剑威(威哥爱编程)17 分钟前
MongoDB面试专题33道解析
数据库·mongodb·面试
小光学长42 分钟前
基于vue框架的的流浪宠物救助系统25128(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
数据库·vue.js·宠物
零炻大礼包2 小时前
【SQL server】数据库远程连接配置
数据库
zmgst2 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
随心............2 小时前
python操作MySQL以及SQL综合案例
数据库·mysql
€☞扫地僧☜€2 小时前
docker 拉取MySQL8.0镜像以及安装
运维·数据库·docker·容器
CopyDragon2 小时前
设置域名跨越访问
数据库·sqlite
xjjeffery2 小时前
MySQL 基础
数据库·mysql