阿里巴巴代码平台架构的演进之路

简介: 这事儿和伽利略有关。

代码平台的发展之路

相信很多做后端服务的同学在看到单机、读写分离、分片这些字眼一定不会觉得陌生。没错,代码服务在发展的开始阶段面临的问题和其他web服务大体一致,所以使用的解决方案也大体一致。

DM_20210813150206_001.PNG

单机服务

众所周知,Git是一种分布式的版本控制软件,每个人的本地都有一份完整的代码版本数据。但为了解决多人协同开发和流程管控(评审、测试卡点等),需要一个集中式的远端中央仓库来完成这些功能,这就是单机服务的来源。

读写分离

随着协同人数的增多,以及提交数量的变多,单机升配也无法解决调用量过高的问题。而通过统计我们发现,对于Git服务读写比例大概是20:1,为了保证主链路提交的正常,我们做了读写分离,来分散压力。通过主备同步来完成数据的同步,并使用一写多读的架构来扩展读服务的能力。

分片

但无论如何做读写分离,所有机器的规格始终是一样的。虽然仓库数量的增加、平台用户的增加,无论是存储还是计算都会达到单机所能承载的极限。这个时候我们采用了分片的方式,即将不同的仓库划分到不同的片中,而每个片都是一个完整的读写分离架构。当一个请求到来时,服务会根据查询库特征信息,决定这个仓库所在的分片,而后又根据接口的读写特性,将请求转发到具体的机器上。有点类似于数据库中的分库分表。这样以来,通过分片+读写分离的架构,我们理论上可以支持水平上的无限扩容。

问题及思考

那么分片+读写分离是否是解决代码服务大规模、高并发问题的银弹呢?在我们看来,答案是否定的。

伴随着代码服务体量的发展,我们解决的核心问题一直以来主要是两个:

  • 集中式的Git存储服务,既是I/O密集型也是计算密集型(Git的压缩算法);
  • 文件数量众多,单个仓库的文件数量也可能是十万甚至百万级,对数据一致性的保证和运维可靠性的挑战极大。

实际上,代码平台架构的发展,就是在这两个问题之间找平衡,以在一定规模情况下保证整个平台的稳定性。但一直没有根本性地解决掉这两个问题。然而随着规模逐步上涨,上述的两个核心问题引发的劣势又逐步变得明显起来。

代码服务主备架构:有状态服务带来的问题

对高可用系统比较熟悉的同学,从名字上应该就看出些许端倪。主备架构的读写分离方案其天然引入的就是有状态服务的问题。

DM_20210813150206_002.PNG

整个系统的请求流转,主要分两次转发:

  • 通过统一的代理层,可将用户的不同客户端请求转发到对应的系统上,如Git命令行客户端的SSH协议和HTTP协议、页面的访问及API接口请求等。
  • 然后对接的模块会将用户不同协议的请求转换为内部的RPC调用,并通过统一的RPC代理模块RPC Proxy和分片服务Shard Config将请求按分片和读写转发到对应的服务上。

读和写操作如何处理

如果是一个写操作(如:push,从页面上对文件、分支等进行新增、删除、修改等操作),请求则会落到仓库对应分片的RW/WO服务器上,在RW/WO服务写入完成以后,再通过Git协议的同步方式,同步到同分片的其他机器上,这样一次写操作就完成了。而对于读操作,则是在仓库对应分片中随机找一个RO的机器进行转发。

问题分析

当某个分片的主节点发生异常(服务crash或服务器宕机等),分片内的机器状态会发生变化。原本的RW/WO状态会置为不可用,Backup的机器会取代原来的RW/WO服务来承接写操作的请求。

从系统的角度上分析,主备架构存在以下四个问题:

1、可用性:

  • 由于读写操作是分离的,所以在写服务器failover期间,服务的写功能是无法使用的;
  • 对于单片而言,写操作是单点的,一台服务波动则整个分片都波动。

2、性能:

  • 主备机器在同步上需要额外的时间开销。对于松散文件、文件压缩的Git仓库,这个耗时比单文件拷贝耗时更久。

3、安全:

  • 用户侧的短时间内的瞬时操作,对于节点同步来说可能是并发的,无法保证同步中的事务顺序。

4、成本:

  • 同分片写,主备机器要求规格完全一致。但由于接收的请求不同,存在严重的资源消耗不均;
  • 由于同步的小文件多,对延时敏感,跨机房异步同步,机器规格一比一复制。

