13倍性能,3倍稳定性提升!UCloud云硬盘做了这些事 | U刻
  • 13倍性能,3倍稳定性提升!UCloud云硬盘做了这些事

    栏目:技术分享

    近期,我们推出高性能SSD云盘,满足用户对高性能的场景需求。SSD云盘相比普通云盘,IOPS提升了13倍,稳定性提升了3倍,平均时延降低了10倍。为了做到这些,我们从去年10月份开始对云盘的架构进行了重新设计,充分减少时延和提升IO能力;并通过复用部分架构和软件,提供性能更好、更稳定的普通云盘;同时逐步引入Stack/Kernel Bypass技术,打造下一代超高性能存储。新架构推出后,已服务了现网用户的3400多个云盘实例,总存储容量达800 TB,集群每秒IOPS均值31万。

    架构升级要点

    通过对现阶段问题和需求的分析,我们整理了这次架构升级的具体要点:

    1 、解决原有软件架构不能充分发挥硬件能力的局限

    2 、支持SSD云盘,提供QOS保证,充分发挥后端NVME物理盘的IOPS和带宽性能,单个云盘IOPS可达2.4W

    3 、支持更大容量云盘,32T甚至更大

    4 、充分降低IO流量的热点问题

    5 、支持并发创建几千块云盘,支持并发挂载几千块云盘

    6 、支持老架构云盘在线向新架构迁移,支持普通云盘在线迁移至SSD云盘

    新架构改造实践

    改造一:IO路径优化

    老架构中,整个IO路径有三大层,第一层宿主Client侧,第二层Proxy侧,第三层存储Chunk层。Proxy负责IO的路由获取以及缓存;IO的读写转发到下一层存储层,负责IO写三份复制。

    而新架构中,路由获取交给了Client,IO读写Client可直接访问存储Chunk层,写三份复制也交给了Chunk。整个IO路径变成了2层,一层是宿主Client侧, 另一层存储Chunk层。

    架构升级之后,对读IO,一次网络请求直达到后端存储节点,老架构都是2次。对写IO,主副本IO一次网络请求直达后端存储节点,另外2副本经过主副本,经历两次网络转发,而老架构三个副本均为两次。读IO时延平均降低0.2-1ms,写尾部时延减低,也有效的降低总体时延。

    改造二:元数据分片

    分布式存储中,会将数据进行分片,从而将每个分片按多副本打散存储于集群中。如下图,一个200G的云盘,如果分片大小是1G,则有200个分片。老架构中,分片大小是1G,在实际业务过程中我们发现,部分业务的IO热点集中在较小范围内,如果采用1G分片,普通SATA磁盘性能会很差。并且在SSD云盘中,也不能均匀的将IO流量打散到各个存储节点上。

    新架构中,我们支持了1M大小的分片。1M分片,可以充分使用整个集群的能力。高性能存储中,因为固态硬盘性能较好,业务IO热点集中在较小范围内,也能获得较好的性能。

    但UCloud元数据采用的是预分配和挂载方案,申请云盘时系统直接分配所有元数据并全部加载到内存。分片过小时,需要同时分配或挂载的元数据量会非常大,容易超时并导致部分请求失败。

    例如,同时申请100块300G的云盘,如果按1G分片,需要同时分配3W条元数据;如果按照1M分片,则需要同时分配3000W条元数据。

    为了解决分片变小导致的元数据分配/挂载失败问题,我们尝试改变IO时的分配策略,即云盘挂载时,将已分配的元数据加载到内存中。IO时,如果IO范围命中已经分配路由,则按内存中的路由进行IO;如果IO范围命中未分配路由,则实时向元数据模块请求分配路由,并将路由存储在内存中。

    按IO时分配,如果同时申请100块300G的云盘, 同时挂载、同时触发IO,大约会产生1000 IOPS,偏随机。最坏情况会触发1000 * 100 = 10W 元数据分配。在IO路径上,还是存在较大消耗。

    最终,新架构中我们放弃了中心节点存储分片元数据的方案,采用了以一套统一规则去计算获取路由的方案。

    该方案中,Client 端和集群后端采用同样的计算规则R(分片大小、pg个数、映射方法、冲突规则);云盘申请时,元数据节点利用计算规则四元组判断容量是否满足;云盘挂载时,从元数据节点获取计算规则四元组; IO时,按计算规则R(分片大小、pg个数、映射方法、冲突规则)计算出路路由元数据然后直接进行IO。通过这种改造方案,可以确保在1M数据分片的情况下,元数据的分配和挂载畅通无阻,并节省IO路径上的消耗。

     

    改造三:支持SSD高性能云盘

    通过上述对比可以看到,NVME固态硬盘性能百倍于机械盘,但需要软件的配套设计,才能利用NVME固态硬盘的能力。

    SSD云盘提供QoS保证,单盘IOPS:min{1200+30*容量,24000} 对于SSD云盘,传统的单线程模式会是瓶颈,难以支持后端NVME硬盘几十万的IOPS以及1-2GB的带宽,所以我们采用了多线程模型。

    为了较快推出SSD云盘,我们还是采用了传统TCP网络编程模型,未使用Kernel Bypass。同时,通过一些软件细节的优化,来减少CPU消耗。

    目前,单个线程写可达6W IOPS,读可达8W IOPS,5个线程可以基本利用NVME固态硬盘的能力。目前我们能提供云盘IO能力如下:

    改造四:防过载能力

    对于普通云盘,新架构的软件不再是瓶颈,但一般的机械硬盘而言,队列并发大小只能支持到32-128左右。100块云盘,持续同时各有几个IO命中一块物理HDD磁盘时,因为HDD硬盘队列并发布较小,会出现较多的io_submit耗时久或者失败等问题。Client侧判断IO超时后,会重试IO发送,造成Chunk端TCP缓冲区积压越来越多的IO包,越来越多的超时积压在一起,最终导致系统过载。

    对于普通云盘,需控制并发提交队列大小,按队列大小,依次遍历所有云盘,下发各云盘的IO,如上图的1、2、3。实际代码逻辑里,还需要考虑云盘大小的权重。

    对于SSD云盘来说,传统的单个线程会是瓶颈,难以支持几十万的IOPS以及1-2GB的带宽。

    压测中,我们模拟了热点集中在某个线程上的场景,发现该线程CPU基本处于99%-100%满载状态,而其它线程则处于空闲状态。后来,我们采用定期上报线程CPU以及磁盘负载状态的方式,当满足某线程持续繁忙而有线程持续空闲时,选取部分磁盘分片的IO切换至空闲线程,来规避部分线程过载。

    改造五:在线迁移

    老架构普通云盘性能较差,部分普通云盘用户业务发展较快,希望从普通云盘迁移至SSD云盘,满足更高的业务发展需要。目前线上存在2套老架构,为了快速达到在线迁移的目的,我们第一期决定从系统外围支持在线迁移。

    迁移流程如下:

    1  后端设置迁移标记;

    2  Qemu连接重置到Trans Client;

    3  写IO流经过Trans Client 到Trans模块,Trans模块进行双写:一份写老架构,一份写新架构;

    4  Trigger 遍历磁盘, 按1M大小触发数据命令给Trans触发数据后台搬迁。未完成搬迁前,IO读经Trans向旧架构Proxy读取;

    5  当全部搬迁完成后,Qemu连接重置到新架构Client,完成在线迁移。

    加一层Trans及双写,使迁移期间存在一些性能损耗。但对于普通云盘,迁移期间可以接受。我们目前对于新架构也正在建设基于Journal的在线迁移能力,目标在迁移期间,性能影响控制在5%以下。

    经过上述系列改造,新的云硬盘架构基本完成了最初的升级目标。目前,新架构已经正式上线并成功运用于日常业务当中。在这里,也谈谈我们正在研发的几项工作。

    1、容量具备无限扩展能力

    每个可用区,会存在多个存储集群Set. 每个Set可提供1PB左右的存储(我们并没有让集群无限扩容)。当Set1的云盘需要从1T扩容至32T 100T时,可能会碰到Set1的容量不足的问题。

    因此,我们计划将用户申请的逻辑盘,进行分Part, 每个Part可以申请再不用的Set中,从而具备容量可以无限扩展的能力。

    2、超高性能存储

    近10年,硬盘经过 HDD -> SATA SSD -> NVME SSD的发展。同时,网络接口也经历了10G -> 25G -> 100G的跨越式发展。然而CPU主频几乎没有较大发展,平均在2-3GHZ,我们使用的一台物理机可以挂6-8块NVME盘,意味着一台物理机可以提供300-500万的IOPS.

    传统应用服务器软件模式下,基于TCP的Epoll Loop, 网卡的收发包,IO的读写要经过用户态、内核态多层拷贝和切换,并且需要靠内核的中断来唤醒,软件很难压榨出硬件的全部能力。例如在IOPS和时延上,只能靠叠加线程去增加IOPS,然而,IOPS很难随着线程的增加而线性增长,此外时延抖动也较高。

    我们希望通过引入零拷贝、用户态、轮询的技术方案来优化上图中的三种IO路径,从而减少用户态、内核态、协议栈的多层拷贝和切换,并结合轮询一起压榨出硬件的全部能力。

    最终,我们选择了RDMA,VHOST,SPDK三个技术方案。

    方案一:超高性能存储-VHOST

    传统模式如下,IO经过虚机和Qemu驱动,再经过Unix Domain Socket到Client。 经过多次用户态内核态,以及IO路径上的拷贝。

    而利用VHOST User模式,可以利用共享内存进行用户态的VM到Client侧的数据传输。在实际中,我们利用了SPDK VHOST。

    研发环境中,我们将Client收到IO请求后立即模拟返回给VM,也就是不向存储后端发送数据,得到的数据如上图。单队列时延可以降低90us,IOPS有几十倍的提升。

    方案二:超高性能存储-RDMA+SPDK

    RDMA提供了一种消息服务,应用程序利用RDMA可以直接访问远程计算机上的虚拟内存,RDMA减少了CPU占用以及内存带宽瓶颈,提供了很高的带宽,并利用Stack Bypass和零拷贝技术,提供了低延迟的特性。

    SPDK可以在用户态高并发零拷贝地以用户态驱动直接访问NVME 固态硬盘。并利用轮询模式避免了内核上下文切换和中断处理带来的开销。

    目前团队正在研发利用RDMA和SPDK的存储引擎框架,研发测试环境中,后端用一块NVME固态盘,我们在单队列和IOPS上可以提升如下:

    包括SPDK VHOST USER的Client侧,以及RDMA+SPDK的存储侧方案,预计12月会推出公测版。

    总结

    过去的一年时间里,我们重新设计和优化了云盘的存储架构,解决了过去老架构的诸多问题,并大幅提升了性能。经过4个月公测,SSD云盘和新架构普通云盘都于8月份全量上线,并保持了极高的稳定性,目前单盘可提供2.4W IOPS。

    同时,为了追求更佳的IO体验,我们引入Kernel/Stack Bypass技术方案,正在打造更高性能、更低时延的存储引擎,预计12月份会推出超高性能云盘公测版,敬请期待!

    8