工夫进入2023年,分布式存储又向何处去呢?哪些场景、业务翻新会成为新的突破口呢?如何帮忙传统产业更好应答海量数据增长和数据翻新的挑战?2023年3月10日,由百易传媒(DOIT)主办、上海市计算机学会与上海交通大学反对的第六届分布式存储高峰论坛(Distributed Storage Forum 2023)于线上举办,十多位业界专家、厂商代表与近万名观众就时下热点关注的话题进行分享、互动和交换。

阿里云智能资深技术专家闫卫斌应邀出席本次论坛,并发表主题演讲。

以下内容依据速记整顿。

闫卫斌:大家好,我是来自阿里云存储的闫卫斌。非常高兴明天有机会在DOIT论坛做一个阿里云对象存储OSS技术架构的分享。


阿里云智能资深技术专家 闫卫斌

我明天分享的题目是:“如何打造具备极致容灾能力的对象存储”。

容灾是分布式存储畛域的一个关键问题。

最根底的是服务器容灾,这是所有对象存储产品都要解决的问题。

进一步,就是AZ(Availability Zone)级故障容灾,AZ也就是可用区。通常一个可用区会映射到一个或者多个数据中心。一个AZ和其余AZ在制冷、供电等方面都是故障域隔离的。几大云厂商也都提供反对AZ级容灾的对象存储产品。

可能有同学会问,做AZ级容灾是不是有必要?大家如果去网上去搜寻一下就会发现,各大云厂商的AZ级故障还是时有发生的,包含一些不可抗灾祸或者制冷、供电中断等故障。从底层逻辑上来讲,AZ级故障是不可能彻底防止的。对于一些高可用的利用,采纳具备AZ级容灾能力的存储产品还是十分有必要的。

Region故障也是同样的情理。每个AZ之间会距离几十公里,然而在一些极其场景,比方高等级地震的时候,那同时影响到一个Region的多可用区也是有可能的。比方最近土耳其7、8级地震,它是有可能导致Region级故障的。各家厂商也有提供一些应答Region故障的产品或者说解决方案,对象存储OSS也有相似的产品,前面会介绍。

本次分享首先会介绍本地冗余,也就是LRS(本地冗余)这个产品做了哪些容灾设计,其次,我会介绍咱们应答AZ故障的ZRS(同城冗余)产品的容灾设计,第三局部是应答Region故障的跨区域复制性能。在第二、第三局部我别离以案例深刻介绍咱们在技术上做的一些改良或者设计。最初分享咱们是如何以智能运维平台来应答生产过程中零碎长时间运行当前架构腐化的问题。

一、LRS(本地冗余产品)的容灾设计

上图右边是咱们OSS零碎模块的划分图,从上到下大抵能够分为四层。

用户申请进来之后,首先会达到咱们的负载平衡,也就是AliLB,AliLB是阿里自研的高性能的负载平衡产品,它是基于LVS原理的。

往下申请会来到业务层,在这一层次要是做协定的解析、各种各样的业务性能的实现。这两层咱们都是一个无状态的设计。在这种无状态的服务外面如何做高可用的呢?咱们会把它的部署按机架来打散并保障两个机架故障状况下,它的服务能力还是足够的。

再往下,申请就会来到索引层,索引层咱们叫做KV,是一个Master Server构造。每个Server又依据字典序划分为多个分区,它的Master跟每个分区的Server都是采纳Raft协定实现的一致性组。

底下就是存储服务盘古,它跟KV相似,也是一个Master Server的构造。区别是它的Server没有采纳一致性组的架构,次要是性能思考。另外在高牢靠上是通过正本或者EC机制来做的。

在LRS产品里,阿里云整体的容灾设计指标是心愿做到两个机架故障不影响服务的可用性和可靠性。

方才曾经提到了无状态服务,对有状态服务的话,他们的一致性组,咱们都是采纳五节点部署的。这五个节点会打散部署在至多五个机架上。这样不言而喻:如果说故障两个机架,还是有少数节点存活,还能够提供服务。

