squid源码分析4—coss存储机制分析

来源:互联网 发布:比较好的淘宝培训机构 编辑:程序博客网 时间:2024/04/28 21:03
分类:

1. Coss 文件系统概述

1.1 概述

循环目标存储机制(Cyclic Object Storage Scheme,coss)尝试为squid定制一个新的文件系统。在ufs基础的机制下,主要的性能瓶颈来自频繁的open()和unlink()系统调用。因为每个cache响应都存储在独立的磁盘文件里,squid总是在打开,关闭,和删除文件。

与之相反的是,coss使用1个大文件来存储所有响应。在这种情形下,它是特定供squid使用的,小的定制文件系统。coss实现许多底层文件系统的正常功能,例如给新数据分配空间,记忆何处有自由空间等。不幸的是,coss仍没开发完善。

1.2 配置

一个coss文件的典型配置如下:

 cache_dir coss /cache/coss0  75000 membufs=128 overwrite-percent=75 max-size=131072 block-size=4096 

75000:表示该coss文件的最大大小,单位是MByte

membufs:表示Mem-Only-Stripe的个数,仅存在于内存中,不会被同步到disk中。主要目的为存放最热门的object

max-size:表示允许存放在coss文件中的最大object

block-size:表示block的大小,该值越大,coss文件的最大大小也越大。

overwrite-percent:表示当前stripe游标与该object原来存放地方的游标之间距离大于整个coss文件长度的75%时,需要进行relocation操作(relocation见后面说明)

1.3 结构分析

逻辑上,coss文件系统以stripe为基本存储单元。其中stripe分为三种类型,Disk-Stripe,Mem-Stripe与Mem-Only-Stripe。其中Mem-Stripe是Disk-Stripe中正在使用的内存复制(待SwapOut至Disk中的Stripe),而Mem-Only-Stripe是仅仅存在内存中,不会同步到Disk中的Stripe,其目的是提高文件系统的内存命中率。coss文件系统包含N+M个stripe,其中N为与物理文件相对应的stripe;M为仅仅存在内存中的stripe(该类型stripe数目默认为10,自定义大小通过membufs定义)。相对应的Stripe编号为0至N,N+1至N+M。

物理上,coss文件系统将stripe细分成block,以block为基本单位。block越大,则coss支持的文件就越大。

1.4 工作机理

在磁盘上,每个coss cache_dir是一个大文件。文件大小一直增加,直到抵达它的大小上限。这样,squid从文件的开头处开始,覆盖掉任何存储在这里的数据。然后,新的目标总是存储在该文件的末尾处。

squid实际上并不立刻写新的目标数据到磁盘上。代替的,数据被拷贝进1MB的内存缓冲区,叫做stripe。在stripe变满后,它被写往磁盘。coss使用异步写操作,以便squid主进程不会在磁盘I/O上阻塞。

象其他文件系统一样,coss也使用块大小概念。每个cache目标有一个文件号码,以便squid用于定位磁盘中的数据。对coss来说,文件号码与块号码一样。例如,某个cache目标,其交换文件号码等于112,那它在coss文件系统中就从第112块开始。因此coss不分配文件号码。某些文件号码不可用,因为cache目标通常在coss文件里占用了不止一个块。

coss块大小在cache_dir选项中配置。因为squid的文件号码仅仅24位,块大小决定了coss缓存目录的最大size:size = 块大小 x (2的24次方)。例如,对512字节的块大小,你能在coss cache_dir中存储8GB数据。

1.5 coss relocation机制

在测试的过程中,我们可以发现即使在全Cache Hit的情况下,也会有大量的IO Write操作。其根源在于relocation机制。

引入relocation机制从我的理解是由于有object purge的操作。因为随着object purge的操作,会引起coss文件的空洞和碎片,如果没有一个有效地机制重新整理coss文件,则coss文件的有效利用率会越来越低。而relocation机制则可以在增加IO write操作的代价下完整coss文件的整理工作。

relocation机制的的工作过程如下:

当squid访问object时,首先会依据用户的配置(overwrite-percent),判断该object是否需要relocation(判断标准:当前stripe游标与该object原来存放地方的游标之间距离大于整个coss文件长度的overwirte-percent时,需要进行relocation操作)。如果需要,则将该object读出来,放至当前stripe的membuf中。待membuf写满后,则swapout至disk中。

从中可以看到由于relocation的原因,原本只有read操作的流程,反而增加了write的操作,这是coss文件系统的一个缺点。但是coss避免了频繁的open,close系统调用。

2. Coss 实现分析

2.1 coss核心数据结构

2.1.1 SwapDir

