前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >性能百万/s:腾讯轻量级全局流控方案详解

性能百万/s:腾讯轻量级全局流控方案详解

原创
作者头像
WeTest质量开放平台团队
修改于 2017-07-19 03:22:21
修改于 2017-07-19 03:22:21
2.7K0
举报

作者:莫家文,腾讯事务型开发工程师

商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。

原文链接:http://wetest.qq.com/lab/view/320.html

WeTest 导读

全新的全局流控实现方案,既解决了目前流控的实现难点,同时保证运行稳定且流控准确的前提下,实现更简单,部署成本更低,容灾能力更强。 该方案组件化之后,可以推广到别的有需要的部门使用,只需简单的接入和部署即可获得全局流控的能力。

一、背景

流控作为容灾体系中必不可少的一环,在请求量超过系统容量的时候,通过拒绝超量请求的方式,防止服务接口的雪崩和系统挂掉。

目前部门只具备单机流控的能力,随着业务的增长和系统复杂度的增加,单机流控越来越不能满足需要,升级流控能力日趋重要。

(一)流控分类

升级流控之前,先简单了解不同流控方式的优缺点:

对比可知,全局流控能能弥补单机流控的缺点,而动态流控又是在全局流控的基础上做更精细化的流控。

(二)现有方案分析

目前全局流控方案主要需要解决两个实现问题:

1、全局计数器使用何种存储

全局计数器存储可以使用redis,也可以使用ckv。

分布式流控很关键一点是将流控服务做成原子化。而做流控需要记录两个信息,计数和计时。比如全局流控阈值设置了5w/s的值,计数器记录了当前的请求数(计数),在达到1s时计数器需失效或清零(计时)。

计数和计时要保证原子操作,目前已知的方式有:

1)使用加锁的方式,比如ckv的cas计数,或者redis+lua技术,但在并发量大的时候,加锁的性能比较无法保证;

2)使用incr的方式,由于目前redis和ckv的incr都没过期时间设置,要满足要求(计数和计时同时原子操作),需改造redis或ckv,使得incr支持过期时间设置,目前已知有改造redis支持过期时间的案例。

2、 如何上报请求

一般统计的方式分两种:

1) 请求全量上报,这样要求存储的访问能力足够强大,优点是流控实时性得到保证;

2) 请求定时批量上报,这样存储的访问压力较小,资源消耗也更少,缺点是流控可能不实时;

一般还需要每台机器部署agent来完成上报和流控判断,业务模块与agent之间要实现通讯。

大体的逻辑结构如下:

注:图片来自文章《MSDK全局流控介绍》

实现难点:

1)将流控服务做成原子化,目前无论使用redis还是ckv,加锁方式并发下无法保证性能,原生的incr方式要解决过期时间的问题,需要的技术门槛和开发成本都比较高;

2)从上报统计方式看,全量上报对请求量巨大的业务部门来说不大可行,定时批量上报又无法保证实时流控;

3)接入全局流控每台机器都需要部署agent,agent能否正常工作影响全局流控的使用,同时部署及运维的成本不低;

二、方案设计

面对目前困难,我们提出这样的疑问: 有没有一套简单可行的方案,能解决上述问题的同时,保证开发成本较低,部署简单,运行稳定,而且流控准确的呢?

(一)轻量级流控方案

方案要点:

1、计数器的key能“计时“

首先选择使用ckv作为计数器存储,相比redis开发会更熟悉,同时维护也更容易,当然该方案也可以选择redis作为计数器存储。

既然使用ckv的cas用作计数在高并发下有性能瓶颈,那么只能使用incr的方式,同时要解决计时的问题。

方案没有对incr增加过期时间的方式,而是将时间信息写入key,把一天按时间划分(比如1s划分一个key)为若干个key作为计数器。这样每个key既能使用incr方式计数,同时也有”计时“的能力,当超过划分时间(比如1s后),就顺移到下一个key上做计数。

