首页 > 其他分享 >想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!

时间:2023-04-24 23:01:01浏览次数:48  
标签:场景 性能 用户 缓存 参数 篇文章 数据量 数据

性能项目中,性能数据是重要的输入资源。但有人用极少的数据,来做较大压力,显然不符合真实场景,虽然拿到的结果好看,但无价值。

性能场景中的数据到底应该做成啥样?RESAR性能工程中,场景里使用的数据要满足:

  • 符合真实环境中的数据分布
    才能模拟出相应的IO操作
  • 符合真实用户输入的数据
    以真正模拟真实环境中的用户操作

分别对应:铺底数据和参数化数据。

1 铺底数据

线上系统架构中,系统常用到的数据分为:

  • 静态数据(红点)
  • 动态数据(绿点)

这也是性能场景中要存入的铺底数据:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据库

若无铺底数据,相当于一个空系统。但生产环境中,这系统肯定不会空,所以要有足够数据。若数据不真实,就无法模拟生产上有真实数据的场景,如应用的内存占用、数据库IO能力、网络吞吐能力。

静态数据,易出现的问题是:

  • 一想到占网络带宽大,就觉得要用CDN
  • 或觉得不模拟静态数据,就不符合真实场景,不支持我们的优化结果

其实数据放在哪,怎么做合理,怎么做成本低,都要综合考虑,不是随大流:

  • 有的官方门户网站没啥流量,技术规划时非把几个图片放CDN,以显示架构多先进
  • 一些企业认为网站上的图片很重要,不懂技术又寻找安全感,非把图片都放到自己的服务器。本来图片就很大,一张有3~4M,用户一访问,自然就慢

这两种极端都不可取。外行指使内行干活,基本没好结果,因为有些外行觉得只要压力发起就可,细节上根本不在乎结果。处理这样问题的最合理方式:

  • 先分析业务逻辑
  • 再判断技术架构实现

1.1 静态数据

通常有两个可存放地方:

  • 服务端的Web层
  • CDN

大系统的流量大,网络带宽就得多。这种情况下,数据必然要放CDN。如果不使用 CDN 技术,数据需要从一个中心服务器传输到用户的设备上,会导致:

  1. 延迟高:由于数据需要从远程服务器传输,因此会增加访问的延迟,降低用户体验。
  2. 网络拥塞:如果所有用户都从同一个服务器上请求数据,会导致网络拥塞,降低整个系统的响应能力。
  3. 安全性问题:如果所有用户都从同一个服务器上请求数据,这也意味着所有用户的数据都存储在同一个地方,一旦服务器遭受attack或数据泄漏,用户的数据就会受到威胁。

因此,使用 CDN 技术可以将数据存储在距离用户更近的服务器上,可以提高访问速度和响应能力,减少延迟和网络拥塞的问题,并且可以提高系统的安全性。

对一些小的业务系统,由于用户不多,整体网络流量要求也少,可将静态数据直接放到负载均衡服务器(如Nginx)或应用服务器。用户访问一次之后,后续访问直接走本地缓存,对系统压力也不会产生多大影响。

1.2 动态数据

需分析,因为有些动态数据可放CDN。

  • 不用任何预热加载时,这些动态数据都存DB
  • 使用预热加载时,这些数据就会转到缓存(也取决于架构设计和代码实现),变成:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据_02

按这样逻辑,真实场景中业务操作的数据量实际有多少,我们就要模拟多少,不然会出现一些问题。当模拟数据量与实际数据量差别较大,会对DB、Cache等造成不同

1.3 影响

① 对DB压力的区别

设线上系统中100万用户,压测时,由于无生产数据,造数据又麻烦,就直接使用1000条甚至更低用户量做性能场景。

一个表里有100万条数据和1000条数据的差别是啥?前提条件:同样硬件环境、数据库、表结构、索引,只是两张表的数据不同。两条SQL:

select * from ob_tuning.temp1_1000 where id = '3959805';
 select * from ob_tuning.temp2_100w where id = '3959805';

因为表数据量不同:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据_03

表操作细节。第一个表(用户量1000):

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据库_04

第二个表(用户量100w):

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_05

只需对比“executing”行就能看到明显差距,它告诉我们当执行语句时,需要的CPU时间明显因为数据量增加而增加。所以,若无足够铺底数据放在性能场景,一开始便注定悲剧。

② 缓存的区别

数据量的多少在缓存中有明显区别:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据库_06

场景中用的数据量越多,缓存必然要求越大。

③ 压力工具使用的区别

压力工具中使用的数据多少,不仅影响着压力工具本身需要的内存,同时也影响着性能场景的执行结果。

④ 网络的区别

不同的数据量,不管是走缓存,还是数据库,对客户端和服务器之间的网络消耗都是差不多的。只要不是缓存在客户那边,都是要走到服务器里转一圈的。