数据方面,咱们有两种数据的寄存模式,有三正本,也有EC。三正本的话,只有做了机架打散,显然是能够实现两机架的容灾的。对于EC,咱们也会保障它的校验块的数量大于等于二。同样也是做机架打散,能实现两个机架故障不影响可用性可靠性。

除了这些数据的扩散形式,咱们还做了十分多的其余的设计来保障高可用。比方数据分片是做全机群打散的,这样做有什么益处呢?如果一台服务器产生故障,如果做全打散的话,是能够利用这个集群里残余的所有机器来并行的做数据修复,这样缩短了数据的重建工夫,相应的也就进步了可靠性。

另外,咱们也会刚性的保留足够的复制带宽。所有的这些,包含集群水位,正本的配置,包含打散形式,还有复制带宽,咱们都会用一个模型来去计算并且测试验证它的可靠性,保障设计达到12个9的可靠性。

二、ZRS(同城冗余)产品容灾设计

艰深来说,OSS ZRS(同城冗余)产品,也叫3AZ型态。它和LRS最次要的区别就是在容灾设计指标上,LRS要容忍两个机架故障,ZRS则是要保障一个AZ外加一个机架故障时不影响可靠性可用性。

略微提一下,假如你一个AZ故障产生当前,如果修复工夫绝对比拟长,那再坏一台机器的概率还是比拟高的。如果在容灾设计上只容忍1AZ的话,最初因为AZ修复期间单台服务器的故障影响了可用性,那就有点得失相当了,所以咱们在设计上特意采纳了1AZ加额定一机架的故障容忍的设计指标。

再来讲讲怎么实现容灾设计的。

在模块划分上ZRS和LRS根本是一样的。次要的区别是模块的打散形式,在LRS里都是跨机架打散,在ZRS里,咱们会把它降级到跨AZ打散,所有的模块都是跨AZ部署的。当然在AZ内还是会做机架级的打散的。

对于有状态服务。有状态服务的一致性组在LRS 都采纳5节点部署,ZRS产品外面就会变为9节点。9个节点会平均打散到3个AZ,每个AZ有3个节点。这个设计是能够容忍4个节点故障的。也就是说能够容忍“1AZ+剩下两个AZ里的某个节点故障”。

在数据的高牢靠方面,后面提过咱们有3正本的EC。3正本不言而喻,只有做了AZ打散,是能够容忍方才提到的容灾设计指标的。EC是要做比拟大的EC配置的从新设计。实践上,3个AZ要容忍1个AZ故障,那数据冗余至多要1.5倍。实际上晚期咱们采纳6+6的EC配置,大家能够了解一个数据集,把它拆分为6个数据块+6个校验块,均匀散布到3个AZ,每个AZ有4个块。这样一个AZ故障的时候,一个数据集里还残余8个块,其实只有有6个就能够复原数据了。所以,这个时候还能够再容忍2个机架故障,相比于容灾设计指标是有肯定的超配。

当然,做了这样的设计之后,看起来是能够容忍“1AZ+额定1机架故障不影响可用性可靠性”,但理论没这么简略。

理论的运行过程中还要思考到十分多的其余因素。比方如何解决跨AZ的超高吞吐的带宽需要?AZ间的提早显然是要比AZ内的提早高很多,如何通过零碎的设计尽量让这个提早的减少不影响到用户?又比如说在1个AZ故障的时候,原本就有1/3的机器不可服务的,如果还要再做数据重建,那又带来十分大的IO放大。如何保障在AZ故障时候的高质量的服务?是有十分大的挑战的。

接下来以方才提到的最初这个挑战为例来做一个绝对深刻的介绍。

下图右边是一个示意图,咱们后面提到了,咱们晚期是用6+6的EC编码。咱们采纳的是RS的编码。在单个AZ故障的时候残余8个块提供服务,其中4个数据块+4个校验块。

简略计算一下,在这种AZ故障的状况下,单台机器或者单块磁盘接受的IO压力,相比在故障前日常状况下大略是什么程度。

产生故障的时候,不言而喻是有2/3的数据是能够间接读取的,也就是说1份IO没有放大。另外有1/3是要通过rebuild来做重建的。重建的话,RS编码至多要读6块数据,不思考额定的校验也要读6块数据能力重建。也就是说有1/3的数据是要读6块能力重建。再思考故障期间只有2/3的机器提供服务。