优势:方案用简单的方式将全局流控服务做成原子化(计数和计时原子化),开发门槛低。

2、请求统计用拉取的方式替换上报

对于请求的统计方式,一般全量上报不可行,所有业务的请求量至少1:1上报到ckv,ckv的容量和是个问题,单key也容易成为热点。定时或者定量批量上报,都无法保证实时流控,特别是请求量大的时候,流控延迟的问题会被放大。

方案抛开原有的上报思维定式,引入配额拉取的概念,替换一般统计上报的方式,取而代之的是每个key初始化时写入流控阈值,每个业务机器并非上报请求量,而是访问ckv拉取配额到本地保存,本地配额消耗完毕再次拉取,类似余库存扣减。

优势:方案减少ckv的访问量,同时保证流控的准确性。

3、部署不需要agent

已有的流控方案都需要每台业务机器部署agent,完成上报请求和流控判断的功能。这样做机器都要部署agent,同时agent的正常使用也要纳入维护。

为了做更轻量的方案,我们考虑agent的必要性,分析发现,agent要完成的功能比较简单,主要功能托管到业务流控api

这样的做法会让业务在调用流控校验时有额外的开销,开销主要是拉取配额访问ckv的时间消耗,正常是<1ms,只要每次拉取配额的值设置合理,分摊到每个请求的耗时就少的可以忽略。

比如拉取配额设置10,即正常10个请求要拉取一次配额,这时流控api会请求一次ckv拉取配额,这个业务请求耗时增加约1ms。

优势:方案不采用agent的方式,部署维护更简单。

4、全局及单机流控同时启用

考虑全局流控不可用的情况,比如ckv挂掉,能否保证业务不受影响且流控可用?

方案对容灾做了充分的考虑,主要解决方式是全局及单机流控同时启用,即基于ckv的全局流控和基于单机共享内存的单机流控都同时工作。

全局流控失效(ckv挂掉或连续超时导致拉取配额失败),流控api判断出这种情况后,暂时停止使用全局流控,而单机流控依然可以正常工作,流控api定期去探查(比如30s)全局流控是否恢复可用,再启动全局流控。

优势:方案有很好的容灾能力,容灾方式简单有效。

5、解决ckv性能瓶颈,流控性能达百万/s

由于使用ckv的incr以及配额拉取的实现方式,全局流控接入服务请求的能力得到成本增长。

目前方案单独申请了一块ckv,容量为6G,使用incr的方式,压测性能达到9w+/s。

对业务空接口(Appplatform框架)做流控压测,使用30台v6虚拟机,单机50进程,压测性能达到50w+/s。

单接口50w/s的请求的服务接入,同样也能满足多接口总体服务请求量50w+/s的全局流控需求。

上述的压测瓶颈主要是Appplatform框架的性能原因,由于拉取配额值是根据流控阈值设定(一般>10),50w+的请求量只有不到5w的ckv访问量,ckv没到瓶颈。

优势:方案使用同等的资源(单独一块6G的ckv),能满足业务的请求量更高,性能达百万/s。

6、支持扩容和动态流控升级

支持平行扩展流控能力,一套全局流控部署能满足流控的服务请求量是达百万/s,更大的服务请求量需要部署多套全局流控。

支持升级到动态流控能力,ckv写入的流控阈值是通过定时管理器完成,目前业务已经做了健康度上报,定时管理器只需要对接健康度数据,分析接口当前请求情况,动态调整流控阈值即可达到动态流控能力。

优势:方案整体简单轻量,扩容和升级都很容易。

接下来详细介绍一下具体方案的实现。

(二)流控逻辑架构

方案涉及几个功能简单、清晰的角色:

1、管理定时器:

根据配置,将频率限制任务的配额值,写入多个带时间信息的key。比如频率限制任务1配了阈值为5000/s的全局流控,那么就以每一秒生成一个kv为例:

key为task1_20170617000000、task1_20170617000001、task1_20170617000002等

value为5000

2、共享内存:

