“分布式数据库测试”这件小事

4年前,我对分布式、数据库、测试这几个领域都很陌生,好奇心与缘分让我和它们相见。 它们每一个都有说不完的故事。而我和它们的故事,则要从测试开始说起。

  • 2024-03-22:补充“测试分层:按系统模块”这一章。
  • 2024-03-21: 读《关于产品质量的思考 – 如何评估质量》有感。 之前这篇博客主要是从“测试人员应该做什么,能做什么,有哪些可能做法” 来描述的。未来会更多补充一些“数据库测试人员能做什么、怎么做”。
  • 2023-05-31: 补充“分层测试:从黑盒到白盒”这一章。
  • 2023-05-25: 补充了测试的一些其它角度:理念与流程、DFX 专业技能。
  • ps: 后续可以注意看这篇博客的 TODO 标记。

QA 就是测试,测试就是 QA?

说到测试,我现在会很本能的想到 QA 这个词。我之前的工作职位叫作 QA, 别的同事也会用这个称呼来代指我的岗位或我所在的小组。“QA 就是测试,测试就是 QA ”, 这可能是很多人的直观印象和认识,我一开始差不多也是这样理解的。

但仔细想想,就会发现这个理解有很多说不通的地方。写单测是测试,研发要写单测, 研发是 QA【纪晓岚式微笑】。但这个说法显然会让少部分研发“恼羞成怒”, 你才是 QA,你全家都是 QA【狗头】。

我以前特意搜过,“什么是 QA,QA 是干啥的?”等类似问题。然后我看了好几篇文章, 当时还做了点笔记。其中有一篇是“网红”文章,它是左耳朵耗子在 2012 年写的《我们需要专职的QA吗?》。我觉得这个“标题”放在 2023 年,仍然足够吸引眼球。 还有两篇是《测试团队与咖啡店》和《软件测试团队“核心价值”的思考》,它们同样引人思考。 我个人觉得这些文章都反映了一个问题,对于如何做好测试这件事情, 行业里还没有一个开源的范本,大家要走的路还很长。一位同事说华为发布出来的产品质量不错。 华为对质量比较看重,有完善的流程支持,质量保障体系比较完善。

QA 全称是质量保证(Quality Assurance),不管是 QA 或是测试这个事情, 它们共同的 宏伟 目标是保障产品质量。作为一名 QA,当时我就在想, 怎样衡量产品质量?什么是保障的好,什么是不好。

质量好坏的量化

“质量好坏”短期往往是难以量化的,数据库业界至今也没有一个好的标准。 测试覆盖率、产品问题数等指标虽然有一定的参考意义,但也有一些显然的不足。 比如,代码行覆盖率即使很高,质量仍然可能很差,而“分支覆盖率”/“MC/DC覆盖率” 等指标又存在“全集难以计算”或“提升成本很高”等问题。对于一个讲究“快速迭代”的行业, 产品问题数则和用户数、新特性数量、以及用户使用场景/时长有明显相关性, 同比环比等计算策略在这样的情况下同样无法使用。

回到 QA 的话题,假设质量好坏能量化,其能反应 QA 工作的好坏么?显然也不能。 举个例子,某个模块质量变好了,完全可能是因为代码换了一位“牛人”来写,鲁棒性更好了。 既然如此,是时候改变一下 QA 的定位和目标了。

2024-03-21 更新:之前是站在“测试人员应该做什么,能做什么”的角度来写这一片博客的, 今天读了唐刘:关于产品质量的思考 – 如何评估质量, 这篇文章里面提到了几种评估质量的维度,记录一下:

  1. bug 维度:漏出去的 bug 数量;bug 收敛趋势,算法是:新修复-新发现; bug 趋向于聚集,这个观点在《软件测试的艺术》这本书也说过。
  2. feature 维度:个人理解讲的就是要保证在质量方面上的花的时间。
  3. 文章还提到了客户场景的测试覆盖。可以理解为 test 角度。

除了这些维度外,个人认为覆盖率是衡量质量一个永恒的指标,就看测试人员是否能把这种覆盖率指标给量化出来。 如用户场景覆盖率、优化规则覆盖率、一致性模型覆盖率等。

