Curve ChunkServer的CPU瓶颈问题
Curve是网易数帆开源的新一代分布式存储系统,具有高性能、高可用、高可靠的特点,可作为多种存储场景的底层存储,包括块存储、对象存储、云原生数据库、EC等。
对于分布式块存储系统来说,IOPS是最重要的一个性能指标。从Curve目前的性能测试情况看,读IOPS瓶颈在Client端——对于6个存储节点的集群,单个Client节点读IOPS接近30万,两个Client节点读IOPS接近60万。而Curve的写IOPS还有一定提升空间——对于6个存储节点的集群,IOPS只能达到26万~28万,而ChunkServer节点CPU使用率接近100%,而底层SSD的使用率则不到90%。因此,随机写IOPS场景是Curve的一个优化重点。
在测试环境A 中部署Curve(具体配置见附录1),在Client节点创建10个卷,进行4KB随机写测试。结果显示,写IOPS约为13.5万,而此时ChunkServer节点的CPU使用率接近100%,而所有SSD的使用率平均不到85%。
这表明,ChunkServer端CPU成为性能瓶颈。考虑到目前测试环境的SSD配置较低,若使用高性能NVME SSD,其IOPS可能比现有SSD高一个数量级,届时CPU性能瓶颈将更为严重。因此,优化CPU性能,释放SSD的I/O能力,是Curve性能优化的一个重要方向。本文围绕Curve的CPU性能优化进行了一些探索和实践。
CPU性能优化方法
在进行CPU性能优化之前,我们必须进行性能测量,对CPU性能进行量化分析,从而有的放矢,针对性优化。
先回顾下CPU的基本工作原理:现代CPU都是多核心架构,软件需要以进程或线程的方式在CPU核心上运行。操作系统会将每个CPU核心的运行时间划分为毫秒级的时间片,然后通过调度算法为每个时间片选择一个就绪的线程执行。时间片结束或者运行的线程需要等待资源(I/O, 锁,条件变量等),操作系统就会进行上下文切换,将对应的CPU核心分配给另一个就绪的线程。
因此,我们可以从线程和CPU两种视角去测量CPU性能。
- 从线程视角,我们可以测量软件线程的CPU时间开销,定位CPU时间开销较大的模块或函数,进行重点优化,这也是一种常用的定位方法;另外,还可以测量线程等待锁的时间,判断是否有不合理的锁竞争影响软件运行效率;而线程等待I/O、条件变量等资源的情况,一般可以从设计和代码层面进行梳理分析,本文不再赘述。
- 从CPU视角,我们可以从外部测量CPU使用率和上下文切换频率,判断CPU时间是否被充分利用(这方面的知识大家都耳熟能详,而Curve在这方面也没有明显问题,因此本文不再赘述);还可以从内部测量CPU微指令运行效率,分析CPU运算单元是否被充分利用,这需要采集CPU内置PMU(Performance Monitoring Unit,性能监控单元)的监控数据,并使用专门的分析方法,从而定位CPU运行的瓶颈。
下文将从这两个角度,分别对Curve的CPU性能进行测量和优化。
Curve的线程级性能分析
线程级CPU性能分析可以从三个方面进行:
- 自上而下的CPU时间分析,即按照软件调用关系,从主函数到各子函数,一层层分解和剖析CPU时间。这样可以大体区分各模块、函数的CPU时间占比,从而确定CPU时间开销最大或者超出预期的模块或函数,为下一步深入分析提供参考。
- 自下而上的CPU时间分析,即按照函数的被调用关系,从最底层子函数向上,一层层追溯各调用分支的CPU时间占比。这种方式可以定位出被多个父函数调用,其总运行时间异常大的函数。
- 线程等待时间分析,上面两方面都是关注的线程在CPU上运行的时间,属于on-CPU分析;线程等待时间分析则关注线程因为等待资源而没有在CPU上运行的时间,属于off-CPU分析。线程可能因为I/O、条件变量等资源未就绪而等待,也可能因为资源竞争(比如锁)而等待,前者一般属于正常情况,而后者需要重点关注。
下面在测试环境B(见附录2)进行4KB随机写测试,然后分别从这三个方面对curve进行CPU性能分析实践。
软件配置如下:
代码版本:d29c4991 (略新于v1.1-beta)
chunkserver数量:每节点20个chunkserver
copyset数量:4000个(测试前已确保leader均衡,range <= 2)
用户卷数量:10个
用户卷大小:30GB
4k随机写IOPS:234k
自上而下的CPU时间分析
使用vtune采集Chun