保存每一个任务流控相关的本机信息,包括流控状态、本地配额、配额锁等。

3、流控API:

业务通过流控api,请求先扣减本地配额(原子操作),如果配额<=0,就从ckv拉取配额到共享内存中,如果没配额拉取,就做说明流控生效。

(三)流控状态机

全局流控过程可以抽象出三个主要状态:

1、全局非流控状态指的是全局流控可用的情况下,但还没触发限流,业务请求可以正常通过;

2、全局流控状态指的是业务请求触发限流,请求不能通过;

3、全局失效状态指的是全局流控由于异常不可用,比如ckv访问超时或挂掉,业务请求可以正常通过;

(四)流控关键流程详解

围绕三个流控状态的跳转,抽象出整个全局流控的核心关键流程:

1、当状态为全局非流控,首先会先扣减本地配额,本地配额<=0时,就走拉取配额流程;

2、当状态为全局流控,本地配额<=0时,先判断key是否发生变化,作用是同一个时间间隔内配额已经消耗完,减少无效的拉取;

3、当状态为全局失效,会判断时间是否已经超过一个设定值,在失效时间内不会尝试拉取配额,作用是减少无效的拉取;

4、 拉取配额先获取原子锁,作用是当业务进程并发拉取时,只有获取锁成功的进程,才能拉取赔额额;

整个流程考虑了所有会发生的情况,围绕三个状态的跳转,正常及异常流程处理都很好的统一到一个流程里。

比如发送ckv不可用的故障,通过拉取配额失败的动作,很好的从正常的全局非流控状态切换到全局失效状态,又通过定时拉配额,去探查故障是否消除,如果消除就回复到全局非流控的正常状态。

三、方案关键问题

(一)机器时间不一致

由于以时间间隔做key,划分不同的时间片并写入流控配额,当机器拉取配额面临个机器时间是否一致的问题。

据了解,时间同步是通过ntp服务来完成,精度在1~50ms之间,一般情况是<10ms。

目前的时间间隔都是1s以上,ntp服务的精度已经满足。

换句话说只要保证ntp服务正常运行,全局流控的单个时间片的计数是准确的。

如果ntp服务没正运行,导致机器时间不一致,会导致同一时刻应该访问同一key的机器,访问了多个key,则会造成计数不准确。

由于ntp服务目前处理方式是通过监控流控任务一段时间内的key的变化情况,及时发现机器时间不一致的情况。具体做法是如果发现某一时刻超过两个kv的配额值发生变化,可以确认机器同一时刻访问key的分布超过合理的范围,有时间有不一致的情况。

(二)计数原子化

为了保证并发情况下配计数的准确性,会使用原子操作的方式处理计数,无需加锁。

1、全局配额是用ckv的incr方式,保证配额拉取扣减的准确;

2、本地配额累加或扣减,对共享内存使用gcc提供的__sync_add_and_fetch的原子操作方式;

(三)配额锁发生死锁

拉取配额使用了加锁,锁的方式是对对共享内存使用gcc提供__sync_bool_compare_and_swap的原子操作方式。

极端情况下,获取锁的进程core掉,就会导致锁无法释放,其他进程需要拉取配额时也获取不了锁。死锁不会影响业务请求正常通过,但由于无法拉取配额,会导致全局流控无法使用。

处理这种情况目前的方式是,判断加锁的时长是否超过合理值 ,具体做法是加锁记录当前时间,正常释放清空这个时间值,获取不了锁的进程判断加锁的时长,大于设定值(1min),说明有死锁情况,主动释放锁。

(四)配额拉取值设定

配额拉取的值的设置起到一个很关键的一步,影响流控的准确性,拉取的效率以及ckv访问压力。

拉取配额值合理,既减少ckv访问压力,减轻业务Api额外的拉取耗时(一般<1ms),同时也能保证流控准确。

