zoukankan      html  css  js  c++  java
  • nginx 的磁盘IO优化

    磁盘IO优化的几个方面

    优化读取

    Sendfile 零拷贝、内存盘、SSD盘
    减少写入
    AIO
    增大error_log级别的日志
    关闭access_log 
    压缩access_log
    是否启用proxy buffering
    syslog替代本地IO
    线程池 thread pool
     
     

    适用于大文件的直接IO

       当磁盘文件超过size大小之后,使用directIO功能,避免Buffered IO模式下磁盘页缓存中的拷贝消耗

    Syntax: directio size | off;  #配置文件最大后表示大于大小
    Default: directio off; 
    Context: http, server, location
    
    
    
    
    
    
    
    Syntax: directio_alignment size;  读取文件缓冲区
    Default: directio_alignment 512; 
    Context: http, server, location
    

      异步IO

    普通IO:当程序发起一个系统调用去读一个文件时,程序这时会被阻塞住等待读取到文件再次执行,这是先到内核空间发起一个read请求,开始去读磁盘数据,读到高速缓存(内存)里,这时唤醒进程继续执行;写的时候是直接写到高速缓存(内存)里,之后自动同步

    异步IO: 当用户发起一个读操作时,程序不会被阻塞在哪里,可以去处理其他请求

    nginx指令启用异步IO

    Syntax: aio on | off | threads[=pool];  # 最后这个是线程池;调应的
    Default: aio off; 
    Context: http, server, location
    
    
    
    Syntax: aio_write on | off;  #设置写时启用AIO;默认是关闭的;
    Default: aio_write off; 
    Context: http, server, location
    

      异步IO线程池的定义,默认未编译--with-threads

    线程池:worker进程在处理时,有一些请求可能会发生一些阻塞,这是我们就不能接受worker进程的阻塞,而是在worker进程里定义一些线程池,由线程池里的线程处理这些可能发生系统阻塞的工作;为什么会出现这样的场景呢:因为nginx在做静态资源服务器的时候,处理了太多的文件,因为处理文件太多,会导致文件缓存的inode失效,因为内存不够大而导致的,一些操作大部分情况下会命中内存中缓存的。

    定义线程池

    Syntax: thread_pool name threads=number [max_queue=number];  #在静态服务的情况下使用线程池
    Default: thread_pool default threads=32 max_queue=65536; # max_queue是定义队列最大长度;threads=32 线程池里线程个数
    Context: main
    

      异步IO中缓存

    Syntax: output_buffers number size;
    Default: output_buffers 2 32k; 
    Context: http, server, location
    

      empty_gif 模块默认是编译进nginx中的

     ngx_http_empty_gif_module

     功能:从前端用户做用户行为分析时,由于跨域等请求,前端打点的上报数据是get请求,且考虑到浏览器接卸DOM树的性能消耗,所以请求透明图片消耗最小,而1*1的gift图片体积最小(仅43字节),故通常请求gif图片,并在请求中把用户行为信息上报服务器;Nginx可以在access日志中获取到请求参数,进而统计用户行为,但若在磁盘中读取1x1的文件有磁盘IO消耗,empty_gif模块将图片放在内存中,加速了处理速度

    Syntax: empty_gif;
    Default: —
    Context: location
    

      记录日志时启用压缩功能

    Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time][if=condition]];  #[buffer=缓存大小][gzip[=压缩比例可选1-9,数字越大压缩的越小,话的时间越多]] [flush=最长刷新时间]
    Default: access_log logs/access.log combined; 
    Context: http, server, location, if in location, limit_except
    

      error.log 日志内容输出到内存中

    场景:开发环境下定位,若需要打开debug级别日志,但大量的debug日志引发性能问题不能容忍,可以将日志输出到内存中

    配置语法

    error_log memory:32m debug;

       查看中日志方法

    gdb-p[worker 进程 ID ] -ex "source nginx.gdb" --batch nginx.gdb脚本内容

    set $log = ngx_cycle->log 
    while $log->writer != ngx_log_memory_writer 
    set $log = $log->next 
    end 
    set $buf = (ngx_log_memory_buf_t *) $log->wdata 
    dump binary memory debug_log.txt $buf->start $buf->end
    

      syslog协议

    sendfile 零拷贝技术

     应用程序普通调用:应用程序先发起一个读请求,从磁盘读到内核再从内核读到应用程序缓存里,然后程序再把缓存里的数据写到内核的socket缓冲再进行发送

    sendfile技术:程序程序只发起一个sendfile 的调用,告诉内核我要把磁盘数据从哪里开始读读取多少字节,然后把读到的数据发送到那个socket套接字上

    sendfile 、直接IO、异步IO同时启用时

    直接IO会禁用sendfile技术

    location /video/ { 
    sendfile on; 
    aio on; 
    directio 8m; 
    }
      当文件大小超过8M时,启用AIO与directio
    

      

    gzip_static 模块: ngx_http_gzip_static_module,通过--with-http_gzip_static_module启用该模块
    功能:检测到同名.gz文件时,response 中通过gzip相关header返回.gz文件的内容
     
    Syntax: gzip_static on | off | always;    #不管客户端是否支持压缩我都把压缩文件发给客户端always ;on是会判断客户端是否会支持压缩
    Default: gzip_static off; Context: http, server, location

    gunzip : 模块ngx_http_gunzip_module,通过--with-http_gunzip_module启用该模块

    功能:当客户端不支持gzip压缩时,且磁盘上仅有压缩文件,则实时解压缩并将其发送给客户端

    Syntax: gunzip on | off;
    Default: gunzip off; 
    Context: http, server, location
    
    
    
    
    Syntax: gunzip_buffers number size;  #打开内存缓存区
    Default: gunzip_buffers 32 4k|16 8k; 
    Context: http, server, location
    

      

    tcmalloc 内存分配器
     更快的内存分配器:并发能力强于glibc;并发线程数越多,性能越好 ;减少内存碎片;擅长管理小块内存。这是谷歌提供的第三方模块介绍:http://goog-perftools.sourceforge.net/doc/tcmalloc.html
    地址:https://github.com/gperftools/gperftools/release
    安装此系统模块
     wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.7/gperftools-2.7.tar.gz
    [root@python ]# tar xf gperftools-2.7.tar.gz
    [root@python ]# cd gperftools-2.7/
    [root@python gperftools-2.7]# ./configure 
    [root@python gperftools-2.7]# make && make install
    查看生成库文件路径/usr/local/lib/
    ll /usr/local/lib/libtcmalloc.so
    
    
    
    草都可以从石头缝隙中长出来更可况你呢
  • 相关阅读:
    文件较验及Google Gson的使用
    SQLite数据库操作
    错误收集
    【记录】Linux安装JDK详细步骤
    【原创】RPM安装软件时解决依赖性问题(自动解决依赖型)
    【原创】rman备份出现ORA-19625
    【原创】rman 全库备份脚本
    【原创】TimeSten安装与配置
    【原创】查询占CPU高的oracle进程
    【参考】查找Oracle最高的几个等待事件以及锁的信息
  • 原文地址:https://www.cnblogs.com/rdchenxi/p/11224326.html
Copyright © 2011-2022 走看看