所以我们认为,数据量是多还是少,对客户端和服务器之间的网络的压力没有什么区别。如果你用的是CDN,那可以做另外的考虑。

⑤ 应用的区别

如果不是在应用中直接缓存数据,我们也认为对应用没什么区别,反正不管是什么样的请求过来,都是要到缓存或数据库中去取数据的,应用的Self Time不会有什么差别,方法依旧要执行。但是,如果你的应用是直接在应用的缓存中存数据的,那就有区别了,同样也是数据量越大,对内存的要求就越大。

基于这几点,可以看到有两个较重要环节:数据库和缓存,这是直接影响。

间接影响,比如数据在数据库中执行得慢了,在同步调用的应用中必然需要更多的应用线程来处理。

假设有一个100 TPS的系统,先忽略其他时间,只看数据库时间。如果数据库执行需要10ms,那应用只需要一个线程就能处理完了。如果数据库需要100ms,而我们仍想达100TPS,应用就得有10个线程同时处理。

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据_07

整个链路上的所有线程、队列、超时等都会因为受到数据量的影响而产生大的变化。

要想模拟出生产时候的样子,铺底数据不能含糊。

2 参数化数据

场景中该用多少量数据,是性能场景中最容易出问题的环节。

参数化数据量应该多少,取决于场景运行多长时间。而在场景运行中,通常用到两类数据:

  • 唯一性数据
  • 可重复使用的数据

2.1 计算方式

① 唯一性数据(如用户数据)

要使用多少参数化数据很容易计算。比如一个运行半小时的场景,TPS如果是100的话,就要18万数据量:

$数据量 = 30min \times 60s \times 100TPS = 18w$

② 可重复使用的数据量

要分析真实业务场景中如何重复,如电商系统中商品的数据量,参数化时就能重复,毕竟多个人是可同时购买同一商品。我们假设平均有1000个用户在10个商品中,那当我们有18万个用户时,就需要1800个商品:

$商品数量 = 18w用户 \div 1000用户 \times 10 商品 = 1800 商品$

若参数化数据量太大,在压力工具中处理不了咋办?如JMeter处理文件参数化数据时,参数化文件太长,会导致JMeter消耗更多时间。这种参数化数据量要求多的情况,可采用连接远程缓存(如Redis)或数据库(如MySQL)的方式做参数化。

2.2 连接Redis做参数化

方法一:直接在JMeter写Beanshell连接Redis取数据

import redis.clients.jedis.Jedis;
   //连接本地的 Redis 服务
 Jedis jedis = new Jedis("172.16.106.130",30379);
 log.info("服务正在运行: "+jedis.ping());
 String key = vars.get("username");
 String value = vars.get("token");
 vars.put("tokenredis",jedis.get(key));

方法二:使用Redis Data Set组件

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据_08

这俩都能用Redis做参数化的数据源。

2.3 连接MySQL做参数化

① 创建一个JDBC Connection Configuration。

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据_09

配置好连接信息,如用户名密码:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_10

② 创建一个JDBC Request

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据库_11

用JDBC Request把数据取回来:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_12

③ 用${user_name}引用参数

完成上述三步,就实现了用DB的方式做参数化。

3 怎么造数据

  • 用户数据
  • 地址数据
  • 商品数据
  • 订单数据

数据量如何设置?

根据第4讲的性能方案,登录TPS如果是每秒150,并且如果按容量场景的需求,在场景连续递增时,大概在20分钟内(这是一个经验值,在具体的场景执行中也会有变化)会递增到最大值,然后再执行10分钟,也就是说总时间大概为30分钟。

但是因为场景是递增的,一开始我们并没有要求达到150TPS,同时登录场景TPS最大值能达到多少,我们现在也没法预知。根据经验来看的话,登录的TPS在当前的硬件环境中,就算是不走缓存,达到三、四百应该是没有多大问题的。

如果按最大400TPS来算,跑半个小时,需要的数据量就是54万,而我们造出来的用户量要远远大于这个量级。这里我们就先造200万的用户量,因为地址的数据量肯定大于用户的数据量,所以会多于200万。

先查当前DB中的数据量,再确定要造多少。

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_13

这数据量级明显不够。

怎么造出那么多数据量?造的数据主要分为:用户数据和订单数据。

  • 登录用户

先了解表结构,造出数据只有符合业务逻辑才能使用。看用户表结构和数据:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据库_14

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_15

地址表:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_16

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_17

造数据时,不要往DB直接写存储过程插数据,除非你清楚表之间关系,且存储过程写得6。否则你会把DB弄得一团乱,最后不得不在数据库的表里改数据。推荐使用接口直接调用来造数据,操作简单,较安全。