行业需要 QA 吗?

前段时间一个群在讨论数据库测试的事情,有ex同事说

好的数据库,不需要 QA。 倒逼研发在开发环节的开头就控制住质量。 丰田模式。

然后又有一个ex同事截图了《分布式系统测试那些事儿 - 理念》这篇文章的一小段话

我们现在很有意思的一个事情是,迄今为止 PingCAP 没有一个测试人员, 这是在所有的公司看来可能都是觉得不可思议的事情

这其实和左耳朵耗子 2012 年那文章讨论的问题有点像,“我们需要 QA 吗?”。 2023 年了,这问题仍然会被大家拿出来讨论,感觉很有意思。

个人觉得《测试团队与咖啡店》这篇文章的观点不错, (不错还不足以形容我对它的看法,很好!三年前的我应该是没能领悟这段话的含义。)

当开发人员对测试团队说“我需要你们在每次提交后对产品进行测试”, 他真正想要的只不过是能够有一种机制,使得每次代码提交之后都能验证产品是不是存在明显的问题。 通过 CI、分层的自动化测试,测试团队可以用更轻松、更快捷也更优雅的方式解决开发团队的问题。 在这个基础上,也许你还可以说服开发团队建立一系列的标准,用于评估产品的生产率和质量, 让测试团队和开发团队一起推动持续的生产率增长和质量提升。

写代码,测试,流程规范与思想理念,每个都得要。谁来做呢?

分布式数据库的测试

特性测试(开发来测如何?)

要保障数据库一个功能或特性的质量,制定合理的测试计划,设计有效的测试用例。 除了要遵守质量保障的流程规范,了解常见的测试用例设计方法,更需要了解甚至熟悉这个功能, 从用户使用方法到底层实现原理。

分布式数据库所涉及的知识面是非常广的,且每个具体的垂直领域都会涉及比较深。 从存储、共识算法、事务、执行器、优化器、网络通信协议等基础理论,到用户负载、 数据库基础运维,再到特定场景或问题的解决方案,要接触了解每一个点,就需要很丰富的积累, 更别说熟悉它们了。可能只有“架构师”的心里才能完整的绘出这副图。

从用户使用角度来看,用户和分布式数据库直接交互的方式主要有三类。第一类是通过 SQL 与之进行数据信息交换。第二类是运维操作,比如扩缩容、滚动重启、配置修改等。 第三类则是数据备份恢复、数据同步等。简单使用数据库的这三类功能, 我相信大部分人稍微花点时间都能掌握个大概。

以 TiDB 的 GC in Compaction Filter 特性为例,在有固定流程规范的背景下, 谁花最少的时间就能学习并掌握这个特性的测试工作呢?我觉得是写代码的人。 因为其它人学 RocksDB 和 Compaction Filter 等繁琐的原理效率很可能不够高。 不过听一位以前的同事说,华为是让测试团队的人来学习,写代码的人负责讲解。 我认为这样做的代价是周期更长,需要的人非常多,好处则是变相引入了 reviewer,测试会更周全。

以上是把“数据库的一个非常细节的功能”当成一个功能/特性,尝试给出我个人对上面“谁来做呢” 这个问题的理解。但如果变换一个看问题的粒度,把 CAP 中的 C 或者 A 当成分布式数据库的一个特性呢,或者把数据库的性能看成一个特性呢, 我觉得上述问题则可以有完全不同的答案。

系统测试与自动化

我觉得自己算是一个喜欢折腾概念的人,因为我感觉概念最能让一个东西从模糊变得具体。 因此我工作的时候花了些时间就去寻找系统测试的概念,比如查维基百科、看《软件测试的艺术》这本书, 但我记忆中,它们都没有给出让我非常信服的定义。比如维基百科是这么说的

系统测试是将需测试的软件,作为整个基于计算机系统的一个元素, 与计算机硬件、外设、某些支持软件、数据和人员等其他系统元素及环境结合在一起测试。 在实际运行环境下,对计算机系统进行一系列的组装测试和确认测试。 系统测试的目的在于通过与系统的软件需求作比较,发现软件与系统定义不符合或与之矛盾的地方。

