Redis运行优化

摘要:redis在运行的过程中如果使用不合适的配置会使其占用内存越来越大,在此我给出我自己的一些优化策略供大家参考,如果你看到我的文章有更好的方法和策略希望也能分享给我,我们一起交流,感激不尽!

代码层级

  • 去除代码里的scan操作
  • 给每个key加过期时间
  • 存储结构用hash

redis策略

  • 绑定本机ip部署redis防止远程连接
  • maxmemory-policy allkeys-lru :从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放
  • maxmemory 12GB 根据实际调整大小

系统限制

  • 内核参数 sysctl.conf
    1
    vm.overcommit_memory=1

Redis的RDB持久化实现是folk一个子进程,然后让子进程将内存镜像dump到RDB文件中。理论上来说是需要跟父进程一样的内存空间,但是由于linux很早就支持的copy-on-write技术,所以实际上并不需要这么多的物理内存的。(vm.overcommit_memory=1表示内核允许分配所有的物理内存,而不管当前的内存状态如何。)

  • 关闭透明大页功能
    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方式
    打开命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 指定本地数据库文件名,一般采用默认的 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的写入很频繁或写入量很大,就会导致占用大量额外的内存来缓存写操作,导致内存爆涨。

命令行方式关闭:

1
2
3
4
5
redis-03:6379> config get appendonly
1) "appendonly"
2) "yes"
redis-03:6379> config set appendonly no
OK

总结

  1. 绑定本机ip部署redis防止远程连接
  2. aof 与 rdb 比较
  3. 代码层级:去除代码里的scan操作,给每个key加过期时间
  4. 存储结构用hash
  5. maxmemory-policy allkeys-lru:从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放
  6. 关闭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 根据实际调整大小

引用

redis.conf配置详细解析

redis官网v3.0配置
redis官网配置

坚持原创技术分享,您的支持将鼓励我继续创作!