知识星球有同学问了这样一个技术问题:
需求场景:线上只读业务,日常峰值QPS 30K 。
前置条件:业务模型、流量模型和数据模型已经评估完成。
压测需求:线上环境压测,最短压测执行时常不低于10min。
面临挑战:线上流量录制得到的测试数据量过大,超过30G,如何存储?
待办问题:如何生成大数据量的测试数据,且可以平衡造数据效率和成本?
延伸问题:如果是自研压测平台,如何支持大数据量的数据在项目中应用实践?
这个问题相对来说比较复杂,复杂的主要因素有高并发、线上环境、大数据量以及效率和成本的问题。
借着回答这个问题的机会,顺带聊聊生成测试数据的几种方法。
1、手动生成:编写SQL语句在数据库中写入数据。
以电商业务为例,模拟用户下单需要有商品有库存,可以在数据库通过编写SQL语句,插入一条商品的SKU和库存数据,然后在执行测试用例时使用。
这种方式简单粗暴,适用于功能测试场景,但不足之处在于容易造成测试环境数据污染,且效率很低。一旦测试所需的数据量超过一定量级,则手动生成测试数据的效率会大大降低。
2、跑批生成:即通过调用业务逻辑接口或批处理任务生成。
在集成测试阶段(接口测试),或者回归测试阶段(自动化测试),有大量的测试用例需要执行。这个时候手动生成测试数据效率就显得很低,且生成的数据很可能不具备业务逻辑上的连贯性。
这个时候可以通过调用业务逻辑接口或者批处理任务,批量生成测试数据文件,然后在执行测试用例时直接引用即可。
当然,这种方式适用于功能和接口测试场景,一旦涉及到几百上千条测试用例执行或者端到端测试场景,这种方式的不足就会体现出来。
特别是对于大规模的自动化测试来说,除了要考虑数据量级、业务链路的数据透传,还要考虑数据的幂等和唯一性等多种因素。
3、线上数据脱敏导出:将生产环境数据库的数据进行脱敏处理后导出使用。
这种方式在六七年前生产全链路压测和线上自动化业务巡检中使用频次较高,后来随着安全审计和风控政策变化,这种方式因为成本高时间久风险大的因素,逐渐被其他更好的方式所替代。
当然,在团队基础技术设施建设还不够完善成熟时,如果你要开展线上环境性能测试,或者线上业务自动化巡检,这种方式是技术演进的必经之路。
所以的脱敏,即安全团队通过对导出数据涉及到的库表和字段进行审核校验,给出结论(哪些可以导出,哪些不可以;哪些需要脱敏,哪些不需要)。
所谓敏感数据,即用户的真实姓名、电话号码、收货地址、银行卡号等信息。常见的处理方式是通过工具生成规则,在导出时将敏感数据替换为测试可用的符合规则和业务逻辑的数据(如电话号码,替换为11100000001)。
话说回来,线上数据脱敏导出的优势还是很明显的,可以生成大数据量的符合业务规则的测试数据。但不足之处在于比较耗时间(安全审计),成本比较高(人力成本、数据存储成本)。
4、线上流量录制回放:借助工具录制线上环境用户真实请求数据并保存使用。
流量录制回放的应用场景很丰富,在性能测试、回归测试、自动化测试以及线上问题快速修复方面有广泛的应用前景,可以帮助技术团队解决复杂业务场景和系统架构下的稳定性保障以及研发过程效率问题。
但看似完美的技术方案在团队中落地时,要面临很多的挑战,主要有如下几点:
- 绝大多数业务都有各种登录状态校验和风控安全考量,录制的数据面临各种校验不通过的问题。
- 很多业务场景非幂等,比如某商品只允许同一ID下单一次,比如三方支付回调和三单匹配问题。
- 很多系统存在各种内外部依赖调用,而录制的数据如果不经过处理直接回放,很多场景会报错。
上述三点主要是技术层面的挑战,在实际工作中,难以落地的原因往往不是技术本身的问题,而是投入产出比的问题。
首先,流量录制回放本身对团队的基础技术设施建设要求较高,这背后就是高昂的前期投入成本和时间成本。
其次,录制的数据要保存、脱敏、加工处理,还要和业务链路以及场景匹配,这个过程只能由工程师人工来进行,且不是短时间就能梳理清楚的,这又是成本的一部分。
再次,技术从调研到完全落地,需要投入试错成本,也需要时间和人力资源去配合。在降本增效大环境下,企业很难在短期内看不到明显直接效益的方向投入巨额成本。
最后,最关键的一点:技术团队从上到下都背负着KPI,越是优秀复杂的技术,落地所需的时间和人力成本越高,KPI会倒逼领导做出短视的决定,这无关对技术的信仰和认可,只关乎个人的职场生存问题。
回答一下这位同学提出的问题。
首先,从问题描述来看,执行一次线上压测基本需要千万级的数据量。上述所说的四种测试数据生成方式中,比较适合她的是第二种和第三种数据生成方法,即:基础铺底数据用线上数据脱敏导出,测试的参数化数据通过跑批生成数据文件。
其次,大数据量的存储,且还要考虑压测时测试数据读取的时延因素。在平衡效率和成本的前提下,有两种解决办法:
- 花钱办法:Redis升配扩容按量购买(30G),压测完成释放资源即可(显性成本高,隐性成本极低)。
- 笨拙办法:将压测数据文件,按照压测节点数量进行水平切割,然后数据文件放压测机本地,这样读取测试数据很快,但文件水平切割和可用性验证比较麻烦。
最后,回答一下延伸问题:自研压测平台,如何支持大数据量的数据在项目中应用实践?
这个问题其实背后隐含两个问题:即数据的生成和存储引用。数据生成的几种方式上面已经介绍过了,这里单独说说测试数据的存储和引用。测试数据的存储和引用有两种方法:
- 如果线上大规模的压测较多,则可以采用轻量级数据库如SQLite进行测试数据存储,压测时直接读取引用即可。
- 如果日常测试环境压测较多,则可以将测试数据保存为文件,压测前通过平台将压测脚本和测试数据文件存储到对象存储组件中。每个测试数据文件和压测任务通过ID绑定,压测执行时下发压测脚本和压测数据文件到压测执行节点,执行完毕删除即可。