软件定义的主要目的是减化部署流程,提高易用性,降低运维成本。当然,最重要的是能够发挥硬件的全部性能,合理分配利用硬件资源,节省硬件开支。
不过,软件定义的超融合虽然有着诸多的优势,但对软件开发商提出了非常高的要求,他们非但要精通各种语言、系统和架构,还必须要熟悉硬件本身的性能,这样才能够保证开发出来的软件能够全部发挥硬件的性能。
关于软件定义带来的硬件性能的损失,比较典型的例子就是软件定义存储导致的磁盘性能的下降,这主要是在全闪存时代背景下,磁盘性能有了非常大的提升,如果在软件定义的过程中还是按照传统机械硬盘的性能还编写系统,那就完全无法发挥闪存的性能。笔者在某超融合的大会上,就曾遇到过一家专门作软件定义存储解决方案的厂商,它们针对Flash时代开发出了裸金属软件定义存储技术,非常好的解决了软件定义存储无法充分发挥全闪存硬件性能的问题。
这里,笔者与大家共同分享一下他们的解决方案和研发思路,希望对大家有所启发。
我们知道,在Flash之前,存储性能的发展是严重滞后于其它硬件性能的发展的,虽然大家通过各种方法来提高磁盘的存储性能,但相较于其它硬件的发展,存储的性能提升并不理想。在Flash时代,存储硬件性能的问题迎刃而解。不过,很多厂商在替换全闪存阵列后,发现存储的性能并没有提高多少,这主要是软件和系统出现了问题。
由于Linux标准的API并没有提供高性能的场景设计,因此操作系统成为了影响系统整体性能的瓶颈,无论你在一个设备上插入多少硬件,调用多少资源,都会发现一个节点一二十万iops就到了这些软件定义存储的上限了,这是因为Linux系统的任务调度,内存管理,以及系统调用,都是非常缓慢,完全不适合Flash时代的需求。
如何解决这一问题呢,裸金属软件定义存储技术是通过以下两种方法解决的:
一是硬件访问要绕过操作系统(stack-bypass);
二是软件运行要绕过操作系统(os-bypass)。
对于硬件的访问要绕过操作系统(stack-bypass)这种技术业内已经有相对比较成熟了,也比较容易实现。比如英特尔提供的DPDK/SPDK,Mellanox的RDMA,都不需要经过操作系统就可以直接访问硬件。但是,软件运行绕过操作系统(os-bypass)的难度却比较大。首先,要绕过操作系统的内存管理,直接访问物理内存,自己来实现内存管理,这中间要考虑NUMA,染色等问题,工程量非常大。其次,任务调度也要考虑的非常清楚,过去解决高并发问题的时候大家就会采用多线程的机制,但是多线程一般在数百并发的时候会变得比较困难,通过引入了协程技术,把任务之间的协作来分配时间片,每个任务处理完之后自动放弃时间片,而不是操作系统让他强制放弃时间片。另外,在事件处理上过去通过操作系统标准来实现,每个事件都跟时间有关,包括硬件系统的时钟中断。但是这个技术并不是非常的高效,在这方面可以采用polling技术,没有时间延期的。
在多核同步上,目前 CPU的核数越来越多,过去编程的时候大家会采用生产者、消费者模型,用线程用来处理任务,但是到现在多核同步并不是一个非常高效的方案,这主要是因为NUMA和cachemiss问题,虽然说NUMA问题CPU解决的还可以,但是仍然不够理想,这时可以采用run-complete模型,每个CPU的核从他接受到任务,到完成任务中间不再任何跳转,避免隐性的CPU开销。
通过以上的方案,能够拿掉尽可能多的环节,包括进出Linux的网络堆栈、Linux的存储堆栈,这样就能够让剩下的流程全是在硬件上运行的。最后,通过这些技术的运用,能够让存储的性能与硬件性能几乎完全一致,不带来硬件性能的任何衰减。
以上,是某厂商针对全闪存时代在软件定义过程中出现的影响硬件性能的解决方案,笔者分享给大家,希望提供一些参考。