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

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

代码平台的发展之路

相信很多做后端服务的同学在看到单机、读写分离、分片这些字眼一定不会觉得陌生。没错,代码服务在发展的开始阶段面临的问题和其他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

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


欢迎大家使用云效云原生时代新DevOps平台,通过云原生新技术和研发新模式,大幅提升研发效率。现云效公共云基础版不限人数0元使用,羊毛不薅白不薅。欢迎点击链接前往阿里云云效官网了解:https://www.aliyun.com/product/yunxiao?channel=hy

相关文章
|
2月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
2月前
|
机器学习/深度学习 算法 测试技术
图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析
本文探讨了基于图的重排序方法在信息检索领域的应用与前景。传统两阶段检索架构中,初始检索速度快但结果可能含噪声,重排序阶段通过强大语言模型提升精度,但仍面临复杂需求挑战
86 0
图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析
|
2月前
|
Cloud Native 区块链 数据中心
Arista CloudEOS 4.32.2F - 云网络基础架构即代码
Arista CloudEOS 4.32.2F - 云网络基础架构即代码
58 1
|
8月前
|
运维 监控 负载均衡
动态服务管理平台:驱动微服务架构的高效引擎
动态服务管理平台:驱动微服务架构的高效引擎
130 17
|
3月前
|
人工智能 自然语言处理 安全
基于LlamaIndex实现CodeAct Agent:代码执行工作流的技术架构与原理
CodeAct是一种先进的AI辅助系统范式,深度融合自然语言处理与代码执行能力。通过自定义代码执行代理,开发者可精准控制代码生成、执行及管理流程。本文基于LlamaIndex框架构建CodeAct Agent,解析其技术架构,包括代码执行环境、工作流定义系统、提示工程机制和状态管理系统。同时探讨安全性考量及应用场景,如软件开发、数据科学和教育领域。未来发展方向涵盖更精细的代码生成、多语言支持及更强的安全隔离机制,推动AI辅助编程边界拓展。
131 3
基于LlamaIndex实现CodeAct Agent:代码执行工作流的技术架构与原理
|
8月前
|
运维 监控 负载均衡
探索微服务架构下的服务治理:动态服务管理平台深度解析
探索微服务架构下的服务治理:动态服务管理平台深度解析
|
8月前
|
运维 监控 安全
探索微服务架构下的服务治理:动态服务管理平台的力量
探索微服务架构下的服务治理:动态服务管理平台的力量
|
6月前
|
Java Linux C语言
《docker基础篇:2.Docker安装》包括前提说明、Docker的基本组成、Docker平台架构图解(架构版)、安装步骤、阿里云镜像加速、永远的HelloWorld、底层原理
《docker基础篇:2.Docker安装》包括前提说明、Docker的基本组成、Docker平台架构图解(架构版)、安装步骤、阿里云镜像加速、永远的HelloWorld、底层原理
686 90
|
3月前
|
SQL 人工智能 前端开发
JeecgBoot 低代码平台 v3.7.4 发布,后台架构大升级
JeecgBoot 是一款基于 SpringBoot2.x/3.x 和 SpringCloud Alibaba 的企业级 AI 低代码平台,采用前后端分离架构(Ant Design & Vue3),支持 Mybatis-plus 和 Shiro。它集成了强大的代码生成器,可一键生成前后端代码,无需手动编写,大幅减少重复工作。平台支持 DeepSeek、ChatGPT 和 Ollama 等主流大模型,提供 AI 对话
237 9
|
5月前
|
SQL 消息中间件 Kafka
Flink+Paimon+Hologres,面向未来的一体化实时湖仓平台架构设计
本文介绍了阿里云实时数仓Hologres负责人姜伟华在Flink Forward Asia 2024上的分享,涵盖实时数仓的发展历程、从实时数仓到实时湖仓的演进,以及总结。文章通过三代实时数仓架构的演变,详细解析了Lambda架构、Kafka实时数仓分层+OLAP、Hologres实时数仓分层复用等方案,并探讨了未来从实时数仓到实时湖仓的演进方向。最后,结合实际案例和Demo展示了Hologres + Flink + Paimon在实时湖仓中的应用,帮助用户根据业务需求选择合适的方案。
946 20
Flink+Paimon+Hologres,面向未来的一体化实时湖仓平台架构设计

热门文章

最新文章