微博基于Docker的混合云平台设计与实践

编者按:本文由王关胜向「高可用架构」投稿,介绍其在台湾 iThome 举办 Container summit 2015技术大会分享精华。转载请注明来自高可用架构公众号「ArchNotes」。


王关胜,微博研发中心运维架构师。2011 年初加入新浪,一直负责微博平台&大数据等业务线的运维保障工作,包括产品稳定性,运维基础设施建设,工具建设等。致力于推进 Docker 在微博的应用,参与建设微博混合云平台 DCP。擅长大规模分布式系统集群的管理与运维,疑难问题分析,故障定位与处理等。对运维工具平台建设、监控、应用性能跟踪及分析、数据化运维等方面有深入的研究。


0?wx_fmt=png2011 年初,新浪微博进入快速发展期,同时也开启平台化的进程,服务器设备,及人力成本大量增加,业务的快速发展,促使运维团队建立了一套完整的运维平台。虽然已稳定运行了 3 年,但随着公有云的逐渐成熟,Docker Container 技术的兴起,一时间各大型企业纷纷开始升级内部运维系统,提供自动化能力的同时,更注重弹性调度。我们也于 2014 年底构建了第一版基于 Docker 的运维平台,并在元旦,春节,红包飞等大型活动中得到了考验。但是要想更好的应对微博的这种业务场景,系统局限性还很多,比如设备申请慢,业务负载饱和度不一,扩缩容流程繁琐且时间长,基于此出发点,2015 年技术团队设计与实现了一套基于 Docker 的混合云平台 DCP。

微博的业务场景及混合云背景

微博目前有 8 亿注册用户,单日活跃用户数达 1 亿多。微博总体分为端和后端平台,端上主要是 PC 端,移动端和第三方开发者,后端平台主要是 Java 编写的各种接口层,服务层及存储层。就前端来说,每日超过 600 亿次的 API 调用,超过万亿的 RPC 调用,产生的日志就达百 T+。对于这么大体量的业务系统,对于运维的要求也很严格,就接口层来说,SLA 必须达到 4 个 9,且接口平均响应时间不能高于 50ms。因此技术团队会面临下述各种各样的挑战。

  • 产品功能迭代快,代码变更频繁

  • 业务模块多,且依赖关系复杂

  • 突发的热点事件,如典型的#周一见# #马航370# #刘翔摔倒# #明星丑闻#

  • 大型活动及春节、元旦保障,如红包飞

下面具体看下春晚时的业务模型:

0?wx_fmt=png每年的元旦,春晚,红包飞会带来巨大的流量挑战,这些业务场景的主要特点是: 瞬间峰值高,互动时间短。基本上一次峰值事件,互动时间都会 3 小时以内,而明星突发新闻事件,红包飞这种业务,经常会遇到高达多倍的瞬间峰值。传统的应对手段,主要是靠提前申请足够的设备,保证冗余;降级非核心及周边的业务;生扛这三种手段。这么做,除了成本高外,对系统进行水平扩容时,耗费的时间也久。

除了来自业务的挑战,在应对峰值事件时,对于运维的挑战也蛮大的。遇到难点较多的环节包括:设备申请太麻烦,时间长;扩缩容流程繁琐。

要完成一次具体的扩容,首先基础运维从采购拿到新机器,录入 CMDB,再根据业务运维提的需求,进行上架到相应的 IDC,机架,操作系统安装,网络配置,最后分给相应的业务运维,就是一台完整的可以登录的机器了。其次,业务运维拿到机器,需要对机器进行初始化配置,并继续服务部署。服务部署好后,经过 check,再挂到负载均衡上,引入流量。设备坏了自动报修,过期下架或替换。具体可看下图

0?wx_fmt=png

这种扩容的方式,除了流程繁琐外,还经常遇到各服务器间环境差异,无法充分利用服务器硬件资源,即使有多余的服务器也无法灵活调度。若采取新申请设备,在大一点的公司申请流程通常较长。一般设备申请是业务方及业务运维发起采购提案,然后相关方进行架构评审,评审通过,则由 IT 管委会评审,再由决策及成本部门评审,评审通过,进入采购流程,再上架,还经常遇到机房机架位不足,这些都导致交付周期变得很长。