我觉得它说的可能没错,未来的某一天,说不定我能理解。但现阶段我觉得它讲的还是过于模糊了。 不过这里有句话还是有点启发的 系统测试的目的在于通过与系统的软件需求作比较。 那本书,我记忆中(我的书怎么不见了,尴尬)没有下定义,但它把性能测试、 配置测试等都划分在系统测试这一章节下,作为其子章节。

我也想当一回发明家,给它来个定义如下

系统测试是对系统大粒度垂直领域进行的测试, 比如性能测试、稳定性测试、正确性测试等。也可以叫做主题测试。

– Cosven

关键字一:垂直领域。数据库的特性何其多,纷繁杂乱,了解熟悉起来费时费脑, 需要很多很多工程师。工程师又叫什么?码农!我觉得这个称呼其实还是挺有有道理的。 学习数据库的小特性,就像了解一个高楼大厦的每块砖是如何码的一样,琐碎,费劲。 关键是,就算花了几辈子去学,可能还不如当初那些亲手码砖块的人熟悉那几块砖, 人家“码农”心里可能一清二楚。但如果你从万千砖块中提取一个垂直领域, 比如承重墙的码法,在这个领域上日积月累,那你可能就是“承重墙砖家”。【笑死】 分布式数据库领域可以有存储、计算、分布式砖家,也可以有性能、正确性、稳定性砖家嘛。 存储砖家加分项是有性能调优经验,那性能砖家加分项则可以是有存储设计经验, 稳定性砖家加分项可以是有分布式系统经验。

关键字二:大粒度。粒度大了,测试时就不需要去了解每个小特性的繁琐细节了。 把分布式数据库当成一个系统,把稳定性当成一个领域,针对这个领域进行的测试则是稳定性测试。 该测试的输入可以很简单,比如上面提到过的 SQL,以及运维操作。 以不同顺序在不同的系统规格下可以组合成为不同的负载。 大自然的混沌力量偶尔也会是成为一种输入,我愿称之为错误注入。 然后把类似“吞吐是否抖动”等作为测试的检测点,这测试就有了。 根本不需要关心数据库是如何解析、执行 SQL 的,也不需要关心数据是如何存储的。【爽歪歪】

相比于单测和集成测试,系统测试的自动化通常会比较复杂,系统测试离研发举例会比较远, 不过 TaaS 是个好东西。

测试分层:从黑盒到白盒

2023-05-31 更新:测试分层这个概念很早之前就知道,但个人对其理解还非常不够。 最近也在面试中多多少少交流了一些测试技术,而其中另我感受最深的一个就是分层测试思想。

分层测试思想说起来还是挺常见的,比如一个常见的开发流程,从编译、静态分析、单元测试、 集成测试、功能测试和系统测试。这是一种维度的分层,这种分层基本是按照时间维度, 基本可以认为,前一个测试没有通过,后面的测试就没必要进行。也还有很多其它的分层维度, 按照子系统/模块分层,mock 其它模块;或按照测试粒度,有黑白灰盒。 这里想探讨(其实是记录)的是按粒度的分层思想的实践。

聊测试这个话题的话,我发现大家最喜欢的还是聊性能测试。稳定性的话, 测试从业者也聊的比较多,兼容性等也比较多。正确性这种似乎就相对比较少了。 昨天听到一个关于“性能测试”的分层实践经验,感觉挺不错的,记录一下:

场景是 AP 数据库,它们不仅会测 TPCH,TPCDS 等标准负载, 还会给每个“算子”设计测试用例,量化每个算子的性能。感觉是一种不错可以落地的实践。 但是它怎样保证测算子的负载是有效的呢?这是一个问题。

