在上一篇文章《 [关于产品质量的思考 - 我的基本认知 ](http://mp.weixin.qq.com/s?__biz=MzI3NDIxNTQyOQ==&mid=2247516062&idx=1&sn=7ea9f23109c27f45df3b1d5dba09dc91&chksm=eb1598f4dc6211e2758cbc0ea62075c1e9885220aec1042cbef567e71d38c51c5f3f2cc1648e&scene=21#wechat_redirect)》中,作者通过亲身经历分享了对产品质量的思考和认知:高质量的产品不仅仅是通过测试来保证的,更是通过在真实场景中不断打磨和改进得来的。本文为“关于产品质量的思考”系列的第二篇,将以 TiDB 产品发版为例,探讨如何评估产品的质量。文章指出了仅仅根据漏出的 bug 数量来评估质量的误区,并介绍了一些有效的评估方法,强调了深入了解客户业务场景的重要性 。
每次 TiDB 发版本的时候,我一定会被前线业务部门或者客户问到的一句话就是『这个版本质量好不好? 』,每次遇到这种问题,我都会非常的无奈,因为我很难给出让人满意的答案。 不过这个问题被问的多了,我自然也会思考,到底如何来评估一个版本质量的好坏?
在开始之前,仍然有如下的几个声明:
- 我说的不一定是对的。我也会定期刷新我自己的认知。
- 这仅仅只是我自己关于质量的思考,是我自己在 PingCAP 的经验总结,也并不一定适用于其他公司。
- 我说的也只是 PingCAP 对于质量评估一些方面,实际我们在内部有更多评估维度和指标。
# 漏出 Bug 数量
我也会跟不少的朋友探讨产品质量问题,有时候我会听到一个很常见的回答,『这个还不简单,就是看在客户那边遇到了多少 bug 就行』。这个不能说没有道理,不过正如我在 [《 关于产品质量的思考 - 我的基本认知》 ](http://mp.weixin.qq.com/s?__biz=MzI3NDIxNTQyOQ==&mid=2247516062&idx=1&sn=7ea9f23109c27f45df3b1d5dba09dc91&chksm=eb1598f4dc6211e2758cbc0ea62075c1e9885220aec1042cbef567e71d38c51c5f3f2cc1648e&scene=21#wechat_redirect)里面提到的,bug 多不一定意味着质量不好。
这里我还想强调另一件事情,通常大家讨论的 bug,属于漏出 bug,也就是已经泄漏到客户那边的 bug,用漏出 bug 数量来评估一个产品质量的好坏,其实已经非常的滞后了,尤其是对于数据库这样的产品来说。根据我这么多年的观察,用户都不怎么倾向升级数据库,甚至在国内一些金融客户,都是按照年为单位来采用发布的新版本,这个反馈周期太长。当然,在云上面提供 TiDB 新版本的服务是能加速这个反馈过程,只不过仍然会有一点滞后性。
当然,这个指标的意义和价值也是非常大的,漏出 bug 对于当前发布的版本属于一个滞后指标,不过它对于下一个要发布的版本是一个实实在在的前置指标。也就是说,我们在下一个发布的版本里面,是要尽量的去修复上一个版本漏出的 bug 的,如果不做这些事情,质量很容易就失控了。
# Bug 收敛
上面我们提到了漏出的 bug 数量,实际在开发版本的时候,我们自己也会自己测试出来非常多的 bug,这些 bug 如果不去修复,仍然会影响我们产品的质量。 为了评估质量风险,我们通常会关注 bug 是否收敛。 这里稍微解释一下 bug 收敛, 关于 bug,一般会有两条曲线,一条是 open 的 bug 数量,另一条是 closed 的 bug 数量,通常对于一个快速迭代的系统来说,open bug 的数量是大于 closed bug 的数量的,随着时间的推移,如果这个差值不断增大, 没有显示出收敛的趋势 ,或者差值控制在一个很小的范围内,我们就会认为 产品的整体质量存在风险。
这里给一个做的很的产品的例子,譬如我们熟悉的 Kubernetes,它在发布几年之后,closed 的 bug 数量已经超过了 open 的 bug 数量。如图:
<!--StartFragment-->
![](https://pic4.zhimg.com/v2-7d29fd920283e61e06765be4b298af0f_r.jpg)
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/9ad65ab1cdd247fc89b687ed4b02a953_image.png "image.png")
参考: https://ossinsight.io/analyze/kubernetes/kubernetes#issues
另外一个非常好的例子是 vscode,几乎从一开始,两条曲线的差值就控制在一个很小的范围:
<!--StartFragment-->
![](https://pic1.zhimg.com/v2-328fce5fc460c52777ec9b4bb8a99424\\_r.jpg)
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/0711850ee8924365911c3707032ac808_image.png "image.png")
参考: https://ossinsight.io/analyze/microsoft/vscode#issues
对于 TiDB 来说,我们从 7.5 开始,在发布 LTS 版本的时候,会严格控制 bug 的收敛,之前 6.x 的版本,我们需要发布几个 patch 版本,才能保证 closed bug 的曲线超过 open bug 的曲线,而在 7.5 发布的时候,我们就已经能够保证 bug 收敛了。不过这里我仍然想强调,bug 收敛并不意味着没有 bug,只是能证明质量并没有变得更加糟糕。
后面,对于 TiDB 这个产品来说,我们会开始控制主干版本的 bug 收敛,我们有一个很有野心的目标,就是真的能让 TiDB 做到主干发布。我们认为,bug 能收敛是主干发布的一个必要条件。
# Bug 的聚簇效应
Bug 的聚簇效应是我自己取的一个名字,这么说可能还是容易让人糊涂,这里举一个能让人印象非常深刻的例子:
通常来说,当我们在家里面见到一只『小强(蟑螂)』的时候,我们已经能预感到,家里面已经有非常多只『小强』了。
<!--StartFragment-->
![](https://pic1.zhimg.com/v2-00ee0a95a5b6ecff2ab7b3cad5d327b4\\_r.jpg)
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/73ad4af0f5c140c58aa0bf29d18c8a88_image.png "image.png")
*注意:因为直接贴实物图恐怕会引起大部分人不适,这里就用 cute 图片代替了。*
在我的认知里面,bug 其实也一样 。『 **当我们在一个模块里面测试发现了一个 bug,大概率这个模块还有更多的 bug。** 』
关于这点认知,我并不确定是否有什么理论依据,我只是根据我多年的经历得到一个很好玩的认知。当然,根据这个认知,我们有时候还能得出一个更好玩的认知:
『 **当一个****研发****团队之前开发的 feature bug 比较多的时候,他们开发的下一个 feature 大概率也有不少的 bug。** 』当然, 事情还是会变好的,随着时间的推移,以及研发团队的成长,到最后就是团队开发的 feature 质量有很大的保证。
所以,在发布某一个版本的时候, 如果要再次确保该版本质量可控,在资源有限的情况下,我们应重点关注之前发现存在 bug 的模块, 以及一段时间写出比较多 bug 的研发团队开发的 feature 上 面。
# Feature 的带宽分配和 T-shirt Size
聊完了 bug,我们再聊 feature。在前面《 [关于产品质量的思考 - 我的基本认知 ](http://mp.weixin.qq.com/s?__biz=MzI3NDIxNTQyOQ==&mid=2247516062&idx=1&sn=7ea9f23109c27f45df3b1d5dba09dc91&chksm=eb1598f4dc6211e2758cbc0ea62075c1e9885220aec1042cbef567e71d38c51c5f3f2cc1648e&scene=21#wechat_redirect)》这篇文章里面已经提到,feature 开发的越多,某种程度上就会有更多的 bug,这个并不会以研发工程师的意志为转移。当然,我们又不可能不开发 feature,不然就丢失了长期的竞争力。
所以我们要做的第一件事情就是控制 feature 的数量,尽量做到竞争力和质量的平衡。在 PingCAP,我们的研发 leader 会跟 PM 达成共识,然后评估好这一段时间 team 的带宽投入,譬如投入整个 team 40% 的人力带宽开发新的 feature,40% 的人力带宽去做质量改进和架构重构,剩下的带宽就做 oncall,客户 support,或者个人成长相关的事情等。在 PingCAP,不同的研发团队在不同的阶段,这个带宽分配比例是不一样的。
规划好带宽分配之后,研发 leader 会使用传统 T-shirt Size 来评估开发一个 feature 需要多少人天,譬如一个 feature 的 size 是 XL,那么就是 1 人月这种。
规划好了这些,从大盘来看,包括但不限于有如下情况的,就可能存在质量风险:
- Feature 个数多,尤其是 XL size 以上的 feature 个数多
- 一位研发工程师参与了多个 feature,尤其是 XL size 以上的 feature 的开发
- XL size 以上的 feature 负责人是一位比较 junior 的研发工程师
- 一个团队,尤其是做 TiDB 内核的团队,在 feature 开发上面的带宽比例偏高,譬如超过 60%
当然,如果具体到某一个 feature,如果 feature specification 定义的不清晰,test plan 没有,对应的 PR 代码行数变更很多,这些都会是这个 feature 自身的质量隐患,我们也需要注意。关于这一点,后面有空再讨论。
# 客户场景的测试覆盖
我有一个梦想,就是『我有无限的资源,能写出无限的测试用例,覆盖掉所有的客户场景,那么 TiDB 几乎就没 bug 了』。这个梦想是如此的宏大,以至于让我完全能清醒意识到,我是在痴人说梦。
所以,我们如何能更加高效的通过添加测试用例来覆盖更多的客户场景,从而保证我们发出去的版本在大多数时候都能正常工作,不会给客户带来惊吓?这确实是一个非常有挑战的事情。
幸运的是,28 原则在这里仍然有效 - 在 PingCAP,20% 的客户几乎贡献了 80% 的问题(这里面的问题不光包括 bug,也包括 oncall 等)。另外我们发现,20% 的这些客户的场景也能复制到其他行业的其他客户上面。
这就给了我们一个很好的指引 - 在资源有限的情况下,只要我们能深入的理解我们 20% 的重要的客户的当前的业务场景,基于这些场景去开发测试用例,我们至少能保证当前阶段大部分场景不会掉链子。20% 的客户的场景测试覆盖率越高,我们对质量就越有信心。当然,如何模拟业务场景,有机会也可以聊聊。当我们觉得 20% 的客户的场景覆盖率不错之后,我们也会逐渐积累更多的场景。
另一个幸运的发现是,我们当前的不少 bug,来自于新开发的功能被重要的客户直接使用,这个在 NA 尤其突出。从某种程度上说,这算是一件好事,它表明很多客户愿意直接尝试我们新的版本。所以我们后面在开发新功能的时候, 会深入与这些客户合作 ,弄清楚他们的业务场景,添加测试覆盖,保证新发布功能的质量。
# 写在最后
上面仅仅列 举了一些我个人从直观角度评估产品质量的问题。 实际上,在PingCAP内部,我们衡量产品质量的指标远远不止上述几点,毕竟我们的产品是数据库, 对于质量的要求是非常高的 。
上面 我也仅仅只是从测试、bug 等几个角度来讲我如何评估产品质量,并没有涉及到代码。关于代码,在我的认知里,复杂度高的代码质量大概率不好,以及大概率有 bug。这块有机会再聊聊代码的复杂性跟质量的关系。
关于质量,还有一点感悟,即使是同一个 TiDB 版本,我们也可能从不同客户听到不同的声音,甚至同一个客户听到不同的声音。这并不奇怪。 不同客户的场景可能不同,甚至同一个客户的业务场景也可能不同,而目前 TiDB 并没有覆盖到所有可能的场景 ,我们只能一点一点地补充不同场景的测试用例。
最后再提一个来自 Oracle 的数据。我曾跟一些来自 Oracle 的同学交流过一个问题, 『在 Oracle,你们有多少个客户场景测试? 』 大部分的回答都是 200 多个。这个数字让我非常吃惊,尽管数字可能不太准确。但如果真的是这样,大概 Oracle 这几百个业务场景测试用例已经对客户场景进行了极度抽象,能够覆盖他们绝大部分的客户群体了。 这就 是当前 TiDB 跟 Oracle 在测试场景上面的一个差距, 我们只能逐步积累经验努力追赶 了。
**参考**
- [关于产品质量的思考 - 我的基本认知 ](http://mp.weixin.qq.com/s?__biz=MzI3NDIxNTQyOQ==&mid=2247516062&idx=1&sn=7ea9f23109c27f45df3b1d5dba09dc91&chksm=eb1598f4dc6211e2758cbc0ea62075c1e9885220aec1042cbef567e71d38c51c5f3f2cc1648e&scene=21#wechat_redirect)
- OSS Insight ( https://ossinsight.io/ )