当前位置:首页 > 问答 > 正文

Redis跑ARM上那些优化,适配细节和性能提升聊聊

关于Redis在ARM架构上的优化、适配细节和性能提升,这个话题主要源于近年来ARM服务器芯片,特别是苹果的M系列和亚马逊的Graviton系列的崛起,以前Redis主要跑在x86服务器上,大家已经习惯了那种环境,当切换到ARM时,虽然Redis本身是C写的,移植过去能直接编译运行,但要想获得最佳性能,甚至超越x86,就需要在一些细节上下功夫,这些工作主要是由社区和像苹果、亚马逊这样的公司推动的。

最基础也是最重要的适配是内存顺序模型的调整,这是ARM和x86一个根本性的差异,x86属于强内存模型,简单说就是CPU对指令的执行顺序和程序员写的代码顺序差不多,不太会乱序,但ARM是弱内存模型,为了提升效率,CPU和编译器可能会对指令进行重排,这在单线程没事,但多线程并发环境下,尤其是在Redis这种对并发和数据一致性要求极高的数据库中,就可能出问题,一个线程在设置一个标志位表示数据准备好了,另一个线程通过这个标志位来判断,在弱内存模型下,写标志位之前的指令可能会被排到写标志位之后,导致另一个线程读到“数据已准备好”的信号时,实际数据还没准备好,Redis源码里大量使用了原子操作和无锁数据结构来保证高性能,在x86上,这些代码可能正常工作,但在ARM上就需要显式地插入内存屏障指令,告诉CPU:“嘿,这个点之前的操作必须全部完成,不能排到后面去。” Redis社区很早就做了这个适配,在关键的地方,比如锁操作、原子计数增减等处,针对不同的编译器(如GCC)和ARM架构版本,使用了合适的原子内置函数和内存屏障指令(如__atomic_thread_fence),确保了无论在哪种CPU上,内存访问顺序都是正确的,数据是一致的,这个适配是正确性的基石,没有它,Redis在ARM上可能会出一些极难排查的诡异bug。

针对特定ARM微架构的优化,这带来了最直接的性能提升,这里亚马逊的贡献很大,他们为了让自己云上的Graviton处理器能更好地运行Redis,做了不少深度优化,并贡献给了社区,一个关键的优化是改进内存分配器,Redis默认使用jemalloc来管理内存,避免传统malloc的内存碎片问题,亚马逊的工程师发现,在Graviton处理器上,默认的jemalloc配置可能不是最优的,他们通过分析发现,Graviton的CPU核心通常有更多的物理寄存器,并且内存访问特性与x86不同,他们调整了jemalloc的线程本地缓存 策略,简单说,就是每个CPU核心都有一小块本地的内存缓存,这样大部分内存分配和释放操作都在自己核心的缓存里完成,不需要去抢全局锁,速度极快,他们优化了这块本地缓存的大小和回收策略,使其更贴合Graviton核心的行为,显著减少了CPU缓存未命中和锁竞争,从而提升了在高并发场景下的性能,根据他们自己的测试和一些公开报告,优化后的Redis在同等配置的Graviton实例上,相比x86实例能有两位数百分比的性能提升,同时成本还有优势。

另一个微架构层面的优化是针对CRC32指令的,Redis的哈希键值对内部实现使用了CRC32算法来进行快速哈希计算,现代的ARMv8架构(从ARMv8-A开始)和x86一样,都提供了CRC32的硬件指令,一条指令就能完成计算,比用软件模拟快得多,Redis代码中已经有针对x86的CRC32指令 intrinsics(一种直接调用CPU指令的C函数)的优化路径,在ARM平台上,需要确保编译器能够识别并使用ARM对应的CRC32指令,这通常通过检查编译器预定义宏(如__ARM_FEATURE_CRC32)并在代码中启用相应的ARM intrinsics(如__crc32cd)来实现,当Redis检测到CPU支持时,就会切换到这条“高速公路”上,CRC32计算速度的加快直接带来了核心数据结构操作的速度提升。

还有一些编译器和构建系统层面的调整,针对ARM架构选择最合适的编译优化选项-march 参数可以指定目标架构,例如-march=armv8-a+crc(表示支持ARMv8-A架构及CRC扩展),让编译器生成更能发挥该架构优势的指令,ARM芯片通常有多个核心,确保编译时开启链接时优化 也能带来一些收益,它能让编译器看到整个程序的所有代码,进行更全局的优化。

Redis在ARM上的优化是一个从“能用”到“好用”再到“卓越”的过程,先是解决了内存模型差异带来的正确性问题,这是底线,像亚马逊这样的玩家深入下去,结合自家ARM芯片的具体特点(如内存子系统),对关键组件(如内存分配器)进行“量身定制”的调优,这是性能大幅提升的关键,确保所有硬件加速指令(如CRC32)都能在ARM平台上被正确识别和使用,榨干硬件的每一分潜力,这些工作使得现在在ARM服务器上运行Redis不仅可行,而且在性价比上往往更具吸引力。

Redis跑ARM上那些优化,适配细节和性能提升聊聊