Memcached 优化指南
针对 Ampere Altra 系列处理器
Memcached是一个开源的内存键值数据存储系统,通常用于缓存任意类型的小块数据,如字符串,或数据库和API调用结果中的对象。由于其基于内存的特性,Memcached旨在通过在RAM中缓存数据和对象来加速动态web应用程序,并减少数据库查找。它是云计算中最具开创性的缓存存储之一,至今仍很受欢迎。
本指南的目的是描述在Ampere® Altra®处理器上以最佳方式运行memcached的相关技巧。
实现应用程序的高性能运行,首先要正确构建应用程序并使用适当的编译器标志(flag)。在我们的例子中,当在Ampere Altra处理器上构建memcached时,我们建议使用GCC编译器版本10或更新的版本从源代码进行构建。较新的编译器往往对新的处理器特性有更好的支持,并结合了更高级的代码生成技术。
我们使用CentOS8作为我们本次优化测试的操作系统。
从SCL存储库下载并安装GCC 10:
sudo yum -y install yum install scl-utils scl-utils-build sudo yum -y install gcc-toolset-10-gcc scl enable gcc-toolset-10 bash
对于其他操作系统,如Ubuntu 20.04 LTS和Debian, GCC 10.2.1也是可用的,可直接从相应的存储库安装。
Libevent是构建memcached所必需的,可以如下方式下载:
sudo yum install libevent-devel
Memcached wiki上的安装指南(https://github.com/memcached/memcached/wiki/Install)有关于在Debian/Ubuntu和Redhat/Fedora上安装Memcached的说明。源代码可在memcached项目页面上获得。我们建议使用最新的稳定版本。
可以使用以下命令下载Memcached。
wget https://memcached.org/latest #you might need to rename the file tar -zxf memcached-1.x.x.tar.gz cd memcached-1.x.x
在继续为Memcached配置构建选项之前,让我们添加一些特定于Ampere Altra处理器的编译器标志:
./configure CFLAGS="-O3 -march=native -mcpu=neoverse-n1" --prefix=/usr/local/memcached make && make test && sudo make install
众所周知,Memcached占用大量网络资源,为了获得良好的性能,内核和网卡(NIC)的调优是必要的。
大多数内核调优配置可以通过sysfs文件系统修改数据结构来设置。但是,有些调整可能需要重新编译内核。一般的内核优化措施是设置操作系统使用64 KB的页面大小。这将提高Ampere Altra处理器上的翻译暂置缓冲区(TLB)的效率。
查看系统上正在使用的页面大小:
getconf PAGESIZE
对于64 KB的页面大小,预期返回值65536。如果不是这样,请检查CONFIG_ARM64_64K_PAGES是否已应用于内核配置文件,重新编译并安装内核,然后重新启动。
CONFIG_ARM64_64K_PAGES=y
考虑到大量的内核配置选项,有时使用预定义的优化配置文件来匹配您的使用场景会更容易。Tuned就是这样一种调优服务,它可以通过设置调优配置文件来配置操作系统来提高性能
以CentOS 8为例,如果Memcached的吞吐量是所关注的主要指标,我们建议使用吞吐量-性能(throughput-performance)的Tuned Profile。该配置文件将CPU调控器(governors)设置为性能模式,这样可以减少调度延迟,最大化I/O吞吐量,并减少交换度值(swappiness),所有这些都可以显著提高性能。
对于Ubuntu,如果它不是操作系统安装的一部分,则可能需要单独安装tuned profile。
sudo apt-get update -y sudo apt-get install -y tuned
为了改进Ampere Altra处理器上的内核调度延迟,我们建议通过更新Tuned Profile文件中的相应设置,将sched_wakeup_granularity_ns更改为5000。
PROFILE_FILE=/usr/lib/tuned/throughput-performance/tuned.conf sed -i 's/sched_wakeup_granularity_ns = 15000000/sched_wakeup_granularity_ns = 5000/g' $PROFILE_FILE
然后使用以下命令启用吞吐量-性能(throughput-performance)的Tuned Profil:
tuned-adm profile throughput-performance
像Memcached这样的应用程序通常被调优为在高吞吐量下运行,同时保持严格的服务水平协议(SLA)。p.99延迟通常是一个常见的标准。为了考虑此类SLA的要求,我们建议调优内核TCP/IP设置,因为传入的请求是通过TCP连接建立的。
我们在Memcached测试中使用的TCP/IP调优设置列表如下:
echo 9999999 > /proc/sys/net/core/somaxconn echo 4194304 > /proc/sys/net/core/rmem_max echo 4194304 > /proc/sys/net/core/wmem_max echo 4194304 > /proc/sys/net/core/rmem_default echo 4194304 > /proc/sys/net/core/wmem_default echo "4096 87380 4194304" > /proc/sys/net/ipv4/tcp_rmem echo "4096 87380 4194304" > /proc/sys/net/ipv4/tcp_wmem echo "4096 87380 4194304" > /proc/sys/net/ipv4/tcp_mem echo 250000 > /proc/sys/net/core/netdev_max_backlog echo 50 > /proc/sys/net/core/busy_read echo 50 > /proc/sys/net/core/busy_poll echo 3 > /proc/sys/net/ipv4/tcp_fastopen echo 0 > /proc/sys/kernel/numa_balancing echo 0 > /proc/sys/net/ipv4/tcp_timestamps echo 1 > /proc/sys/net/ipv4/tcp_low_latency echo 0 > /proc/sys/net/ipv4/tcp_sack echo 1 > /proc/sys/net/ipv4/tcp_syncookie
除了内核TCP/IP设置之外,我们还需要确保应用程序能够利用大多数网卡(NIC)内置的硬件卸载功能,例如Generic-Receive-Offload,它可以聚合属于同一流的多个传入数据包,以及large - receive - offload,它可以将属于同一连接的传入TCP/IP数据包合并到一个大的接收段中,然后将其传递给内核。
具体操作如下:
ethtool -K <NIC_NAME> gro on ethtool -K <NIC_NAME> lro on
对于像Memcached这样的网络绑定(network-bound)工作负载,强烈建议将网卡中断(irq)分布在多个核心上,以避免出现瓶颈。参考文档 2 是关于SMP IRQ关联的一个非常好的参考。
建议使用以下命令检查网卡支持的硬件通道数量,以确保通道数量与网卡的通道容量匹配:
ethtool -l <NIC_NAME> sudo ethtool -L <NIC_NAME> combined <CHANNEL_NUM>
Memcached本身是可以做些调优来更好地匹配实际应用环境。调优它的一个很好的起点是Memcached内置的统计功能。可以通过使用telnet连接到memcached并运行它来研究统计数据:
telnet localhost 11211 Connected to localhost. Escape character is '^]'. telnet> stats STAT pid 23599 STAT uptime 675 STAT time 1211439587 STAT version 1.2.5 STAT pointer_size 32 STAT rusage_user 1.404992 STAT rusage_system 4.694685 STAT curr_items 32 STAT total_items 56361 STAT bytes 2642 STAT curr_connections 53 STAT total_connections 438 STAT connection_structures 55 STAT cmd_get 113482 STAT cmd_set 80519 STAT get_hits 78926 STAT get_misses 34556 STAT evictions 0 STAT bytes_read 6379783 STAT bytes_written 4860179 STAT limit_maxbytes 67108864 STAT threads 1 END
get_hits和get_misses值特别重要,它们可用于计算Memcached的缓存命中/未命中比率。像Memcached这样的内存缓存的经验法则是将缓存命中率保持在90%以上。
清除值(evictions value)计算从缓存中清除的未过期项的数量,以便为新项腾出空间。清除次数过多可能表明缓存过度使用或分配的内存量不足。
最后,Memcached线程的数量可能是影响Memcached总体性能的一个设置。对于像Ampere Altra系列处理器这样的高核数处理器,我们建议在研究性能扩展时增加线程数量以使用尽可能多的核。极高的线程数可能导致锁争用,从而降低性能。在启动Memcached时,可以通过使用-t选项来更改线程数。
在生产环境中对Memcached这样的应用程序进行微调需要对其用法和端到端软件堆栈有深入的了解。我们希望本指南中讨论的设置可以帮助提高Memcached的性能,并建议参考这里提供的所有配置选项,以更好地匹配您的使用。