前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >天天P图 - 分布式频控系统的设计和优化

天天P图 - 分布式频控系统的设计和优化

作者头像
天天P图攻城狮
发布2018-05-28 17:10:58
2.5K6
发布2018-05-28 17:10:58
举报
文章被收录于专栏:天天P图攻城狮天天P图攻城狮

为什么要做分布式频控系统?

相信之前刷屏的“八一军装照”和“小学生证件照”大家都不陌生。类似这样的运营活动突然涌入的巨大流量对天天P图后台造成的冲击不可小觑。就拿军装照来说,短短三小时,后台请求量就由10W/min突发到110W/min,短时间内无法调集足够多的机器来应对这些突发的流量,所以一套智能的分布式频控系统就非常有必要了。另外,随着天天P图人脸融合这一极具创意的技术知名度越来越高,也越来越多的第三方想和我们进行合作,使用我们的人脸融合能力。针对不同的第三方给予不同容量的后台处理能力也是很有必要的。综上,分布式频控系统的设计和开发提上日程。

图1 八一军装照

频控系统可用来对流量的削峰管理,使进入后台的流量尽在掌控之中,对后台的过载和雪崩防护可谓意义重大。它还可以对使用同一个接口的不同用户进行不同的频控额度管理,提供差异化服务。

当前厂内厂外很多业务都使用单机频控。单机频控只能做简单的流量拦截,简单而又粗暴,不考虑集群中各机器性能的差异性,不考虑逻辑系统的真实容量及容量可变性,进行简单的设置和拦截。要想全局频控和智能频控,还是得自己做一套!

频控策略的设计

根据一些现有方案的研究,我大致把频控策略分为以下几类:

图2 几种频控策略的对比

即时消费即时结算模式

该模式的原理是,接入层每收到一个请求都去频控中心进行频控校验,如果超限,进行拦截,如果未超限,请求放行,进行下一步的业务逻辑处理。

该方案有其优点,实现简单,频控实时性好。

但该方案对业务是阻塞的,而且性能低,每一次请求都需要访问频控中心,进行存储读写。该方案不具有接入层的抗流能力,即频控中心压力会随着接入层涌入请求量同比例放大。

预付费模式

该模式原理是,间隔一段时间去频控中心拉取一定流量额度,等这些额度消耗完了再去频控中心拉取下一批额度。根据有无额度,决定是否拦截。

该方案较第一种方案性能大幅提升,并具有极高的抗流能力。因为该模式不需要每次访问频控中心。

但该方案额度难以较好分配。一种分配方案是根据接入机数量,进行平均分配。这种方案没法考虑机器性能的差异,并且机器数并不是一成不变的,不具有良好的扩展性,而且如有机器出现故障,会影响整体的频控准确性。

先消费再结算模式

该模式是在前两种模式的基础上进行优化改进创造而来。

原理是,先放行一定数量的请求,然后批量上报到频控中心进行校验。根据校验结果,来决定接下来的请求是否拦截。

该模式是一种异步批量上报模式,对业务来说非阻塞,具有极高的性能和抗流能力。只是实时性稍差一点。但频控系统作为业务系统的辅助系统,该方案相对于其他优点来说,实时性稍差可以接受。故频控系统采用该种方案。

频控系统完整结构

如下图所示,频控系统分agent(FcAgent)和频控中心server(FcSvr)两块。agent和业务CGI部署在同一机器中,频控server负责进行频控的校验。

图3 频控系统架构图

共享内存kv用来存储各接口的频控结果,共享内存队列用来存放通过的请求记录。请求进入CGI后,只需要读取共享内存中该接口的频控结果,即可决定对该请求是否通行或者拦截。如果通行,向共享内存队列插入一条通行记录,再进行接下来其他的业务逻辑处理。FcAgent负责从共享内存队列中提取通行记录,累积到一定量后,向FcSvr进行上报检验是否频控超限,将获取的结果写回到共享内存kv中供下一次请求校验使用。

频控的配置信息存储在Redis中,使用运营系统进行频控额度等配置信息的更新。

频控计算方法

关于频控计算方法,业内主要分为计算器法、滑动窗口法、漏桶算法、令牌桶算法。计数器法简单,但是存储成本较高,而且有边界问题。