这四个系统上缺陷带来的问题,在一定使用规模和服务稳定性要求下是可以容忍的。但随着商业化的深入和用户规模的增长,这些问题的解决变得迫在眉睫。接下来我将和大家分享在过去的一年中,我们团队对这些架构上问题的思考和解决思路。

代码服务多副本架构:消灭有状态的存储服务

在上一个小节中,我们已经比较清晰地认识到架构上面临的四个问题主要是有状态服务带来的。那么在新架构的设计中,我们的目标只有一个——消灭有状态的服务。目标有了,如何去实现?我们首先对业内几个流行的分布式系统做了深入的了解和学习,比如ETCD、Paxos协议的学习等。同时我们也学习了代码服务的老大哥——Github开源的寥寥文章,但Github认为分布式架构是他们的核心竞争力,所以可参考的文章较少,但从这些文章中我们依然深受启发。首先对于任何架构升级,要能做到“开着飞机换引擎”,让架构软着陆是架构升级的保底要求。因此在grpc的代理层之上没有任何的改动。从内部的RPC调用以下则是我们新架构实施的地方。

和前一节的不同,在新的底层设计中:

  • 我们希望设计一个GPRC D-PROXY的模块,能将gRPC的请求做到写时复制,从而达到多写的第一步;
  • 其次在Proxy Config的模块中来存放仓库、副本、机器等元数据;
  • 再次通过一个分布式的锁(D-Lock)来完成对仓库级别的锁控制;
  • 最后我们希望有一个快速的算法能计算仓库的checksum,快速识别仓库的副本是否一致。

DM_20210813150206_003.PNG

通过这些模块的组合完成仓库多副本的并发写入、随机读取,我们就可以去除底层存储节点的状态,从而能将仓库的副本离散到不同机房中。此外得益于机器与副本的解耦,每个服务器都可以有独立的配置,这也为后续的异构存储打下了基础。

代码服务多副本架构的实现

有了基础的设计,通过MVP的实现,我们验证了这个架构的可行性。并通过一年多的时间进行开发和压测,最终将我们的多副本架构成功上线并逐步开始提供服务。在实现过程中,我们为这个系统起了一个颇有意义的名字——伽利略,因为在我们的多副本架构中,最小的副本数是3,而伽利略在发明了天文望远镜观察到火星的卫星恰好就是3个。我们希望秉承这个不停探索的精神,所以起了这个有意义的名字。在具体的设计中,我们通过对gRPC proxy模块的改写,让来自用户的一次写操作完成写复制,并通过对git的改写以支持分段提交。我们基于git的数据特性,编写了checksum的模块,可以对git仓库进行快速的全量和增量一致性计算。

DM_20210813150206_004.PNG

伽利略架构在系统架构层面解决了之前主备架构带来的问题:

1、可用性提升:多写和随机读让底层的git存储服务不存在写单点和failover的切换问题;

2、写性能提升:副本并发多写,让底层的副本间不存在主备复制的时间开销,性能比肩单盘;

3、安全:写操作的分段提交和锁的控制,在解决分布式系统写安全的基础上也控制了用户写操作的事务性;

4、成本大幅度降低:

  • 每个副本都会承担读写操作,水位平均
  • 副本与机器解耦,释放机器的规格限制,可以根据仓库的访问热度采用不同涉及机型和存储介质

说了这么多,当用户执行push后,在伽利略中会发生什么呢?我们用一个动画来简单演示下:

DM_20210813150206_005.GIF

  1. 用户3和用户4是两个着急下班的同学,他们本地master分支分别是提交3和提交4;
  2. 底部灰色的圆圈代表的是服务端一个仓库三个副本的装填,可以看到其中两个master分支指向的是提交2,而其中有一个可能因为网络或者其他原因导致其master的指向为1;
  3. 当用户3和用户4前后提交了代码,由于用户3更快达到服务,所以会率先启动写的流程;
  4. 在一个写的流程开始,首先会对当前仓库副本的一致性进行检查,系统很容易就发现落后的副本1与其他两个副本不一致,因此会将其标记为unhealthy。对于unhealthy的副本,是不会参与伽利略写或读的任何操作;
  5. 当用户4的请求也被受理后,也会触发一致性检查,但是由于副本1已经被标记为unhealthy,所以对于用户4的流程,这个副本就“不可见”了;
  6. 在用户3的进程检查后,发现多数副本是一致,则认为是可以写入的,便会将非引用数据传输到副本中;同理用户4的进程也是一样,且因为非引用数据不会变更分支信息,所以不需要加锁,可以同时操作;
  7. 当用户3的进程收到非引用的数据传输成功后,便要开始进行引用的更新,这时第一步先去抢占这个仓库的锁。很幸运锁是空闲的,用户3的进程加锁成功,开始改写副本的引用指向;
  8. 当用户4的进程也完成了非引用数据传输后也开始进行引用的更新。同样,再更新操作前要去抢锁,但发现锁已经被占用,则用户4的进程进入等待阶段(如果等待超时,则直接告诉用户4提交失败);
  9. 当用户3的进程改写引用成功后,会释放掉仓库锁。此时服务端的仓库的master分支已经被修改为指向3。用户3可以开心下班了;
  10. 当锁被释放后,用户4的进程快速抢占,并尝试修改引用指向,但发现更改的目标引用master已经和之前不同(之前是2,现在是被用户3更改的3),此时用户4的进程会失败并释放掉锁。在用户4的本地会收到类似“远端分支已经被更新,请拉取最新提交后再推送”的类似提示。