代码造数据,就要做下面的分析。

用户表和地址表有对应关系,可通过下面代码查,地址表中的MemberID就是用户ID

@Override
 public int add(UmsMemberReceiveAddress address) {
     UmsMember currentMember = memberService.getCurrentMember();
     address.setMemberId(currentMember.getId());
     return addressMapper.insert(address);
 }

造用户数据,就是实现注册流程。

先分析用户注册的代码,直接把其中的注册代码部分拿过来用。具体调用代码:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_参数化_18

造数据需要关心注册流程?若我们是调接口造数据,就不需要;但若写代码开启多线程造数据,就得了解接口之间的调用关系。

截出中间一部分,分析它们的调用关系:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据库_19

注册用户表中的密码都是加密的,可通过注册用户实现类代码:

@Override
 public void register(String username, String password, String telephone, String authCode) {
 ...............................
     //获取默认会员等级并设置
     UmsMemberLevelExample levelExample = new UmsMemberLevelExample();
     levelExample.createCriteria().andDefaultStatusEqualTo(1)  ;
     List<UmsMemberLevel> memberLevelList = memberLevelMapper.selectByExample(levelExample);
     if (!CollectionUtils.isEmpty(memberLevelList)) {
         umsMember.setMemberLevelId(memberLevelList.get(0).getId());
     }
     //插入用户
     memberMapper.insert(umsMember);
     umsMember.setPassword(null);
 }

就可直接写一段代码来造用户数据:《造用户代码.java》

有用户数据,还要下单用户的地址等详细信息,才能完成下单。

  • 用户地址

根据用户地址资源路径找到Controller层,查看用户地址的代码调用关系,如下:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据_20

然后找到用户地址的关键代码:

@Override
 public int add(UmsMemberReceiveAddress address) {
     UmsMember currentMember = memberService.getCurrentMember();
     address.setMemberId(currentMember.getId());
     //插入地址
     return addressMapper.insert(address);
 }

从这段代码中,我们可以观察到这几个信息:

  • 调用地址接口需要用户登陆态,通过登陆态来解析用户ID号;
  • 用户ID号是地址代码中的MemberID号;
  • 用户ID号是自增加。

具体参考请见《造用户地址代码.java》

通过上面代码,再开启Java线程池,就可把基础数据快速造完。造用户地址数据的时间记录:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据_21

最后造出:

想要性能提升?看看这篇文章告诉你性能场景的数据该怎么做!_数据库_22

表中的订单数据会在做基准场景时补充上去。等这些数据量都有了,我们在容量场景中就有了足够的铺底数据。

4 总结

性能场景中的数据到底应该做成什么样子。

造数据方法很多,不用拘泥于某种造数据手段,只要能快速造足够数据量就好。

RESAR性能工程中,性能场景需要两类数据:铺底数据和参数化数据。铺底数据需满足:

  • 一定要造出符合生产量级的数据量;
  • 数据量要真实模拟出生产的数据分布;
  • 数据要真实可用。

参数化数据需要满足这两个条件:

  • 参数化数据量要足够;
  • 要符合真实用户的输入数据。

有这些知识,就不会造数据时混乱。

5 FAQ

  1. 为何要造符合生产量级的数据量?
  2. 为什么参数化时要用符合真实用户的输入数据?

通常我们执行性能脚本时不会执行一次,若按上面30min 100TPS的场景,对不可重复使用的数据,若我们每次执行前做一次数据,太不易用啦,但不造数据还不行,如何解决这样的数据问题?做数据库备份回滚。

静态铺地数据指图片、视频这些吗?是的。

参数化数据是否影响压测机的性能,看压测机压力就可以了吧?是的。不过要分析了参数化数据量的具体影响才能判断。

若压测环境跟生产环境硬件配置不对等,那数据量是否也等比缩放?也要缩放,不过不一定等比。要做基准测试才知道。

参数化直接从DB取,连接DB,查询数据需消耗时间,且占用数据库资源,这种参数化方式很明显对压测的性能有影响,为何推荐这种方式?

在参数化数据多的时候,建议用缓存或数据库中直接取数据的方式。但是你可以不用被测系统的缓存或数据库,独立搭建一个专门存参数化数据的缓存或数据库即可。

jemeter参数化文件一般超过多少条数据量会使jmeter成为瓶颈?没有定论。还是得看一下参数化的是什么。

造出生产量级数,确保应用,数据库,缓存在生产压力下运行;参数化用户输入数据,保障了数据多样性,造数很容易造成数据同化严重,热点集中,不能再现真实,400TPS跑半个小时,是否应该是72万数据量?

若数据在每个用户使用时是唯一的,那就应该是72万的数据量。

