• 基于滑动窗口的性能指标衡量算法


    前言


    在复杂的分布式系统中,存在着各种性能指标,比如系统请求数,请求响应时间等等。这些指标在一定程度上可以反映出系统运行的快慢程度。但是这里我们如何做到更加准确的判断,而不是说只要出现异常指标,就认定系统有问题,显然这是不合理的。今天,笔者来为大家讲述基于滑动窗口的性能比较算法。如何收集,利用历史数据,来进行当前性能指标的比较。

    基于滑动窗口的数据采集


    当我们说系统出现“变慢”现象的时候,这个其实是和“过去的时间”作对比,所以我们感觉到它有点慢。同样的,我们要想更加科学地比较这其中的性能差异,就需要用到历史数据。

    对于历史数据而言,因为时间是连续的,所以我们要对时间做分片,也就是说,是一段,一段的。这一段的周期可以是10分钟,或半小时等等。在这里,我们用更加专业的词语描述,就叫窗口。每个窗口对应一定的时间区间,随着时间向前滑动。对于每个窗口内,都会有对应时间区间内的性能统计指标数据,比如说我们有该窗口内的总请求数,以及总耗时,这个时候我们可以求出这个窗口的平均响应时间。

    那么有了这些窗口数据,我们如何去使用这些数据呢?一个重要的原则是保证数据指标的平滑性。简单地说,我们不能简单暴力地直接使用上个窗口的数据,然后规定出一个规则,比如超出上个指标多少多少倍以上,当前系统就认定为“慢”的。

    一种更平滑的做法是,在当前窗口即将结束时,获取到上个窗口的数据,乘上衰减因子,再叠加当前窗口的即时数据,然后把这2个数据的和作为新的“上个窗口”的指标数据。等这个时间窗口过去了,这个衡量阈值就是刚刚过去的窗口的指标平均值。

    图示过程如下:
    在这里插入图片描述

    通过以上步骤算出的上个窗口的性能数据,就可以拿来与当前数据进行比较,如果数值超过前面的阈值数据,就表明,系统变得异常了。

    基于滑动窗口的衰减算法


    下面是基于滑动窗口的衰减算法(以系统响应时间为衡量指标),大家可以对照上面笔者阐述的过程。

      /**
       * 在当前窗口的尾声阶段,做窗口的滑动
       * @param enableDecay
       */
      void updateAverageResponseTime(boolean enableDecay) {
        for (int i = 0; i < numLevels; i++) {
          double averageResponseTime = 0;
          // 获取当前窗口的指标数据,算出平均响应时间
          long totalResponseTime = responseTimeTotalInCurrWindow.get(i);
          long responseTimeCount = responseTimeCountInCurrWindow.get(i);
          if (responseTimeCount > 0) {
            averageResponseTime = (double) totalResponseTime / responseTimeCount;
          }
          // 获取上个窗口的数据
          final double lastAvg = responseTimeAvgInLastWindow.get(i);
          if (lastAvg > PRECISION || averageResponseTime > PRECISION) {
            if (enableDecay) {
              // 算出新的值,当前平均时间+上个窗口的衰减值得到
              final double decayed = decayFactor * lastAvg + averageResponseTime;
              // 新的值作为上个窗口的新的数据值
              responseTimeAvgInLastWindow.set(i, decayed);
            } else {
              // 不考虑衰减的情况
              responseTimeAvgInLastWindow.set(i, averageResponseTime);
            }
          } else {
            responseTimeAvgInLastWindow.set(i, 0);
          }
          responseTimeCountInLastWindow.set(i, responseTimeCount);
          if (LOG.isDebugEnabled()) {
            LOG.debug("updateAverageResponseTime queue: {} Average: {} Count: {}",
                i, averageResponseTime, responseTimeCount);
          }
          
          // 重置当前窗口数据,准备下个窗口的数据统计
          responseTimeTotalInCurrWindow.set(i, 0);
          responseTimeCountInCurrWindow.set(i, 0);
        }
      }
    

    然后将此衰减操作,放在定时器里,就能模拟出滑动窗口的效果了

  • 相关阅读:
    luogu P2827 蚯蚓
    CHOI1001/1002 火车进出栈问题
    hdoj4699 Editor
    反弹shell监控
    AppScan 9.0.3.6 crack
    Spectre & Meltdown Checker – CPU芯片漏洞检查脚本Linux版
    Microsoft IIS WebDav 'ScStoragePathFromUrl' Remote Buffer Overflow (CVE-2017-7269)
    Shodan新手使用指南
    The Art of Subdomain Enumeration (转)
    DDOS攻击方式总结 (转)
  • 原文地址:https://www.cnblogs.com/bianqi/p/12183590.html
Copyright © 2020-2023  润新知