邮箱:oxwangfeng@qq.com
分类: 架构设计与优化
2016-08-13 23:34:53
nginx 1.9.8及其以上版本才支持slice。当在编译时添加了--with-http_slice_module,那么slice模块的相关配置就会启用。
Nginx配置样例如下:
比如nginx设置的slice为2M,那么每个分片是2M。
nginx一开始并不知道要发几个range子请求,它会根据配置的slice 2m;,先发起一个2m的range请求,这个请求返回的Content-range头会给出文件总长度,这样nginx就知道一共需要发几个range请求来取完所有内容。
假如原始range请求的访问是0.8M-5.3M,即,这个range请求会在nginx内部被转变成r1(0-2M)、r2(2-4M)、r3(4-6M)三子请求,顺序分别发送到ats上;
Nginx内部实现方法是:
1.首先发送range 为r1(0-2M)的子请求,则在响应头中包含Content-Range: bytes 0- 2097152/(content_length),content_length为源站整个文档的长度。Nginx根据content_length作出相应处理。
如果content_length<4M,则只需要继续发送r2即可;
如果content_length>5.3,则继续发送r2,r3三个子请求,不过是顺序发送;
Nginx收到这三个子请求后,再进行合并处理,将0.8M-5.3M内容发送到client;
优势
1. 切片存储的好处:每个子请求收到的数据都会形成一个独立文件,这个文件就是通过proxy_cache_key $uri$is_args$args$slice_range;来定位的,也就是说文件跟key有绑定关系。这种将片缓存为独立文件的方式,还获得了一个额外的优势。就是如果某个片取源连接断掉,那么前面已经缓存的片依然有效。试想一个大文件(在未开启分片的功能下)在最后还有几个字节就收完的时候,连接突然断了,那么前面的内容都会作废,努力全都付诸东流了。这是基于完整文件的缓存模式下,一个很讨厌的问题。
缺点
1. 当文件很大或者 slice 很小的时候,会按照 slice 大小分成很多个子请求,而这些个子请求并不会马上释放自己的资源,可能会导致文件描述符耗尽等情况。
问题
1. 各个slice子请求是全部发送到一个后端,还是负载均衡的发送到所有的后端呢?如何设置?
先说说nginx的负载均衡策略:
1.1. hash key [consistent]; 按照key的value进行一致性hash;比如按照client发过来的$uri$args进行一致性hash;
很多环境都是如下配置的:
1.2 ip_hash;按照client的ip进行hash;
1.3 默认是rr,即轮训策略;
如果让range自请求发送到不同的ats服务器上,则可以设置hash规则为:
hash $uri$is_args$args$slice_range consistent;