“对于唯一性数据(比如用户数据)来说,我们需要使用多少参数化数据是非常容易计算的。比如一个运行半小时的场景,TPS 如果是 100 的话,那就需要 18 万的数据量”要模拟每一个压测请求都是不同的用户发起的,这里需要构造18万个不同用户。

铺底数据就是已存在的数据,参数化数据就是压力测试发起请求时产生的新数据?

参数化数据有两种。一种是用户输入的但数据在铺底数据中没有;还有一种是铺底数据中必须有的数据,比如说用户名之类的。

真实环境下单都是要真正的支付钱的,这个怎么解决

如果对方提供测试系统就可以连。如果不提供,那只能mock了

尽量模拟真实用户效果,但像我们测试web一般都是忽略了css,js等直接测试主接口,这是否合理?

对后端的压力来说,是合理的。若从用户角度,显然不合理。 所以要做相应换算。

标签:场景,性能,用户,缓存,参数,篇文章,数据量,数据
From: https://blog.51cto.com/u_11440114/6222011

相关文章

  • tracecompass 基于trace+log 分析系统性能问题的gui 工具
    tracecompass是eclipse社区贡献的,支持对于trace以及log进行方便的分析,可以用来快速分析系统性能问题支持多种trace格式,包含了linux,标准jaeger,linpacp,lltng,gdbtrace是一个很不错的工具,同时官方也提供了比较完备的资料可以参考说明tracecompass是一个值得使用的工具,值得......
  • MySQL性能分析工具的使用
    在数据库调优种,我们的目标就是响应时间更快,吞吐量更大。利用宏观的监控工具和微观的日志分析可以帮我们快速找到调优的思路或方法。一、数据库服务器的优化步骤   二、查看系统性能参数在MySQL种,可以使用showstatus语句查询一些MySQL数据库服务器的性能参数和执行频率......
  • 性能测试常用语
    QPSQueriesPerSecond(读操作)意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。TPS(写操作)是TransactionsPerSecond的缩写,也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户机向服务器......
  • Rust、Go 和 Swift 在性能和并发性方面有何差异?
    Rust是一种系统编程语言,旨在快速、安全和并发。其性能令人印象深刻,可以生成快速高效的机器代码。Rust 的编译器使用 LLVM 基础架构,它针对目标架构优化了代码。此外,Rust 的所有权和借用系统确保内存得到有效管理,没有任何运行时开销。Rust的并发模型是基于actor模型的,也就是说并......
  • 浅析低代码开发的典型应用构建场景
    在数字经济蓬勃发展的大势之下,企业软件开发人员供给不足、开发速度慢、开发成本高、数字化和智能化成效不明显等问题日益凸出,阻碍了企业的数字化转型。而近年来,低代码的出现推动了经济社会的全面提效,也成为人才供求矛盾的润滑剂。低代码迎合企业数字化转型需求,一方面降低软件开发......
  • Redis Plus 来了,性能炸裂!
    来源:https://developer.aliyun.com/article/7052391什么是KeyDB?KeyDB是Redis的高性能分支,专注于多线程,内存效率和高吞吐量。除了多线程之外,KeyDB还具有仅在RedisEnterprise中可用的功能,例如ActiveReplication,FLASH存储支持以及一些根本不可用的功能,例如直接备份到AWSS3。Ke......
  • 性能测试-全栈性能测试修炼宝典jmeter实战【杭州多测师_王sir】【杭州多测师】
    全栈性能测试修炼宝典jmeter实战中关于tps计算和并发线程数的计算、以及性能场景的设计 ......
  • PostgreSQL 性能优化之 - 大锁与long sql/xact的蝴蝶效应
    PostgreSQL性能优化之-大锁与longsql/xact的蝴蝶效应来自:阿里云数据库 2016-03-16 6554举报简介:在使用数据库时,某些特定的因素结合在一起,就可能引发蝴蝶效应。导致数据库性能的急剧下降。本文要讲的是和以下几个因素有关的:因素1PG的锁排队机制,即使没有获得锁,只要在锁......
  • 软件工程:阿姆达尔定律,性能设计和优化的指导原则
    hi,我是熵减,见字如面。在软件开发中,你是否做过性能的优化,譬如:有一个图片处理的程序,其中包含一个函数用于对图片进行滤镜处理。该函数中包含两个部分:一个可并行化的部分和一个串行部分。可并行化的部分用于对图片的每个像素进行计算,而串行部分用于对处理后的图片进行保存操作。......
  • Mybatis中的<![CDATA[]]>标签在判断日期场景中的使用
    背景在使用mybatis时我们sql是写在xml映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义。如大于号>会被转义为>转义后的可读性不是很直观,如果想让其看起来更加直观可读性更强的话,则需要使用<![CDATA[]]>来圈起来不被转义的符号以此来解决这个问题。......