文档章节

高并发系统设计之开放平台API接口调用频率控制系统

李景枫
 李景枫
发布于 2016/04/17 02:07
字数 1688
阅读 445
收藏 25
点赞 1
评论 0

先描述下基本场景: 

系统API接口日均调用次数预计1亿次,提供5台服务器。 

需要做两种层面的控制: 

> 单IP、单应用每小时调用次数不超过10000次 

> 单应用、单用户、单接口每小时调用次数不超过1000次 

要求每次对频控系统的调用的响应时间在20ms内。 

此外,应用开发者和开放平台所属公司关心调用次数统计数据,如当天某应用所有接口被调用总次数、当天某应用某接口被调用次数、当天某应用用户使用数等。

    根据上面,我们可以直接得到系统响应度要求和计算得到系统吞吐量要求,计算公式如下: 

频控系统吞吐量(系统每秒能够处理的请求数)  

   = 80% * 1亿 / (24小时 * 60分钟 * 60秒 * 40% * 5) = 4630tps 

    80%、40%是指一天中有80%的请求发生在40%的时间内,是粗略的估算值。5是服务器数量。所以得到吞吐量要求为4630tps。前期设计系统时必须参考这些性能指标,后期压测系统时必须根据这些指标设计测试计划。 

    总结下系统设计需要达成的目标: 

  • 请求的响应足够快 

  • 能支撑4630tps 

  • 占用的CPU、内存等硬件资源不能太夸张(隐性设计目标)


A、数据结构设计

    计数是典型的key-value数据结构。 

    可能想到的最简单最自然的方式是下面这样的: 

K(app_id, ip) => V(count, startTime, lastTime) 

K(app_id, uid, interface_id) => V(count, startTime, lastTime) 

    startTime记录的是第一次调用的发生时刻,lastTime记录的是最近一次调用的发生时刻,它们用来判断是否应该重置计数值count和是否该拒绝调用。 

    为了节省内存,有必要对key和value做特殊设计,最次的方案当然是直接拼接上面各个字段。但这是非常不合理的,我们来简单估算下: 

假设应用有10,000个,平均每个应用的用户数为100,000,接口数为50,独立访问IP地址为1,000,000,那么数据项总共为: 

10,000 * 1,000,000 + 10,000 * 100,000 * 50 = 600亿 

那么如果每个数据项节省1个字节,能够节省的总数据存储是600G,这是非常可观的。 

    对于Key,一种更优方案是先拼接Key的字符串,然后MD5得到32位定长字符串作为Key,Key定长的话或许对性能提升也会有一定帮助。 

    对于Value,count、startTime、lastTime信息不能丢失,那么或许可以考虑下面两种优化方案: 

  • 无损压缩Value字符串,比如使用Snappy字符串压缩算法,但压缩和解压缩会带来额外的CPU计算消耗,需要权衡 

  • 计数不需要太精确,所以可以牺牲一定精确度换取空间节省。或许我们可以利用 CountingBloomFilter?Key需要重新设计为:MD5(app_id, interface_id, 现在距离1970年1月1号的小时数),Value就是CountingBloomFilter数据结构了,每个调用先根据app_id、 interface_id、现在距离1970年1月1号的小时数计算32位MD5值,然后得到所属的CountingBloomFilter(如果没有就 创建),然后每次先检查是否已达到最大插入次数,如果是则直接返回,如果不是才插入。但 是我们别忘了一点:CountingBloomFilter支持最大重复插入次数为15,远小于这里的1000次和10000次。所以很残酷,CountingBloomFilter不适合这种方案。但这是一个很好的起点,Value的数据结构虽然不能用 CountingBloomFilter,但或许可以用其他的优化数据结构,请看:http://blog.csdn.net/hguisu/article/details/7856239。

    另外频率控制一般可以采用“令牌桶算法”,这里不再深入,可以参考: 

    http://en.wikipedia.org/wiki/Token_bucket

