写点什么

4 个 9 是如何炼成的?

  • 2014-04-14
  • 本文字数:3489 字

    阅读完需:约 11 分钟

随着 2014 年元旦微博平台抗峰的顺利通过,2013 年微博平台核心服务接口的可用性指标被定格在 99.991%。

微博服务可用性提升是 2013 年微博平台技术团队的一个重要目标,为此,平台内部还特别建立的微博平台的 SLA 指标体系,其中微博平台核心服务接口(主要以 feed 服务相关接口为主)的可用性指标为:全年平均接口请求性能 <100ms 的比例 >99.99%,即 4 个 9 的可用性指标。

我们的挑战在哪里?

说到 feed 服务大家都知道,feed 服务是微博最核心,最有价值的服务,于是它也是产品经理们花心思最多的地方,各种产品功能策略逐步在 feed 服务中实现,“Feed 置顶”、“关键词屏蔽”、“热门推荐”等等,伴随而来的是服务依赖的增多,虽然微博平台对内部的各个依赖资源及服务模块都有 SLA 指标的要求,但就算所依赖的各个服务的可用性都是在合理性能下的 99.99%,假设 feed 服务依赖于 9 个服务模块,理论上 feed 服务的可用性只能达到 99.99% ^9=99.91%,即只能保证 3 个 9 的可用性。更何况,feed 服务实际依赖不止 9 个资源或服务模块,甚至有些依赖的服务模块由于某些限制确实还不能达到 4 个 9 的可用性指标。这些情况都对服务的可用性形成很大的威胁,对我们的完成目标造成很大的挑战。

我们做了什么?

为了完成 4 个 9 可用性的目标,一方面微博平台内部建立标准的 SLA 指标体系,无论是资源,还是服务,都严格定义 SLA 指标(主要包括性能标准和可用性),并且实行服务分级策略,对于一般重要的(弱依赖)资源或服务执行标准的 SLA 标准,而对于非常重要的(强依赖)资源或服务,实行高要求的 SLA 标准,同时投入足够的资源和人力确保关键依赖服务的 SLA 指标的优化保障。另一方面,根据 feed 服务自身的业务特点,以所依赖资源或服务的 SLA 指标数据为基础,制定合理的容错和保障策略,通过在架构方面的策略改造,保证服务的健壮性,提升服务的可用性。

对于服务的 SLA 指标,最主要的就是明确性能标准和到达这一标准的服务调用比例(即可用性),以 mysql 资源为例:单次请求性能 <50ms, 整体满足此性能标准的请求比例 >99.99%,(当然,这个指标需要根据具体的业务特点、sql 的复杂程度等具体情况进行不同的定义,不能一概而论)。 明确了依赖服务的 SLA 指标,我们就可以从架构上通过一些策略保障整体服务品质,而不必过份依赖特定的资源和服务,具体有如下几个方面:

  1. 超时控制:

从 connect timeout 到 socket timeout 细化超时指标和处理策略。Feed 服务依赖了 10 多个资源或服务模块,偶尔会有某个服务出现问题,或者网络的抖动导致请求超时,如果 feed 服务无差别的进行等待,那将是一个噩梦。所以,feed 服务根据业务特点,把这些依赖进行分级,然后再依据强弱依赖关系,对 SLA 指标进行分级,最后对各个依赖的请求分别设定异常处理阈值。以 Feed 置顶功能对资源的依赖为例,置顶微博 ID 存放在缓存 memcached 中,在 feed 聚合时需要从 memcached 取出这个数据,而平台对这个资源的 SLA 要求为 <50ms,>99.99%,正常情况下都能满足整体服务性能,但当遇到特别情况比如网络抖动,很多获取置顶微博 ID 的请求将超过阈值,如果对请求超时不进行有效控制,就会影响到整个 feed 的请求。所以,在这种情况下,feed 服务从架构上,对置顶功能的资源依赖明确了超时控制,一旦对这个资源请求时间超过 80ms(一般情况下,这个阈值要比依赖资源确认的 SLA 标准稍微放宽一些,确保正常情况下这个超时控制策略不会误伤正常业务功能),则断开请求,避免影响到整个 feed 请求,而这种策略,就是通过资源的 connect timeout 和 socket timeout 来实现的。尽管在这种资源问题的情况下,置顶微博可能会偶发不显示,但 feed 的最主要功能没有受到影响。可见,这种对依赖隔离非常重要,对于任何依赖不能无止境的信任。
2. 阻塞与容错:

对于必要的依赖,要有一定的容忍度(限定在 SLA 之内),通过请求队列,自动容错降级等方式容忍短期的服务波动,同时还需要一定的自动修复策略,保证依赖服务恢复后,主服务能够快速自动恢复。

Feed 服务中最典型的阻塞容错策略是 feed 的发表模块,当你发表一条微博时,微博内容并不是直接存入 mysql 中,而是暂存在消息队列中,然后再由专门的消息处理模块对这些消息进行处理,进行更新入库。这样做把 feed 服务对 3 个左右的 mysql 依赖降低到对一个轻量级的消息队列的依赖,可靠性一下子提高了一个档次。当前类似这样通过阻塞及容错策略进行依赖降级或隔离的场景还有不少。
3. 手动开关:

然而,在一些特殊的情况下,有些依赖的资源或服务可能长时间不可用,这样导致服务一直受到影响。尽管我们有前面所说的比如超时控制等一些保护策略,但这些保护策略也在消耗这一定的时间。短时间波动的问题可以非常好解决,但对于相对持续较长的问题,则很难达到效果。这是就需要我们手动切断依赖,等依赖问题恢复后再打开。

有人可能提出,为什么不能在超时控制的策略之上,自动增加这种开关机制能?实际上,对于非常核心的资源服务依赖,一般性的问题都不允许进行降级,如果采用自动降级策略风险将非常大,因为自动降级的边界非常难以判断,这种情况最好的方式就是采用手动降级的方式。(一旦实施了这个,一般都是出现了非常严重的问题,服务品质已经收到影响,只是尽可能的把影响降到较小范围。类似于“断臂保命”)
4. 容量规划:

容量规划是每个系统必须认真面对的问题,单机容量(qps)=最大处理线程数/单次请求平均响应时间,系统容量(qps)=单机容量*机器数*r(容量系数),特别值得一提的是,分布式系统中的容量系数需要细致评估。另外,对于容量评估也要根据系统的演进经常的进行 review,微博平台一般每个季度进行一次容量评估,同时明确定义一下 SLA 指标的修正,特别是重大活动之前需要提前评估。比如,对于微博服务,在元旦,春节都需要提前规划准备。而对于冗余量的问题,日常 30% 的冗余,确保一般突发事件引起的流量增长可以正常承受。
5. 降级与限流:

容量评估能够解决可以预见的流量峰值请求,但作为开放的互联网服务,经常会有你不能预见的流量请求来冲击你,甚至有时你预见了将有超出你系统容量的请求,却来不及完成扩容。这时候就需要我们考虑如何避免流量超出容量导致整体服务 crash。就像说,吃掉你能吃掉的,对于吃不掉的就快速扔掉; 这就需要一定的降级和限流策略。

对于这个降级与限流,实际处理时一般分为两级:单一实例的容器保护策略,整体集群服务的业务保护策略。

对于单一实例的容器保护策略(以 tomcat 为例)主要涉及 maxThreads,acceptCount,具体处理策略如下图:(阈值处理指标需要根据具体业务场景来定)(如图:容器保护策略)

对于整体集群服务的业务保护策略,重点保证服务间的隔离,避免相互影响,主要涉及 single task count,single task limit,具体处理策略如下图:(如图:业务保护策略)

以上通过具体的业务场景,简单介绍了在已知 SLA 标准的基础上,通过五个方面策略,确保服务可用性的提升,而这五个策略中任何一个策略都只能解决一方面的问题,他们是相辅相成,相互补充的:(如图:)

另外,在确定的 SLA 体系下,为了保障以上架构策略的稳定有效,还需要有完善的监控体系,以及一定的压测及演练机制。

对于服务的监控体系,就像我们的眼睛,可以快速的发现潜在的问题和风险,比如:容量问题,资源异常状态,等等,同时配合一些提前制定的处理预案,能够将系统的问题消灭在萌芽状态,将大事化小,小事化了。

有关监控系统的建设,这里边有个非常重要,又容易被大家忽视的问题,就是易用性问题,我们的经验是,一定要能把监控数据转化成易于理解的图标。好的监控系统应该让运维人员一眼就能看出问题。这样的系统,运维同学才喜欢用,才有生命力。 比如:微博平台的 dashboard。

对于服务的压测与演练机制,主要是根据 SLA 数据及架构策略预案,制定演练计划,尽早发现架构或策略的问题。用以确定阀值是否有效? 容错是否合理? 开关是否生锈? 容量是否准确?当前微博平台主要使用的是自己开发的 touchstone 系统,通过 tcpcopy 的方式模拟线上真实流量及场景,确保压测和演练的有效性。(有关 touchstone 系统在 @微博平台架构 官方微博上有专门的文章介绍,这里不再赘述)

以上是微博平台在服务可用性提升方面的一些实践经验,其实还有很多可以进一步提高的方面,2014 年我们继续努力!也欢迎感兴趣的同学一起就这个话题交流探讨!

感谢丁雪丰对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-04-14 00:0110714

评论

发布
暂无评论
发现更多内容

React Context

程序员海军

7月月更

AIRIOT答疑第6期|如何使用二次开发引擎?

AIRIOT

二次开发 物联网低代码平台

一篇搞定Redis中的BigKey问题

知识浅谈

redis 底层原理 7月月更 签约计划第三季

一篇文章读懂人工神经网络

天狼

人工智能 神经网络 算法 ann

Starfish Os X MetaBell战略合作,元宇宙商业生态更进一步

小哈区块

知识管理系统推动企业信息化发展

Baklib

面试官:4年经验没碰过Nginx? Nginx入门,图文超详细

LoneWalker、

nginx

java零基础入门-如何统计字符串中每个字符的出现次数?

喵手

Java 7月月更

mysql 最大建议行数2000w,靠谱吗?

京东科技开发者

MySQL 数据库

一篇文章带你走进pycharm的世界----别再问我pycharm的安装和环境配置了!!!

是Dream呀

Python 后端 pycharm 编译器 环境

如何实现一个好的知识管理系统?

Geek_da0866

小程序容器技术超有料,可以让移动研发效率大幅提升

Speedoooo

跨端开发 降本增效 研发效率 小程序容器

你的列表很卡?这4个优化能让你的列表丝般顺滑

岛上码农

flutter ios 前端 安卓 签约计划第三季

深度 | 自动驾驶数据服务进入2.0时代

澳鹏Appen

人工智能 自动驾驶 计算机视觉 智能驾驶 激光雷达

一文读懂Plato Farm的ePLATO,以及其高溢价缘由

西柚子

建筑云渲染的应用正在扩大,越来越多的行业急需可视化服务

Finovy Cloud

云渲染 GPU渲染

HarmonyOS 3纯净模式可限制华为应用市场检出的风险应用获取个人数据

科技汇

如何让个性化推荐即刻触达?云原生数据库GaussDB(for Redis)来助力

华为云开发者联盟

数据库 云原生 后端

怎样实现文档协同?

Baklib

Java之路必读与知识点分析

魏铁锤

如何对话CIO/CTO

凌云Cloud

销售 企业管理系统 CIO To B业务

Starfish Os X MetaBell战略合作,元宇宙商业生态更进一步

西柚子

【Meetup预告】OpenMLDB+OneFlow:链接特征工程到模型训练,加速机器学习模型开发

第四范式开发者社区

人工智能 机器学习 数据库 AI 特征平台

小程序助力智能家居生态平台

Geek_99967b

物联网,

一种比读写锁更快的锁,还不赶紧认识一下

华为云开发者联盟

高并发 开发 ReadWriteLock StampedLock

8000字讲透OBSA原理与应用实践

华为云开发者联盟

后端 OBS 运价计算 OBSA

【图解】三次握手,四次挥手 —— 用心看这一篇就够了

攻城狮杰森

计算机网络 TCP/IP 数据传输 7月月更

leetcode 452. Minimum Number of Arrows to Burst Balloons 用最少数量的箭引爆气球(中等)

okokabcd

LeetCode 数据结构与算法 贪心算法

如何查看蓝牙耳机的蓝牙版本

贾献华

7月月更

一文读懂Plato Farm的ePLATO,以及其高溢价缘由

BlockChain先知

数据管理的重点

奔向架构师

数据管理 7月月更

4个9是如何炼成的?_语言 & 开发_李庆丰_InfoQ精选文章