// 一行cache_dir配置对应一个SwapDir结构struct _SwapDir {    const char *type;    int cur_size;  // 本目录当前所有object的大小总和    int low_size;      int max_size;  // 本目录支持的最大字节数    char *path;    // 本目录路径    int index;         /* This entry's index into the swapDirs array */    squid_off_t min_objsize; // 支持的最小object    squid_off_t max_objsize; // 支持的最大object    RemovalPolicy *repl;     // 老化策略    ......        // 针对FS的各个接口函数    STINIT *init;      /* Initialise the fs */    STCHECKCONFIG *checkconfig;   /* Verify configuration */    STNEWFS *newfs;      /* Create a new fs */    STDUMP *dump;      /* Dump fs config snippet */    STFREE *freefs;      /* Free the fs data */    STDBLCHECK *dblcheck;   /* Double check the obj integrity */    STSTATFS *statfs;      /* Dump fs statistics */    STMAINTAINFS *maintainfs;   /* Replacement maintainence */    STCHECKOBJ *checkobj;   /* Check if the fs will store an object */    STCHECKLOADAV *checkload;   /* Check if the fs is getting overloaded .. */    /* These two are notifications */    STREFOBJ *refobj;      /* Reference this object */    STUNREFOBJ *unrefobj;   /* Unreference this object */    STCALLBACK *callback;   /* Handle pending callbacks */    STSYNC *sync;      /* Sync the directory */    // 针对该FS的object各个接口函数    struct {   STOBJCREATE *create;   STOBJOPEN *open;   STOBJCLOSE *close;   STOBJREAD *read;   STOBJWRITE *write;   STOBJUNLINK *unlink;   STOBJRECYCLE *recycle;    } obj;    ......    struct {   int blksize; // block大小    } fs;    void *fsdata;  // 指向cossinfo};

该结构是对squid一个文件系统的抽象,各个文件系统分别实现其中的各个接口函数,数据格式等。

2.1.2 cossinfo

针对文件系统数据格式的信息。

struct _cossinfo {    dlink_list membufs;  // 指向存放mem-stripe和mem-only-stripe的链表    struct _cossmembuf *current_membuf; // 指向当前的membuf    off_t current_offset;   /* in bytes */  // 指向整个coss文件的offset      unsigned int blksz_bits;    unsigned int blksz_mask;   /* just 1<<blksz_bits -="" 1="" *="" float="" minumum_overwrite_pct;="" overwrite-percent配置值="" int="" minimum_stripe_distance;="" 计算出来的relocation需要的距离="" numstripes;="" 按照配置的coss大小,计算出来的可以存放stripe的数目="" struct="" _cossstripe="" *stripes;="" 存放stripe信息的数组首地址,每个stripe的信息存在stripes[i]中="" curstripe;="" 当前在使用的stripe号="" max_disk_nf;="" coss文件的最大block数目="" mem-only-stripe相对应的信息="" off_t="" current_memonly_offset;="" _cossmembuf="" *current_memonly_membuf;="" nummemstripes;="" mem-only-stripe的个数="" *memstripes;="" 指向mem-only-stripe="" curmemstripe;="" };="" <="" pre="" style="word-wrap: break-word;">

2.1.3 cossstripe

stripe结构

struct _cossstripe {    int id;    int numdiskobjs; // 本stripe中包含的object数目    int pending_relocs; // 等待relocate操作的object数目,只有relocate完成后,才可以    struct _cossmembuf *membuf;     dlink_list objlist; // 本stripe中的object列表,结构为storeEntry};

2.2 关键流程分析

2.2.1 Cache Miss流程

Cache Miss时需要调用storeCreate创建一个StoreEntry。其中storeCreate中通过调用SD->obj.create()接口创建。在coss文件系统中具体实现为storeCossCreate()。

storeCossCreate主要完成以下处理:

  • 调用storeCossAllocate在stripe中分配一块内存,并且得到swap_filen;
  • 调用storeCossAdd把object添加到curstripe中的objlist中;
  • 调用storeCossMemBufLock,锁住curstripe,以防止swapout至disk;

在完成create后,obj需要调用SD->obj.write()接口把obj中的内存数据写入disk。在coss文件系统中具体实现为storeCossWrite()。

storeCossWrite主要完成以下处理:

  • 复制buf数据至当前curstripe的Membufs;
  • 当Membufs中的数据满了后,则swapout到disk上;

正是由于这种机制,如果拷贝的Membufs时机延后,而又有新的req过来,需要分配新的Membufs。因此会导致Membufs数目不断上涨,不断占用内存。为了防止出现这种情况,cossinfo中增加了maxfullstripes分量。当到达上限时,storeCossCreate则会失败。

2.2.2 Cache Hit流程

Cache Hit流程总体上是从Mem或者Disk中读取Hit住的Req的reply数据。这些操作主要通过SD->obj.open()和SD->obj.read()。其中coss文件系统中具体实现为storeCossOpen()和storeCossRead()。

storeCossOpen主要完成以下处理:

  • 首先判断是否是Mem Hit(即在cossinfo中的membufs),如果是,则锁定该Membufs,不允许swapout;
  • 如果不是Mem Hit则从Disk中读取。如果判断需要relocate至当前stripe,则relocate至当前stripe,并把数据拷贝至当前的mem-stripe。如果不需要relocate,则把数据拷贝至Mem-Only-Stripe。

storeCossRead主要完成以下处理:

  • 调用storeCossCreateReadOp()创建异步读操作;
  • 调用storeCossKickReadOp()完成读操作列中的操作;

2.2.3 Cache Purge 流程

Cache Purge流程完成删除Object的过程。其调用接口为SD->obj.unlink。在coss文件系统中具体实现为storeCossUnlink。

storeCossUnlink主要完成以下处理:

  • 删除对应stripe中objlist中的索引信息。
0 0
原创粉丝点击