右上角有一个简略的算式,能够看到,故障期间每台机器或者每块盘接受的IO压力是日常的4倍。换个角度来解读一下,如果这个机器的IO能力是100%的话,那要保障在故障当前还是高可用的,日常最多只能用到它IO能力的25%。思考还要留肯定的平安水位,假如打个八折,那可能就只有20%了,这个数据不言而喻是十分夸大的,给咱们带来一个很大的挑战:要么让ZRS产品相比LRS只能提供低的多的IO能力,要不然就是要接受高的多的老本。

正因为有这样的挑战,所以EC的编码方式,尤其是在同城冗余型态下EC的编码方式始终是咱们继续投入的钻研或者改良的方向,咱们也做了十分多的工作,提出了本人独创的AZC的编码,这个编码算法自身也有在顶会中发表论文。

这里做一个简略的介绍。

简略来说,AZC编码就是把本来1维的EC编码升级成了2维。程度方向,是一个AZ间的编码,咱们首先会把一些数据块划分为多个小组。每个小组内,如果以上图左侧的示意图为例,每个小组是“2个数据片+1个校验片”做了一个2+1的RS编码。用小的EC配比有一个益处,在AZ故障的时候重建代价小,相比后面要读6份重建,当初只有读2份就能够了。

当然这种小配比的EC也是有毛病的,代价就是它的容灾能力差,可靠性低。因为只有有2个机架故障,丢掉2个分片,它的数据就无奈复原了,这显然是不可承受的。所以在垂直方向,也就是AZ内,咱们又把多个分组内的数据块联合到一起,额定做了一个垂直方向的编码。通常,比如说用12个片,额定再加2-3个校验块做一个RS编码,两者联合起来就能在12个9可靠性的前提下,依然能保障在AZ故障的时候重建的IO放大是比拟小的。

当然AZC也不只是AZ故障重建代价低的益处。通过一些认真的编码配比的抉择,它的数据冗余相比后面提到的6+6 EC也是要好十分多的。

后面也提到,咱们会在垂直方向做一个AZ内的RS编码。这也就是说日常状况下,如果AZ内有机器故障,是能够在AZ内本地重建的,能够完全避免跨机房的重建流量。也就是说,AZC编码其实是在AZ的故障重建代价和数据冗余的老本和日常的跨机房重建流量这三个方面获得了一个比拟好的均衡。相比6+6 RS编码晋升是微小的,依据这个公式简略算一下,流量放大倍数从4降到了2,换句话说,也就是说IO利用能力晋升了整整1倍。

近几年,从ZRS产品业务状况上的察看,越来越多的客户开始器重AZ级容灾能力,应用ZRS的比例越来越高。在香港故障当前,很多客户把他们的数据存储转到了ZRS型态上。很多自身曾经在用LRS的客户,也想无缝的降级到ZRS。

针对这些需要,联合后面做的各种技术改良,阿里云推出了两个大的降级。第一,将以前不反对归档型的ZRS 降级到反对归档类型。另外在迁徙能力上做了十分多的工作,反对LRS无缝迁徙到ZRS,曾经在线下以工单的形式帮十分多的客户实现了迁徙,产品化的迁徙性能也马上会推出。

后面介绍的是AZ级故障的应答,接下来我介绍一下第三局部。

三、Region故障的应答

Region故障的应答,次要是跨区域复制性能。

上图右边是一个简略的示意图。

后面提到,咱们有服务层OSS Server,也有索引层KV Server。所有的申请在达到KV Server之后,增删改操作都会有一条redolog,而且这个redolog是能够定序的。所以为了实现跨区域复制,首先咱们减少了Scan Service,它的性能就是扫描所有的redolog来生成复制工作,并且是可定序的复制工作。

这里要强调一点——咱们的复制工作是异步的,它跟用户的前台申请齐全解耦,也就是说它出任何问题,是不影响用户的前台业务的。在图里用不同的色彩进行了辨别。