对这个记忆比较深的原因还是在于:思想大家都懂,但能落地不容易。 比如这个思想要在一个分布式存储的共识算法层去落实,则可能需要自己设计实现新接口, 甚至 mock 底层存储,这样实践难度明显就更大一些。其实回看一下, 特性测试和系统测试就是一种典型的按粒度分层的测试。根据过去经验, 特性测试对于重要的子系统/模块的质量保障还是非常重要的。

分层测试是一个非常棒的思考角度,也是一个非常好的实践思路。 以后可以多关注分层测试的实践经验,找点灵感。TODO

测试分层:按系统模块

数据库主要几个模块:传输层(或者叫协议层);优化器层,包括 SQL 解析、改写、执行计划优化与生成; 事务层;执行层(火山模型;MPP);存储层(保证数据的可用性,正确性)。

  • 优化器,常见问题有几类:rqg,sqlancer。
    • 正确性:比如表达式改写错了。
    • 性能:执行计划不优/跳变等。
  • 事务层,常见问题是正确性:jepsen + model。
    • MVCC/隔离级别的正确性。
    • 与算子/缓存/索引等结合的正确性。
    • 混沌场景的正确性,比如时钟、节点挂。
  • 执行层,常见问题是性能以及稳定性,正确性问题也是重点:性能测试,压力测试,rqg。
    • 如某算子性能回退
    • 执行过程 OOM。
    • 某算子 panic
    • 算子计算错误。
  • 存储层,常见问题是:系统测试,model/property-based testing。
    • 高可用,比如混沌场景。混沌测试。
    • 性能稳定性(比如compaction,补数据)。
    • 数据一致性与正确性(比如多副本数据一致性等)
    • 运维时的易用性与正确性(比如某个节点挂了补副本,上下线节点等)
  • 传输层,常见问题偏功能或稳定性相关的,比如包太大,链接管理等。

待完善(TODO)

2023-05-25:这篇博客之前一个核心的思想是:开发应该对质量负责, 开发参与特性测试是一种高性价比的实践。测试则可以专注在测试效率提升, 以及系统测试的某一个垂直领域。但后来我在思考职业规划的时候, 觉得这个思路还有一些可以补充的地方。主要是几个方面:开发应该怎样进行特性测试; 垂直领域之下的专业技能是什么;质量理念与测试活动。

系统可测性

下面问题是否是可测性的需求的征召?

  1. 对一个特性的质量没有把握时,没把握的原因会不会就是可测性不行?

对于可测性,自己感觉理解还比较浅,下面罗列一些常见的话题,以便以后学习

  1. valuable(产生实际价值的)
    1. failpoint/syncpoint: 确定性的错误注入
    2. continous profiling: 性能问题定位
    3. invariants: 正确性测试
    4. metrics:问题定位,负载模式判定
  2. unknown(可能有价值的)
    1. telemetry: 功能覆盖率??
    2. 100% MC/DC test coverage (ref: sqlite3):提升质量信心?
    3. valgrind:内存问题定位?
    4. tracing:问题定位?包括性能以及稳定性。

发散性思维???

很气愤,刚花了一个小时画好的脑图,被我不小心移到回收站之后,要收我巨款才能还原, MindMeister,建议不要用!!!还是自己写个文字版吧。

  • 大的分类:功能测试和系统测试
  • 性能测试
    • 基准测试:一定的负载和压力下的性能表现
    • 容量测试:例如单机规模,集群最大规模
    • 扩展性测试:水平线性扩展,垂直扩展
  • 稳定性测试
    • 可靠性测试(crash 测试,破坏性测试)
    • 可用性测试(可恢复性测试)
    • 性能抖动测试:
    • 长稳测试(压力测试):
  • 兼容性:升降级;配置兼容性;内核工具兼容性。
  • 一致性:事务(ACID);数据副本一致性。
  • 安全

数据库子系统的测试技术

  • SQL 执行:随机测试。
  • 优化器:???sqlancer?
  • 共识算法/一致性:不变量/混沌工程/可测性(jepsen)。
  • 性能:分层;mock;profiling。

质量理念与测试活动

  • 测试流程
  • 质量量化
  • 用例/bug管理
  • ???

带着故事睡觉

故事是讲不完的,睡觉!

Updated:

Comments