除了业务扩容的繁琐,公司内设备利用率也不均衡,主要表现在三个地方:

  1. 各个业务组的服务器利用率各不相同,大家对利用率的理解不一致,导致有些设备未能得到充分利用,这也会导致更大的成本压力。

  2. 各个业务模型不同,比如有的业务高峰是在晚 22 - 23 点,有的业务则在中午。

  3. 在线业务与离线业务完全分离,导致成本也高,对于离线业务,可在低峰继续跑在线业务

正因为这些挑战,怎么能更好的解决,技术团队想到基于 Docker,及公有云来构建一套具有弹性伸缩的混合云系统。利用过去的私有云加公有云,以及公司内闲置的运算资源,混合云,兼具安全性与弹性扩展能力。其特点如下图

0?wx_fmt=png

有了这套混合云系统后,不仅能很好的整合内部运算资源,解决内部的弹性需求外,当系统面临流量剧增的峰值事件时,也可以将过多的流量切入外部公有云,减轻内部系统的压力。

两种云内的设备如何使用呢?内部私有云设备安全性高,可控度也高,只要对硬件资源进行优化配置,用它来处理固定的工作负载。而公有云的设备则具有标准化,自动化的特性,可以快速因临时需求,在流量暴涨时,可以快速创建大量 ECS,扩容业务工作负载的能力。而对于公司,可以利用公有云这种按需付费的机制,减低硬件的运营成本。因此采用混合云架构,就可以兼具私有云及公有云的优点,可以同时拥有安全与弹性扩容能力,使业务工作负载可以在业务间进行漂移,低负载的业务就应该使用更少的设备,反之亦然。而基于 Docker 来做,对于上述情况来说,复杂度降低很多。

三大基础设施助力微博混合云

微博混合云系统不单只是一般的混合云,而是应用了 Docker,透过 Docker Container 快速部署的特性,解决海量峰值事件对微博系统带来的压力。过去公司在面对峰值事件,一般采取的作法是,首先评估需要多少额外设备,并向外部公有云申请机器分摊流量。然而,除了可能低估应付峰值事件所需的设备外,即使事先準备了足够的 VM,其部署时间成本也远高于 Docker,无法即时帮助公司分摊过多外部请求。

而微博 Docker Container 平台的混合云核心设计思想,主要是借鉴银行的运作机制:民众可以把钱存在银行,而需要使用金钱的时候,只需要提领一部分,剩余的存款银行可以拿去进行投资。而微博则借鉴银行的这一套运作模式,在内部设立一个运算资源共享池外,还导入了外部公有云。

而要微博实现高弹性调度资源的混合云架构,其中实现的关键则是 Docker。刚开始我们思考该要使用裸机还是 VM 架构,作为 Docker Container 的基础设施。后来,考量如果要采用 VM,内部机房架构要进行许多改造。所以,目前微博的内部私有云使用裸机部署,而外部公有云则采用阿里云弹性计算服务(ECS)的 VM 架构。等平台建设成熟后,还可以应用其他厂商公有云,如 AWS 等。

构建 Docker Container 平台基础架构的 3 大关键,包含 Docker 在裸机上的部署架构、改进版的 Docker Registry 以及负载均衡组件 Nginx Upsync 模块

第一是 Docker Container 的裸机部署方案,透过 IP 位址以及 Port 定义一个唯一的 Container 服务,而每台主机上则可以开启多个 Container,各个具有不同的功能。

0?wx_fmt=png

每一个 Container 服务所产生的行为日志,会经由一个名为 Scribe 的 Container 集中收集。而集中后的数据则可进行用户行为分析。对于容器类监控数据,则是透过建立 CAdvisor Container,将 Container 运行产生的资料,传送至 ELK(Elasticsearch、Logstash 及 Kibana)开源监控软体,进行分析。对于业务数据,通过 Graphite,监控业务系统的运作状况。

第二则是 Docker Registry,我们使用 Docker 官方提供的 Docker Registry,构建了私有的 Registry Hub,并且透过这个私有调度 Docker Container 需要的镜像。

0?wx_fmt=png

今年基于 V2 版的 Registry Hub,将存储引擎改为使用分布式开源存储平台 Ceph,并且在 Docker Registry 前端结合 Nginx,实作负载平衡功能。这个过程中,比较麻烦的是,在 Docker 版本升级过程中必须让系统能够兼容新旧版本的 Registry Hub,而前端 Nginx 可以分析系统需求,辨別要从新版本或是旧版本 Docker 仓库下载镜像。而外部公有云,则是透过镜像缓存 mirror,不必像私有云一样,部署完整的镜像仓库。

