nginx针对大文件缓存改造设计一(分块缓存及索引设计)

目录

1.nginx原生web缓存处理

2.nginx原生web缓存缺陷

3.nginx缓存改造思路


nginx原生web缓存处理

        nginx缓存索引及配置信息存在于

        struct  ngx_http_file_cache_s {

            ngx_http_file_cache_sh_t   *sh;   //共享内存(主要保存缓存索引信息)

            ngx_slab_pool_t                *shpool;  //共享内存的slab内存分配器

            ngx_path_t                        *path;     //缓存所配置的路径

            ngx_path_t                       *temp_path;  //缓存临时文件路径 可配置

            off_t                                  max_size; //配置的最大缓存大小

            size_t                                bsize;//缓存传输块大小

            time_t                               inactive; //conf配置的缓存有效期 缓存超过有效期时间 会被cache manager主动清理

            time_t                               fail_time;//主要在缓存共享内存中申请内存失败 失败的时间

            ngx_uint_t                        files; //缓存加载进程loader 中使用的文件加载数量

            ngx_uint_t                        loader_files; //加载缓存文件数量阈值

            ngx_msec_t                       last; //cache的最近时间

            ngx_msec_t                       loader_sleep;  //达到loader进程休眠的条件的休眠时间间隔

            ngx_msec_t                       loader_threshold; //loader休眠的时间阈值(由当前时间和last时间差获得)

        }

        nginx缓存索引管理

       typedef struct {
            ngx_rbtree_t                         rbtree;           //缓存索引红黑树
            ngx_rbtree_node_t               sentinel;        //红黑树哨兵节点

            ngx_queue_t                         queue;         //LRU FIFO队列 用于缓存淘汰算法

            ngx_atomic_t                        cold;

            ngx_atomic_t                        loading;     //缓存是否处于加载状态(防止重复出现加载)

            off_t                                      size;        //缓存所占磁盘大小

            ngx_uint_t                             count;    //缓存数量

            ngx_uint_t                             watermark;   //缓存水位值(共享内存不足 触发水位值更新 同时触发缓存强制清理 以获取内存空间  默认被设置的值为缓存数量的7/8)

        } ngx_http_file_cache_sh_t;

        nginx缓存与代理之间的关系

        nginx针对大文件缓存改造设计一(分块缓存及索引设计)

上述的流程是nginx web代理及缓存处理的基本流程


nginx作为缓存服务器存在的缺陷

1.nginx缓存以key值生成对应的缓存文件存在于磁盘中  缓存会产生大量的文件,这样在写入缓存和读取缓存的过程中,会产生大量的随机IO 同时在大量的请求时 会造成比较明显的IO负载同时可能会产生大量的文件描述符(系统有文件描述符数量限制)

2.在不使用nginx slice模块功能的前提下 请求端需要等待nginx下载数据完成才能获取数据 大文件请求尤为明显

3.启用nginx slice模块 可以避免2的问题 但是会产生大量小文件及随机读写 而且缓存难以管理


nginx缓存目前改造思路

   考虑到目前的业务以流媒体点播业务为主  也就是以大文件访问为主  基本的改造思路方向是通过slice作为分块请求的依据,将分块获取的数据 (一个url对应于一个缓存文件)  按块的方式保存在缓存文件中 并且建立对于缓存中分块数据的索引,这样能降低对于IO的负担及减少文件描述符的数量  同时缓存命中时的数据获取的效率较高

位于缓存文件中的数据样式如下

--mgic魔数(用以区分文件类型)---
--文件概要元信息-- --文件分块元信息---
--缓存头信息 (用于校验)--
--缓存key--
--http头部信息--
--分块数据---
--分块数据---
--分块数据--

分块数据生成的顺序由请求端行为决定 不会按照源文件的顺序生成