squid源码分析4—coss存储机制分析
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; // 支持的最小objectsquid_off_t max_objsize; // 支持的最大objectRemovalPolicy *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; // 指向当前的membufoff_t current_offset; /* in bytes */ // 指向整个coss文件的offsetunsigned 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主要完成以下处理:
正是由于这种机制,如果拷贝的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中的索引信息。
squid源码分析4—coss存储机制分析相关推荐
- Apache Spark源码走读之6 -- 存储子系统分析
Spark计算速度远胜于Hadoop的原因之一就在于中间结果是缓存在内存而不是直接写入到disk,本文尝试分析Spark中存储子系统的构成,并以数据写入和数据读取为例,讲述清楚存储子系统中各部件的交互 ...
- 看Volley源码,对HTTP缓存机制分析
Volley是android官方实现的HTTP请求库,实现非常优美,这里暂不分析. 可是在网络请求时它有一个对response code == 304 的判断,这个让我很纳闷,度娘加谷哥很久发现,原来 ...
- EOS源码备忘-Push Transaction机制
这里我们讨论EOS Push Transaction 的逻辑,这块EOS与Eosforce实现有一些区别,我们会着重点出. 关于wasm相关的内容我们会有一片专门的文档分析. 我们这里通常将Trans ...
- 分析开源项目源码,我们该如何入手分析?(授人以渔)
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~ 1 前言 本文接上篇文章跟大家聊聊我们为什么 ...
- 还不错的云盘网盘PHP系统源码+支持对接云存储
正文: 还不错的云盘网盘PHP系统源码+支持对接云存储,快速对接第三方云存储,支持七牛.又拍.阿里OSS.AWS S3.Onedrive.自建远程服务器,当然,还有本地存储. 自定义主题配色,图片.音 ...
- vue-router 源码阅读 - 文件结构与注册机制
文章目录 0. 前备知识 1. 文件结构 2. 入口文件 2.1 rollup 出口与入口 2.2 Vue.use 3. 路由注册 3.1 install 3.2 VueRouter 前端路由是我们前 ...
- 云豹直播系统源码接入华为云存储,含问题及解决方法
云豹直播系统源码接入华为云存储该怎么做? 一.云豹直播系统源码接入华为云存储的前期准备工作 1.注册云服务账号开通对象存储服务. (1)登录公有云网站.在页面右上角单击"注册".按 ...
- 最新云盘网盘PHP源码系统源码+对接云存储/附安装教程
最新云盘网盘PHP源码系统源码+对接云存储/附安装教程 2022最新云盘网盘PHP系统源码,支持快速对接第三方云存储,支持七牛.又拍.阿里OSS.AWS S3.Onedrive.自建远程服务器,当然, ...
- JDK源码分析——Java的SPI机制分析与实战
重点提示:在我博客中的所有的源码分析的实例,我都将会放到github上,感兴趣的朋友可以下载下来调试运行,我相信还是可以有所收获的.我的目的是让所有读到我博客的朋友都可以了解到有价值的东西,学习到ja ...
最新文章
- 为了控制Bean的加载我使出了这些杀手锏
- Socket的三个关联函数
- 零元学Expression Blend 4 - Chapter 40 Flash做的到的Blend也可以!轻松制作拥有动画的MenuBar!(上)...
- 密码学 / 哈希算法
- Java黑皮书课后题第8章:*8.33(几何:多边形的子面积)一个具有四个顶点的凸多边形被分为4个三角形,编写一个程序,提示用户输入4个顶点的坐标,然后以升序显示四个三角形的面积
- rxjs里使用from operator从一个generator里生成Observable
- ASP.NET Core 整合Autofac和Castle实现自动AOP拦截
- linux ip地址漂移,Linux 实现高可用性(HA) —之ip 漂移方法(vrrp)
- 信息学奥赛C++语言:输出学生序号与成绩
- 广二师的计算机专业好不,广东技术师范学院和广东第二师范学院哪一个更好?...
- 服务器机房项目总结,机房建设项目总结报告.doc
- 域控设定PC定时关机策略操作流程-呈上
- 标书的总结和感受(对标书整体流程的理解,和细节的把控
- win10远程桌面连接凭据怎么设置_如何解决Win10远程桌面提示你的凭证不工作?...
- Java操作word模板插入图片
- ionic ion-refresher刷新完毕
- 华为三层交换机路由配置案例_华为三层交换与路由配置
- 计算机社团活动展望未来,社团展望未来演讲稿(2)
- 机器学习中qa测试_学会区分人工智能和机器学习,并了解QA测试方法
- C语言1115数组最小值,C语言数组[共52页]
热门文章
- 2023年上半年北京杭州/广州深圳软考中/高级报名入口
- 2006德国世界杯32强口号-励志篇
- python代码电影人物关系_自动更新高清电影文件中文名python代码
- 51单片机也能玩TFT彩屏-第2季第3部分-朱有鹏-专题视频课程
- android方法不混淆,android app进行代码混淆实例详解
- MSP430的定时器
- linux运维常用巡检表格,Linux系统巡检常用命令
- linux设备寄存器映射,linux LCD驱动 及 ARM 寄存器映射
- 见证中国云势力崛起,博睿数据实力入围2021~2022 Cloud 100 榜单
- 新一届ACM图灵奖得主以及其贡献