滑动窗口只是在计数器法上面进行精度再切割,降低了边界问题发生的风险,存储成本依旧很高。

漏桶算法原理是设定桶的一个恒定水流出速率,如果请求的流入速率大于桶设置的流出速率,桶自然会溢出,从而频控超限。漏桶算法可保证桶的流入速率即请求流入速率不超过设定的某一固定值。令牌桶算法本质和漏桶算法类似。只是说是定时向桶里匀速放入令牌,通过桶里是否有令牌来决定是否频控超限。

图4 漏桶算法示意图

这里采用基于漏桶算法的分布式改进算法进行频控的校验计算。

按照传统漏桶算法,当请求进来时,需要计算桶当前水量,桶剩余水量,根据剩余水量是否溢出来判断是否超限。随后更新当前时间戳,桶当前水量,已放行水量。用来进行下次的秒级频控和总额度频控。

一次频控校验需改写多个字段的值,需进行事务性保证。如果加锁的话,又极大影响了服务的性能。所以这里采取一次频控校验只需INCR更新当前桶水量即可,桶的其它信息(桶重置时间戳、秒级频控值、桶容量、已放行总量、频控总额度)进行缓存处理。

根据更新后的桶当前水量值减去这段时间流出的水量,即可知道桶的剩余水量。桶剩余水量减去桶容量,即可得桶溢出水量。

这里采用桶溢出时间这个概念进行频控拦截依据。桶溢出水量除以秒级频控值,即为桶溢出时间。桶溢出时间,即表明系统在该段溢出时间内,是不允许放入请求的。将该溢出时间返回给FcAgent,CGI在该溢出时间之后才放行新的请求。

图5 溢出时间的计算方法

频控总额度是否超限的判断依据是缓存中的已放行总量加上当前桶已放行量(桶当前水量-桶初始容量)是否超出总频控额度。

桶只有在桶配置信息发生变更或者桶长时间未有请求流入时才会进行重置。此时需要刷新桶缓存信息。

该种改进可保证频控计算的原子化,一次INCR操作即可完成秒级频控和总额度频控的校验。

异步上报的难点

几个问题制约着异步上报时间间隔不能太长也不能太短。

a) 频控延迟问题

异步上报必然会带来频控延迟问题。上报间隔越长延迟越严重。所以从这个角度看,上报间隔越小越好。

b) 突刺消耗问题

突刺消耗指一个时间周期内,前一段时间就消耗了全部流量,导致后一段时间无流量消耗,请求全部拦截。从这个角度看,上报间隔越小越好。

c) 匀速误限问题

匀速误限指请求速率不均匀导致被匀速削峰后造成误限。匀速误限一般在整体请求速率低于频控速率而局部请求速率高于频控速率的情况下发生。从这个角度看,上报间隔越长越好。

图6 匀速误限示意图

d) 频控压力问题

上报时间间隔越小,对频控中心压力越大。从这个角度看,上报间隔越小越好。

综上几个问题考虑,上报间隔既不能太小也不能太大。另外,仅仅以时间间隔作为上报依据的话,不管时间间隔设置多小,也难以解决突发高流量情况下,流量瞬间超限的情况。所以这里采用时间和个数两个维度,进行异步上报的依据。

个数维度解决频控延迟、突刺消耗、频控压力、流量突发问题,时间维度解决匀速误限、请求稀少问题。

那么,个数维度中的个数该怎么选定呢?假如全局每秒允许流入1000个请求,有10台接入机,这里的个数维度就绝对要小于1000/10,即最多累积10个请求就必须进行频控上报,否则就可能出现超限风险。当然,需要考虑频控上报到频控中心的请求延迟,所以要在该个数基础上进行一定倍数的缓冲,即设定一个缓冲倍数,个数维度即为1000/10/缓冲倍数,以该数值作为个数维度的间隔依据。

个数间隔 = 频控值/最大机器数/缓冲倍数

时间间隔 = 300ms

图7 异步上报时机

高可靠保证:容灾与纠错

a) 系统模块的容灾