有了工作之后,第二个重要的模块就是图外面的Sync Service,它的性能就是把每个复制工作去源端读取数据,通过跨区域复制的专线或者公网把它写到目标端去。除了实现这个复制工作自身以外,也要做很多其余的性能,比如说各种维度的QoS,还有在目标端写入的时候,因为用户本人也有可能间接写入,所以要做一致性的数据抵触的仲裁等等。

这部分我也挑了一个性能来做一个绝对深刻的介绍,我选的是RTC性能,顾名思义就是数据复制工夫管制。

一句话来表白,开启了RTC当前,OSS会对跨区域复制的RPO工夫做一个SLA承诺。在以前如果不开启的话是不提供承诺的。大多数状况下是能够秒级实现复制的,另外,对长尾状况也保障P999的对象能够在10分钟内实现复制。另外,咱们还提供了十分多的复制进度的监控,比方复制的带宽量、数据量,复制的提早状况,残余多少没有实现的复制工作等等。

为了实现这些,咱们后盾做了十分多的技术改良。

首先,因为是一个跨区域的复制,所以带宽资源十分贵重,在带宽资源管理上做了多维度的隔离。首先就是租户间的隔离,任意的用户不能影响到其余的用户。另外,其余的业务的跨区域的流量不能影响到这个RTC服务的流量。以及其余类型的多种维度的QoS隔离。

除了隔离以外,在优先级上也做了十分多角度的划分。最直白的就是开启了RTC,那在复制带宽上就有更高的优先级。另外,在同一个客户的RTC的复制边内,曾经提早了的这些工作,相比刚生成的工作就有更高的优先级等等。

除了物理资源的治理,在架构上也做了很多革新来晋升复制的实时性。

举一个例子,OSS的对象,一个对象是能够反对数十T大小的。如果在这个对象上传实现之后才开始复制,那显然不可能做到秒级复制,所以在开启了RTC之后,咱们会用更多的IO来保障复制的实时性。简略来说,没开启RTC的时候,咱们是在一个PART 上传实现之后触发一个复制工作,如果开启了RTC,那就会在每个PART的1MB或者其余大小的分片上传完之后就会生成一个复制工作。这样能力有比拟好的实时性保障。

另外,也做了多种维度的精细化的监控,包含对RPO破线的报警等等。

正是因为所有的这些改良,咱们才有信念对客户承诺RPO的SLA 的保障。

四、避免良好的容灾设计在执行中逐渐腐化

后面介绍完了咱们对服务器故障、AZ级故障和Region故障容灾上的设计,然而理论的运行过程中也不是这么简略的,就像一个良好的架构设计在执行较长时间之后会有各种各样的腐化问题,容灾设计也是同理。

举一个简略的例子,后面讲了要有IO压力管制,不论是20%还是40%,总是要有一个IO水位的管制的。假如线上用户的业务状况增长短时间冲破了容灾水位,如果不及时做扩容的话,那其实就曾经丢失了容灾能力了,这就是一个典型的腐化问题。

又比如说后面讲了各种EC、3正本的数据分布,现实的状况它是应该散布平均的,但如果某个版本的软件在这些数据分布算法上出了bug,那它有可能导致散布不平均。

所有这些问题都会导致容灾设计生效。

OSS如何应答这些问题呢?咱们会做一些常态化的运维演练,再联合监控报警和主动修复性能来解决这些容灾腐化问题。

这些性能次要都是通过咱们的智能运维平台提供的,最初一部分会对咱们的智能运维平台做一个介绍。

1.对象存储OSS智能运维平台-数据湖仓

运维的根底是数据,要有丰盛的数据,才有做智能运维的根底。

在OSS这里,咱们通过多年积攒,积淀了十分多的数据。上图左下就是运维平台收集的数据的示意。比方各种各样的监控数据,如网络探针,能够从内部探测,晓得某个区域不可用了;比方服务器的角度,有机器的多种维度数据;利用角度,有每个过程,每个模块的日志等各种数据;零碎的角度,有内核的内存、CPU、磁盘、过程等等多种维度的数据。

