Linux
分类: LINUX
2015-07-07 15:16:34
Disk layout
在web应用中,ts根据用户请求的url,计算出这个object对应的key值,该值是一个由2个64位整数构成的数组,也就是4个32位的整数。ts通过对第一个32位整数做hash映射查找到object对应的Dir所在的segment,再通过第二个32位的整数做hash找到对应的bucket,最后在这个bucket上找到第一个没有使用的Dir,由此就得到了该object对应的索引。如果计算object的key值的算法足够高效,且每一级映射也足够高效,则正如理想模型所示,每个bucket中object数目为4个,在桶中查找一个未被使用的索引速度就会很快。
索引的格式
Directory在物理上按顺序包含三部分内容,分别是header,索引区,footer。header与footer对应的内存数据结构为VolHeaderFooter,它包含了很多维护索引区以及读写操作的元信息。这里,最重要的数据结构就是每一个segment对应的freelist的首节点元素构成的数组,由此就把整个索引区串了起来。
每个索引对应内存数据结构为Dir,是一个由5个16位的整数构成的数组,共10个字节。这些字节维护了一个object保存在磁盘上的所有元信息。
iocore/cache/P_CacheDir.h中提供了很多宏用于操作Dir。比如,宏dir_set_offset用来将一个object在磁盘上的位置信息保存下来,它使用Dir的第一个,第五个的所有16位,以及第二个元素的低八位,共40位,存储一个object在disk上的位置。
object的存储格式
数据结构Doc对应的是一个object在磁盘上的格式。
ts以一个fragment为单位,如果一个http响应,也就是一个object的大小小于一个fragment,则视它为一个小文件,否则,ts认为它是一个大文件。这个fragment的大小是可配置的,在records.config文件中通过修改proxy.config.cache.target_fragment_size即可,默认为1M
如果一个http响应作为一个object是一个小文件,ts是使用一个Doc完全保存该object的内容。这时,hdr保存响应头,data保存响应体
如果一个http响应是一个大文件,这时ts首先单独使用一个Doc保存响应头的内容,而对于响应体,根据fragment的大小,会被切分为好几个fragment,每个fragment使用一个Doc保存。在响应头的head中,frags数组维护的是每个fragment在整个http响应内容中的位置信息。
对于小文件,该object生成的key值保存在first_key中。而对于一个大文件,整个http响应作为一个object生成的key值保存在first_key中,这个key值由响应头对应的Doc使用,由此在cache查找时,首先找到的就是一个http响应的头部。响应头的Doc的元素key保存的是第一个fragment的key值。而对于每个fragment,第一个fragment通过随机算法生成一个随机数作为一个key值保存在其对应的key中,后续的每个fragment的key值都是以前一个fragment的key值为种子随机生成的。
通过随机算法计算每个fragment使用的key值,这样做的好处是使得所获取的key值尽可能离散,从而映射到索引区的不同bucket中,避免了一个bucket不会维护太长的Dir链表。
下图描述各个fragment是如何通过随机数算法联系起来的:
第一个fragment的key值需要保证不和first_key冲突,否则重新随机生成一个,直到不冲突为止。