系统某个模块出现故障是必须要考虑的情况。在当前分布式频控系统中,如果频控中心svr或者存储系统出现故障怎么办?常见的处理策略可能是要么请求全部放行,要么请求全部拦截。全部放行有造成冲垮业务服务的风险,全部拦截将会导致全业务不可用,显然都不是完美的解决方案。

在这里,可以引入局部频控策略。那么,局部频控的依据是什么呢?当然是上一次的频控结果了。在上一次频控结果的基础上,进行本地计算当次请求是否超限。

局部溢出时间 = max(0, (上次溢出时间 + 请求量/单机秒级频控量 - (当前时间戳-上次时间戳))

计算出的局部溢出时间如果大于0,表明请求在接下来该段时间内将进行拦截。

b) 局部纠错机制

除了对系统核心模块的容灾策略,多线程高并发下的数据准确问题也是系统高可靠的重要一环。Agent模块间隔异步批量频控校验避免了同一业务同一时刻发生频控校验的情况,然而网络异常情况下仍然可能出现频控结果逆序到达的情况。加锁太影响性能,而且发生逆序情况也是低概率事件,所以这里引入局部纠错机制对于逆序到达的频控结果直接废弃,避免对频控准确性造成影响。

那么,怎么判断频控结果是否逆序到达呢?我们的判断依据是:同一时刻收到的频控溢出时间后者必定大于前者。如同时先后收到溢出时间为30ms,20ms,则20ms这次直接剔除。

即如果该次溢出时间小于上次溢出时间减两次结果时间间隔的值,则认为该次结果为逆序,不予采信。

下图是采取容灾和纠错策略前后的频控效果图。 红色曲线代表实际请求每秒流入量,蓝色曲线代表实际请求每秒放行量。当蓝线越趋近于直线,表明频控准确率越高。

图8 无容灾纠错频控效果图

图9 有容灾纠错频控效果图

从上面两张效果图对比可以看出,局部频控和纠错解决了频控质量的波动问题,使得每秒请求放行量基本处于直线水平。

更智能的频控:动态频控

当某个调用方调用某个接口流量超过了当初设定的频控值,是不是就是直接进行拦截呢?我们这边对不同的调用方给予不同的评级,对于vip调用方(如人民日报),如果请求流量超限的话,会结合当前图片处理系统的处理能力,进行自动的频控值上调,达到动态频控的目的,最大限度地发挥图片系统的图片处理能力。

对于非vip的用户,如果流量超限,对于超限的流量也可以将流量引导到P图的下载,实现流量变现,降低图片系统的压力。

以下为动态频控流程图。多级预警、人工扩容和自动扩容相结合、超限流量变现,实现更智能的频控。

图10 动态频控流程图

极高的频控性能

a) 根据压测和线上表现,该分布式频控系统频控准确率超过99%(某时间段实际放行请求数/某时间段限制放行请求数),局部波动不超过2%(某秒多放行或少放行请求数/每秒频控值)

b) 每个业务每秒只会对频控中心产生接入机器数*缓冲倍数次请求,故接入层可抵御百万级每秒的涌入请求(取决于接入层的系统性能)

c) 2台4核8G虚拟机组成的频控中心系统性能可达10w/s,可支撑约2500个业务的频控校验

最后附上线上频控系统监控图。蓝色代表实际每秒放行请求量,红色代表实际请求涌入量。蓝色基本呈一条直线,表明频控效果良好。

图11 频控效果监控图


作者简介:jianghongwu(吴江红),天天P图后台开发工程师

文章后记: 天天P图是由腾讯公司开发的业内领先的图像处理,相机美拍的APP。欢迎扫码或搜索关注我们的微信公众号:“天天P图攻城狮”,那上面将陆续公开分享我们的技术实践,期待一起交流学习!

加入我们: 天天P图技术团队长期招聘 (1)图像处理算法工程师,(2)Android/iOS开发工程师,期待对我们感兴趣或者有推荐的技术牛人加入我们(base在上海)!联系方式:ygdai@tencent.com/keyishen@tencent.com/kesenhu@tencent.com

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 天天P图攻城狮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么要做分布式频控系统?
  • 频控策略的设计
  • 频控系统完整结构
  • 频控计算方法
  • 异步上报的难点
  • 高可靠保证:容灾与纠错
  • 更智能的频控:动态频控
  • 极高的频控性能
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档