资讯专栏INFORMATION COLUMN

聊聊Elasticsearch的ExponentiallyWeightedMovingAverage

Tony_Zby / 1848人阅读

摘要:序本文主要研究一下的实现了,它是线程安全的其构造器要求输入及越大表示新数据权重越大旧数据权重越小返回的是的值,不过它存储的是的形式,返回的时候使用转换会方法使用计算新值,然后使用方法来实现原子更新实例方法测试算法的计算逻辑测试

本文主要研究一下Elasticsearch的ExponentiallyWeightedMovingAverage

ExponentiallyWeightedMovingAverage

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/ExponentiallyWeightedMovingAverage.java

public class ExponentiallyWeightedMovingAverage {

    private final double alpha;
    private final AtomicLong averageBits;

    /**
     * Create a new EWMA with a given {@code alpha} and {@code initialAvg}. A smaller alpha means
     * that new data points will have less weight, where a high alpha means older data points will
     * have a lower influence.
     */
    public ExponentiallyWeightedMovingAverage(double alpha, double initialAvg) {
        if (alpha < 0 || alpha > 1) {
            throw new IllegalArgumentException("alpha must be greater or equal to 0 and less than or equal to 1");
        }
        this.alpha = alpha;
        this.averageBits = new AtomicLong(Double.doubleToLongBits(initialAvg));
    }

    public double getAverage() {
        return Double.longBitsToDouble(this.averageBits.get());
    }

    public void addValue(double newValue) {
        boolean successful = false;
        do {
            final long currentBits = this.averageBits.get();
            final double currentAvg = getAverage();
            final double newAvg = (alpha * newValue) + ((1 - alpha) * currentAvg);
            final long newBits = Double.doubleToLongBits(newAvg);
            successful = averageBits.compareAndSet(currentBits, newBits);
        } while (successful == false);
    }
}

ExponentiallyWeightedMovingAverage实现了EWMA,它是线程安全的;其构造器要求输入alpha及initialAvg;alpha越大表示新数据权重越大旧数据权重越小

getAverage返回的是averageBits的值,不过它存储的是double的bit形式,返回的时候使用Double.longBitsToDouble转换会double

addValue方法使用(alpha * newValue) + ((1 - alpha) * currentAvg)计算新值,然后使用averageBits.compareAndSet方法来实现原子更新

实例

elasticsearch-7.0.1/server/src/test/java/org/elasticsearch/common/ExponentiallyWeightedMovingAverageTests.java

public class ExponentiallyWeightedMovingAverageTests extends ESTestCase {

    public void testEWMA() {
        final ExponentiallyWeightedMovingAverage ewma = new ExponentiallyWeightedMovingAverage(0.5, 10);
        ewma.addValue(12);
        assertThat(ewma.getAverage(), equalTo(11.0));
        ewma.addValue(10);
        ewma.addValue(15);
        ewma.addValue(13);
        assertThat(ewma.getAverage(), equalTo(12.875));
    }

    public void testInvalidAlpha() {
        IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> new ExponentiallyWeightedMovingAverage(-0.5, 10));
        assertThat(ex.getMessage(), equalTo("alpha must be greater or equal to 0 and less than or equal to 1"));

        ex = expectThrows(IllegalArgumentException.class, () -> new ExponentiallyWeightedMovingAverage(1.5, 10));
        assertThat(ex.getMessage(), equalTo("alpha must be greater or equal to 0 and less than or equal to 1"));
    }

    public void testConvergingToValue() {
        final ExponentiallyWeightedMovingAverage ewma = new ExponentiallyWeightedMovingAverage(0.5, 10000);
        for (int i = 0; i < 100000; i++) {
            ewma.addValue(1);
        }
        assertThat(ewma.getAverage(), lessThan(2.0));
    }
}

testEWMA方法测试算法的计算逻辑;testInvalidAlpha测试alpha参数的校验;testConvergingToValue则测试ewma值的收敛

小结

ExponentiallyWeightedMovingAverage实现了EWMA,它是线程安全的;其构造器要求输入alpha及initialAvg;alpha越大表示新数据权重越大旧数据权重越小

getAverage返回的是averageBits的值,不过它存储的是double的bit形式,返回的时候使用Double.longBitsToDouble转换会double

addValue方法使用(alpha * newValue) + ((1 - alpha) * currentAvg)计算新值,然后使用averageBits.compareAndSet方法来实现原子更新

doc

聊聊rsocket load balancer的Ewma

ExponentiallyWeightedMovingAverage

ExponentiallyWeightedMovingAverageTests

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/34513.html

相关文章

  • 聊聊<em>Elasticsearchem>SizeBlockingQueue

    摘要:序本文主要研究一下的继承了,同时实现了接口它的构造器要求输入及参数有个类型的参数用于记录的大小,它在等方法都会维护这个参数其中方法会判断当前是否大于等于,如果大于等于则直接返回而方法则直接抛出继承了,它提供了一个线程安全的方法 序 本文主要研究一下Elasticsearch的SizeBlockingQueue SizeBlockingQueue elasticsearch-7.0.1/...

    iliyaku 评论0 收藏0
  • 聊聊<em>Elasticsearchem>TaskScheduler

    摘要:序本文主要研究一下的定义了,它实现了接口,它包含三个属性定义了类型的,其为方法将包装为,然后到中则出来,如果不为则判断是否大于等于,条件成立的话则将其从中移除,然后在为的时候返回的方法会使用的注册一个的延时任务的方法调用了方法, 序 本文主要研究一下Elasticsearch的TaskScheduler TaskScheduler elasticsearch-7.0.1/libs/ni...

    harryhappy 评论0 收藏0
  • 聊聊<em>Elasticsearchem>RoundRobinSupplier

    摘要:序本文主要研究一下的实现了接口,其方法使用来选择数组的下标,然后返回该下标的值的构造器创建了两个,分别是及方法执行的是方法执行的是的及方法都接收参数,通过该来选取小结实现了接口,其方法使用来选择数组的下标,然后返回该下标的值的构造器创 序 本文主要研究一下Elasticsearch的RoundRobinSupplier RoundRobinSupplier elasticsearch-...

    baoxl 评论0 收藏0
  • 聊聊<em>Elasticsearchem>RunOnce

    摘要:序本文主要研究一下的实现了接口,它的构造器要求输入,同时构造了变量方法会先使用将由设置为,如果成功则执行代理的的方法方法则返回值实例方法验证了顺序多次执行的场景方法则验证了并发多次执行的场景则验证了使用作为的场景小结实现了接口,它的构 序 本文主要研究一下Elasticsearch的RunOnce RunOnce elasticsearch-7.0.1/server/src/main/...

    lindroid 评论0 收藏0
  • 聊聊<em>Elasticsearchem>AtomicArray

    摘要:序本文主要研究一下的封装了并定义了,提供了方法转换为而方法则使用了的方法来实现另外及都会判断是否为,不为则重新设置为的构造器根据创建了及方法会调用的方法来设置结果,之后判断是否都完成了,完成的话判断是否有,有则回调,没有则调用的方法 序 本文主要研究一下Elasticsearch的AtomicArray AtomicArray elasticsearch-7.0.1/server/sr...

    leanxi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<