1、CBS数据调度系统的演进历程 前端
CBS存储系统,主要为腾讯云的CVM提供高性能、高可靠、低成本的块存储服务。 CBS数据调度系统,是基于存储系统构建的统一的数据调度服务。为何要构建统一的数据调度呢?
在2015年时它仅仅做为快照系统存在,仅是保存在云上的数据,目的是为了提升整个数据的安全性。用户会对数据进行备份,若是这个时候数据丢失,能够利用快照对其恢复。
上云业务还没有规模化,快照系统的业务量不大,并且快照备份自己是离线业务,因此针对IO时延时延方面并不敏感。 但随着业务上云愈来愈多,云盘的规模也愈来愈大。利用回滚的能力,来作镜像生产云服务器,数据调度系统拓展了新的应用场景,同时,系统回滚能力也要求愈来愈高,时延方面也逐渐敏感。 随着CBS业务不断快速增加和架构不断演进,催生出另外一个全新数据调度场景——云盘的在线迁移。
云盘在线迁移是什么意思?某些场景下须要将云盘从一个存储仓库迁移到另一个存储仓库,并且是在线迁移,对用户的业务是无损的。
它有一个特色是对时延的抖动敏感,用户的业务已经运行了,对整个时延抖动的要求是极低的。 咱们把前文所述的数据能力抽象出一个统一数据调度平台,负责咱们离线的数据和在线的数据打通。它当前涵盖主要三个场景:数据保护、云服务器批量生产和云盘在线迁移。下文将围绕这三个场景一一展开。
首先介绍整个数据调度系统的三层架构,第一层是业务中控层,中控是高可用服务,负责接受前端的业务请求,无论是打快照仍是作回滚,以及云盘迁移,都会到咱们的中控层,再转发任务给数据调度层。
数据调度层是集群模式,会把调度任务按照逻辑地址划为大小相同的数据块,并把块信息给到传输层,那么传输层看到的就是一个个的数据块,数据调度层会告诉传输层节点这个数据块源端在哪里,目的在哪里,再由传输层节点完成了数据的搬迁功能。
数据调度系统,为CBS构筑离线存储系统和在线存储系统、在线存储系统之间数据流动能力。数据库
2、典型业务场景以及面临的挑战缓存
(1)数据保护
用在咱们的平常备份,也就是重要的业务数据要作备份,万一哪天有损坏,咱们恢复到前一天或者前一段时间点的数据。这是咱们经常使用的平常备份。目前产品能力有手动快照和按期自动快照两种。
(2)业务恢复
业务恢复指的是,假如你业务受损了,也能够快速的恢复。还有一种场景就是系统重装来恢复环境,假如说你的系统作了测试,想恢复到原来的现场,咱们能够经过系统重装来完成。 2. 镜像生产云服务器 (1)镜像制做
经过云盘制做镜像,就是一次快照的建立。
(2)镜像生产云服务器
镜像制做完成以后,咱们用镜像去批量部署应用,这样就可以达到快速的部署业务的目的。
(3)镜像异地复制
假如咱们的业务须要容灾,或者说同一镜像须要多地域的部署业务,就能够经过把镜像从一个地域复制到另一个地域完成,就是镜像的跨地域复制能力。 安全
(1)资源均衡
为了提高用户的体验,须要仓库间资源均衡调度。
(2)架构升级
CBS新架构,不管是产品性能仍是用户体验方面,都有很大的提高,须要对云盘作架构升级,须要把云盘从老系统迁到新的系统里。
(3)硬件批次故障
若是出现了批次的硬件故障,须要把仓库里的全部的云盘迁出到正常的仓库里面,这依赖云盘迁移能力。 服务器
无感备份:数据备份要作到无感备份。网络
秒级开机:在镜像生产云服务器的场景下,为了提高用户体验,须要镜像生产开机以后可以立马启动,而不是要等镜像数据所有下载完成。架构
业务无感知:不能给用户业务形成可感知的时延抖动。并发
3、CBS数据调度系统关键技术app
对于数据保护技术,传统行业经常使用的就是快照。提到快照,不得不说经常使用的两种快照技术: 负载均衡
(1)COW技术
写时复制,就是当建立完快照,再去写这个同一个地址块的时候,须要把原来的地址块中数据先拷贝到新分配的地址块空间中,再更新源地址块中数据。
(2)ROW技术
写访问时,须要从新定向到另一个地址块空间上去。
对于COW和ROW的实现机制,首先是写时复制。如上图所示,在T1时刻对源卷打下快照,上面蓝色部分是源卷的地址块指针,中间的橙色是磁盘上真正的物理空间——数据块,这个时候源卷和快照的卷,地址块指针都指向相同实际的物理空间。 以访问block4为例,当打完快照想更新block4的数据的时候,写时复制的作法就是先重分配一个新block5,把block4的数据先拷贝到block5里面去,而后再把快照的数据块逻辑地址指针指向第5个数据块,用户io再更新block4数据块。 通过此次写过程以后,咱们能够看到源卷的仍是指原来的这四个物理block地址,快照这边其实有一个指针映射的过程,从原来的block4转变到block5。
写时复制有一个性能问题,就是把block4的数据读出来,写到block5里面去,而后再同时有一次元数据更改,最后是用户写入到block4上面去,就是一个用户写会放大到“一次读、三次写”的过程。 COW技术存在严重的写放大问题,影响写的性能,它适用的场景是读密集型。ROW跟COW不同的地方,在于若是用户打完快照再写block4空间,会新分配一个block5,用户数据再写入block5,修改源卷逻辑地址指针映射。ROW除用户写外,只增长一次元数据写操做。这主要是影响读性能,适用于写密集型场景。 ROW和COW它们各有各的应用场景。在分布式存储领域,卷的数据是打散在一个存储集群的不少块硬盘或者ssd上;因为数据打散,读的性能比单物理盘好不少。另外,存储系统多会采用cache技术优化读性能,因此如今分布式存储系统快照多采用ROW模式来实现。
数据调度系统,采用多版本ROW机制实现快照技术。什么是多版本呢?其实就是用版本号去区分快照点数据,建立一次快照,整个卷的版本号会加一。
举个简单例子,一个卷假若有四个数据块,刚开始创卷并写入数据的时候,T0时刻打一次快照,这个时候咱们要把备份的数据备份到离线存储器里,很明显咱们要把A、B、D三个块搬迁到离线存储系统里去。 假如说这个时候用户再来写A块,由于卷的版本是2,会为A块再从新分配新的数据块A',A'块的版本号记录为2。写C块,由于是第一次写,以前没有分配物理块,那么此次就分配一个物理块C版本号记录为2。到T2时候再打快照能很明确知道,T0时刻到T2时刻新修改的数据块,也就是要把A'和C块搬到离线存储系统里。
CBS快照,是快照建立时候的数据的完整备份,采用全量加增量结合的方式备份数据。
全量是T0时刻以前没有打快照的,这个时候的数据所有备份到离线系统。那么在T2时刻建立快照只备份从T0时刻到T2时刻的中间修改的那一部分增量数据,这是全量加增量的备份机制。 建立快照,对用户而言要达到秒级完成。当调度系统收到快照请求,首先到中控层,通知CBS存储系统卷版本号加一,存储系统收到请求后,将更新后的卷版本号同步给CBS客户端。
从CBS客户端新写入的数据携带新版本号写入到存储侧,存储侧就为写请求分配新版本物理block,达到经过block版本区分快照数据仍是卷数据。 存储系统响应了以后,就告诉用户建立快照成功了。这个时候快照数据还在咱们的CBS存储系统里,快照数据异步搬迁到离线存储系统中。
数据调度层按照卷逻辑地址大小,切分红数据块大小,再告诉数据传输层,一个一个块从存储系统读出来,上传到咱们的离线存储系统,这样就完成了数据的备份。之因此要异构存储快照数据,主要是基于快照数据可靠性来考量的
假如建立快照后,用户的云盘数据出现了损坏,用户想回退到某个指定快照点。由于是全量加增量,那怎么知道指定快照点有哪些数据是当前有效的?换句话说,备份完了后怎么知道这个快照点有哪些是新增数据?哪些是须要依赖于旧快照点的数据?
全量加增量的备份方式,经过快照链来标识,快照链会做为元数据持久化;每一个快照点具体备份了卷线性地址空间中的哪些数据块经过bitmap来标识,bitmap中为1的bit位表示该逻辑block有数据备份到离线系统中;数据备份完成后,调度系统会把bitmap元数据一块儿写入离线存储系统中。
当咱们选定一个快照点(好比快照点3)进行回滚的时候,看到当前第一个块A3,对应的bitmap的bit位为0,表示没有数据,那就依次向前看依赖的快照点,发现A2是最新的数据,就能够不往前找了,以A2数据为准。
看第二个数据块,自己就有最新数据,那我就以数据块B3为准。第三个数据块没有,再往前,发现到它的依赖节点也没有的话,再依次往前发现也没有,那就是这个数据块就是没有数据的。
第四个数据块,一样的方式查找依赖的快照点,直到找到D1;最终将A二、B三、D1数据块搬迁到云盘里面去,恢复到了你当时打快照点3时场景。
调度系统经过对指定快照点以及依赖的快照点进行数据合并,而后进行数据回放来回到指定快照点建立时刻的场景,这是一个回滚的流程。
对于镜像,好比在一台云服务器上,预装一些软件,对云盘进行快照并制做成镜像,这个镜像是预装环境一个模板,经过这个模板可以批量复制相同软件环境的云服务器。
在数据调动系统以前,镜像是宿主机从镜像系统下载后写入CBS云盘,整个镜像下载完成后,云服务器才启动起来。
这种方式有诸多不足之处。首先,若是镜像文件很大的话,下载时间很长,影响开机时间;其次,由于宿主机上面还有其余云服务器,下载镜像占用宿主机带宽,其它云服务器会受影响;再次,咱们要维护这样一个镜像系统,须要很大的资源开销。 通过场景分析,能够用数据调度系统的回滚能力支撑镜像批量生产云服务器功能。
首先镜像制做用快照建立能力就可以完成,而后把镜像放到咱们的离线系统里面。若是须要批量发放云服务器,再经过调度系统从离线的存储系统,将镜像文件导入到云盘上面就能够访问。 对这两种方式作一个对比,从建立时间和资源的占用,速度的资源占用和成本方面,经过回滚建立云服务器具有以下几大优点: 第一,就是秒级建立,不须要所有下载完成,云服务器就能够开机,下文也会介绍其技术细节。 第二,镜像下载是没有通过宿主机的,这样的话对母机的资源没有额外开销,不会影响宿主机上其余云服务器。
第三,数据调度系统是个现成的系统,没有增长额外资源、成本的问题。
综上所述,经过回滚能力生产云服务器,自然就解决了以前镜像生产子机存在的痛点。 6. 秒级回滚 怎样作到开机后立马可以启动呢?其实开机后能不能启动,取决于云服务器是否正常进行io访问。
调度系统提供了一个秒级回滚的能力,经过回滚能让咱们的云服务器很短期开机启动。
云服务器启动要访问CBS云盘上的镜像数据,但镜像从离线存储系统搬迁到云盘上是逐步完成的,要访问的数据不必定已经搬迁到云盘上。
建立云服务器的时候数据调度系统会启动从离线系统到云盘按卷逻辑地址的线性顺序搬迁,将卷的逻辑分红数据块,一块一块地往CBS云盘上数据搬迁。
好比有一块云盘共有7个block,当已经完成了前两个block的搬迁,但用户想访问的是第5个block,此时CBS客户端会判断当前尚未完成第5个block的搬迁,就主动通知数据调度系统,把第5个搬迁到CBS盘上去;调度系统收到这样的请求,会把第5个block优先搬迁到CBS盘上。 搬迁完了以后,通知客户端,block5已经搬迁完成,客户端就能够把访问block5的io下发给存储侧。 也便是,在正常的用户io路径上,增长了一次数据块从离线存储系统到在线存储系统的搬迁过程,只是会增长极短延时,但不会致使启动慢。
经过前文的介绍咱们知道,优先搬迁实际上是当用户io访问的数据块还没搬迁到CBS云盘场景下,先将io在客户端挂住,同时优先将该数据库从离线系统到在线系统搬迁,而后将用户io下发的过程。
这里有一个io在客户端挂住的动做,而挂住时间长短取决于优先搬迁的整个时延,咱们经过优化优先搬迁时延来减小io抖动。
经过镜像生产子机这个典型的应用场景来讲,镜像通常会批量发放云服务器,镜像数据自己就是一个典型的热数据访问问题。
为了起到提升用户体验的做用,也便是为了优化用户io在优先中的时延问题,调度系统将镜像数据做为热点数据缓存在传输层,作了一层镜像数据cache,来缩短访问时延。
第一次去传输层加载数据的时候,cache未命中,就从离线存储系统中加载上来,写到咱们的CBS系统,同时数据块缓存到咱们的cache里面。
第二次加载就能命中,减小访问离线存储系统的时延。不管优先搬迁仍是数据搬迁,这层cache对优化用户时延和减轻底层离线系统的负载是有很大做用的。
为了支持整个云服务器的并发生产能力,调度系统针对系统水平扩展能力作了一些优化。如上图所示,左边是优化前地域部署的一个中心系统,一个数据调度层,另外一个数据传输层。
这里会有两个问题:第一,中控层覆盖整个地域,一旦故障,就会影响整个地域的云服务器的生产。
第二,单个大地域里分不少的可用区,其实跨可用区的访问存在时延,并且还挺大的。基于这种考虑,把大的部署模型拆分红小的部署系统,同时加强系统内部可弹性扩展,系统间提高平行复制的能力。 把大地域部署拆分红小可用区部署数据调度系统,一方面缩小故障率,另外一方面缩小了跨可用区访问的一个时延的问题,这对调度系统的弹性能力有很大提高,有利于应对CBS业务的快速增加。 系统支持水平扩展能力以后,怎么保证在一个小系统内负载均衡?
这里总结了几个方面分享给你们。咱们是经过静态和动态相结合的方式保证整个系统负载均衡。静态经过心跳上报负载信息,咱们在建立的时候经过卷式作快照,都是基于云盘而言的,这样咱们根据云盘的ID作一次哈希,保证调度层各个节点上卷规模基本一致。
同时,由于每个云盘的访问的量包括数据量,负载状况都不同,调度系统根据负载状况再进行动态均衡,若是调度层单节点之间负载差超过了设定的预值,调度系统就会启动动态的再均衡,将高负载节点上的任务调度到低负载节点上,达到各个调度节点之间的负载尽可能保持均衡。 再就是传输层,用了哈希的策略,保证各个传输节点均衡。由于传输节点就是看到数据块的搬迁,它只要保证数据块的搬迁是均匀的,那就能够了。 但其实哈希也有少许的不均衡状况,同一个镜像数据块访问会落到同一个传输结点上,批量发放云服务器时,会出现同一时刻访问同一个数据块形成传输层局部热点问题,调度系统经过冗余几个副原本解决局部热点访问问题。
假如说调度节点出现了故障,任务在调度层节点间怎么作平滑切换呢?
首先对于节点故障的探测,这里采用的是心跳探测、业务失败率统计以及外围监控探测相结合完成调度层节点的故障探测。
一旦发现调度层节点故障,上报给中控层,中控节点就启动任务从故障节点切换到另外一个正常节点。
若是是备份任务,用户对时延不感知,切换速度要求不高;但回滚时,数据访问的优先搬迁须要调度层节点介入,若是不能及时将任务切换到正常的调度节点上,将会致使io卡住,体验不好。
为了解决这个问题,CBS客户端访问故障节点失败后,轮询下一个调度节点,从下一个调度节点获取当前任务服务的调度节点地址信息,并快速切换,达到快速恢复io的目的。
任务的元数据是共享的,调度节点均可以访问到;目的调度节点会根据惟一的任务key再把原数据加载出来。以上是任务平滑切换的基本机制。
除了镜像生产,还有镜像的跨地域复制。首先,须要两套数据调度系统支持,经过两个地域的调度系统中控层,完成镜像元数据的传输。
A地域调度层和传输层负责从A地域把数据块读出来写到B地域来,完成搬迁后,A地域的中控层通知B地域中控层已经完成了数据的搬迁,B地域中控层通知调度层去完成源和目的数据一致性校验,保证数据可靠传出。 那为何A地域的系统不能既负责传输又负责校验呢?这至关于一我的既是裁判又是运动员,容易出问题发现不了。基于数据安全考虑,传输和校验分开进行。
云盘迁移,是将云盘从一个存储仓库迁移到另外一个存储仓库,业务无感知。迁移最核心的两个点:数据可靠性和业务无感知。
数据可靠性将在下文展开论述,这里重点介绍如何作到业务无感知迁移。
要作到业务无感知,关键在于迁移过程当中用户io时延不会有明显增长,为了达到这个目的,数据调度系统引入一个IO接入层,把用户的IO和调度系统底层的顺序搬迁IO隔离开,作到用户IO与顺序搬迁IO隔离,减小IO抖动。 云盘迁移过程当中,用户IO如何访问云盘数据呢?
接入层作按搬迁数据块大小将卷划分红block列表,同时维护每个block状态。block有三个核心状态,状态之间会流转。若是是读请求,就统一读源仓库;若是是写请求,则根据访问block当前状态,按下面规则来处理。
第一个是未搬迁状态,用户IO访问的话,IO写到源仓库。
第二个状态是正在搬迁中,接入层会暂时把IO挂住,等调度层把数据搬迁完,挂住的IO再放下去,写到原仓库和目的仓库。IO挂住的几率极低,运营统计不到十万分之一。
为何访问已搬迁状态的block,IO要同时写源端和目的端呢?这里是为了提高系统可用性,假如说底层出现了任何故障,CBS客户端只须要将IO链路上断开,基于iscsi断链重连会自动切回原仓库中去,由于源仓库数据是完整的,IO的自愈能力就比较高了。 迁移完了以后,把客户端的IO路径切到目的仓库。这个时候的IO路径,也是基于iscsi的I端到T端的断链重连的过程。经过引入接入层,整个IO路径,时延上只是增长了一段网络开销,时延抖动很是低,目前云盘在线迁移,业务感知不到。 云盘迁移里的功能点很是丰富,还有一套辅助的系统——云盘迁移决策系统,它能根据当前仓库的负载状况,各个盘的历史访问状况,作一系列的预测,而后来发掘仓库是否有容量、流量风险,提早决策,选择一批合适的云盘,选择最优的目的仓库,发起迁移,提早解除资源风险,这也是为CBS业务增加在运营上作的一些建设。
以上三个场景,面临一个共同的挑战就是数据可靠性。
在快照制做镜像场景,从在线存储里面把数据读出来,写入到咱们离线存储里面,调度系统的数据块会增长MD5校验头部一块儿写入离线存储系统中;回滚的时候,调度系统从离线系统读出来再计算一次MD5,检查数据是否有损坏。
元数据除了MD5校验外,还会跨地域备份,加强数据可靠性,同时增强跨地域巡检。
咱们在IO路径上常遇到悬空IO的一些问题,好比说链路切换的时候有一些IO还没落盘,卡到路上,残留的IO会把新写的数据覆盖的问题。
这种问题在云盘迁移过程当中表现尤其明显,由于云盘迁移涉及两次io链路切换:从原仓库切到接入层、从接入层切到目的仓库,其实这些链路切换过程都会有IO的残留问题。那么调度系统如何解决这个问题呢?
关键是引入版本号机制,低版本数据不能覆盖高版本数据。每一条链路上版本号不同,咱们在底层存储上作了一些保证,设定了高版本数据能够覆盖低版本数据,但低版本数据不能覆盖高版本数据。
调度系统为每一条链路指定一个新版本,版本号随切换顺序递增,这样低版本数据即便有残留,也不会覆盖新链路上的数据,由于新链路上的数据版本号高。
4、将来演进方向
6、Q&A