- linux 部署
- 安全
- 配置客户端连接
- 内存管理
- 基准测试
linux 部署
1. 设置内存相关的参数
sudo sysctl -w vm.overcommit_memory=1
sudo sysctl -w vm.swappiness=0
可以使用
echo vm.overcommit_memory=1 >> /etc/sysctl.conf
echo vm.swappiness=0 >> /etc/sysctl.conf
持久化到系统配置
Redis使用的是写时复制、并不需要使用与数据集大小相同的内存才能复制、但是linux会默认检测是否有足够空闲内存来复制父进程的所有内存页、
这可能会导致进程由于OOM而崩溃、日志如下:
Can't save in background: fork: Cann't allocate memory
通过设置 vm.overcommit_memory=1 让系统在调用alloc时即使没有足够的内存也能执行成功
vm.swappiness则定义了linux内核中将内存中的内容copy到交换分区的大小
启用虚拟内存后、redis会尝试访问位于磁盘中的内存页、这将导致redis进程被磁盘IO阻塞、
所以、为了避免这种情况、总是将其置为0
2. 禁用透明大页功能
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
cat >> /etc/rc.local << EOF
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
EOF
开启透明大分页、可能会导致持久化时的子进程创建缓慢、所以建议关闭
3. 网络优化
sudo sysctl -w net.core.somaxconn=65535
sudo sysctl -w net.ipv4.tcp_max_sync_backlog=65535
backlog队列是存放挂起tcp连接、
持久化:
echo "net.core.somaxconn=65535" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_sync_backlog=65535" >> /etc/sysctl.conf
4. 将进程可以打开的文件数设为更高的值
ulimit -n 288000
注意: 必须将nofile 设置的小于 /proc/sys/fs/file-max 的值
可以使用cat检测目前的设置
redis soft nofile 288000
redis hard nofile 288000
进行持久化存储
ulimit -Hn -Sn 检测是否存储成功
此处是设置 一个进程打开的最大文件数量、要确保大于配置中 maxclients 选项的值
安全
1. 绑定服务器ip
eg. bind 127.0.0.1 192.168.1.1
2. 不进行端口监听、只进行unix套接字通信
port 0
unixsocket /var/run/redis/redis.sock
unixsocketperm 766
3. 使用密码认证
requirepass {{pass}}
若开启了主从复制、需要将主实例的密码添加到所有从实例的配置文件中
masterauth {{pass}}
4. 启用保护模式 protected mode
若redis启用了保护模式、且监听所有端口、同时禁用了密码验证、则redis只响应本地回环接口和unix套接字的查询
配置客户端连接
1. 配置网络参数
timeout 0
tcp-backlog 511
2. maxclients 最大客户端连接数
maxclients 5000
tcp-keepalive 300 按tcp-keepalive指定的时间间隔发送tcp ack通知此客户端依然活跃
若一个客户端没有响应tcp活跃的状态、该客户端会被视为下线
eg. 在有防火墙时、在客户端和防火墙之间的空闲连接超过1800s时、会中断连接、而client和server
都不会收到连接已断开的通知、从server来看、连接依然是活跃的、服务器就不会释放连接
从client的角度来看、一旦发现连接断开就会进行重连、这样会导致redis连接数持续增加
为了避免这种问题、最后将tcp-keepalive的值设为合适的时间、长时间无联系、就释放连接
3. 配置客户端的缓冲区参数
client-output-buffer-limit
redis不会直接将命令的输出发送给client、而是先将结果填充到每个连接的缓冲区、
然后将内容一次性的发送出去、不同类型的输出缓冲区大小是不同的
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
0代表不限制/最好作出限制、防止误用keys等命令占用过大内存
内存管理
使用info memory来查看redis内存使用情况
重点关注:
1. used_memory 已使用的内存
2. maxmemory 可分批的最大内存 0表示无限制
3. maxmemory_policy 是表示达到内存限制后的key淘汰策略
默认 noeviction 不淘汰、在写入时提示错误
还应该注意避免键的频繁淘汰、它会影响server的性能
基准测试
redis-benchmark 工具
redis-benchmark --help 查看帮助
redis-benchmark -t set -c 100 -n 10000 -r 1000000 -d 256
对单个API进行性能测试
redis-benchmark -t set -c 100 -n 10000 -r 1000000 -d 256 -P 10000
使用 -P选项查看pipline带来的性能提升
测试lua脚本
redis-benchmark -n 10000 script load "redis.call('set', 'foo', 'bar')"