腾讯的业务体量非常庞大,在 2019 年,腾讯已拥有超过了 100 万台服务器,其中,社交业务包括 QQ 和空间的体量有近 20 万台服务器,且分布在全国三地。
把 QQ 这头大象搬到云上并非易事。作为腾讯最庞大、最悠久、最复杂的业务之一,QQ 各系统间存在强耦合。上云过程中需要确保对用户零影响,其难度可想而知。
面对重重挑战,QQ 是如何迎难而上的呢?本文即将从整体规划、方案执行、里程碑中的挑战等方面介绍其中的技术细节,希望能为大家提供借鉴。
一、整体规划
1.上云整体规划
QQ 上云规划时进行了系统化的梳理,包括业务评估、容量评估、业务架构、组织体系(比如运维职责的变化、研发流程的变化、资源预核算的变化、故障处理流程的变化)。
最重要的是,QQ 的技术体系跟着公有云进行了转变,确定迁移方案、迁移工具、风险预案、回滚预案、混合云预案、多云预案等。
以过程划分,QQ 上云整体规划包含以下三个阶段。
- 基础设施上云,简单说就是把基于物理网络的自研 IDC 设备搬到云上,使用基于虚拟网络的云 CVM 来搭建。
- 微服务和容器化改造,支持自动扩缩容。
- 架构和存储升级,全面融入云生态。
其中,基础设施上云是最底层、最基础的第一步,本文将重点介绍。
2. 基础设施上云规划
基础设施上云的规划分为两个阶段。
- 完成所有核心功能模块在云上的搭建,并调度 1000 万在线用户到云上。
- 完成整体基础设施上云,并做好云上的三地调度演习。
在计划推行的过程中,腾讯内部多个技术团队精诚合作,共同应对复杂挑战。然而,随着 QQ 逐步放量上云,面向海量服务的挑战才刚刚开始。
二、方案执行
QQ 上云方案执行前,有预测试、预验证的过程。一些核心模块(譬如高并发,或延迟非常敏感的模块)在云上经过了充分压测。真正迁移后,还有更多挑战需要灵活应对。
1.QQ 后台服务搬迁上云主要挑战
QQ 后台服务搬迁到云上部署,有这几类主要挑战:
- 安全问题
腾讯云提供的官网 VPC 可以通过配置反向代理被外网访问,相比受自研环境保护的内网环境,缺乏自我保护的能力,搬到云上貌似更容易被恶意入侵。
- 依赖问题
QQ 后台服务依赖关系复杂,无法一次性将全部服务都迁到云机房。统计后发现,QQ 后端主要的核心模块平均依赖 40+ 个后端模块。其中很多是外部的模块,比如安全、架平存储,这些模块云上支持的时间未定,前期只能先穿越到自研 IDC 访问。
- 容灾问题
部署到云上的模块,需要通过云机房到自研机房的专线进行通信,若专线发生故障,可能导致云机房成为孤岛。一开始云机房只在广州部署,无法做到云环境内部多地容灾而后云自研云机房。
- 灰度问题
QQ 即时通讯的特点,决定了用户对 QQ 的实时性要求很高,怎样合理灰度,做到用户对上云过程零感知,是一座需要跨越的大山。
2. 面临挑战,如何解决
- 应对安全问题
结合云上的安全产品,以及原来自研的安全服务和安全策略,腾讯有一套混合云的安全通用体系。
首先在公有云的大网里,划出独立的私有网络 VPC-X
即有外部访问的模块(如 QQ 接入层 SSO、内网接入层 OIDB 等),可以部署在普通的 VPC 中,而核心业务需要做外部隔离部署。为此,QQ 运维和腾讯云一起建设了没有外网环境的 VPC-X 专用云环境,并通过策略打通了普通 VPC 和 VPC-X 之间必要的访问路径,拒绝其他访问。
云上有丰富的安全产品:主机上有主机防护,漏洞扫描;业务层有应用防护;运维有运维安全。QQ 内部积累的一些安全方案,也已回馈到云上。
事实上,整个公有云的安全策略和私有云是一样的,没有什么根本性的差别。
- 应对依赖和容灾问题
上云过程要需要进行灰度迁移,而迁移过程会不可避免地造成自研机房和云机房的带宽穿越,为此,需提前评估自研机房到云机房所需的带宽。
假如使用城市方案,专线带宽应该跟现有的三地部署方案对齐。QQ 核心系统大概需要几十G的带宽。若采用 IDC 方案,QQ 里面有很多业务使用有状态的寻址方式,把同城内的机房全部打散访问(类似一致性哈希)。因此,把广州云当做深圳的 IDC 后,广州云和深圳的专线穿越会增大。参考深圳内部的 IDC 穿越带宽,预计需要增加几十G的带宽。
为此,开发者们评估了自研到云机房的带宽:支持 QQ 几大核心系统(接入、消息、状态、资料、关系链、登录)所需要的带宽为N。而所有 QQ 基础功能都迁移到云上,则至少需要 2N 的带宽。考虑到容灾问题,实际上拉了两条专线互备(防止专线被挖断形成孤岛),即为 QQ 上云专门搭建 4N 的带宽专线。
- 应对灰度问题
QQ 后台的模块众多,一下子上云并不现实,为了确保服务切换的平滑稳定,需要考虑以下情况:
(1) 有问题时影响尽可能少的用户。
(2) 用户数据完好性:有问题时不能导致用户数据丢失或错乱。
(3) 机器维度回退:云上环境有问题时,可以随时禁用,全部切回自研环境。
(4) 用户维度回退:用户登录云 IP 有问题,能够自动切换到自研 IP,不影响用户使用 QQ。
为此,需从 3 个维度制定灰度的 3 条主线:
(1) 用户维度
简单说,就是灰度的用户量级。主要考虑用最少用户量级来发现问题。
(2) 后台模块维度
其实就是哪些模块先上,哪些模块后上。主要考虑哪些模块出问题对用户的影响最小。
基本思路是:
(1) 先上接入层,验证云上的链接能力;
(2) 再上逻辑层,逻辑层通过一定用户量级验证没问题;
(3) 再上数据层,确保用户数据一致性。
(3) 后台 Set 维度
一个 Set 可以认为是一套闭环的系统,比如资料后台的一个 Set,包含“接入层+资料逻辑层+资料数据层”。这个维度的灰度,可用来确定一套系统里需要多少机器上云。
对于纯逻辑层来说,每个模块上两台机器(两台是为了考虑故障容灾,只需确保有一台在工作),就可以构造一个闭环的 set,但对于数据层来说,一个 set 需要的机器包含一份全量用户的数据拷贝。
从灰度的角度来说,逻辑层就是堆机器的过程,数据层是先上一份最小的数据拷贝,并且先只放开“读”服务,等到其他所有环境都验证可行,才切“写”服务到云上。
结合上面 3 个维度,总体的灰度过程是:
(1) 内部验证+接入层(验证三通接入、用户级和机器级调度能力)
(2)0-100 万用户+接入层灰度扩容(小规模验证,观察用户反馈)
(3)100W+ 逻辑层灰度及扩容
(4)100W~500W+ 数据层同步数据
(5)500W+ 数据层读
(6)500W~1000W+ 数据层写
(7)1000W~5000W+ 广州云 1 亿在线演习
(8) 南京云+天津云 +0~5000W
(9) 天津云/南京云 +5000W~1 亿
(10) 天津云/南京云/广州云新 3 地调度演习
(11) 天津/上海自研机房下架,保留深圳自研机房观察 1 年
(12) 深圳自研机房下架
灰度过程中,通过客户端服务质量、服务间调用延迟、全网拨测等监控指标判断业务是否有问题。另外,此时整个服务运营体系已经转变,QQ 必须适应相应的调整:
(1) 基础运维和公共运维团队变成由公有云的运维团队来支持。
(2) 运营流程也发生很大的变化,服务 SLA 要跟公有云服务商一起制定。
(3) 监控工具的选择,或改造原有的监控工具,或者换用云上成熟的监控 SaaS 服务。
三、里程碑中的挑战
基础设施上云,从用户量级的角度来考虑,主要有几个里程碑:
(1)500 万是速度和质量的平衡。
(2)1000 万开始迎接海量的挑战。
这里分析下每个里程碑里会遇到的重点问题:
里程碑1:五百万在线
在 0 到 500 万在线的这个阶段,需要重点关注可行性的问题,即各个系统怎样做好充分的验证,才能确保在云环境里成功跑起来。
- 丢包问题
丢包问题一般只是表象,真实的丢包原因隐藏着各种环境的适配问题、稳定性问题、质量问题。在 QQ 上云的过程中,丢包问题频繁出现,是所有问题中最棘手的。
这里列举在这个阶段遇到的两个丢包 case:
case 1:网关问题。
在资料后台的搭建过程中,曾发现 UDP 的丢包率较大,且可稳定复现在某些用户上。通过问题定位发现,发包和收包逻辑均正常,于是怀疑数据在链路上丢了。最终发现是物理网关的问题:只要是 UDP 分片,且 IP 头后面第三个第四个字节为 3503(0D AF)就必然导致丢包,同时也发现这个问题只在第一代网关设备(VSG)出现。于是腾讯找到网关设备厂商协商,把一代网关升级为二代网关(NGW),解决了该问题。
case 2:VPC 缓存会话问题。
这其实是上个问题的延续。在一代网关(VSG)升级到二代网关(NGW)的过程中,触发了 VPC 在宿主机 SDN 转发实现上的一个 bug,导致 UDP 丢包。一开始腾讯云在切换路由时是先删后加,当 VPC 内有 NAT 网关的默认路由时,就会导致流量转发到 NAT 网关。当路由加回来时老会话不会更新路由,因此老会话中断,而新发起的会话能正常工作。刚好自研机房有几台机器访问 OIDB 的 UDP 四元组一直不变,会话就会一直不老化,导致业务一直异常。最后这个问题靠重启业务进程解决,后续腾讯云团队也修复了这个 bug。
这个时候遇到的其他丢包 case 还包括“专线被挖断、机器故障、机器性能问题”等,不过大多不是大面积问题,其影响范围较小,相关技术负责人能及时地解决大部分问题。
- 获取 VIP 问题
QQ 调度系统依赖用户侧上报接入 IP 的可用性和耗时,来判断接入服务是否健康,并做最优的调度策略。因此,调度系统需要知道用户实际链接的对外 IP(从后台角度看是 TGW 对外提供的 VIP)。在自研环境中,TGW 把 VIP 通过 IP 层的目标 IP 传给 QQ 接入层 SSO,SSO 通过 getsockname 系统调用就可以获得外网用户看到的 VIP。但到了云上环境,接入层使用 CLB 接入,CLB 传给 SSO 的时候,目标 IP 填写的是 SSO 所在虚拟机自身的内网 IP。因此,在客户端不做升级,不修改登录协议的情况下,调度系统无法获得 VIP。
解决办法之一是客户端升级协议,但这样的话老用户无法上云,无法保证上云的进度。
另一个办法是修改 CLB 的实现,对齐 TGW,把外网 IP 传给 SSO。在多方技术团队的努力下,最终决定按此方案实现。不过因为 CLB 依赖 TGW/GRE 的实现,还需要 TGW 团队、TLinux 内核团队的配合,并需要将全网腾讯云的机器进行内核升级,整个修复的周期比较长,预期是 3 个月。
但 QQ 上云的进度,不能因此推迟 3 个月,为此,开发者们制定了一个临时方案:通过配置文件,配置 VIP 到 RIP(Realserver IP,虚拟机内网 IP)的映射关系。这个方案要 RIP 与 VIP 一对一映射,但在现网环境中,RIP 到 VIP 的映射关系是多对多的(为了降低 TGW 和 SSO 的相互依赖,保证 SSO 多通路负载均衡)。在上云初期 SSO 机器较少的时候,人工确保一对一映射是没问题的,但随着上云机器数和用户数增多,一对一映射将无法满足现网质量要求。
里程碑2:一千万在线
从 500 万到 1 千万的阶段,云设施的基础能力已经验证没有问题,但网络质量、时延的问题更为凸显。
- 丢包问题
随着云上用户量的增长,很多新的问题被暴露出来,比较典型的还是丢包问题。
这个时候遇到的丢包问题,大概有如下这几种情况:
(1) 虚拟机默认缓冲区太小。
(2) 物理母机缓冲区大小设置太小。
(3) VPC 会话数限制太小,VPC 在实现上会存储网络访问的五元组会话,QQ 后台大量使用 UDP,而且因为 QQ 体量比较大,五元组的数量很大,超过 VPC 的限制。
- 批量死机问题
这是群 Server 在部署的时候遇到的一个问题:3 台机器一起死机,定位后发现是同一台云主机死机了。
在自研环境中,群 Server 是使用实体机 M10 来搭建的,到了云环境,采用相同内存大小的虚拟机来搭建。运维在部署的时候,若把主备本应该分开部署的机器放到同一台实体机上了,这对业务来说简直是灾难。
最后,技术同事们协商确定,由运维来确保同个模块分配的机器不能处于同一台物理机上,实现方式是:在业务同一个集群下的配置组别,打散母机。
四、找对方法,加速上云
在 QQ 上云过程的细节里,有很多方法可以选择,也离不开一些技术工具和平台的支持。这里从“数据库的迁移模式”、“MySQL 数据搬迁”、“数据中心同步”、“云管平台”、“云原生”、“TKE 引擎”这几个方面来进行简单介绍。
1. 数据库的迁移模式
在私有云到公有云的数据搬迁模式中,QQ 有三种模式可以选择。
(1) 私有组件数据迁移到公有云
腾讯内部有很多自研的数据库,像 QQ 的 Grocery KV 存储使用的是内部私有协议,云上没有对应服务。业务需要将数据从私有组件迁移到 Redis。
QQ 采取了冷迁移的方式,先将数据全备,然后把数据导到云上 Redis 集群,导完后再做新增数据追加(用数据同步中心来实现),数据同步完之后进行业务切割:留一个业务低峰期时间,比如晚上凌晨 2 点,花 1 分钟把数据路由服务从自研 IDC 切到公有云 Redis 集群上。
(2) 开源组件到公有云
腾讯内部有一些业务是在开源组件之上做的二次开发(如基于单机 Redis 实现自研分布式 Redis 集群)。这些基于自研或开源组件的数据迁移到公有云上对应的数据服务,可通过 DTS 迁移工具来实现。
腾讯云上的 DTS 也可以来做自助迁移。这个工具甚至不需要运维操作,开发团队自己在 DTS 窗口上输入几个参数,点个搬迁按纽后即可自助搬迁。搬迁完成后还可自动切换。
(3) 私有组件直接上云
有时云上暂无一些特定组件,业务也没有资源改造私有组件为云的标准服务,此时可将组件集群直接在云上部署一套,数据通过同步中心或主备备等方式搬迁到公有云上。
2. MySQL 数据搬迁
QQ 的 MySQL 数据搬迁分“主—从”和“主—备”两种模式。
主—从的模式
它通过内部的 DNS 类名字服务而非 IP 和 PORT 来寻址:先分配业务一个实例的名称,然后通过 DNS 拿到这个实例的 IP 端口,再去访问具体的实例。然后,从自研的 IDC 使用腾讯云 DTS 迁移工具,把数据导到云的 MySQL。数据自动导入完成后,开发团队只需要在云上切换服务就可以完成数据实例的迁移。这种方式适合一些数据体量不大的业务数据迁移。
主—备的模式
即在深圳自研有数据库服务器的主和备,在云机房新部署几台备机。通过主备同步的方式,把所有数据都同步到云机房。然后将云机房的某台备机切换成主机,将自研的主机降级为备机。这样就切换为云机房主备,自研机房备的模式。
3. 数据同步中心
更复杂的是数据同步中心。它适合业务量大,有全国多地分布且对延迟不敏感的业务,譬如 QQ 空间的点赞、发表说说等。它有如下特性:
服务模块写数据时,统一写到各地的接入代理,代理再统一写入一地;
写服务的转发存储会将新增记录同时写到各地自研或云机房,实现最终数据一致性;
用户就近读,比如华北的用户,就读华北云的这个数据存储集群,华南就读华南的数据存储集群;
通过同步中心的方式完成大规模数据的混合云同步。当要增加一个成都云区域,只需在当地增加一套同步服务。增加路由服务规则后,同步服务就会自动把数据同步到成都的云机房。
一般从深圳自研同步到上海和天津时延迟达几十毫秒,不适合金融行业等延时高敏感业务模式。
4. 云管平台
之前腾讯内部的配置系统、监控系统、CMDB 等都是基于私有云的管理模式。业务上云之后,它们要改造成支持混合云、多云的管理模式。譬如业务模块会有 50 个实例在腾讯云上,30 个实例在海外云上,30 个实例在内部私有云里,那么 CMDB 必须要支持多云的资源管理。
图中可以看到,帐号体系、预核算、企业安全、监控等应用工具或平台,都要改造以适应混合云模式。以帐号体系为例,QQ 的开发者们以公有云的帐号登录云官网来购买、使用和运营公有云上的资源。但如何把帐号所使用的资源成本核算到对应的业务,员工离职或转岗后资源怎么回收或转移,帐号如何绑定给企业组织架构,云官网帐号登陆如何与内部 OA 鉴权等,都是必须提前解决的问题。
5. 云原生
在开发方法、业务交付、云原生服务等方面,腾讯内部的 TAPD 研发管理工具、工蜂代码仓库、蓝盾、橘子 CI、QCI、coding 已集成为工具链,在云上打造了一个持续集成、持续部署的 DevOps 流水线闭环,QQ 上云也收益于此。QQ 以前是包交付,现已大量使用容器交付方式。
在微服务这块(如 SF2、SPP、TAF 等),QQ 使用了大量的微服务框架,这些微服务框架还将进行迭代升级。
6. TKE 引擎
K8S 平台上,QQ 用了腾讯的 TKE 引擎,这是一个跟 K8S 完全兼容的引擎。一个用户在腾讯云上买了 K8S 服务,自己内部也部署了 K8S 集群。他们的容器可以随时、同时交付到腾讯云和他们本身的 K8S 集群,而不用做任何改动。通过容器交付,可以不用考虑环境依赖等问题。
通过将 TKE 跟 QQ 的业务特性适配,腾讯做出了一些更能满足业务场景的 K8S 应用功能:
(1) 跨地域
QQ 是三地分布,上云后又增加了自研和云的机房属性。原生 K8S 不支持跨地域的,因此腾讯的 TKE 引擎增加了跨地域的特性。
(2) 弹性伸缩能力
TKE 有基于 CPU 负载等基础容量的弹性伸缩能力。在 TKE 优秀的伸缩能力之上,腾讯还做了功能叠加。根据业务长期的趋势和业务突发活动,通过算法来预估容量在什么时间窗会达到多少水位,以准备相应的容器资源来提前几小时扩容,应对突发流量。
(3) 权限限制
某些业务对权限是基于 IP 鉴权的。比如内部的业务模块访问 MySQL 时,要授权 MySQL 给这些 IP 放行。容器是很难去做这种基于 IP 的权限管理,QQ 的做法是将容器固定 IP,交付时注册到 CMDB 上,完成鉴权等自动化交付流程。
(4) 开发工具
腾讯内部有很多 CI/CD 的优秀工具,开发团队可以在镜像仓库选到自己适合的工具,在 CI、CD、CO 都能保持自己的习惯。
(5)海量业务
在管理体系、安全、审计、服务监控、日志、告警等功能特性上,腾讯增加和优化了近百个特性,满足 TKE 与海量业务的结合。
从腾讯自研业务上云以及一些合作伙伴的案例,可以得出上云的五大趋势:
(1) 全面拥抱 DevOps,研发效率更高效;
(2) 内部的优秀工具上云,让云能提供更好的服务;
(3) 彻底拥抱云原生,用云来满足业务快速迭代,资源弹性伸缩的需求;
(4) 开发团队心态更加开放,主动与开源社区协同,贡献更多的功能特性;
(5) 在 QQ 全量上云的过程中,很多问题边上云边解决。整个公有云的基础设施和服务已经被锤炼得更加成熟。
五、小结
QQ 上云,好比开着火车换引擎。
现在,QQ 已经把了华南、华东、华北三大区域的用户全都迁到了云上,实现完整的 QQ 公有云上服务。是的,“开着火车换引擎”,我们做到了!
这次自研上云的成功,一方面为腾讯云的进一步壮大打下坚实的基础,另一方面,也为 QQ 自身的技术重生埋下伏笔。
QQ 的未来,从此刻开始改变。