Skip to content

Redis 系统参数优化

Linux内核参数优化

内存管理参数

overcommit_memory

  • 默认值:0
  • 建议值:1
  • 说明:控制内存过度分配行为
    • 0:内核根据启发式算法决定是否允许过度分配
    • 1:允许所有内存过度分配
    • 2:禁止内存过度分配
  • 配置方式
    bash
    sysctl -w vm.overcommit_memory=1
    # 永久生效
    echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf

overcommit_ratio

  • 默认值:50
  • 建议值:90(当overcommit_memory=2时生效)
  • 说明:设置内存过度分配的比例,计算公式为:总可用内存 = 物理内存 + 交换分区 × overcommit_ratio%
  • 配置方式
    bash
    sysctl -w vm.overcommit_ratio=90
    echo "vm.overcommit_ratio = 90" >> /etc/sysctl.conf

swappiness

  • 默认值:60
  • 建议值:1-10
  • 说明:控制内核将内存页交换到交换分区的倾向
    • 0:尽量不使用交换分区
    • 100:积极使用交换分区
  • 配置方式
    bash
    sysctl -w vm.swappiness=1
    echo "vm.swappiness = 1" >> /etc/sysctl.conf

transparent_hugepage

  • 默认值:enabled
  • 建议值:never
  • 说明:禁用透明大页,避免Redis延迟波动
  • 配置方式
    bash
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    echo never > /sys/kernel/mm/transparent_hugepage/defrag
    # 永久生效,添加到/etc/rc.local

网络参数优化

net.core.somaxconn

  • 默认值:128
  • 建议值:1024-65535
  • 说明:定义监听套接字的最大连接队列长度
  • 配置方式
    bash
    sysctl -w net.core.somaxconn=1024
    echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf

net.ipv4.tcp_max_syn_backlog

  • 默认值:128
  • 建议值:1024-65535
  • 说明:定义TCP SYN队列的最大长度
  • 配置方式
    bash
    sysctl -w net.ipv4.tcp_max_syn_backlog=1024
    echo "net.ipv4.tcp_max_syn_backlog = 1024" >> /etc/sysctl.conf

net.ipv4.tcp_fin_timeout

  • 默认值:60
  • 建议值:15-30
  • 说明:定义TCP连接处于FIN-WAIT-2状态的最长时间
  • 配置方式
    bash
    sysctl -w net.ipv4.tcp_fin_timeout=30
    echo "net.ipv4.tcp_fin_timeout = 30" >> /etc/sysctl.conf

net.ipv4.tcp_keepalive_time

  • 默认值:7200
  • 建议值:600
  • 说明:定义TCP连接发送keepalive探测包的间隔时间
  • 配置方式
    bash
    sysctl -w net.ipv4.tcp_keepalive_time=600
    echo "net.ipv4.tcp_keepalive_time = 600" >> /etc/sysctl.conf

net.ipv4.tcp_tw_recycle

  • 默认值:0
  • 建议值:1
  • 说明:启用TCP TIME_WAIT套接字的快速回收
  • 配置方式
    bash
    sysctl -w net.ipv4.tcp_tw_recycle=1
    echo "net.ipv4.tcp_tw_recycle = 1" >> /etc/sysctl.conf

net.ipv4.tcp_tw_reuse

  • 默认值:0
  • 建议值:1
  • 说明:允许重用处于TIME_WAIT状态的套接字
  • 配置方式
    bash
    sysctl -w net.ipv4.tcp_tw_reuse=1
    echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf

文件系统参数优化

fs.file-max

  • 默认值:约8192
  • 建议值:1000000
  • 说明:定义系统级别的最大文件句柄数
  • 配置方式
    bash
    sysctl -w fs.file-max=1000000
    echo "fs.file-max = 1000000" >> /etc/sysctl.conf

Redis配置参数优化

内存相关参数

maxmemory

  • 默认值:0(无限制)
  • 建议值:物理内存的70%-80%
  • 说明:设置Redis使用的最大内存量
  • 配置方式
    txt
    maxmemory 16gb