以上就是多个用户同时提交时,伽利略系统内部发生的事情。眼力好的同学可能会问,那在系统中被判定unhealthy的副本会怎么办呢?这个就是刚才在架构实现中提到的运维系统会做的事务补偿了,运维系统在收到unhealthy上报和定时扫描后都会触发对unhealthy副本的修复,修复后的副本在确认一致后会置为healthy并继续提供服务,当然这个过程在判断修复是否一致也是加锁操作的。

代码托管运维管理平台

除了上小节提到的副本修复,在系统运行中,还需要很多的运维操作。以往这些都是由运维同学操作的。Git服务涉及数据和同步,比单纯的业务系统要运维复杂度要高,对应运维风险也比较高。在过去的一年中我们结合以往的运维经验,以及新架构的需要,以工具化、自动化、可视化为目标,为伽利略系统打造了对应的运维管理平台:

DM_20210813150206_006.PNG

通过这个平台我们大大提升了运维的质量、也充分释放了运维人员的精力。

原文链接
本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从工具到平台|默安科技研发安全一体化管理平台正式发布

作者|默安科技 数字化转型浪潮下,软件研发安全的重要性毋庸置疑。 据第三方权威调查,接近92%的已知安全漏洞发生在软件应用程序中,且应用中每1000行代码至少出现一个业务逻辑缺陷。 在近年来如火如荼的攻防演练中,应用程序成为…

如何避免 Go 命令行执行产生“孤儿”进程?

简介: 在 Go 程序当中,如果我们要执行命令时,通常会使用 exec.Command ,也比较好用,通常状况下,可以达到我们的目的,如果我们逻辑当中,需要终止这个进程,则可以快速使用 …

杭州南江机器人现在是否量产_传亚马逊正开发家庭机器人,高约1米可移动

点击右上角关注我,成为科技圈最靓的仔!智东西(公众号:zhidxcom)编 | 王颖 导语:据外媒报道,亚马逊计划今年推出一款可移动家庭机器人,高度约为1米,可通过语音控制。智东西7月15日消息&#xff0…

OpenYurt 联手 eKuiper,解决 IoT 场景下边缘流数据处理难题

简介: 云计算的出现促使物联网实现爆炸式增长。在设备规模和业务复杂度不断攀升的趋势之下,边缘计算因其能够将计算能力更靠近网络边缘和设备,从而带来云性能成本的降低,也在这波浪潮之下得到快速发展。 作者 | OpenYurt 社区 云…

OS2ATC 2021:开源协作,和而不同

12月26日由中科院软件所主办,清华大学、北京大学以及鉴释科技承办的第九届开源操作系统年度技术会议(OS2ATC)正式拉开序幕,百余位重量嘉宾莅临现场,围绕大会主题“开源协作,和而不同”共同探讨操作系统开源…

ChaosBlade:从混沌工程实验工具到混沌工程平台

简介: ChaosBlade 是阿里巴巴 2019 年开源的混沌工程项目,已加入到 CNCF Sandbox 中。起初包含面向多环境、多语言的混沌工程实验工具 chaosblade,到现在发展到面向多集群、多环境、多语言的混沌工程平台 chaosblade-box,平台支持…

揭秘阿里云 RTS SDK 是如何实现直播降低延迟和卡顿

简介: RTS NetSDK是未来直播和通信一体化SDK的基石。在RTS NetSDK之上,加一个Multimedia Framework,以及QoS消息处理,就可以构成一个一体化SDK。这对于已经有自己的Framework的客户来说是个好消息,不需要为直播和通信分…

Forrester云原生开发者洞察白皮书,低代码概念缔造者又提出新的开发范式

