部署

# 用 root 身份执行下面命令, 最后再启动 redis server
echo never > /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag

echo never > /sys/kernel/mm/transparent_hugepage/defrag
cat /sys/kernel/mm/transparent_hugepage/defrag
sysctl -w net.core.somaxconn=262144
sysctl -w vm.overcommit_memory=1
sysctl -p

# swappiness, 该数值表示在激活 swap 前的空闲内存百分比. 
# 比如, 60, 表示内存占用到 40% 时, 就会考虑 swap 
# 0 表示尽可能不使用.
# 100 表示尽可能使用
cat /proc/sys/vm/swappiness


# 启动(普通用户身份)
ulimit -n 65535
redis-server

原则

  • 不要用 keys , 可用 scan | hscan 代替
  • 能用 hash 就不要用大 string 对象
  • 不要用 hgetall , 可用 mhget 等批量命令. 实在要全部, 也建议用 hscan
  • 尽可能用 pipeline
  • 开启 slowlog , 并经常排查.

关于 THP

  • 查看系统级别的使用情况 grep AnonHugePages /proc/meminfo
  • 查看每个进程 sudo grep -e AnonHugePages /proc/*/smaps | awk '{ if($2>4) print $0} ' | awk -F "/" '{print $0; system("ps -fp " $3)} '

开启 THP

127.0.0.1:6679> SLOWLOG get 10
 1) 1) (integer) 301035
    2) (integer) 1567742947
    3) (integer) 1745
    4) 1) "HINCRBY"
       2) "tc_30112"
       3) "bid2019-09-06"
       4) "1"
 2) 1) (integer) 301034
    2) (integer) 1567742947
    3) (integer) 1058
    4) 1) "HINCRBY"
       2) "tc_-1_1_f_"
       3) "bid2019-09-06"
       4) "1"
 3) 1) (integer) 301033
    2) (integer) 1567742705
    3) (integer) 1521
    4) 1) "HINCRBY"
       2) "tc_-1_1_f_"
       3) "bid2019-09-06"
       4) "1"

可以看到, 连一个 HINCRBY 命令都要耗时 1.0~1.7 ms

线上服务好像关闭了 THP, 依然会有这种简单的命令执行耗时超 1ms

关于 EHP

  • 查看是否开启 grep -i HugePages_Total /proc/meminfosysctl vm.nr_hugepages
  • 查看标准大页大小 grep Hugepagesize /proc/meminfo (通常是 2048KB, 即 2M)
  • 获取普通页大小 getconf PAGESIZEgetconf PAGE_SIZE

关于 3.X 版本

低版本的 redis , 在平时使用 redis-cli 来执行一些维护任务时要特别注意, 每次调用 redis-cli 会默认发送一条 COMMAND 命令(具体请参考另一篇博文. redis-cli自动发送command命令的问题 ). 如果任务比较频繁, 在高并发下也是会影响 redis 的.

我自己修改了下代码, 将这个调用 COMMAND 命令的方法注释掉, 然后重新编译了一个.

https://github.com/emacsist/redis-3.2-clean

参考资料