拉取配额值不合理,设置过大会造成机器剩余的配额浪费,需要配额的机器可能没配额,导致产生错误流控。设置过小会导致本地配额消耗完(本地配额值<0),配额拉取滞后,造成流控生效延后,拉取次数过多,ckv访问压力大,业务api拉取效率低。

配额值的设置是:单机阈值与拉取值的比值为50。比如全局流控阈值 10000/s,机器数20,平均单机流控阈500/s,配额值设定为10。

目前是通过压测观察的经验值得来,拉取值设置是否合理,还有待后续观察和分析。

四、方案运维

(一)部署及扩展

部署:

1、管理定时器的部署,只需单独部署到脚本机上;

2、业务模块添加流控api,已经接入原来单机流控的业务,无需改动业务逻辑代码,只需要替换旧的静态库和依赖的的头文件即可(待给出详细接入);

扩展:

方案支持平行扩展,一套全局流控部署能满足流控的服务请求量是50w+/s,更大的服务请求量需要部署多套全局流控。平行扩展一套主要的变更包括:申请新的ckv,使用新的一块共享内存以及新的流控任务配置。

(二)监控报警

1、对流控任务做了可视化监控

主要监控及跟踪各流控任务的基本使用能够信息,以及当前和历史流量情况

2、机器时间不一致的监控及上报

主要监控流控任务一段时间内的key的变化情况,及时发现机器是否时间不一致

(三) 容灾/故障处理

1、管理定时器接入zk主从切换组件,在单点挂掉的情况下可以切到另外一台机器上,保证timer的可用性。

2、当ckv连接超时或无法访问时,对应的流控状态会变成全局失效,过一段时间会自动重新拉起。所以出现ckv不可用的情况,只需要恢复ckv,接入全局流控的服务会自动恢复可用状态。

五、方案升级

(一)完善监控和告警

目前流控监控只是对流控任务使用情况做了简单的展示,流控的历史情况等其他必要的信息还没能查询及展示。

还有待补充的监控有机器时间不一致监控,监控发现的问题需要告警,以便于人工及时介入。

有待规划的监控和告警后续再补充。

(二)流控方案升级

流控升级下一步是从全局流控升级到动态流控,所需健康度数据已经上报,而接入的方式目前可以直接在管理定时器上面增加配额调整的能力,这个扩展很方便。重点应该是怎么去根据上报的健康数据分析并实现动调整当前配额值。

配额调整大致的思路如下:

注:图片来自于理财通的《接入层限流介绍》

WeTest压测大师运用了沉淀十多年的内部实践经验总结,通过基于真实业务场景和用户行为进行压力测试,帮助游戏开发者发现服务器端的性能瓶颈,进行针对性的性能调优,降低服务器采购和维护成本,提高用户留存和转化率。

功能目前免费对外开放中,点击链接:http://wetest.qq.com/gaps 即可体验!

如果对使用当中有任何疑问,欢迎联系腾讯WeTest企业qq:800024531

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
天天P图 - 分布式频控系统的设计和优化
相信之前刷屏的“八一军装照”和“小学生证件照”大家都不陌生。类似这样的运营活动突然涌入的巨大流量对天天P图后台造成的冲击不可小觑。
天天P图攻城狮
2018/05/28
2.7K6
服务端频率控制的几种实现方式
对于某一个接口I,请求频率阈值T,假设请求均匀分散到N台服务器上,每台服务器上接口I的频率阈值就是T/N,这样每台机器通过检查接口I的本地请求频率就可以做频率控制。
腾讯 BBTeam 团队
2018/05/31
4.2K0
CRS : 腾讯云 Redis 产品架构解析
该文介绍了如何基于自研的Grocery框架实现可伸缩的Redis服务,并提供了成本、容量、性能等方面的优化措施。同时,还介绍了一种实现无缝数据迁移的机制,以及一种高可靠的、可扩展的、高性能的Redis服务。
腾讯云开发者社区
2017/04/27
13.9K0
CRS : 腾讯云 Redis 产品架构解析
QQ 红包技术方案全解密 (一)
serena
2017/06/06
6.3K3
QQ 红包技术方案全解密 (一)
微服务常见限流方案及TSF限流原理
在微服务高并发的一些场景下,微服务之间的调用量不断增加,大流量因素很可能会引起服务雪崩,微服务的稳定性对业务系统的影响也比较大。一般微服务容错组件都提供了限流的方式来保护我们的系统,本文主要介绍微服务限流的几种主流方案与适应的场景。
腾讯云开发者
2025/01/15
5011
微服务常见限流方案及TSF限流原理
如何保证核心链路稳定性的流控和熔断机制?
仅从设计优化、服务拆分、自动扩容等方面进行优化,有时候并不能完全解决问题。比如,有时流量增长过快,扩容流程还来不及完成,服务器可能就已经抗不住了
码农架构
2020/11/16
6150
如何保证核心链路稳定性的流控和熔断机制?
基于redis实现分布式服务限流器
在后台开发中,服务端的限流器是一个很常见并且十分有用的组件,利用好限流器可以限制请求速率,保护后台服务。 比较常见的限流器分为两种,漏桶算法和令牌桶算法。
用户5326575
2022/06/28
1.9K0
基于redis实现分布式服务限流器
全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等
自 2015 年春节以来,QQ 春节红包经历了企业红包(2015 年)、刷一刷红包(2016 年)和 AR 红包(2017 年)几个阶段,通过不断创新玩法,活跃度节节攀升,成为春节一大玩点,给火红的春节带来一抹亮色。2017 年除夕,AR 红包、刷一刷红包再创新高,抢红包用户数达 3.42 亿,共刷出红包 37.77 亿个。
JackJiang
2019/01/07
1.9K1
业务上云使用腾讯云日志服务方案
日志服务(Cloud Log Service,下文简称CLS服务)是腾讯云提供的一站式日志数据解决方案,可以快速便捷的接入,享受日志采集、日志存储到日志内容搜索、统计分析等全方位稳定可靠的日志服务。下文讲解业务接入腾讯云日志服务方案。
覃春善
2020/11/04
5.2K1
百万 QPS 前端性能监控系统设计与实现
作者:李振,腾讯云前端性能监控负责人 什么是前端性能监控(RUM) 腾讯云前端性能监控 (RUM) 是一站式前端监控解决方案,用户只需要安装 SDK 到自己的项目中,通过简单配置化,即可实现对用户页面质量的全方位守护,真正做到了低成本使用和无侵入监控。前端性能监控专注于 Web,小程序等大前端领域,主要关注用户页面性能(页面测速,接口测速,CDN 测速等)、质量(JS 错误,Ajax 错误等),并且通过联动腾讯云应用性能监控实现对前后端监控一体化的打通。点击了解 RUM 详情。 前端性能监控技术架构历史
腾讯云可观测平台
2021/12/15
1.9K0
大规模 codis 集群的治理与实践
小时光
2017/11/01
6.6K0
大规模 codis 集群的治理与实践
微服务接口限流的设计与思考
微服务拆分之后,系统之间的调用关系错综复杂,平台的整体复杂熵升高,出错的概率、debug 问题的难度都高了好几个数量级。所以,服务治理便成了微服务的一个技术重点。服务治理本身的概念比较大,包括鉴权、限流、降级、熔断、监控告警等等,本文聚焦于限流,根据笔者的实战经验,分享一些对微服务接口限流的思考。
lyb-geek
2022/03/10
6500
微服务接口限流的设计与思考
高并发场景下如何保证系统稳定性
导语 微服务产品团队为了广大开发者朋友们可以更好的使用腾讯云微服务产品,将持续为大家提供微服务上云快速入门的指引性文档,内容通俗易懂易上手,本篇为本系列的第二篇,为开发者朋友们详解高并发场景下限流的解决方案,欢迎大家收看。 作者简介 刘远 腾讯云泛互联网首席解决方案架构师 本篇文章将从以下四个方面为大家详解高并发场景限流解决方案: 秒杀场景架构概述 限流实现原理及方案选型 限流配置实践 云书城沙盒环境演示 秒杀场景架构概述 场景特点 在电商行业里,商家经常会做商品促销的活动,来进行品牌推广或
腾讯云中间件团队
2022/11/22
1.5K0
高并发场景下如何保证系统稳定性
常见限流算法以及限流在单机分布式场景下的思考
今天来说说限流的相关内容,包括常见的限流算法、单机限流场景、分布式限流场景以及一些常见限流组件。
程序员小猿
2021/01/19
1.4K0
常见限流算法以及限流在单机分布式场景下的思考
这次,我们为您优化了一个小世界!QQ小世界Feed云优化改造+MongoDB集群性能升级
万字长文,详细讲述PCG功能开发一组如何优化改造QQ小世界Feed云系统及腾讯MongoDB团队如何对小世界MongoDB集群进行性能优化,对比看看您的小世界是否面临同样的问题呢,建议收藏学习! 本文结构速览奉上: 一、业务背景 二、小世界Feed云系统面临的问题及挑战 2.1 老Feed系统主要问题 2.2 新场景下Feed云的问题 三、数据库存储选型 四、小世界Feed云系统改造及优化过程 4.1 Feed云优化改造及成果收益     4.1.1 Feed云优化改造-UFO     4.1.2 Fee
腾讯云数据库 TencentDB
2022/05/30
1K0
这次,我们为您优化了一个小世界!QQ小世界Feed云优化改造+MongoDB集群性能升级
代码层走进“百万级”分布式ID设计
面对互联网系统的三高(高可用,高性能,高并发),数据库方面我们多会采用分库分表策略,如此必然会面临另一个问题,分库分表策略下如何生成数据库主键?那么今天针对此问题,我们就聊聊如何设计一款“百万级”的分布式ID生成器。
得物技术
2022/08/30
6160
代码层走进“百万级”分布式ID设计
服务高可用利器 —— 限流算法介绍与示例
分布式后台服务在面临高并发挑战时,为了保障服务的高可用,业界已经有较为成熟的经验和方法,往往需要采取如下几种措施:
恋喵大鲤鱼
2022/12/02
6040
服务高可用利器 —— 限流算法介绍与示例
蚂蚁 Service Mesh 双十一后的探索和思考(上)
2019 年 Service Mesh 在蚂蚁大规模落地并完美支撑双十一核心链路,对于落地过程在去年已经有系列文章解读。而在此之后的一年多时间,Service Mesh 在蚂蚁又在如何演进呢。本文介绍蚂蚁 Service Mesh 在双十一落地之后所做的探索和思考。
CNCF
2021/03/15
4490
蚂蚁 Service Mesh 双十一后的探索和思考(上)
海量服务器安全高效管控系统设计
"鹅厂网事"由深圳市腾讯计算机系统有限公司技术工程事业群网络平台部运营,我们希望与业界各位志同道合的伙伴交流切磋最新的网络、服务器行业动态信息,同时分享腾讯在网络与服务器领域,规划、运营、研发、服务等层面的实战干货,期待与您的共同成长。 网络平台部以构建敏捷、弹性、低成本的业界领先海量互联网云计算服务平台,为支撑腾讯公司业务持续发展,为业务建立竞争优势、构建行业健康生态而持续贡献价值! 一 背景 现代互联网企业伴随着业务的不断高速增长,服务器总数及系统维护人员也不断增加,分布在全球各地的IDC数量及类型也
鹅厂网事
2018/02/05
2K0
海量服务器安全高效管控系统设计
腾讯 SNG 监控数据的创新应用
本文将向大家分享SNG监控十年来变革背后的驱动因素和立体化的监控方案,最后给大家展示最新的智能监控的应用场景。
织云平台团队
2018/08/07
7.9K3
推荐阅读
相关推荐
天天P图 - 分布式频控系统的设计和优化
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档