对于镜像服务,总共包含 3 层架构。包含最底层操作系统、中间层的运行环境如 Java、Tomcat,及最上层的 Container。而在调度 Container 时,透过使用 dockerignore 指令,减少不必要的文件、目录,借此减低映像档的容量。除此之外,在镜像标签命名上,我们则禁止使用「Latest」做为镜像标签。这是由于不同使用者对于标签的理解不一,可能会误以为是代表映像档最新的版本。

而第三则是独立研发的 nginx upsync 模块,去年刚开始使用 container 时,将container 挂到 nginx 后,必须通过重启或 reload 指令,使流量生效。而这个过过程中,nginx 对于特別大的并发流量会发生运行不稳定的情形,因此后来开发了 nginx upsync 模块,不通过 reload 指令重启,也可以保持系统稳定运作。针对两种模块进行比较,发现流量大时,用了 nginx upsync 模块,不做 reload,单机扛量多了 10% 的请求,且性能并不会降低。

Nginx upsync 的核心功能主要是:

  1. Fix Nginx reload时带来的服务抖动

  2. Fix Web Container的服务发现

项目已开源至 github 上:https://github.com/weibocom/nginx-upsync-module

其架构如下

0?wx_fmt=png

微博混合云 DCP 系统设计核心:自动化,弹性调度

目前开发的 Docker Container 混合云平台,包含 4 层架构:主机层、调度层及业务编排层,最上层则是各业务方系统。底层的混合云基础架构则架构了专线,打通微博内部资料中心以及阿里云。

主要思想:来源于官方三驾马车(Machine + Swarm +Compose)

0?wx_fmt=png

DCP 混合云系统的设计理念,总共包含 4 个核心概念:弹性伸缩、自动化、业务导向等。

DCP 系统,最核心 3 层架构:主机层、调度适配层及编排层。

主机层的核心是要调度运算资源。目前设计了资源共享池、Buffer 资源池,配额管理,及多租户管理机制,借此实现弹性调度资源。

而调度层则通过 API,把调度工具用 API 进行包装,而微博 4 种常用的调度工具组合包含:Docker、Swarm、Mesos 及自主开发的 Dispatch。

而最上层的则是负责业务编排及服务发现。编排层也包括了大数据工具Hadoop,进行大数据分析的业务场景。

对于调度来说,最重要的就是资源管理,Mesos 处理这个是最合适不过了,很多公司就专用其做资源管理,比如 Netflix 写了一个 Titan 调度服务,其底层资源管理则是通过 Mesos。在调度组件中,使用最多的还是 swarm,dispatch。

可以看下面这个场景:这也是私有云内部资源流转的最佳实践

0?wx_fmt=png

当业务 A 多余的运算资源导入混合云共享池时,此时流量暴涨的业务 C,可从共享池调度业务 A 的运算资源,而峰值事件后,便可以把多余的运算资源归还至共享池。

DCP 对于物理主机的流转,基于资源共享池、Buffer 资源池,配额管理,及多租户管理机制,其实非常复杂,详情可以去看我在台湾 iThome 举办 Container summit 2015 技术大会上分享的内容。这里可以看一下一台物理主机的生命周期(状态流转图)

0?wx_fmt=png

引入阿里云做为第三机房,实现弹性调度架构

起初,对于是否采用混合云的架构,技术团队也是做了一番考虑的。目前微博机房的部署架构总共分为 3 层,依次是最上层域名以及负载均衡层。中间则是Web 层,包含各种前端框架,RPC 层以及中间件(Middleware)。而最下层则包含 MySQL、Redis、HBase 等资源架构。

微博核心服务主要分布在 2 个机房,两者互相做为灾难备份用途,而第 3 个机房则采用外部阿里云。混合云架构总共有 2 种部署方案。

第 1 种部署方案,将阿里云视为数据中心,底层架构与微博内部机房一样部署。内部机房采用 nginx 做为负载均衡层,但外部公有云则 SLB 引入流量。其他阿里云的中间 Web 层则与内部机房架构一致。不过,出于存储数据需要考虑的因素较多,初期把阿里云做为应付大量峰值时的方案更为简单,存储永久性数据的MySQL、HBase暂不部署于阿里云。

而第 2 种部署方案则把应付峰值事件需要的弹性计算能力迁移到阿里云。第 2 种部署方案困难之处,需要把微博的内部业务进行改造,让微博中间 Web 层,直接对阿里云机房进行 RPC 调用。此种方案部署结构相较比较简单,也让混合云架构具有实现可行性。