maxmemory-policy

  • 默认值:noeviction
  • 建议值:根据业务场景选择
    • volatile-lru:从设置了过期时间的键中,删除最近最少使用的键
    • allkeys-lru:从所有键中,删除最近最少使用的键
    • volatile-ttl:从设置了过期时间的键中,删除剩余TTL最短的键
    • volatile-random:从设置了过期时间的键中,随机删除键
    • allkeys-random:从所有键中,随机删除键
    • noeviction:不删除键,内存不足时返回错误
  • 配置方式
    txt
    maxmemory-policy volatile-lru

maxmemory-samples

  • 默认值:5
  • 建议值:3-10
  • 说明:设置LRU算法的采样数量,值越大越精确,但CPU消耗越高
  • 配置方式
    txt
    maxmemory-samples 5

网络相关参数

tcp-backlog

  • 默认值:511
  • 建议值:与net.core.somaxconn保持一致
  • 说明:设置TCP监听队列的长度
  • 配置方式
    txt
    tcp-backlog 1024

timeout

  • 默认值:0(无超时)
  • 建议值:300
  • 说明:设置客户端连接的超时时间(秒)
  • 配置方式
    txt
    timeout 300

tcp-keepalive

  • 默认值:300
  • 建议值:60
  • 说明:设置TCP keepalive探测的间隔时间(秒)
  • 配置方式
    txt
    tcp-keepalive 60

持久化相关参数

save

  • 默认值
    txt
    save 900 1
    save 300 10
    save 60 10000
  • 建议值:根据业务需求调整
    • 减少save策略的频率,降低RDB生成对性能的影响
    • 或使用AOF持久化替代
  • 配置方式
    txt
    save 3600 1
    save 600 100
    save 300 1000

appendfsync

  • 默认值:everysec
  • 建议值
    • everysec:每秒同步一次,平衡性能和数据安全性
    • no:由操作系统决定同步时机,性能最佳但数据安全性最低
    • always:每次写入都同步,数据最安全但性能最差
  • 配置方式
    txt
    appendfsync everysec

no-appendfsync-on-rewrite

  • 默认值:no
  • 建议值:yes
  • 说明:在AOF重写期间,是否暂停AOF同步,提升重写性能
  • 配置方式
    txt
    no-appendfsync-on-rewrite yes

线程相关参数

io-threads

  • 默认值:1
  • 建议值:CPU核心数的1/2到2/3(Redis 6.0+支持)
  • 说明:设置I/O线程数,用于处理网络I/O
  • 配置方式
    txt
    io-threads 4

io-threads-do-reads

  • 默认值:no
  • 建议值:yes(Redis 6.0+支持)
  • 说明:是否使用I/O线程处理读操作
  • 配置方式
    txt
    io-threads-do-reads yes

系统资源限制优化

进程文件句柄限制

  • 默认值:通常为1024
  • 建议值:65535
  • 配置方式
    bash
    # 临时生效
    ulimit -n 65535
    
    # 永久生效,编辑/etc/security/limits.conf
    echo "redis soft nofile 65535" >> /etc/security/limits.conf
    echo "redis hard nofile 65535" >> /etc/security/limits.conf

进程数限制

  • 默认值:通常为1024
  • 建议值:65535
  • 配置方式
    bash
    # 临时生效
    ulimit -u 65535
    
    # 永久生效,编辑/etc/security/limits.conf
    echo "redis soft nproc 65535" >> /etc/security/limits.conf
    echo "redis hard nproc 65535" >> /etc/security/limits.conf

栈大小限制

  • 默认值:通常为8192
  • 建议值:10240
  • 配置方式
    bash
    # 临时生效
    ulimit -s 10240
    
    # 永久生效,编辑/etc/security/limits.conf
    echo "redis soft stack 10240" >> /etc/security/limits.conf
    echo "redis hard stack 10240" >> /etc/security/limits.conf

性能测试与验证

测试工具

