zoukankan      html  css  js  c++  java
  • 017.redis 在实践中的一些常见问题以及优化思路(包含 linux 内核参数优化)

    fork 耗时导致高并发请求延时

    RDB 和 AOF 的时候会存在 RDB 快照生成、AOF rewrite,耗费磁盘 IO 的过程

    主进程 fork 子进程的时候,子进程是需要拷贝父进程的空间内存页表的,也是会耗费一定的时间的

    一般来说,如果父进程内存有 1 个 G 的数据,那么 fork 可能会耗费在 20ms 左右,如果是 10G~30G,那么就会耗费 20 * 10,甚至 20 * 30,也就是几百毫秒的时间

    info stats 中的 latest_fork_usec,可以看到最近一次 fork 的时长

    redis 单机 QPS 一般在几万,fork 可能一下子就会拖慢几万条操作的请求时长,从几毫秒变成 1 秒

    优化思路:fork 耗时跟 redis 主进程的内存有关系,一般控制 redis 的内存在 10GB 以内;否则 slave -> master 在全量复制等时候就可能会出现一些问题

    AOF 的阻塞问题

    redis 将数据写入 AOF 缓冲区,单独开一个线程做 fsync 操作,每秒一次

    但是 redis 主线程会检查两次 fsync 的时间,如果距离上次 fsync 时间超过了 2 秒,那么写请求就会阻塞

    everysec,最多丢失 2 秒的数据

    一旦 fsync 超过 2 秒的延时,整个 redis 就被拖慢

    优化思路:优化硬盘写入速度,建议采用 SSD,不要用普通的机械硬盘,SSD 大幅度提升磁盘读写的速度

    主从复制延迟问题

    主从复制可能会超时严重,这个时候需要良好的监控和报警机制

    在 info replication 中,可以看到 master 和 slave 复制的 offset,做一个差值就可以看到对应的延迟量,如果延迟过多,那么就进行报警(可以写一个 shell 脚本去监控)

    主从复制风暴问题

    如果一下子让多个 slave 从 master 去执行全量复制,一份大的 rdb 同时发送到多个 slave,会导致网络带宽被严重占用

    如果一个 master 真的要挂载多个 slave,那尽量用树状结构,不要用星型结构

    树,意思就是说,让一个节点下面的 slave 不要太多,可以通过 replication 的方式去配置

    如果是在 redis cluster 中应该不会存在这种问题

    vm.overcommit_memory

    该信息是在 redis 启动的时候一些警告信息,这些警告信息可以通过调整 linux 内核配置达到性能的优化

    [root@eshop-cache03 ~]# cat /var/log/redis/7008.log
    1418:M 24 Mar 13:10:59.513 * Increased maximum number of open files to 10032 (it was originally set to 1024).
    1418:M 24 Mar 13:10:59.513 # Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now.
    1418:M 24 Mar 13:10:59.513 * No cluster configuration found, I'm 728e473d6e5e36ddb051c600c7708f23733c46f7
                    _._                                                  
               _.-``__ ''-._                                             
          _.-``    `.  `_.  ''-._           Redis 3.2.8 (00000000/0) 32 bit
      .-`` .-```.  ```/    _.,_ ''-._                                   
     (    '      ,       .-`  | `,    )     Running in cluster mode
     |`-._`-...-` __...-.``-._|'` _.-'|     Port: 7008
     |    `-._   `._    /     _.-'    |     PID: 1418
      `-._    `-._  `-./  _.-'    _.-'                                   
     |`-._`-._    `-.__.-'    _.-'_.-'|                                  
     |    `-._`-._        _.-'_.-'    |           http://redis.io        
      `-._    `-._`-.__.-'_.-'    _.-'                                   
     |`-._`-._    `-.__.-'    _.-'_.-'|                                  
     |    `-._`-._        _.-'_.-'    |                                  
      `-._    `-._`-.__.-'_.-'    _.-'                                   
          `-._    `-.__.-'    _.-'                                       
              `-._        _.-'                                           
                  `-.__.-'                                               
    
    1418:M 24 Mar 13:10:59.626 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    1418:M 24 Mar 13:10:59.626 # Server started, Redis version 3.2.8
    1418:M 24 Mar 13:10:59.626 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
    
    
    • 0: 检查有没有足够内存,没有的话申请内存失败
    • 1: 允许使用内存直到用完为止
    • 2: 内存地址空间不能超过 swap + 50%

    如果是 0 的话,可能导致类似 fork 等操作执行失败,申请不到足够的内存空间

    下面的命令在日志里面就已经提示出来了

    cat /proc/sys/vm/overcommit_memory
    echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
    sysctl vm.overcommit_memory=1
    

    swapiness

    # 查看 linux 内核版本
    cat /proc/version
    

    如果 linux 内核版本 ❤️.5,那么 swapiness 设置为0,这样系统宁愿 swap也不会 oom killer(杀掉进程)

    如果 linux 内核版本 >=3.5,那么 swapiness 设置为 1,这样系统宁愿 swap 也不会 oom killer

    保证 redis 不会被杀掉

    echo 0 > /proc/sys/vm/swappiness
    echo vm.swapiness=0 >> /etc/sysctl.conf
    

    最大打开文件句柄

    Increased maximum number of open files to 10032 (it was originally set to 1024).
    
    # 如果该命令不可用,可以去百度搜索不同的版本命令
    ulimit -n 10032 10032
    

    自己去上网搜一下,不同的操作系统,版本,设置的方式都不太一样

    tcp backlog

    WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    
    cat /proc/sys/net/core/somaxconn
    echo 511 > /proc/sys/net/core/somaxconn
    

    参考

    -中华石杉:亿级流量电商详情页系统实战(第二版):缓存架构+高可用服务架构+微服务架构
    -Mrcode笔记本

  • 相关阅读:
    NYOJ-开灯问题
    cocos2dx 3.0 飞机大战
    Java 实现享元(Flyweight)模式
    MongoDB 操作手冊CRUD查询指针
    均值滤波
    cxf调用c#的webservice
    SharePoint 2013 术语和术语集介绍
    Unity3d 网络编程(二)(Unity3d内建网络各项參数介绍)
    linux服务器在运行210天左右宕机
    好的用户界面-界面设计的一些技巧
  • 原文地址:https://www.cnblogs.com/codecheng99/p/12383668.html
Copyright © 2011-2022 走看看