zoukankan      html  css  js  c++  java
  • Nginx Open File Cache

    Nginx 的 open_file_cache 相关配置可以缓存静态文件的元信息,在这些静态文件被频繁访问时可以显着提升性能。

    被缓存的文件元信息包括:

    • fd,文件被打开一次后,fd保留使用
    • size
    • path
    • last modified time

    这里有个配置示例:

    open_file_cache max=64 inactive=30d;
    open_file_cache_min_uses 8;
    open_file_cache_valid 3m;
    

    max=64 表示设置缓存文件的最大数目为 64, 超过此数字后 Nginx 将按照 LRU 原则丢弃冷数据。

    inactive=30d 与 open_file_cache_min_uses 8 表示如果在 30 天内某文件被访问的次数低于 8 次,那就将它从缓存中删除。

    open_file_cache_valid 3m 表示每 3 分钟检查一次缓存中的文件元信息是否是最新的,如果不是则更新之。

    2 为什么只缓存文件元信息而不缓存文件内容?

    这个问题的关键是 sendfile(2).

    Nginx 在 serve 静态文件的时候用的是 sendfile(2), 当然前提是你配置了 sendfile on, sendfile(2) 直接在 kernel space 内传输数据,对比使用 read(2)/write(2) 省去了两次 kernel space 与 user space 之间的数据拷贝。而同时这些被频繁读取的静态文件的内容会被 OS 缓存到 kernel space。在这样的机制下,我们缓存中有文件的 fd 和 size,直接调用 sendfile(2) 就可以了。

    如果要 Nginx 连内容一起缓存,那就需要每次文件变化都要用 read(2) 将数据从 kernel space 复制到 user space,然后放在 user space,每次应答请求的时候再从 user space 复制到 kernel space 然后写入 socket。比起前面的方式,这样的方式毫无优点。

    3 在文件缓存更新周期内文件发生变化了会发生什么?

    上面提到的配置中,30 天无访问丢弃,每 3 分钟做一次信息有效性监测,我们暂且把 3 分钟叫做缓存更新周期。那在这 3 分钟之内文件发生变化了会怎样呢?

    3.1 文件被删除

    由于 nginx 还持有原文件的 fd,所以你删除此文件后,文件并不会真正消失, client 还是能通过原路径访问此文件。即便你删除后又新建了一个同名文件,在当前缓存更新周期内能访问到的还是原文件的内容。

    3.2 文件内容被修改

    文件内容被修改可以分为两种情况:

    文件大小不变或增大
    由于 nginx 缓存了文件的 size 并且使用 这个缓存中 size 调用 sendfile(2),所以此种情况的后果是:
    • 从文件开始到原 size 字节中的变化可以被 client 看到。
    • 原 size 之后的内容不会被 sendfile(2) 发送,因此 client 看不到此部份内容。
    文件大小减小
    此种情况下,由于同样原因,nginx 在 HTTP Header 中告诉 client 文件大小还是原来的尺寸,而 sendfile(2) 只能发送真正的文件数据,长度小于 HTTP Header 中设置的大小,所以 client 会等待到自己超时或者 Nginx 在 epoll_wait 超时后关闭连接。

    4 如何设置?

    • 如果你的静态文件内容变化频繁并且对时效性要求较高,一般应该把 open_file_cache_valid 设置的小一些,以便及时检测和更新。
    • 如果变化相当不频繁的话,那就可以设置大一点,在变化后用 reload nginx 的方式来强制更新缓存。
    • 对静态文件访问的 error 和 access log 不关心的话,可以关闭已提升效率。
  • 相关阅读:
    【转】【C++】【MFC】各种数据类型大小
    【转】【C++】【MFC】关于RADIO BUTTON的使用方法
    【C++】【MFC】创建新的线程函数
    【C++】【MFC】定义全局变量的方法
    【Quartus错误】Internal Error: Sub-system: AMERGE
    【转/TCP协议编程】 基于TCP的Socket 编程
    SQL递归查询(with as)
    SQL查询月、天、周、年(MySql的实例对比)
    sql 基础语句
    经典SQL语句大全
  • 原文地址:https://www.cnblogs.com/cmfwm/p/7659179.html
Copyright © 2011-2022 走看看