这次讲一下Fregata重构中的一个重要内容-自动伸缩,主要是解决两个方向的问题:

1、突发流量需要人工介入,不及时也太耗费人力

2、周期性波动的数据处理,在波峰波谷时不同处理方式

为了解决这些问题,我们在重构的Topology基础上,增加了伸缩容功能,可以增减

Parser和Sink的个数。下面介绍一下伸缩功能的一个基础,那就是如何判断伸缩。

状态

基本状态

在讨论这个功能时,我们一度非常困惑于如何对状态进行定义和划分还有转化。

我们阅读了很多关于状态机的文章和demo,定了4个基础状态:

1、固定状态(不可以缩、也不可以扩)

2、最大(不可以扩,可缩)

3、最小(不可以缩,可扩)

4、中间状态(可扩,可缩)

Topology中的Parser和Sink都有自己各自的状态,独立计算互不影响。

按照其并行度的最小值、最大值、当前值来作为定义状态的基础参数

	this.statesRules.add(new FixedStatus(super.componentType, 1, 1, 1));
        this.statesRules.add(new MinStatus(super.componentType, 3, 1, 1));
        this.statesRules.add(new BriskStatus(super.componentType, 3, 1, 2));
        this.statesRules.add(new MaxStatus(super.componentType, 3, 1, 3));

匹配、转化

我们的状态匹配方式就是最简单的遍历

        for (IStatus status : this.statesRules) {
            IStatus result = status.matchStatus(upperBound, lowerBound, cur);
            if (result != null) {
                return result;
            }
        }

趋势

每个周期的监控指标都会输入到当前状态中,指标的计算会得出一个当前的趋势(伸、缩、不动)。

在当前状态中,保持一个时间序列的趋势集合,当连续N次趋势产生时,就会触发状态的改变,也会

触发一个Action事件。每种状态因为其特点不同,对趋势的处理也会有所不同。

伸缩分类

伸缩我们主要分为两类:

1、Topology的伸缩,也就是增减并行度。

2、K8s的Deployment的伸缩,也就是增减副本数。

Topology内

我们是优先对Topology进行调整,这样的代价是最小的。

Docker副本数

当Topology已经是最小时,就考虑适当的减少Docker副本,进一步释放资源。

收益

无论是哪种伸缩,都可以帮助我们在流量增大时,自动提升处理能力去应对,在数据量小的时候,减少对

外部的负担,减少Tcp连接数、HDFS小文件数、提高数据的密度等。