Chinaunix首页 | 论坛 | 博客
  • 博客访问: 635243
  • 博文数量: 356
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2287
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-08 17:08
文章分类

全部博文(356)

文章存档

2023年(3)

2022年(7)

2021年(33)

2020年(47)

2019年(36)

2018年(221)

2017年(1)

2015年(1)

2013年(7)

我的朋友

分类:

2018-09-21 17:14:57

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 

// 一行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<

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中的索引信息。
阅读(2563) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~