zoukankan      html  css  js  c++  java
  • Redis持久化之大数据服务暂停问题

    Redis持久化是有两种方式:RDB和AOF

    对这两种方式的官方文档的翻译请看:

    http://latteye.com/2011/11/redis-persistence.html

    RDB就是快照存储,比如“每1个小时对redis进行快照存储”。那么,

    save这个参数就应该设置
    save 3600 1000   //前一次快照3600秒后,当有超过1000个key被改动的时候就进行一次快照更新
    RDB快照产生dump.rdb文件,当每到快照时间,更新文件。

    AOF是存储所有的写操作,分两个步骤:
    fsync和rewrite
    fsync是把内存中的写操作写入aof文件中
    rewrite是将写操作合并,比如set aa 1; set aa 2; 两个操作应该写成一个操作set aa 2;

    如果数据量小的话,啥问题也没有

    现在假设服务器是20G内存,而且服务器上仅仅只有跑redis一个占内存的进程,就是说redis最多可以跑20G物理内存
    现在压入13G的redis数据(可以使用phpredis循环压入,但是要注意设置php的运行内存大小,最好使用pipeline的方式,否则php出现内存不足的error)

    尝试1,我们只使用RDB的方式
    当进行快照的时候(测试时候可以把快照间隔时间定成30秒或更短)
    top查看进程

    26376 test 16 0 13.5g 13g 7488 D 0.0 42.8 6:48.24 redis-server

    32459 test 18 0 13.5g 13g 7200 D 1.3 42.8 0:23.22 redis-server

    看到有两个进程,同时在运行,并且占用同样大小的内存数,和起来竟然占用26G之大~!

    现在redis服务端上两个进程都运行,看看客户端:
    测试redis-cli set操作:

    redis 10.1.0.108:6379> set test2 22

    耗时(40.47s)近1分钟

    就是说在大数据量的时候,做RDB,redis服务会暂停近1分钟!这个就是redis持久化的时候的服务暂停现象。

    好吧,为了保证数据容错性,我们的快照一般是要频繁快照的,所以暂停一分钟是不可容忍的。

    现在尝试使用AOF+RDB

    1 将RDB的快照时间设置为1天(由于加上了AOF,所以这个时间是合理的)。

    2 1次性压入1000w左右的string数据到redis中(大概有5G数据量)

    3 查看性能表现:

    第一个步骤fsync:

    redis会从内存中逐渐生成appendonly.aof  在这个过程我试了下set和get操作都是没有暂停现象的(很好~!)

    好了,现在appendonly.aof生成了,有5.7个G

    -rw-r--r-- 1 root root 4186238374 Mar 6 15:50 appendonly.aof

    第二个步骤:调用BGREWRITEAOF重写aof文件

    这个时候top查看:

    看到也是两个redis-server服务开着。说明rewrite的时候是fork一个子进程在rewrite的,主进程是进行着redis服务的。

    这个时候redis-cli调用检查

    get操作:无延时

    set操作:出现了延迟现象 !!

      

    这个说明AOF在重写的时候会占用服务器的大量CPU和内存资源,导致服务出现短暂暂停现象!
    但是为什么get操作没有出现延迟现象呢?
    参考官网文章,看到一个配置项:
    no-appendfsync-on-rewrite

    这个配置项是设置在rewrite的时候是否对新的写操作进行fsync。no表示进行fsync,yes表示不进行

    默认是设置为no

    现在将这个配置项设置为yes(我们对于rewrite的aof文件硬盘大小没有很大要求)

    重新进行测试:

    对同样的5.7G的AOF操作进行一次BGREWRITEAOF。

    get操作:无延迟

    set操作:无延迟

    很好!说明在rewrite的时候如果不进行fsync操作,主进程和子进程是互不干扰的。

    那么如果rewrite的时候对新的写操作不进行fsync,那么新的aof文件里面是否会丢失这个写操作呢?

    答案是不会的,redis会将新的写操作放在内存中,等待rewrite操作完成的时候,将新操作直接挂在aof中。

    好了,至此,这个问题应该已经可以过去了。

    推荐几个文章:

    对数据持久化的一些想法:http://www.yiihsia.com/2011/04/%E5%AF%B9redis%E6%95%B0%E6%8D%AE%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/

    (这个文章提供了一个非常好的方法,当数据量大,内存足够的情况,一台机子上尽量多开几个redis,甚至可以考虑有几个cpu就开几个redis,这样,每个redis的内存量不会太大,就不会有大数据量服务暂停问题,这个也是考虑到了redis是单线程的,能尽量利用CPU)

    redis的内存陷阱:http://www.iteye.com/topic/808293

    (这个文章很好解释了问什么大数据量的时候会出现服务暂停)

    Copy on write does not seem to work.: http://code.google.com/p/redis/issues/detail?id=150

    ----------------------

    作者:yjf512(轩脉刃)

    出处:http://www.cnblogs.com/yjf512/

    本文版权归yjf512和cnBlog共有,欢迎转载,但未经作者同意必须保留此段声明

    实时了解作者更多技术文章,技术心得,请关注微信公众号“轩脉刃的刀光剑影”

    本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

  • 相关阅读:
    my first android test
    VVVVVVVVVV
    my first android test
    my first android test
    my first android test
    ini文件
    ZZZZ
    Standard Exception Classes in Python 1.5
    Python Module of the Week Python Module of the Week
    my first android test
  • 原文地址:https://www.cnblogs.com/yjf512/p/2382733.html
Copyright © 2011-2022 走看看