既要应对庞大的用户量、日均数十亿 PV 的高并发、PB 级别的数据存储等问题的挑战,同时又要求保证系统的高可用和弹性伸缩,并且能够根据需要进行快速迭代扩展,令人头疼的系统架构到底应该怎么做?
多年发展下,互联网架构经历了从简到繁的演进过程,从单体架构到集群架构、分布式架构再到微服务架构,每一种架构都是为了解决问题而生。在软件发展的不同时期、阶段,对技术的理解、选择和应用都有着不一样的诉求,架构的选型只有“合适与不合适”,永远没有“哪个更好”的说法,这也说明了在企业系统架构演进的过程中,实践要比理论更能给开发者灵感。想知道亿级用户架构怎么做?想观摩百微秒延迟的架构套路?那就不要错过这篇技术大咖分享的实践干货。
2020 年 9 月 14 日 -25 日,腾讯云官方开发者社区 - 云 + 社区联合贝壳找房共同举办的线上直播沙龙已圆满落幕,本期主题聚焦在 [架构演进],多位技术专家在线分享,从百秒微时延的深度解密、日调 1000 亿的架构演进、降本提效的架构统一之路、亿级用户的架构挑战等话题出发进行探讨,为立志提升架构能力的程序员在线解惑,从理论到实践讲透关于架构那些事儿。
以下内容经由 InfoQ 编辑整理自云 + 社区 [架构演进] 系列直播速记。
百微秒时延,腾讯云云硬盘 CBS 架构深度解密
随着云计算的逐步普及,越来越多用户在云上部署其核心业务。大型数据库、高性能 NoSQL、日志检索、DevOps 等 IO 密集型场景对云上存储提出了更高的要求。为应对日益严苛的用户需求场景,腾讯云云硬盘团队自主研发了最新一代存储引擎 HiSTOR,实现单路时延 150 微秒、单卷百万 IOPS 的超高性能。
在本场分享中,腾讯云存储专家工程师王银虎从 CBS 云硬盘的定义出发,展开对 CBS 架构演进、CBS 新的挑战、CBS 低延时结构优化以及 CBS 延时优化成果四个维度进行了详细讲解。
CBS 云硬盘即基于分布式技术实现的,能够提供个人电脑硬盘的所有能力,并且在高性能、可靠性和可用性进行了增强,提供持久化的块存储服务。目前,CBS 已经经过了三代架构的演进——CBS apllo、CBS atlas 和 HiSTOR。
那么,CBS 存储系统架构到底是怎么样的呢?
如上图所示,CBS 的存储系统 HiSTOR 的特点是极简架构,整个集群分为客户端、存储集群、控制集群三部分,客户端直接访问存储,中间没有传统的存储系统的接入模块。值得一提的是,其不仅提供的是块存储服务,而是多种存储类型服务共享的一个平台。物理成本上节约了 50% 左右,在可靠性、可用性和数据安全方面也存在显著提升。
众所周知,云盘相对本地盘主要的劣势即延时比较高,CBS 在这一点上是如何做出突破的呢?总结起来就是两个方面,一是怎么把并发做上去,二是怎么把延时做下来。
“把并发做上去”是分布式存储天然的优势,技术上相对低延时更好实现。解决“低延时”有两种手段,首先用更快的硬件去解决,另外是把软件 IO 栈做到尽量的扁平化。基于软件的维度考虑延时优化, CBS 具体是从四个维度入手:分布式架构、CBS 接入端、CBS 存储、CBS 网络。
分布式架构
CBS 的存储系统用的路由方式是一致性哈希,哈希路由如何推送到客户端是一个难点。本身路由的变更是由控制集群维护的,更新后如果直接推送客户端的话看起来很简单,但面对云上的集群规模就会发现问题。腾讯目前是上百万台的规模,如果把一个信息推送到上百万个节点根本是不可行的事情。
为了解决这个问题,“惰性路由同步”被创造出来,集群管理节点变更后不再是直接推送客户端,而是推送到存储节点,再由节点中转到客户端。其原理就是,存储节点比客户端节点数量少得多,推送到存储节点对中心控制节点的负载是可以容忍的。因为是多副本存储,数据到了存储节点后还有一次复制的过程,需要再复制成多份数据存到节点上去,这时候虽然架构上是极简的,但写的时候有两次的路由,就相当于数据走了两跳。
CBS 接入端
借助英特尔高性能存储开发套件 SPDK,可以直接在虚拟机上把数据旁路出来。IO 设备如果是虚拟机,SPDK 可以做 IO 的后端,直接把数据同步出来,再把客户端做到 SPDK 里面,这个数据路径是要短非常多。总结下来就是用 SPDK 的接入方式取代了 iSCSI 的接入方式,用零拷贝的轮询方式取代了原来两线程数据共享的方式。
CBS 存储引擎
CBS 存储引擎是基于 CEDA 框架(基于微服务模型、事件驱动的开发框架)实现的,胶片里面有个 DATA POOl,即数据池,IO 过来之后从数据池中分配数据存储的内存,整个生命周期数据不做拷贝,因此可以做到数据零拷贝。存储引擎访问硬盘用的也是 SPDK 方式,可以尽量地减少访问硬盘时在用户端内核进行切换的时间消耗。在这个过程中,用户态的任务调度可以让一个 IO 的处理从进存储引擎到访问存储硬件整体在一个进程里面做,没有切换的开销,这样就可以把延时做到极致。
CBS 网络
在 CBS 极速云盘中,一方面,RDMA 和 TCP 并存的状态使得其在故障的时候可以快速自动切换;另一方面,面对 RDMA 的拥塞控制,CBS 除了硬件提供的拥塞控制能力外,应用层也做了控制,比如存储和客户端的交互用的 RDMA_read 方式,过滤了拷贝过程,对大 IO 比较友好,但是交互流程要多几跳,小 IO 并不使用。从交互协议层面来说,当需要带宽的时候用的是 read 方式,当需要优化延时时使用 send/recv 方式。
在 CBS 网络模型的三种交互方式中,存在的主要问题是频繁的上下文的切换以及太多的数据拷贝。用户态协议栈的作用就是减少数据拷贝和上下文的切换,如上图所示,腾讯做 ZTCP 的特点是同时支持零拷贝,RDMA 不需要软件支持而是硬件,协议栈卸载到硬件里面以求做到旁路掉内核、数据零拷贝,这些技术要求同时达到就可以将延时降到最低。
经过不断的技术深耕,目前 CBS 延时优化已经能够做到 100 us 到 120 us 之间,给产品的目标是希望年底能够做到 50 us 到 100 us 的水平。
日调 1000 亿,腾讯微服务平台的架构演进
随着业务增长,许多中小型公司会面临业务增长体量较快、现有架构体系跟不上业务增长速度、微服务系统上线后变得不稳定等问题。如何用开源组件搭建稳定运行大流量的微服务系统?如何实现微服务的划分,使微服务的系统和平台更为稳定?本场分享中,腾讯专家工程师刘智新讲解了腾讯云中间件团队在微服务平台演进过程中的思考、落地与挑战。
微服务之间如何进行调用?
可以通过服务注册和发现的能力模块进行机器实例的互相发现和调用。目前市面上已经有很多成熟的注册发现组件,如 zookeeper,nacos,Consul 等。Consul 本身作为一个开箱即用,并且支持 http 请求,同时拥有丰富的文档和简单的 API 的系统被很多的中小型公司青睐和使用。
如何实现多租户?
实现多租户的能力,需要在原有的 Consul-server 集群之前,加一层 Consul-access 层。具体改造分三步走,第一步:当 access 接收到注册请求后,会将该请求翻译成一个 KV 请求,然后存储到 Consul-server 上;第二步:心跳请求会被 Consul-access 拦截,翻译成 KV 请求,存在 Consul 集群上;第三步:服务发现请求会将服务注册的 KV 内容和心跳 KV 内容合并再返回给客户端。
通过增加 access 层还能够解决 Consul-server 没有办法无限水平扩容的问题,这个架构思想非常通用,当底层系统有瓶颈无法水平扩容时,可以想办法把压力上提到一个可以水平扩展的层级,将压力转移出去,从而使整个系统变得更加稳定。比如数据库中间件和背后的 mysql。对于 Consul-server 集群的瓶颈问题,可以以 Consul-server 集群为粒度进行水平扩容。
CP 系统如何做到高可用?
Consul 是一个 CP 系统,根据 CAP 定理,CP 系统是没法做到高可用的,所以我们只能尽可能的在别的环节来加强,如从客户端、SDK 和 access 层来弥补 CP 系统的可用性。
在 SDK 层中,优化分两步走:第一步将定时拉取改为了 watch 机制,缩短通知客户端更新列表的时间的同时增加了本地缓存,这样一来,每次拉回来的服务列表都会存储在本地,机器 crash 或者 Consul 集群不可用时,不至于危及整个微服务系统。最后增加零实例保护,如果从 Consul 拉取的列表为空时,不替换内存中的数据,也不刷新缓存。
第二步加强心跳上报的流程,心跳上报是 put 请求,所以这里需要设置 readtimeout,默认是 1min。这里要注意的是,1min 可能是两个心跳周期,如果客户端和 Consul 之间的网络抖动或者丢包会直接造成 1 分钟内不可用,所以这里首先要设置 readtimeout,一般推荐 5s 左右。同时需要配套增加重试机制,否则一次失败就会导致一个生命周期掉线。
着眼于 access 层,在计算机系统里,每增加一个中间层,解决一些问题的同时,也会带来一些问题,特别是在可用性上。access 对于客户端来说就是服务端,所以要尽可能的保证每个请求的成功,主要在三点上为可用性增强建设。
第一,和 SDK 的一样,减少 timeout 和重试,但是由于 raft 的实现机制,我们只需要重试最多 1/2+1 次就行。第二,当出现某个极端场景,比如整个 Consul-server 集群不可用,我们需要增加一个兜底集群。第三,还需要增加主动发现问题的能力,这里要增加集群探测的 agent,定时发送请求给每台 access 和每个 Consul-server 集群,出了问题及时告警。
如何让服务之间的调用变得更加稳定?
从上图可以看出,在 feign(在这里配置需要访问的微服务名称) 和 ribbon(负载均衡模块) 之间增加了 hystrix 和 fallback,分别对应着熔断和容错这两个能力。通过熔断模块,可以防止整个微服务被某一个半死不活的微服务拖死,要知道,在微服务体系或者说分布式系统里,服务半死不活远比服务整个宕掉难处理的多。
反观容错,其使用场景并不是非常频繁,更多是针对一些不那么重要的接口返回一些默认的数据,或者配合熔断等其他治理能力进行搭配使用。当 ribbon 选定了实例之后,要正式发起调用的之前,可以添加一个重试和超时,加上重试和超时,如果真的能够配置好这几个参数,能将系统稳定性提升一大截。
实际上,这些增强并不需要用户修改业务逻辑,基本上都是配置和依赖,但是正确的配置和使用这些开源组件,可以让整个系统变得更加稳定。
降本提效,贝壳搜索推荐架构统一之路
搜索和推荐是用户获取信息的两种主要方式,在贝壳也是帮助客户找到房子的主要手段。在本场分享中,贝壳搜索推荐部平台架构负责人高攀详细介绍了贝壳在将搜索与推荐两套系统的架构演进之路,并对两者的架构统一过程进行了深度解读。
贝壳搜索平台架构演进
从 2018 年的 100 多个业务、日均 5 个亿的流量发展到 2020 年的 500 多个业务、日均 20 亿流量,贝壳搜索平台总共经历了 4 个阶段的架构演进。最开始的架构非常简单,底层用到的是 SolrCloud,上层是两个服务,写入服务和查询服务,是一个非常简单的搜索服务。
在升级为平台之后,其业务接入量的增多暴露出人力对接式协作流程的繁琐,为改变此状况,贝壳开发了搜索云平台。其核心思路是把整个业务对接的流程进行线上化、产品化、自助化。但存在两个问题,首先是整体效率低下,其次大部分是人工配置上线,很容易出错。
从解决问题的角度出发,搜索云平台有了如上图所示的一套核心思路,即把配置统一放到 Mongo 里面,整个联调通过后可以一键把 RD 环节配置重复到 QA 环节。验证通过之后,一键把配置重复到线上,省去了中间人工修改配置上线到测试到开工到整个过程,提高它的迭代效率。同时整个业务接入平台化,上层的可视化模块可以直接看到分词效果、数据流同步情况以及数据变更记录等等;通过耗时统计可以方便的看出耗时比较长的是哪个环节,从而提高效率;以平台管理打通数据流的依赖,实现自助接入;底层是监控报警平台,包括全链路追踪平台、监控平台、报警平台和值班管理。
随后的发展中,通过查询层、召回模块等进一步完善了服务治理平台,包括注册中心、配置中心、负载均衡、消息总线、熔断降级、链路追踪、监控报警和服务编排,最终形成了现在的搜索中台。
贝壳推荐平台的架构演进
贝壳推荐平台的架构演进也经历了四个大的迭代,最早期就是简单的基于内容和规则的推荐引擎,后面进一步增加了用户画像和协同过滤进行个性化推荐,在通过实时计算和实时模型实现个性化推荐,最后为了提升业务接入效率推荐平台做了一个大的迭代,形成了智能推荐平台。
个性化推荐下业务接入效率和效果迭代效率并不尽如人意,其整个推荐服务下面的离线和实时差不多,主要重构的是中间的“推荐”服务,也就是一个业务对应一个服务,不能长久。为解决这个问题,贝壳在中间的推荐服务做了一个大的重构,不再是每个业务单独推荐,而是整个体系支撑所有的业务,每来一个业务都复用整套的推荐服务。为了达成效果,贝壳将整个推荐服务拆分为应用层、计算层、数据层、模型层。
贝壳搜索推荐架构统一
实际上,搜索和推荐的目的、流程、功能架构都是相通相似的,用一套架构、一个套代码来完成不仅可以提升整体的能效,也能达到降本增效的作用。核心目的就是通过搜索架构的统一达成一个 1+1 大于 2 的效果。此外,还有一些附带的好处,如提升整体的稳定性。
如上图所示,搜索推荐的整体架构统一之后和之前的架构是相似的,在集成之后,上层还是通过业务方去调用统一的网关,做流量分发、降权等等。大变动是在查询层,对整体的分析搜索,推荐原来相同的模块、不同的模块,调动相同的策略、不同的策略,整体做一个整合。最新的架构核心分为六个模块,包括中控模块、意图管理模块、召回模块、排序模块、重回模块、理由模块。在存储方面增加了向量检索引擎、图检索引擎、KV 检索引擎三大检索引擎。剩下的模块和之前推荐和搜索都是一样的,同样会实时回流业务方的埋点日志然后做实时个性化的推荐。
亿级用户,腾讯看点信息流推荐系统的架构挑战
看点信息流每天为亿级用户提供海量实时推荐服务,除了大并发 / 低延迟 / 高性能等传统架构挑战以外,还有很多推荐系统特有的架构挑战难题。在本场分享中,腾讯看点 - 独立端推荐研发中心总监彭默从腾讯看点信息流实战经验出发,揭晓架构如何做可以帮助推荐系统达到更好的推荐效果。
信息流经过多年发展,从架构层面来讲都是大同小异。从架构出发,存在四点问题:首先,推荐系统效果想要获得提升,系统实时性要如何做;其次,扩大召回计算量也可以提升系统的效果,但这里要注意一个问题,并不是并行度越高越好,要注意大扇出的问题;第三,被传统后台优化所忽略的是如何做用户内容的曝光过滤,看似简单的功能实行时会存在很多问题;第四,一百个召回下要如何提高开发效率。
如何提升系统实时性?
特征系统之于推荐系统来说,特征越多算法效果越好。特征系统的线上挑战很大,以腾讯系统为例,每秒钟的峰值达到千亿个特征,换算成流量每秒能达到 TB 级,有别于多级缓存、文件行同步的传统特征系统设计方案,腾讯系统的各个服务在使用特征时,通过 API、lib 库的方式,特征数据已经通过后端的特征计算好,push 到各个机器上面,这样只需要查就可以了。此外,将特征做成分片式,不仅减少了单机下对内存的消耗,还减少了很多的跨网络调用。
在用户模型上具有挑战的地方是长期画像 T+1 的处理,对于腾讯来说,每天需要处理百亿级流水,处理时间是 4-5 个小时,一般处理分为几个步骤:首先是对数据进行预处理,进行不同特征的计算;其次是外部流水应用的处理,看机器的数量,机器多直接并行算就能很快,这里要考虑性价比;第三是每次请求实时模型打分。
接下来看 online learning,线上样本如何拼接,模型如何做?主要在两方面,第一是将样本拼接进行优化,最早是通过小试做样本,后来通过实时进行拼接,人均点击提升 2.1%;第二是模型更新,由小时级全量 update vs 部分增量 + 定时全量分钟级 update,借助腾讯内部的融达系统,能够让其很快地执行。
在内容入库和索引服务上,内容的时效性很重要,内容改变之后线上化必然需要多个索引去做多个 ABTest,为了实现深层次的 Test,腾讯设计了自研索引目录,通过 hash 后以列表的形式进行处理,考虑到整个物品数量是千万级,想要单机可以扛下,方法是单机多部署,保障线上性能表现。
如何做推荐系统的性能优化?
目前推荐后端耗时要在 500 毫秒以下,如果不做优化,会飙升到一秒,这样的系统基本处于不可用的状态。性能优化后能够减少将近 50% 的耗时,归纳起来主要在于三点:首先是架构层面尽量做分布式并行的并行计算;其次是很多计算可以统一起来进行打分;第三是可以用近线计算改进在线计算,用户特征不会发生变化。
如何做用户曝光内容过滤?
如图所示,在做用户曝光内容过滤时,有三点考量:其一,优化布隆过滤器设计,节省内存;其次注意晚高峰,这时候用户投诉重复多;其三,真实曝光的很多内容是后台曝光了,但用户没有看到,重新召回这些内容进行推荐,对点击效果提升很大。
100+ 路召回下有哪些问题需要考虑?
一百多个召回不可能做到每个人都有专门的召回,但开发效率又不能降低,对此,腾讯设计了一个默认的召回打分模型,优势有四:其一提升效率,各路召回不再需要自己打分,全部由 PE 完成;其二召回粗筛,设置用户兴趣向量的实时计算、物品向量的离线计算,在线只算多目标;其三召回模型,对初筛结果做精细化计算,特征量更多,精度更高一些;其四是采用分布式并行计算提升计算量。
优秀程序员,如何提升架构能力?
在“架构演进”系列直播的最后一场中,腾讯云块存储与虚拟化总监马文霜、贝壳找房基础平台总经理 / 腾讯云最具价值专家「TVP」王超、同程艺龙机票事业群 CTO/ 腾讯云最具价值专家「TVP」王晓波三位大咖同台,对程序员该如何提高个人架构综合能力这一话题进行了分享。
分享伊始,三位大咖从以往的工作经验中分享了个人对架构演进的理解,从不同角度讲述了架构演进历史。最后,王晓波总结道,合格的演进应该来自真正的需求,当需求发生变化时需要更多更新更好的体验,架构也在继续下一步的演进。从不同的角度来看整个架构演进史,不管是程序员、架构师还是用户,其实都觉得这么多年来我们敲的每一行代码都在产生一步一步巧妙的变化,最后达到了今天我们看到的这样一个效果。
在如何快速把控项目架构上,马文霜最关注的点是“可控”。他认为应该有一种快速的、简单的架构,去快速地试错,然后先把这个原型搭出来,这个是不是用户要的,高可用、高并发、高性能,哪些更重要,投入相应的资源在这个上面去做相应的演进。
王超则认为架构师要根据自己的业务情况设计相应的架构,他表示,如果他接手一个全新的项目,首先会摸盘现有系统的情况,先把整个代码的关键逻辑或者分层结构列出来,之后再去分析风险点,提出解决方案。
王晓波则就这个话题分享了接手新项目时该如何从零做起,他从两种项目情况进一步阐述道,一种是打造全新的、零开始的项目,只需要按部就班的去做即可。另一种情况是接手了一个完全陌生领域的业务系统,挑战会相对变大。面对后一种情况,他建议开发者首先要把整个系统的边际和现在的系统逻辑过程看完,然后把业务梳理清楚,最后基于这样的业务和技术以及自己的思路重新且完整地设计出一个新的架构。
对于如何综合提升架构能力这一话题,三位大咖也分享了自己的看法。
马文霜提到,比较有效的途径就是去做不同类型的项目,从解决业务问题的角度出发去进行更多的练习。即使没机会参与到其他的项目里面,也要去看一些关于架构的技术书籍,或者是在云 + 社区看各位老师的架构分享直播,学习一下高可用架构的思路和方法论。同时,也还是要通过自己去搭建环境、模拟真实的业务场景,比如可以借助腾讯云上的负载计算器,去挂逻辑服务器,就可以搭建一个简单的、具有横向扩展能力的系统,以此来练手。
王超则从自己的个人成长经历出发,总结了主动、开放的心态、深入和拥抱开源这四点学习态度。王晓波则认为,想要成为一个优秀的架构师首先要定义的是自己想成为一个怎样的架构师,需要给自己设定一个目标,比如如果想要掌握 Linux,那未来就需要掌控整个存储设施。其次要学会从全局的角度去看待整个项目、整个系统,要完成的任务的边界在哪里,难度在哪里,结偶部分在哪里,从技术进行突破,才可以设计出优秀的架构。
多年来架构系统更迭不断,很多行业问题也在这个过程中成功破解,但究其根本,技术创新的源头还是一代代不懈深耕的开发者们。优秀架构师的成长之路并不是一蹴而就的,需要不断地学习、试错和实践。正是源于对技术同样的热忱,让大家相遇在云 + 社区沙龙直播间,跟随技术大咖的前进脚步探索自己的架构之路。未来腾讯云还将举办更多技术布道活动,积极拥抱开发者,携手谱写架构新时代。
扫码,即可观看视频回顾
评论