论坛首页 Java企业应用论坛

Redis 常见的性能问题和解决方法

浏览 14936 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-07-03   最后修改:2012-07-04

 

1.Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。

 

2.Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。

 

3.Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

下面是我的一个实际项目的情况,大概情况是这样的:一个Master,4个Slave,没有Sharding机制,仅是读写分离,Master负责写入操作和AOF日志备份,AOF文件大概5G,Slave负责读操作,当Master调用BGREWRITEAOF时,Master和Slave负载会突然陡增,Master的写入请求基本上都不响应了,持续了大概5分钟,Slave的读请求过也半无法及时响应,Master和Slave的服务器负载图如下:

 

Master Server load:

 

Slave server load: 

 

上面的情况本来不会也不应该发生的,是因为以前Master的这个机器是Slave,在上面有一个shell定时任务在每天的上午10点调用BGREWRITEAOF重写AOF文件,后来由于Master机器down了,就把备份的这个Slave切成Master了,但是这个定时任务忘记删除了,就导致了上面悲剧情况的发生,原因还是找了几天才找到的。

 

no-appendfsync-on-rewrite的配置设为yes可以缓解这个问题,设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入。最好是不开启Master的AOF备份功能。

 

4.Redis主从复制的性能问题,第一次Slave向Master同步的实现是:Slave向Master发出同步请求,Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的命令转发给Slave,初次同步完成。第二次以及以后的同步实现是:Master将变量的快照直接实时依次发送给各个Slave。不管什么原因导致Slave和Master断开重连都会重复以上过程。Redis的主从复制是建立在内存快照的持久化基础上,只要有Slave就一定会有内存快照发生。虽然Redis宣称主从复制无阻塞,但由于磁盘io的限制,如果Master快照文件比较大,那么dump会耗费比较长的时间,这个过程中Master可能无法响应请求,也就是说服务会中断,对于关键服务,这个后果也是很可怕的。

 

以上1.2.3.4根本问题的原因都离不开系统io瓶颈问题,也就是硬盘读写速度不够快,主进程 fsync()/write() 操作被阻塞。

 

5.单点故障问题,由于目前Redis的主从复制还不够成熟,所以存在明显的单点故障问题,这个目前只能自己做方案解决,如:主动复制,Proxy实现Slave对Master的替换等,这个也是Redis作者目前比较优先的任务之一,作者的解决方案思路简单优雅,详情可见 Redis Sentinel design draft http://redis.io/topics/sentinel-spec

 

总结:

1.Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。

2.如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

3.为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。

4.尽量避免在压力较大的主库上增加从库

5.为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<--Slave1<--Slave2<--Slave3.......,这样的结构也方便解决单点故障问题,实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变。

 

今天暂时写这么多吧,以后再补充。

 

   发表时间:2012-07-04  
给力,长见识了。
0 请登录后投票
   发表时间:2012-07-04  
不用redis做数据库的话,只做缓存用的话,master-slave就没必要了吧,不如节省点空间,多起几个服务,把数据切分一下。
本身故障率就不大
0 请登录后投票
   发表时间:2012-07-04  

 

 

实践总结:

1.Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。

master要是重启怎么办?把数据从slave拷贝过来?

2.如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

3.为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。

4.为了充分利用CPU,可以在同一个服务器上启多个Redis实例,实例个数最好和CPU个数相同。

master在做数据备份的时候好像会启动另外一个cpu,也就是说这时会有两个cpu在处理了。

5.为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<--Slave1<--Slave2<--Slave3.......,这样做也方便实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变。

  个人觉得这个得看场景。一个节点挂掉,后面的都挂了。。。。

今天暂时写这么多吧,要睡觉了,以后再补充。

 

0 请登录后投票
   发表时间:2012-07-04  
wangqj 写道
不用redis做数据库的话,只做缓存用的话,master-slave就没必要了吧,不如节省点空间,多起几个服务,把数据切分一下。
本身故障率就不大


Sharding并不一定提高性能,如果数据量不大没有必要做Sharding,如果只做缓存的化,可以不用持久化数据。
0 请登录后投票
   发表时间:2012-07-04  
islandhn 写道

 

5.为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<--Slave1<--Slave2<--Slave3.......,这样做也方便实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变。

  个人觉得这个得看场景。一个节点挂掉,后面的都挂了。。。。

 

 

恩,这个主要是解决Master挂了的问题,Slave挂了很容易可以恢复,Master挂了如果数据量大恢复的时间就比较长。

0 请登录后投票
   发表时间:2012-07-06  
温柔一刀 写道
islandhn 写道

 

5.为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<--Slave1<--Slave2<--Slave3.......,这样做也方便实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变。

  个人觉得这个得看场景。一个节点挂掉,后面的都挂了。。。。

 

 

恩,这个主要是解决Master挂了的问题,Slave挂了很容易可以恢复,Master挂了如果数据量大恢复的时间就比较长。

我觉得应该图状结构更好,可以有多个slave,有的专门用来做只读操作,有的用来做持久化

0 请登录后投票
   发表时间:2012-07-06  
温柔一刀 写道
wangqj 写道
不用redis做数据库的话,只做缓存用的话,master-slave就没必要了吧,不如节省点空间,多起几个服务,把数据切分一下。
本身故障率就不大


Sharding并不一定提高性能,如果数据量不大没有必要做Sharding,如果只做缓存的化,可以不用持久化数据。



做缓存,多服务,Sharding也是必须的,不过Sharding所带来的一致性,容错等处理要做好。
0 请登录后投票
   发表时间:2012-07-07  
我想问楼主,如果要写内存快照的时候,你说会阻塞主线程的工作,这个时候客户端是不是会出现连接超时的异常呢??还有就是为什么会阻塞主线程呢,我看好像多出了一个线程单独处理呀,难道和java虚拟机的垃圾回收机制一样,需要那个时候数据是不可以动的???
0 请登录后投票
   发表时间:2012-07-07   最后修改:2012-07-07
finallygo 写道
我想问楼主,如果要写内存快照的时候,你说会阻塞主线程的工作,这个时候客户端是不是会出现连接超时的异常呢??还有就是为什么会阻塞主线程呢,我看好像多出了一个线程单独处理呀,难道和java虚拟机的垃圾回收机制一样,需要那个时候数据是不可以动的???

客户端会出现拿不到资源异常,不会阻塞Redis主线程,是磁盘io阻塞导致主线程无法处理写入请求
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics