https://www.jianshu.com/p/3195663af83e
Redis所有的数据都在内存中,而内存又是非常宝贵的资源。常用的内存优化方案有如下几部分:
一、配置优化
二、缩减键值对象
三、命令处理
四、缓存淘汰方案
目前大部分公司都会将 Web 服务器、数据库服务器等部署在 Linux 操作系统上,Redis优化也需要考虑操作系统,所以接下来介绍 Linux 操作系统如何优化 Redis。
Redis是内存操作,需要优先使用内存。设置overcommit 为1。是为了让 fork 操作能够在低内存下也执行成功。Linux 操作系统对大部分申请内存的请 求都回复 yes,以便能运行更多的程序。因为申请内存后,并不会马上使用内存,这种技术叫做 overcommit。 vm.overcommit_memory 用来设置内存 分配策略,有三个可选值
WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never>/sys/kernel/mm/transparent_hugepage/enabled
OOM(Out Of Memory)killer
机制是指 Linux 操作系统发现可用内存不足时,强制杀死一些用户进程(非内核进程),来保证系统有足够的可用内存 进行分配。 为使配置在重启 Linux 操作系统后立即生效,只需要在/etc/sysctl.conf
追加 vm.swappiness={bestvalue}
即可echo vm.swappiness={bestvalue} >> /etc/sysctl.conf
查看 swap 的总体情况 free-m 如下服务器开启了8189M swap,其中使用了 5241MB
可以通过 ulimit 查看和设置系统当前用户进程的资源数。其中 ulimit-a 命令包含的 open files 参数,是单个用户同时打开的最大文件个数:
#You requested maxclients of 10000 requiring at least 10032 max file descriptors.
#Redis can’t set maximum open files to 10032 because of OS error: Operation not permitted.
#Current maximum open files is 4096. Maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase ‘ulimit –n’.
ulimit –Sn {max-open-files}
maxmemory
大小的内存之后就开始拒绝后续的写入请求,该参数可以确保Redis因为使用 了大量内存严重影响速度或者发生OOM(out-of-memory
,发现内存不足时,它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存)。此外, 可以使用info命令查看Redis占用的内存及其它信息。timeout 150
tcp-keepalive 150 (定时向client发送tcp_ack包来探测client是否存活的。默认不探测)
appendonly no
config set maxclients
去设置最大连接数。根据连接数负载的情况。降低Redis内存使用最直接的方式就是缩减键(key)和值(value)的长度
常用压缩方法对比
Redis基于C/S架构模式,基于Redis操作命令是解决响应延迟问题最关键的部分,因为Redis是个单线程模型,客户端过来的命令是按照顺序执行的。比较常见的 延迟是带宽,通过千兆网卡的延迟大约有200μs。倘若明显看到命令的响应时间变慢,延迟高于200μs,那可能是Redis命令队列里等待处理的命令数量比较多 要分析解决这个性能问题,需要跟踪命令处理数的数量和延迟时间。 比如可以写个脚本,定期记录total_commands_processed
的值。当客户端明显发现响应时间过慢时,可以通过记录的total_commands_processed
历史数据值来判 断命理处理总数是上升趋势还是下降趋势,以便排查问题 在info信息里的 total_commands_processed
字段显示了Redis服务处理命令的总数。
LPUSH
或 RPUSH
,通过多参数构造形式一次性把1000个元素发送的Redis服务上。下面是Redis的一些操作命令,有单个参数命令和支持多个参数的命令,通过这些命令可 尽量减少使用多命令的次数。redis 内存数据集大小上升到一定大小的时候,就会进行数据淘汰策略。如果不淘汰经常不用的缓存数据,那么正常的数据将不会存储到缓存当中。 我们通过配置redis.conf
中的maxmemory
这个值来开启内存淘汰功能。
maxmemory
值得注意的是,maxmemory为0的时候表示我们对Redis的内存使用没有限制
根据应用场景,选择淘汰策略maxmemory-policy noeviction
内存淘汰的过程
首先,客户端发起了需要申请更多内存的命令(如set)。
然后,Redis检查内存使用情况,如果已使用的内存大于maxmemory则开始根据用户配置的不同淘汰策略来淘汰内存(key),从而换取一定的内存。
最后,如果上面都没问题,则这个命令执行成功。
config set maxmemory 100000
config set maxmemory-policy noeviction
volatile-lru
下面看看几种策略的适用场景allkeys-lru
:如果我们的应用对缓存的访问符合幂律分布,也就是存在相对热点数据,或者我们不太清楚我们应用的缓存访问分布状况,我们可以选择 allkeys-lru策略。allkeys-random
:如果我们的应用对于缓存key的访问概率相等,则可以使用这个策略。volatile-ttl
:这种策略使得我们可以向Redis提示哪些key更适合被eviction。
另外,volatile-lru
策略和volatile-random
策略适合我们将一个Redis实例既应用于缓存和又应用于持久化存储的时候,然而我们也可以通过使用两个Redis实例来达 到相同的效果,值得一提的是将key设置过期时间实际上会消耗更多的内存,因此我们建议使用allkeys-lru
策略从而更有效率的使用内存