而这 2 种方案都会依赖 VPC 网路,如果有没有专线,想实现公有云的弹性计算能力几乎是不可能。因为公网调度资源的延迟时间太高,无法应付微博大量的业务。因此,技术团队与跟阿里云合作,在两边建立了内部专线,让阿里云机房与微博的机房互通。

大规模集群操作自动化:设备申请,初始化,服务上线

微博 Docker Container 混合云 DCP 设计思想,核心目标就是透过自动化操作大规模集群,进行弹性调度资源的任务,要完成此任务,必须经过 3 个流程:设备申请、设备初始化及服务上线。

弹性扩容任务所需要的设备来源是内部的集群以及外部的阿里云。而申请到足够设备后,也必须对设备进行初始化、部署环境及配置管理。最后一步则是将服务上线,开始执行 Container 调度以及弹性扩容的任务。

第 1 步骤则是申请设备,而设备申请借鉴于银行机制的概念。私有云的设备来源,主要来自离线集群、低负载集群以及错峰时间空出的多余设备。具体来说:离线集群并不是时时刻刻都在执行运算,即使稍微减少计算资源,也不会对业务产生重大影响;而工作负载较低的集群,如果有多余的资源也可以进行调度。此外,微博有上百个业务线,每个业务线峰值出现的时间点都不一样,而在此种状况下,各业务也可以互相支援,共享多余的计算资源。

0?wx_fmt=png

而不同业务的集群则各自独立,并且具有独立的资源池。集群内可以自由调度资源,例如,缩小 A 服务的规模,将多余的运算资源分派给 B 服务。若集群要调度外部资源,也有设计配额制度,控制每个集群分配到的资源。在集群外,必须看 Buffer 池是否有足够的资源,如果足够的话,可以直接将 Buffer 池内的设备初始化,进行使用。

反之,如果 Buffer 池内的资源不足,也必须查看是否有足够的配额,可以直接申请机器。当设备申请完成,直接分配给 Buffer 池后,随即被纳入 DCP 使用,所有可调度的主机只能通过集群自己的 Buffer 池。

第 2 步骤则是设备初始化;通过自己开发的工具系统,可以达到操作系统升级自动化、系统操作 API 化。而服务器所依赖的基础环境、需要的软体等环境配置,透过配置管理工具 Puppet,将需要的配置写成模块,并使用 RPM 机制打包,进行安装。

在初始化流程中,必须要支持软件反安装模式,例如,当A业务要调度设备时,其他业务在交付设备前,必须要先透过反安装程序,将要设备恢复为最原始的状态。

而目前业界中的一些做法也可以免去初始化的流程。例如导入为 Container 而生的容器操作系统,像 CoreOS、RancherOS 或 Red Hat Atomic。不过,虽然这样可以,但是此种做法的可维护度高,但是缺点在于迁移设备的成本较高。

第 3 步骤则是利用完成初始化的设备,开始进行服务上线。目前一线的运维人员,只要在系统页面上输入服务池名称、服务类型、Container 类型、需要 Container 数量以及镜像地址等参数,即可在 5 分钟内完成扩容,扩容完成后,系统也会产出完整的报告,列出扩容程序中,执行的步骤,以及每件任务的成功、失败状况。

总体来说:一键扩容流程如下

0?wx_fmt=png

应用微博Docker混合云,不怕峰值事件

在用微博混合云 DCP 时,优先调度内部的共享池资源的运算资源。但是在红包飞、春晚时,则必须调度外部的运算资源。平日的正常状况下,阿里云只需提供几百个运算节点,并且在 5 到 10 分钟内完成部署任务。但是,面对春晚、红包飞的峰值流量,则要提供数千个节点。这对阿里云的机房也是有较高要求的。

目前 Docker 混合云 DCP 平台,去年 10 月完成第一版,Container 数量千级。截止发稿,基本上手机微博,微博平台,红包飞,在今年的春晚,都会基于此系统进行峰值应对。上线以来,达成了微博所设定每次水平扩容时间低于 5 分钟的目标。「有这样的弹性调度能力时,系统面对大型活动的峰值压力就小很多。」

本文由王关胜投稿,想更多交流上述话题,可以回复 join 申请进群。转载本文请注明来自高可用架构 「ArchNotes」微信公众号并包含以下二维码。


640?wx_fmt=png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值