简介: 云原生时代的到来为开发者群体带来了前所未有的机遇,让开发者可以更加专注业务价值创造与创新,并使得人人成为开发者成为现实。广大开发者如何转型成为云原生开发者?运维等专业人员在云原生时代如何避免边缘化的囧境&#x…

彻底理解内存泄漏,memory leak

作者 | 码农的荒岛求生来源 | 码农的荒岛求生内存申请就好比去停车场找停车位,找到停车位后你就可以把车停在这里。从这个类比看什么是内存泄漏呢?内存泄漏看上去是停车场的车辆只进不出导致最终找不到停车位,从程序员的角度看就是内存只申请…

动态后台获取_后台管理系统的权限以及vue处理权限的思路

一般来说,在(后台)管理系统(最早的企业级的项目和网站的后台管理系统现在大部分人都叫后台管理系统)中才会有权限之说。权限分为功能级权限和数据级权限。这篇文章主要谈论功能级权限。一、名词解释:权限的…

ARMv9刷屏 —— 号称十年最大变革,Realm机密计算技术有什么亮点?

简介: 让我们看下ARMv9机密计算相关的新特性Realm。 ARMv9的新闻刷屏了。ARMv9号称十年以来最重大变革,因此让我们看下ARMv9中机密计算相关的新特性Realm。(注:本文是对Introducing the Confidential Compute Architecture的部分翻…

JVM性能提升50%,聊一聊背后的秘密武器Alibaba Dragonwell

简介: 你要知道的关于Alibaba Dragonwell一些重要优化措施。 今年四月五日,阿里云开放了新一代ECS实例的邀测[1],Alibaba Dragonwell也在新ECS上进行了极致的优化。相比于之前的dragonwell_11.0.8.3版本,即将发布的dragonwell_11.…

34 年了,“杀”不死的 Perl!

作者 | 祝涛 出品 | CSDN(ID:CSDNnews)2021年12月18日,Perl迎来了自己34岁的生日。当程序员聊到Perl会聊些什么呢?在各大平台搜索Perl时,你会发现大家对Perl的态度呈现出一种两级分化的状态&#xff…

“不服跑个分?” 是噱头还是实力?

简介: Linux内核社区常常以跑分软件得分,来评价一个优化补丁的价值。让软件跑高分,就是实力的体现! 一、背景:性能之战 “不服跑个分”已经沦为手机行业的调侃用语,但是实话实说,在操作系统领域…

Medusa 又一个 Shopify 的开源替代品!

作者 | Eason来源 | 程序员巴士Medusa是一个开源的headless商务引擎,具有速度快且可定制的优点。由于 Medusa 分为 3 个核心组件 - 公开的REST API headless商务部分、商店的前端以及admin面板 - 大家可以自由地整体使用该平台或者来适配设置电子商店。在本教程系列…

coredump 瘦身风云

简介: minicoredump神也! 继上一篇非典型程序员青囊搞定内存泄露问题后,美美地睡了一觉。睡梦中,突然金光闪闪,万道光芒照进时光隧道,恍惚来到大唐神龙年间。青囊此时化身狄仁杰高级助理,陪同狄…

谁来拯救存量SGX1平台?又一个内核特性合并的血泪史

简介: 今天的故事主角,是一个被称为Flexible Launch Control的SGX平台特性。 前言 自从Intel内核开发人员Jarkko Sakkinen于2017年9月2日在intel-sgx-kernel-devlists.01.org邮件列表上发出v1版的SGX in-tree驱动以来,时间已经过去了3年多了…

DataWorks 功能实践速览

简介: DataWorks功能实践系列,帮助您解析业务实现过程中的痛点,提高业务功能使用效率! 功能推荐:独享数据集成资源组 如上期数据同步解决方案介绍,数据集成的批数据同步任务运行时,需要占用一…

spring 事务隔离级别和传播行为_Java工程师面试1000题146-Spring数据库事务传播属性和隔离级别...

146、简介一下Spring支持的数据库事务传播属性和隔离级别介绍Spring所支持的事务和传播属性之前,我们先了解一下SpringBean的作用域,与此题无关,仅做一下简单记录。在Spring中,可以在元素的scope属性中设置bean的作用域&#xff0…

长江存储发布PCle4.0 固态硬盘致态TiPro7000,顺序读取7400MB/s

2021年12月29日,长江存储重磅发布全新消费级旗舰固态硬盘产品致态TiPro7000。该产品采用基于Xtacking(晶栈) 2.0架构的长江存储第三代三维闪存芯片,支持PCle Gen4x4接口、NVMe 1.4协议,顺序读取速度高达7400MB/s。该产…