邮箱:oxwangfeng@qq.com
分类: 服务器与存储
2016-03-07 15:49:16
情景:
url1:curl -i -H "host:"
url2:curl -i -H "host:" -H "range:bytes=54611900-54611905"
url1是非range请求,请求的是整个vidio文件;而url2是range请求,请求的是vidio文件非常靠后的一个片段文件。
当url1 发起http请求以后,马上发起url2 http请求;由于url1 http请求超时很长,url2 http就会一直等待,直到url1的缓存(url1 buffer中包含了url2所请求的内容)满足要求,url2 才返回客户端;这可能导致url2的wait io等待时间特别长;
程序逻辑:
在CacheVC::openReadMain中,
1.进入CacheVC::openReadMain函数
2.在wait io等待中,seek_to=0,所以不处理里面的逻辑;(p672)
3.重点是bytes的值; bytes = doc->len - doc_pos;而doc->len 和doc_pos都等于一个fragment的大小(CONFIG proxy.config.cache.target_fragment_size INT 1048576)
这种情况下,bytes会一直等于0,所以会一直跳转到Lread;(p751)
Bytes:要读取的字节数;bytes=0表示这个fragment没有要读取的数据;
4.进入Lread:
dir_probe:查找索引;在这儿,查找索引失败,只有最后一次查找成功;
writer_done();表示已经有writes了,返回false,否则返回true;在这儿一直false;
在805行,设置句柄函数CacheVC::openReadMain();
然后调用VC_SCHED_WRITER_RETRY,这个函数是非常重要的函数,表示一直尝试执行这个调度(状态机里面的函数,这儿指CacheVC::openReadMain),直到有副本到达;
5. 最后终于在P783,查找索引成功,进入生产者消费者模式;
注:
1.每个fragment都有一个key,而对于这样的大文件而言,包含了很多key;对于url2(range)的dir_probe,key也是变化的;根据测试,得出这样的结论,只有当range的数据在writer(非range)的数据到来之前,key一直是由writer(非range)所控制的(因为我发现只有url1 http读完一个fragment,才会调用next_CacheKey,这时才会影响到url2的索引查找的key的变化(如果url2的key不变,会一直进行索引查找));
2.在p783行,当非range请求处理完一个fragment后,查找索引,dir_probe,成功后,调用CacheVC::openReadReadDone,里面有设置next_CacheKey的部分;
3.如果url1的buf中已经包含了url2所请求的数据,就直接是调用cache::open_read,然后openReadFromWriter,然后选择openReadStartEarliest;这个流程和第一个流程不一样;
4.上面都是在read while write机制下进行的;
流程图: