我们喜欢 Redis,因为它速度快(而且有趣!),因此当我们开始考虑扩展 Redis 时,首先要确保我们已尽一切努力最大限度地提高其性能。
让我们首先了解一些重要的调优参数。
Redis 默认最大客户端数为 10,000 个;达到此最大值后,Redis 将对所有新连接响应错误。如果您有很多连接(或很多应用实例),则可能需要设置得更高。您可以在 Redis 配置文件中设置最大同时客户端数
maxclients 20000
默认情况下,Redis 没有最大内存限制,因此它将使用所有可用的系统内存。如果您使用复制功能,您会希望限制内存使用量,以便为副本输出缓冲区留出开销。为系统保留内存也是一个好主意。例如 25% 的开销。您可以在 Redis 配置文件中更新此设置
# memory size in bytes
maxmemory 1288490188
Redis 服务器使用 tcp-backlog
的值来指定完整连接队列的大小。
Redis 将此配置作为 listen(int s, int backlog)
调用的第二个参数传递。
如果您有很多连接,则需要将此值设置得高于默认值 511。您可以在 Redis 配置文件中更新此设置
# TCP listen() backlog.
#
# In high requests-per-second environments you need an high backlog in order
# to avoid slow clients connections issues. Note that the Linux kernel
# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
# in order to get the desired effect.
tcp-backlog 65536
正如 redis.conf
中的注释所示,可能还需要在操作系统层面增加 somaxconn
和 tcp_max_syn_backlog
的值。
扩展 Redis 的一个简单方法是添加读副本,从而减轻主节点的负载。当您的工作负载以读操作为主(而不是写操作为主)时,这种方法最有效。您可能希望副本可用并仍然提供旧数据,即使复制尚未完成。您可以在 Redis 配置文件中更新此设置
slave-serve-stale-data yes
您还需要防止在副本上进行任何写操作。您可以在 Redis 配置文件中更新此设置
slave-read-only yes
在高负载下,由于内存分配,偶尔会出现性能下降。这是 Redis 的创建者 Salvatore 过去在博客中提到过的问题。性能问题与透明大页(transparent hugepages)有关,如果需要,您可以在操作系统层面禁用它。
$ echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled
如果您计划在高性能环境中处理大量连接,我们建议调优以下内核参数
vm.swappiness=0 # turn off swapping
net.ipv4.tcp_sack=1 # enable selective acknowledgements
net.ipv4.tcp_timestamps=1 # needed for selective acknowledgements
net.ipv4.tcp_window_scaling=1 # scale the network window
net.ipv4.tcp_congestion_control=cubic # better congestion algorithm
net.ipv4.tcp_syncookies=1 # enable syn cookies
net.ipv4.tcp_tw_recycle=1 # recycle sockets quickly
net.ipv4.tcp_max_syn_backlog=NUMBER # backlog setting
net.core.somaxconn=NUMBER # up the number of connections per port
net.core.rmem_max=NUMBER # up the receive buffer size
net.core.wmem_max=NUMBER # up the buffer size for all connections
如果您没有为 Redis 用户设置正确的文件描述符数量,您将看到指示“Redis 无法设置最大打开文件数…”的错误。您可以在操作系统层面增加文件描述符限制。
以下是使用 systemd 在 Ubuntu 上的一个示例
/etc/systemd/system/redis.service
[Service]
...
User=redis
Group=redis
...
LimitNOFILE=65536
...
然后,您需要重新加载守护程序并重启 redis 服务。
提高性能的一种方法是防止 Redis 与处理任何网络流量的 CPU 运行在同一核心上。这可以通过为网络接口启用 RPS 并为 Redis 进程设置 CPU 亲和性来实现。
这是一个示例。首先,我们可以在 CPU 0-1 上启用 RPS
$ echo '3' > /sys/class/net/eth1/queues/rx-0/rps_cpus
然后,我们可以将 redis 的 CPU 亲和性设置为 CPU 2-8
# config is set to write pid to /var/run/redis.pid
$ taskset -pc 2-8 `cat /var/run/redis.pid`
pid 8946's current affinity list: 0-8
pid 8946's new affinity list: 2-8