写点什么

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:0110764

评论

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

Flink State 和 Fault Tolerance(二)

Alex🐒

flink 翻译 flink1.13

Java性能问题定位命令

hasWhere

cpu突然变高定位步骤

hasWhere

AI 转型必看|算法工程师的 AI 启示录

百度大脑

人工智能

【架构师训练营】电商业务微服务拆分设计

eoeoeo

物联网发展,行业新领域

anyRTC开发者

音视频 WebRTC 智能硬件 智能安防 实时通讯

一文读懂云原生 go-zero 微服务框架

晨雨听风

GitHub Web Go 语言

Cilium 首次集成国内云服务,阿里云 ENI 被纳入新版本特性

阿里巴巴云原生

容器 云原生

618技术特辑(四)疯狂剁手的同时,电商隐私安全你注意到了吗?

华为云开发者联盟

电商 数据安全 云安全 618 隐私安全

Java版本发布历史

hasWhere

技术干货 | Windows桌面端录屏采集实现教程

ZEGO即构

RTC 录屏采集

标准物模型:设备无缝对接,IOT界的福音

华为云开发者联盟

物联网 IoT 物模型 标准物模型 IoT Stage

bzz节点挖矿分发系统开发案例

薇電13242772558

区块链

Windows Core Audio 音频开发技术指南

拍乐云Pano

超全Redis命令总结,墙裂建议收藏,说不定就用上了呢

北游学Java

Java redis

RDMA打造存储利器

焱融科技

文件 高性能 数据中心 分布式存储

干货|车来了APM应用性能体验实践

APM App 稳定性 APP稳定性

618技术特辑(三)直播带货王,“OMG买它”的背后,为什么是一连串技术挑战?

华为云开发者联盟

CDN 直播 618 低时延 视频直播

Python——嵌套

在即

6月日更

架构训练营模块 6 作业 - 江哲

江哲

性能排查常用Linux命令

hasWhere

开发效率提升50%以上,爱奇艺官网主站的Nuxt实践

爱奇艺技术产品团队

大前端 开发 nuxt

云图说|数据仓库服务 GaussDB(DWS) 的“千里眼、顺风耳”—数据库智能运维

华为云开发者联盟

数据库 数据仓库 GaussDB(DWS) 云图说 数据仓库服务

推理综艺的正确打开方式!爱奇艺玩转智能技术,“互动+内容”引爆迷综季

爱奇艺技术产品团队

Flink+Hologres助力伊的家电商平台建设新一代实时数仓

Apache Flink

flink

好的目标管理:SMART原则

石云升

创业 职场经验 管理经验 6月日更

JAVA语言基础(五)--数组

加百利

Java 后端 6月日更

中国信通院云大所与dbaplus社群开启战略合作,共同推动多项标准落地

dbaplus社群

OpenKruise :SidecarSet 助力 Mesh 容器热升级

阿里巴巴云原生

容器 云原生

华云大咖说 | 华云数据与福昕鲲鹏携手共建国产云生态

华云数据

IDEA搭建DCM4CHEE开发环境

birdbro

intellij-idea 医学影像 DICOM PACS DCM4CHE

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