阿里云自身有50多个的横向的撑持零碎,有十分多的数据积淀,咱们的运维平台也做了买通。在数据处理上的话也是十分有挑战的。这里以一个最简略的OSS拜访日志的例子。咱们的拜访日志每秒钟有亿级的日志条目,在解决上的压力是十分大的,解决的性能、老本都是问题。咱们做了十分多的工作,比方采集端,会在本地做一些加工解决,例如过滤、聚合之类的来缩减数据量。

在缩减完之后,咱们会应用阿里云的各种性能十分弱小的产品,比如说SLS、Blink来做数据的实时处理。解决的这些后果会存储到ODPS或者OSS本身这样的存储产品外面供后续应用。

对一些离线的数据、简单的数据处理,咱们会用到基于OSS的数据湖计划来解决。

2.对象存储OSS智能运维平台:运维动作自动化

如果把这个智能运维平台比作一个人,数据就像是人的眼睛。接下来,我要讲的运维动作有点像人的手脚,给咱们提供静止能力。

在这一块,咱们的理念有点像Linux 平台的理念。首先研发同学会把各种各样的原子操作、原子运维动作都做脚本化,有点像Linux里的一个个命令,每个命令只实现一件事件,这些运维动作的准则也是每个脚本只实现一件事件。而后咱们的运维平台赤骥提供的工作流性能,有点像Linux里的管道,相似一个个简略的命令,用管道组合起来提供一些简单的性能。运维平台通过工作流,能够把各种根底的运维动作组合起来,实现一些简单的运维动作,比如说集群上线,集群下线。

当然,有些运维动作相对来说是比较复杂的。以数据迁徙为例,在架构上,通过把一个对象拆成META元数据和 DATA数据两局部,右下角就是一个对象的简略示意,能够看一个 META的KV对联合用户元数据的KV对加若干个数据KV对,就组成了一个对象。通过这样的架构设计,就能实现提供几个根底的运维动作:

第一,能够把一个Bucket数据打散到多个存储集群,每个集群的比例还能够依照须要做不同的调节,不肯定齐全对等。

第二,能够通过迁徙局部数据来做一些灵便的容量调度。

有了眼睛和手脚之后,在大脑的指挥下就能够做一些简单的高级动作了,对运维来说,也就是说能够实现一些简单的运维工作。

3.对象存储OSS智能运维平台:简单运维工作

以咱们怎么应答容灾腐化的例子来做一个收尾吧。

后面提到过一个例子,就是当业务压力增长,让某个ZRS集群的IO压力超过了平安水位线,这个时候运维平台首先会收到报警信息。

收到报警信息之后,咱们会提前有一些预设的规定,比方报警继续了超过多长时间,报警外面产生的IO压力,用户的IO行为是继续的,而不是一个刹时的行为。明确了这些信息之后就会做出决策,而后就要做数据的调度来把一部分IO压力迁徙到别的集群,来让本来这个集群的IO水位复原到平安水位。这个时候它就要去调度后面说的那些数据迁徙的原子能力来做迁徙。这个时候问题就来了:因为数据和IO压力其实不是间接关联的,关系比较复杂,到底要调度哪些数据、调度多少数据能力迁徙走想要的那么多IO压力呢?这个又用到了数据,就是后面讲的咱们积淀了各种各样的数据,其中就有用户的每个Bucket的IO行为的用户画像。

左边这张图就是其中某个维度的示意。一个用户Bucket,咱们会继续跟踪他读取的行为。举一个例子,比如说你上传了一天内的数据,你到底有多少比例是读它的,1-3天的有多少比例,3天以上的有多少比例。有了这个比例划分,再联合一个用户每天IO行为的总量的变动状况,就能够在后盾计算出来,是调度新写入的数据效率更高,还是迁徙写入了某个工夫以上的的数据效率更高、以及要迁多少。

计算出这个后果之后就开始真正做执行了,通过工作流去把指定的数据搬迁到其余集群之后,本来这个集群的IO压力就复原到平安水位,等于说靠智能运维平台,研发人员能够把各种束缚都积淀为这样的简单运维工作来录入智能运维平台上,保障在长时间运行下所有容灾设计都像预期的那样去工作。

以上,就是本次分享的次要内容,感激各位的观看。

原文链接

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