redis-benchmark

bash
# 基本测试
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

# 测试特定命令
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000 set __key__ __val__

# 测试内存使用
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000 --test-memory 1024

memtier_benchmark

bash
# 安装
apt-get install memtier-benchmark

# 基本测试
memtier-benchmark -h 127.0.0.1 -p 6379 -c 100 -t 4 --ratio 1:1 -n 100000

监控指标

Redis监控指标

  • 内存使用率used_memory_rss / maxmemory
  • 命中率keyspace_hits / (keyspace_hits + keyspace_misses)
  • 连接数connected_clients
  • 命令执行速度instantaneous_ops_per_sec
  • 过期键数量expired_keys
  • 驱逐键数量evicted_keys

系统监控指标

  • CPU使用率:关注用户态和系统态CPU使用率
  • 内存使用率:关注Redis进程的RSS内存和系统内存使用率
  • 网络流量:关注Redis实例的网络输入输出流量
  • 磁盘I/O:关注持久化操作的磁盘I/O负载

常见问题(FAQ)

Q1: 为什么要禁用透明大页?

A1: 透明大页会导致Redis延迟波动,因为当Redis尝试修改大页中的小部分数据时,会触发整个大页的复制(写时复制),这会消耗大量CPU资源并导致延迟峰值。禁用透明大页可以使Redis的延迟更加稳定。

Q2: overcommit_memory应该设置为1还是2?

A2: 对于Redis来说,建议将overcommit_memory设置为1。因为Redis使用fork()创建子进程进行RDB持久化和AOF重写,当overcommit_memory=1时,内核会允许fork()成功,即使系统内存不足,这可以避免持久化操作失败。而overcommit_memory=2则可能导致fork()失败,影响持久化功能。

Q3: maxmemory应该设置为多少?

A3: 建议将maxmemory设置为物理内存的70%-80%。这样可以为系统保留足够的内存用于运行其他进程和缓存文件系统数据,同时充分利用可用内存来存储Redis数据。

Q4: 如何选择合适的maxmemory-policy?

A4: 选择maxmemory-policy时需要考虑业务场景:

  • 如果大部分键都设置了过期时间,且希望优先保留最近使用的键,可以选择volatile-lru
  • 如果键没有设置过期时间,或者希望从所有键中淘汰最近最少使用的键,可以选择allkeys-lru
  • 如果希望根据键的剩余TTL来淘汰键,可以选择volatile-ttl
  • 如果对数据丢失不敏感,或者希望随机淘汰键,可以选择volatile-random或allkeys-random
  • 如果不允许数据丢失,可以选择noeviction,但需要确保内存充足

Q5: io-threads应该设置为多少?

A5: 建议将io-threads设置为CPU核心数的1/2到2/3。例如,对于8核心CPU,可以设置为4-6。设置过多的I/O线程可能会导致线程间切换开销增加,反而影响性能。同时,需要开启io-threads-do-reads选项,让I/O线程同时处理读操作,以充分利用多核优势。

Q6: 为什么要调整swappiness参数?

A6: Redis是内存数据库,应该尽量避免使用交换分区。将swappiness设置为较低的值(如1-10),可以告诉内核尽量不要将Redis的内存页交换到磁盘,从而减少因为交换导致的性能下降。

Q7: 如何验证参数优化的效果?

A7: 可以通过以下方式验证参数优化的效果:

  1. 使用redis-benchmark或memtier_benchmark进行性能测试,比较优化前后的吞吐量和延迟
  2. 监控Redis的关键指标,如命令执行速度、命中率、连接数等
  3. 监控系统资源使用情况,如CPU、内存、网络和磁盘I/O
  4. 观察业务应用的响应时间变化

Q8: 所有参数都需要优化吗?

A8: 不需要。参数优化应该根据实际的业务场景和系统配置进行调整。建议先监控Redis的运行状态和性能指标,找出瓶颈所在,然后针对性地优化相关参数。盲目调整所有参数可能会导致性能下降或系统不稳定。