滑动窗口

基础

TCP滑动窗口协议(Sliding Window Protocol),是 TCP协议 的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发一个分组就停下来等待确认。因此该协议可以加速数据的传输,提高网络吞吐量。

在介绍滑动窗口的框架时候,大家先从字面理解下:

  • 滑动:说明这个窗口是移动的,也就是移动是按照一定方向来的。
  • 窗口:窗口大小并不是固定的,可以不断扩容直到满足一定的条件;也可以不断缩小,直到找到一个满足条件的最小窗口;当然也可以是固定大小。

为了便于理解,这里采用的是字符串来讲解。但是对于数组其实也是一样的。滑动窗口算法的思路是这样:

  • 1)我们在字符串 S 中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个「窗口」。

  • 2)我们先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的字符串符合要求(包含了 T 中的所有字符)。

  • 3)此时,我们停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的字符串不再符合要求(不包含 T 中的所有字符了)。同时,每次增加 left,我们都要更新一轮结果。

  • 4)重复第 2 和第 3 步,直到 right 到达字符串 S 的尽头。

算法

Sliding window algorithm is used to perform required operation on specific window size of given large buffer or array.

滑动窗口算法是在给定特定窗口大小的数组或字符串上执行要求的操作。

This technique shows how a nested for loop in few problems can be converted to single for loop and hence reducing the time complexity.

该技术可以将一部分问题中的嵌套循环转变为一个单循环,因此它可以减少时间复杂度。

简而言之,滑动窗口算法在一个特定大小的字符串或数组上进行操作,而不在整个字符串和数组上操作,这样就降低了问题的复杂度,从而也达到降低了循环的嵌套深度

经典实现

hystrix实现-HystrixRollingNumber

在hystrix中,一个滑动窗口,包含若干个桶(默认是10个),每个桶保存一定时间间隔内的统计数据(默认是1s)。下面看一个官方的例子:

hystrix-sliding-window.png

上图中,每个矩形框代表一个桶,每个桶记录着1秒内的4个指标数据:成功量、失败量、超时量、拒绝量。这10个桶合起来就是一个完整的滑动窗口。

从业务上讲,值得注意的是:桶对象有一个不可变的属性-windowStart,它表明该桶对象用来保存[windowStart, windowStart + bucketSizeInMillseconds)时间段内的统计信息。

从技术来讲,值得注意的是:因为每个桶都会被多个线程并发地更新指标数据,所以桶对象需要提供一些线程安全的数据结构和更新方法。为此,hystrix大量使用了CAS,而不是锁。

hystrix使用一个环形数组来维护这些桶,并且它的环形数组的实现类似于一个FIFO的队列。该数组实现有一个叫addLast(Bucket o)的方法,用于向环形数组的末尾追加新的桶对象,当数组中的元素个数没超过最大大小时,只是简单的维护尾指针;否则,在维护尾指针时,还要通过维护首指针,将第一个位置上元素剔除掉。可以看出,该环形数组的表现类似于FIFO队列。

更新统计数据时,都是向当前最新的bucket中更新的,因此hystrix的滑动窗口类HystrixRollingNumber中提供了getCurrentBucket()方法,获取当前最新的bucket。其执行流程如下:

hystrix-window.png

可以看出:滑动窗口每次只向前滑动一个bucket,因此非常的平滑。

应用

滑动窗口计数器

滑动窗口计数器在普通的固定窗口计数器基础上又划分了若干个小窗口,每个小窗口维护一个独立的计数器,然后随着请求时间的推移,这个滑动串口按照小窗口的步长向前推进,同时保证在推进中滑动窗口中所有小窗口中的请求值不超过门限值,可以解决固定窗口中的一些缺陷(如突刺现象)。

Q1:每个bucket什么时候更新,谁更新的,定时器?

Q2:如何保证更新时间的精度,保证时间间隔相同,在每个桶的边界更新,稍有阻塞,时间到下一个bucket怎样处理?

hystrix-go

参考

  1. 滑动窗口算法基本原理与实践
  2. 如何实现滑动窗口
posted @ 2018-06-16 10:11  yuxi_o  阅读(563)  评论(0编辑  收藏  举报