摘要:redis在运行的过程中如果使用不合适的配置会使其占用内存越来越大,在此我给出我自己的一些优化策略供大家参考,如果你看到我的文章有更好的方法和策略希望也能分享给我,我们一起交流,感激不尽!
代码层级
- 去除代码里的scan操作
- 给每个key加过期时间
- 存储结构用hash
redis策略
- 绑定本机ip部署redis防止远程连接
- maxmemory-policy allkeys-lru :从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放
- maxmemory 12GB 根据实际调整大小
系统限制
- 内核参数
sysctl.conf
vm.overcommit_memory=1
Redis的RDB持久化实现是folk一个子进程,然后让子进程将内存镜像dump到RDB文件中。理论上来说是需要跟父进程一样的内存空间,但是由于linux很早就支持的copy-on-write技术,所以实际上并不需要这么多的物理内存的。(vm.overcommit_memory=1表示内核允许分配所有的物理内存,而不管当前的内存状态如何。)
- 关闭透明大页功能
echo never > /sys/kernel/mm/transparent_hugepage/enabled
(操作系统后台有一个叫做khugepaged的进程,它会一直扫描所有进程占用的内存,在可能的情况下会把4kpage交换为Huge Pages,在这个过程中,对于操作的内存的各种分配活动都需要各种内存锁,直接影响程序的内存访问性能,并且,这个过程对于应用是透明的,在应用层面不可控制,对于专门为4k page优化的程序来说,可能会造成随机的性能下降现象。)
冷备方式
redis提供两种方式,他们是 RDB和AOF
RDB
将数据库的快照(snapshot)以二进制的方式保存到磁盘中。AOF
则以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的。
RDB
优点:
节省磁盘空间、恢复速度快,就是一个镜像,适合大规模的数据恢复;
对数据完整性和一致性要求不高
缺点:
在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是会占用cpu性能。
优化策略(改redis的配置):
- AOF 与 RDB ,使用RDB方式
打开命令
# 指定本地数据库文件名,一般采用默认的 dump.rdb
dbfilename dump.rdb
# save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中。官方出厂配置默认是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的数据快照写入磁盘。
若不想用RDB方案,可以把 save "" 的注释打开,下面三个注释。
# save ""
save 900 1
save 300 10
save 60 10000
# 指定本地数据库存放目录,一般也用默认配置
dir ./
# 配置存储至本地数据库时是否压缩数据,默认为yes。
# Redis采用LZF压缩方式,但占用了一点CPU的时间。若关闭该选项,但会导致数据库文件变的巨大。建议开启。
rdbcompression yes
- 关闭aof:
appendonly no
(appendfsync everysec:每一秒写入aof文件,并完成磁盘同步。
appendfsync no 不即时同步,由操作系统控制何时刷写到磁盘上,这种模式速度最快,减少io,数据安全性下降,但是会产生僵尸进程
appendfsync always:每个命令都写入aof文件,并完成磁盘同步)
- 为什么不使用AOF?
AOF 是redis的一种持久化方式,用来记录所有的写操作,但是随着时间增加,aof文件会越来越大,所以需要进行重写,将内存中的数据重新以命令的方式写入aof文件。
在重写的过程中,由于redis还会有新的写入,为了避免数据丢失,会开辟一块内存用于存放重写期间产生的写入操作,等到重写完毕后会将这块内存中的操作再追加到aof文件中。
从原理中可以了解到,如果在重写过程中redis的写入很频繁或写入量很大,就会导致占用大量额外的内存来缓存写操作,导致内存爆涨。
命令行方式关闭:
redis-03:6379> config get appendonly
1) "appendonly"
2) "yes"
redis-03:6379> config set appendonly no
OK
总结
- 绑定本机ip部署redis防止远程连接
- AOF 与 RDB ,应该使用RDB方式
- 代码层级:去除代码里的scan操作,给每个key加过期时间
- 存储结构用hash
- maxmemory-policy allkeys-lru:从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放
- 关闭aof:appendonly no
(appendfsync everysec:每一秒写入aof文件,并完成磁盘同步。
appendfsync no 不即时同步,由操作系统控制何时刷写到磁盘上,这种模式速度最快,减少io,数据安全性下降
appendfsync always:每个命令都写入aof文件,并完成磁盘同步)
7. 内核参数sysctl.conf
vm.overcommit_memory=1
Redis的RDB持久化实现是folk一个子进程,然后让子进程将内存镜像dump到RDB文件中。理论上来说是需要跟父进程一样的内存空间,但是由于linux很早就支持的copy-on-write技术,所以实际上并不需要这么多的物理内存的。(vm.overcommit_memory=1表示内核允许分配所有的物理内存,而不管当前的内存状态如何。)
8. 关闭透明大页功能 echo never > /sys/kernel/mm/transparent_hugepage/enabled
(操作系统后台有一个叫做khugepaged的进程,它会一直扫描所有进程占用的内存,在可能的情况下会把4kpage交换为Huge Pages,在这个过程中,对于操作的内存的各种分配活动都需要各种内存锁,直接影响程序的内存访问性能,并且,这个过程对于应用是透明的,在应用层面不可控制,对于专门为4k page优化的程序来说,可能会造成随机的性能下降现象。)
9. maxmemory 12GB 根据实际调整大小
评论