如今快手有 80 亿条海量短视频,1.5 亿的日活,每天仍然有超过 1500 万条以上的新增短视频。如何根据用户的个性化需要,把海量视频精准的分发给用户,让有户得到独特的体验,感受科技带来的幸福感,这是一个复杂的技术问题。快手的用户界面非常简洁,在简洁接口背后是非常复杂的一套后端系统。
以下内容是快手科技基础平台架构师曹福祥在 2018 北京 ArchSummit 全球架构师峰会快手科技技术专题中分享,快手服务治理平台 KESS 的设计理念和实战。
快手服务架构和服务化背景
快手的公司使命是用科技提升每一个人独特的幸福感,这其中就包括让每一个普通人都有机会被世界所看到,以及看到更广阔的世界。这里需要解决一个问题,如何让所有视频都有机会被看到,同时也不能让低质量或者用户不感兴趣的视频影响用户的体验,换句话说,如何解决十亿级长尾视频的高效分发。
为了解决这个问题,快手采用了独特的技术架构,一是前端入口非常简洁,关注、发现、同城三个 Tab,二是极其复杂的后端架构,通过 AI 和大数据技术实现视频内容理解和个性化推荐,从而解决内容分发的问题。
快手的后端服务架构包含多个业务模块,比如视频处理、推荐、广告、消息系统等,每一个模块都可能由成百上千的微服务组成。这是一个非常复杂的微服务网络,并且其规模也随着用户规模和开发团队扩张而增长。如何在保障整体服务质量的同时,还能保证新业务的开发效率和质量,需要一个统一的服务治理方案,来解决微服务开发运维过程中的各类问题。
服务治理平台方案选型
这里列出了服务治理的几个基本要求。首先要有完善的基础平台和组件,包括配置中心,服务发现、监控平台,以及服务开发框架。第二,支持多语言,因为快手的业务特点,主要使用的语言有 Java 和 C++,还有少量业务会使用 Node.js、Python。第三,高可用、高可伸缩性。第四,快手的服务原来主要部署在物理机和虚拟机上,现在又增加了容器化部署平台,需要兼容所有的部署平台。
除此之外,还有几个核心痛点,第一,服务治理平台自身的可用性要达到足够高。第二,要支持跨数据中心的路由管理。第三,有状态服务管理,这部分在大部分常见方案中支持不多,后面详述。第四,复杂服务调用网络上的质量监控。
这是四个核心痛点,加上前面的四个基本要求,根据这些依据来做服务选型。
首先快手调研了一些开源的方案,看看是否可以做一些定制化的开发,这样做的优点是有大量的业界经验可以借鉴,可以少踩坑,前提是改造成本不能太高。
常见的开源方案有很多,为了方便比较,快手把常见的服务治理方案从需求出发做了一个简单的分类。
第一类是简单的基于分布式协调系统的方案,比如基于 Zookeeper 的临时节点来做。这类方案缺点比较明显,之前 Netflix 和阿里都有专题文章分析了这类方案的弊端,从 CAP 理论的观点来讲,配置中心和服务发现需要尽量高的可用性和分区容忍度,一致性要求相对较低,一般认为最终一致即可。这与 Zookeeper 的设计模型有一定的偏差。
第二类是服务发现和配置管理中心方案。比如国内很多公司使用的 Consul,以及今年阿里刚刚开源的 Nacos。
第三类是集成服务治理的单语言 RPC 框架,比如说 Spring Cloud,还有 Dubbo。
第四类是集成服务治理的多语言 RPC 框架,比如腾讯 2017 年开源的 Tars。
第五类是容器化的平台。Kubernetes 和 Istio。前者是大家比较熟悉的一个容器化管理平台。Istio 是基于 Kubernetes 的一个 service match 实现,今年 7 月刚刚发布了第一个正式版本.
这些方案,有的在基础需求上有所欠缺,比如说不支持多语言或者缺少一些组件;还有一些在核心痛点上没有足够的支持。比如,服务治理平台本身的可用性,需要从底层做大量的改造,开发成本非常高。
经过调研,快手决定自研,自研除去解决基本需求和核心痛点之外,还有一个附带的好处,能够快速迭代,能够在业务发展非常快的情况下,快速跟进业务提出的各种需求。
痛点分析和设计理念
下面分析一下四个核心痛点,它们从何而来的,自研的 KESS 平台又是如何解决这些问题的?
痛点一:服务治理平台自身的可用性。服务治理平台非常基础,一些公司把它称为元服务,即服务之服务,它的可用性决定了业务服务可用性的天花板。首先看一下 KESS 的多数据中心的架构。
快手有国际化业务,把相对独立的国家和地区称作 division。比如图中 central division 是指国内的,另外还有韩国、印度等。在每一个 division 内部会有多个数据中心。其中有一个是主数据中心,其他的是从数据中心。KESS 负责从主数据中心到从数据中心的数据同步。主数据中心是全局配置唯一的可写入端。一旦主数据中心发生了灾难,可以将另一个可用的数据中心切换为主,在较短时间内恢复功能。这里比较核心的一个高可用设计,在于它的配置分发部分。
上图展示了主从两个数据中心的情况。底层的存储虽然使用了 ZK,但使用方式非常节制,仅仅把 ZK 当做一个小数据量的 KV 存储,由上层来处理多个机房之间的数据同步。并且不依赖于 ZK 的通知机制,采用既推又拉的方式去同步数据。事实上,可以把 ZK 换成任何能够满足要求的存储系统,包括 MySQL。
在底层的存储之上,设计了一个配置同步协议,这个协议里定义了一个最小同步单元,其中所有配置项的修改是原子可见的,整体上满足 BASE 原则,即基本可用,软状态,最终一致性。
Mandator 是每个数据中心的协调模块,是主从热备的,负责数据同步。每一个机器上还会运行一个 Agent,Agent 负责同步数据到本地的文件系统和共享内存中。SDK 定期扫描本地缓存,获取数据更新。
这里,第一解决了多数据中心数据同步的问题,第二实现多层的缓存以及持久化,第三,任何一个模块如果出现了故障,有备用的模块,如果没有备用模块,也有一个缓存,保证它的读可用性。
在配置分发之上建设了服务发现机制,在设计中也包含了一些中间缓存来确保某些模块暂时失效时,业务的无感知。
痛点二:跨数据中心的路由管理
对于多数据中心部署的服务,通常是需要就近访问的,一方面能保证低延迟,另一方面也能减少专线故障对可用性的影响。但也有一些例外,比如说机器资源可能不均衡。在快手,因为业务规模扩张太快,经常出现某个数据中心机器资源紧张的情况。一些服务在特定数据中心没有机器可以部署,就近访问就会失败。另外,在节假日,用户访问量通常会增长,需要提前估算流量安排机器扩容,但估算可能会不足。
再一个,下游业务可能会发生故障,这个时候需要把原来就近访问的请求分发到其他可用的数据中心去。所以我们提供了这样的功能,在正常的情况下都是就近访问的,但是遇到突发情况,能够快速把某个服务的流量按比例调度到其他数据中心去。
痛点三:有状态服务管理
有状态服务管理是较少提到的话题,因为它比较复杂,一般在业务架构设计中是要尽量避开的。为什么快手需要有状态服务,主要分为两种情况,一是在特定的领域存在有状态服务的开发需求,比如高并发的消息服务、推荐系统、多媒体数据理解等。二是业务服务无状态,实际上是把状态交给了分布式存储。当业务规模不断扩大的情况下,已有的分布式存储方案可能不是特别适用,需要做定制化开发。
一个典型案例,快手的私信服务,可以理解为是一个 IM 服务。这个服务管理了用户手机和快手服务之间的长连接。长连接就是一个状态,长连接建立好之后还会有一个用户会话数据,这也是状态。一旦服务重启,这些状态就会丢失,用户就会掉线,虽然可以在客户端做一些 cover,但不是特别理想。
所以把这个状态和业务逻辑做了解耦。一是把长连接的管理拆分为一个服务,它逻辑非常简单,非常稳定,很长时间都不需要去更新它。二是把业务逻辑做成一个无状态的模块,它更新比较快,但是重启也不会导致用户掉线。三是开发了一个 Crux 服务存储会话数据。它是持久化的,支持多地多活,能支撑千万级的读写 QPS。为此我们牺牲了写读一致性,写入之后可以容忍在十毫秒之内读到即可。它是一个非常定制化的分布式存储服务。Crux 服务目前支撑了主 APP 的私信服务,同时有千万级用户在线,1.5 亿的日活。
对于 Crux 这样的有状态服务的开发,有一些共通的做法。首先要对这个数据做分片,让它可以伸缩;然后需要主从多副本,能够支持自动 Failover。还要支持平滑扩缩容。以及对于快手来讲,一定要支持多数据中心。KESS 将这些业务无关的逻辑抽象为一个统一的有状态服务管理模型:预分片、自动平衡以及状态迁移,来帮助用户简化有状态服务的开发。
痛点四:复杂服务网络的监控
在复杂服务调用网络上的质量监控,主要有如下一些需求:
服务依赖梳理,在做服务改造或者容量预估时,需要了解上下游的情况。
如何监控服务整体质量指标,而不是单机指标?
出了故障,怎么定位?
为了解决这些问题,我们开发了 RPC Monitor 监控系统,它主要有以下几个核心功能。
能够实时的查看整体服务的可用性。
对可用性做多维的分析。比如除了实例维度之外,还要能够对机房维度、错误类型维度、主被调的不同维度来做分析,帮助快速定位问题。
3.报警功能。上图右侧是一个手机报警页面。从图中我们可以看到成功率曲线的陡降很可能是跟 QPS 上涨有关。工程师也可以通过下面的图表和链接去查看更多维度的信息来判定问题根源。
4.调用链分析。比如上图是现实当中某一个服务上下游的情况,其中红色的小点代表微服务,背后可能有成百上千的实例,线条代表调用关系,线条的颜色代表调用的成功率。
痛点分析和设计理念
KESS 的整体架构
上图是 KESS 平台整体的架构。KESS 目前在快手得到了广泛的应用。目前 KESS 上管理了几千个微服务,几万台服务器,在四个国家和地区都有部署,分布在十多个数据中心。
平台的整体可用性是 99.997%,之前发生过一次 Zookeeper BUG 导致的故障,写可用性受到了影响。
跨数据中心的路由管理功能在快手内部每个月大概有一百多次的使用。RPC Monitor 每天会发出几百个报警信息,发现并定位了后端工程方面几乎 100% 的故障。
关于未来计划
目前快手有更多的新语言开发者加入,需要服务平台继续支持更多的编程语言。服务网格是业内比较关注的领域,它能有效地提高工程师的开发效率,目前我们也在探索其结合方式。再有,多数据中心给业务架构设计增加了很多复杂性,我们希望能在基础平台的层面做更多的适配,简化业务设计开发的负担。