B、数据存储设计

    考虑到性能要求,肯定需要用到Cache,这里打算选用Redis。再根据上面的估算,数据项总共有600亿,所以不可能把所有数据项全部放到Redis Cache中(假设每个Cache项占100个字节,估算下需要多少内存。 

所以我这里采用冷热数据分离方案。有这么三类数据: 

  • 冷数据存放在MySQL数据库,按照app_id、uid进行水平Shard 

  • 不冷不热数据采用Hash结构压缩存储在Redis,具体结构下面会提到 

  • 热数据放在另外的Redis库中,并且“展开式”存储以改善访问性能 

   

    热数据的所谓“展开式”结构是指将上面两个维度的计数分开,即存成类似下面这两种结构: 

K取MD5(app_id, ip, 现在距离1970年1月1号的小时数),V取一个长整型值表示计数 

K取MD5(app_id, interface_id, uid, 现在距离1970年1月1号的小时数),V取一个长整型值表示计数 

    Redis Cache失效时间:

    所有Redis Cache数据的失效时间设置为1小时到1小时1分钟之间的某个随机值,这样能某种程度上避免缓存集体失效引起的“雪崩”。 

    冷热数据迁移过程:

    数据的冷热一直在发生着改变,所以冷热数据之间需要进行迁移。 

    第一种方案是由后台进程定期将

  • 热数据中符合冷数据标准的数据移动到不冷不热数据缓存

  • 将不冷不热数据中符合热数据标准的数据迁移到热数据缓存

  • 将不冷不热数据中符合冷数据标准的数据迁移到MySQL数据库

  • 将MySQL数据库中符合不冷不热数据标准的数据迁移到不冷不热数据缓存

    判断冷热的标准是基于每天计算一次的历史平均每小时调用次数。 

    第二种方案是在调用时主动进行迁移,基于最近50次调用的平均时间间隔来判断(也就是对于每一个数据项还要存储一个它最近50次调用的平均时间间隔),迁移过程同第一种。


© 著作权归作者所有

共有 人打赏支持
李景枫

李景枫

粉丝 80
博文 58
码字总数 43962
作品 3
深圳
架构师
开放平台API接口调用频率控制系统设计浅谈

先描述下基本场景: 系统API接口日均调用次数预计1亿次,提供5台服务器。 需要做两种层面的控制: > 单IP、单应用每小时调用次数不超过10000次 > 单应用、单用户、单接口每小时调用次数不超过...

优雅先生 ⋅ 2014/09/11 ⋅ 17

视频汇聚云平台——千眼一平台

千眼一平台是一款用于进行视频资源的集中管理、分发的视频云平台。用户可以在平台上控制不同层级的视频观看及相关功能权限。其更强调视频功能的快速调用以及平台的开放性,可以说是一种完全融...

拾联科技 ⋅ 2016/11/25 ⋅ 0

浅谈国内取得突破的AGV几项应用技术

  1、移动机器人车体控制技术   在移动机器人的实际应用中,由于用户所需要运载的货物不同,经常需要更改传感器、驱动器的类型及数量。为了提高机器人研发设计的工作效率,增强产品的核心...

中国机器人 ⋅ 01/02 ⋅ 0

淘宝开放平台回顾与前景展望

引语:云计算一出,很多人风风火火的讲PaaS,然而真刀实枪干过,而且能无保留的、站在架构师的角度讲些技术的不多,本文是淘宝架构师岑文初的一篇力作,值得云计算技术爱好者细读。 回顾 淘宝...

mj4738 ⋅ 2013/01/10 ⋅ 0

服务流量控制及限流

服务流量控制及限流 青蜂侠2017-07-2821 阅读 服务控制 工作上在开发类似 淘宝开放平台 的点评到综的开放平台,需要针对不同的API做流量控制,后期还需要针对不同属性的服务商(上线状态,部...

青蜂侠 ⋅ 2017/07/28 ⋅ 0

开放平台api的调用安全问题

我想实现类似新浪微博或者腾讯微博那样的功能. 给客户一个appId和appKey就能调用我的api. 我想知道这种api调用是每次都用appId来检查权限吗? 各位大神,我再补充一些吧.需求说完整一些....

xuchao ⋅ 2014/01/22 ⋅ 4

“Ceph浅析”系列之四——Ceph的结构

本文将从逻辑结构的角度对Ceph进行分析。 4.1 Ceph系统的层次结构 Ceph存储系统的逻辑层次结构如下图所示[1]。 自下向上,可以将Ceph系统分为四个层次: (1)基础存储系统RADOS(Reliable,...

红薯 ⋅ 2014/04/01 ⋅ 0

RESful 风格轻量级 Web 服务框架--Archer-Framework

概述 archer-framework是一个旨在构建RESful风格WEB服务的轻量级框架。 主要特点 采用面向服务的设计,服务端提供的API可以为PC WEB端、移动端、微信公众号等不同的客户端提供服务。 易于构建...

echrist ⋅ 2016/09/12 ⋅ 1

“CEPH浅析”系列之四——CEPH的结构

本文将从逻辑结构的角度对Ceph进行分析。 4.1 Ceph系统的层次结构 Ceph存储系统的逻辑层次结构如下图所示[1]。 自下向上,可以将Ceph系统分为四个层次: (1)基础存储系统RADOS(Reliable,...

Yason_Luo ⋅ 2014/04/02 ⋅ 9

解密微博红包:架构、防刷、监控和资源调度

编者按与传统意义上的红包相比,近两年火起来的“红包”,似乎才是如今春节的一大重头戏。历经上千年时代传承与变迁,春节发红包早已成为历史沉淀的文化习俗,融入了民族的血脉。按照各家公布...

技术小阿哥 ⋅ 2017/11/27 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vim编辑模式、命令模式

编辑模式 vim要从一般模式进入编辑模式只要按字母 i 、I、a、A、o、O键就可以了 要从编辑模式回到一般模式按键盘上的Esc键即可。 按键 作用 i 在当前字符前插入 I 在光标所在行的行首插入 o ...

黄昏残影 ⋅ 28分钟前 ⋅ 0

OSChina 周五乱弹 —— 如果有一天不当程序员了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @guanglun :分享off的单曲《我唱情歌给你听》 《我唱情歌给你听》- off 手机党少年们想听歌,请使劲儿戳(这里) @小小编辑 :#如果不做程序...

小小编辑 ⋅ 35分钟前 ⋅ 5

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

Java8新增的DateTimeFormatter与SimpleDateFormat的区别

两者最大的区别是,Java8的DateTimeFormatter也是线程安全的,而SimpleDateFormat并不是线程安全。 在并发环境下使用SimpleDateFormat 为了能够在多线程环境下使用SimpleDateFormat,有这三种...

人觉非常君 ⋅ 今天 ⋅ 0

多线程如何控制执行顺序

线程的生命周期说明: 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、...

MarinJ_Shao ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Django第一期

安装Django 去https://www.djangoproject.com/download/ 下载最新版的Django,然后解压放到Anaconda\Lib\site-packages目录下,然后cmd进入此目录,输入安装命令: python setup.py install ...

大不了敲一辈子代码 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部