写点什么

Aeron 中这么多空闲策略选哪个?

用户头像
BUG侦探
关注
发布于: 刚刚
Aeron中这么多空闲策略选哪个?

接上文《Aeron 是什么?》https://xie.infoq.cn/article/27422063a2cadcc054187135e


Aeron 提供了一系列等待策略,一般是应用于消息订阅程序,用来定义没有消息可以处理的时候应用线程应该做什么。

1. IdleStrategy 类型

空闲策略接口定义了两个方法:

  1. idle:空闲的动作,比如 sleep;

  2. reset:重置内部状态

通过这两个方法就能实现不同的空闲策略。

1.1 SleepingIdleStrategy

调用 LockSupport.parkNanos(this.sleepPeriodNs) 让出一段 CPU 时间。

1.2 SleepingMillisIdleStrategy

调用 Thread.sleep(this.sleepPeriodMs) 让出一段 CPU 时间。

适用于机器资源较低或者应用逻辑复杂的场景。

LockSupport.parkNanos 和 Thread.sleep 的主要区别在于 parkNanos 不会被中断,并且性能更好。

1.3 YieldingIdleStrategy

通过调用 Thread.yield() 让出当前线程的 CPU 时间片,重新变成就绪状态,并重新竞争 CPU 调度,它可能会获取到,也有可能被其他线程获取到。

1.4 NoOpIdleStrategy

空实现,什么都不做。

这可能导致 TTSP (Time To SafePoint) 问题,可以通过添加 JVM 参数解决:-XX:CompileCommand=dontinline,org.agrona.concurrent.NoOpIdleStrategy::idle。

1.5 BusySpinIdleStrategy

通过自旋(ThreadHints.onSpinWait())来等待,因为自旋期间不会放弃 CPU 使用权,所以这种策略 CPU 占用率会非常高,适用于高吞吐,低延迟,硬件资源充足的场景。

另外这也可能导致 TTSP 问题,解决方法与上面一样。

1.6 BackoffIdleStrategy

自旋 + yield + parkNanos,在性能和 CPU 占用率之间有很好的折中,延迟不均匀,是 aeron 的默认策略。

几个核心参数:

  • maxSpins:最多执行几次 ThreadHints.onSpinWait();

  • maxYields:最多执行几次 Thread.yield();

  • minParkPeriodNs:parkNanos 的最短时间限制;

  • maxParkPeriodNs:parkNanos 的最长时间限制。

2. 测试

我们使用 Aeron Ipc 做为 Service Mesh Sidecar 的通信组件,下面测试了两个服务之间的时延情况,重点关注了 BusySpinIdleStrategy 和 BackoffIdleStrategy 两种等待策略,以下是它们的测试对比结果:

(测试固定 1000 QPS)

需要说明的是,以上的平均时延并不是 Aeron Ipc 这一步的时延,而是我们 Service Mesh sidecar 场景端到端的平均时延。

总结

从测试结果来看,如果不关心 CPU 占用率的话,使用 BusySpinIdleStrategy 或者配置一些激进的 BackoffIdleStrategy 参数,可以达到极低的时延;但是如果需要平衡 CPU 占用率那么时延会增加一些。







发布于: 刚刚阅读数: 2
用户头像

BUG侦探

关注

还未添加个人签名 2021.06.08 加入

专注于发掘程序员/工程师的有趣灵魂,对工作中的思路与总结进行闪光播报。

评论

发布
暂无评论
Aeron中这么多空闲策略选哪个?