ATS读小文件(内存命中)

一个资源根据其大小可能会存在多个存储对象中。如果足够小(连同doc结构的大小小于一个fragment的size),连同这个资源的meta信息一起存储在一个doc中。如果比较大,第一个存储对象保存资源的meta信息,后面跟着若干个fragment存着资源的content。这里讨论小文件读行为,并且内存命中,在资源第二次命中的时候才有可能是内存命中。整个流程在主状态机流程的入口函数是Cache::open_read,正流程如下:

Cache::open_read: 计算的到vol。运行了dir_probe函数,确定了缓存查询的结果。获取了dir,对CacheVC对象的key和dir进行了初始化。生成一个CacheVC对象,之后的操作都是这个CacheVC对象是事儿了。设置回调函数为Cache::openReadStartHead,设置完回调函数会执行do_read_call,最终返回了EVENT_RETURN,执行了事件回调函数,就是刚刚设置的Cache::openReadStartHead。

CacheVC::do_read_call: 初始化doc_pos为0。解析dir,获取fragment大概大小(dir_approx_size)。决定是否应该写到ssd中(dir_inssd),如果已经是从ssd中读了,就肯定不写了。每个vol都会对应自己的ssd,每个vol都会维护一些历史数据用来判断热度相关的数据。最终执行CacheVC::handleRead,最终返回了EVENT_RETURN。

CacheVC::handleRead: 获取偏移量(dir_get_offset)。 在内存中查询(vol->ram_cache->get函数会根据records.config中的配置项proxy.config.cache.ram_cache.algorithm指向不同的函数)。如果内存查询命中了,会将这个资源从队列中取出来重新插入,这样就是最新的了,详见 RamCacheLRU::get函数。内存命中的话在这个函数里面就已经获取到了doc。

CacheVC::openReadStartHead: 每次读cache操作都会执行一次,获取这个资源相关的信息。确定一个alternate,通过判断alternate的key是否就是doc的key来判断这个alternate是不是要找的那个。如果是的话判断是不是single fragment,如果满足len = heln + total_len + 72,认为是小文件。获取doc_pos,即为doc的大小与整个资源的metadata的大小的和。获取next key(对于小文件没必要,但是也执行了),执行begin_read,这个函数主要判断了是否需要evacuate,由于小文件都会存在一个fragment,而此时已经都到了内存中,所以不需要考虑evacuate问题。最后将回调函数设置为 CacheVC::openReadMain,并且之行缓存主状态机事件回调函数 HttpCacheSM::state_cache_open_read,传递的参数是 CACHE_EVENT_OPEN_READ

CacheVC::openReadMain: CacheVC::openReadStartEarliest函数之后进入这个函数,为了找到第一个fragment的偏移量,在while (i > 1)中完成。计算整个请求当前尚未响应的数据大小,当前fragment尚未发送的数据。

时间: 2024-10-07 05:31:44

ATS读小文件(内存命中)的相关文章

ATS读小文件(磁盘命中)

理想状况下,一个文件第一次访问,缓存查询结果是MISS.第二次以及之后的请求查询结果都是HIT,直到资源在缓存中过期.第二次查询在ats中的行为是内存MISS并且磁盘HIT,这里讨论这种状况.主要函数和流程如下: Cache::open_read: 计算的到vol.运行了dir_probe函数,确定了缓存查询的结果.获取了dir,对CacheVC对象的key和dir进行了初始化.生成一个CacheVC对象,之后的操作都是这个CacheVC对象是事儿了.设置回调函数为Cache::openRead

ATS读大文件(命中)

大文件存储结构和小文件完全不同,小文件占一个fragment就够了,小文件占若干个fragment.小文件第一个是doc只存一些信息数据,包括http头,资源的content存在于若干个fragment中,默认每个fragment展1048576字节,在proxy.config.cache.target_fragment_size中可以改.一个fragment中有72个字节是doc,剩下的是资源的content.ats会先读第一个fragment,然后以循环的方式读取若干个fragment,直到

ATS写小文件

与读缓存类似,写缓存也有大文件小文件的区分,这里讨论写小文件.整个流程如下: Cache::open_write: 根据key生成一个新key作为earliest_key,不过小文件的话貌似earlist_key没用.根据CacheV->first_key计算的到vol.执行Vol::open_write,在Vol::open_write中进行了简单的aggregation buf的错误检查就执行了OpenDir::open_write.最后将CacheVC::openWriteMain设置为回

FileOutputStream字节输出流和FileInputStream输入流(切记:out是输出到本地中,in是输入到程序中)这里介绍大文件和小文件的读取方式

//FileOutputStream public class FileOutputStreamDemo { /**字节流:适用于任何文件,以字节为单位,进行读写操作  *字节流操作步骤:  *1.创建文件对象  *2.创建字节流  *3.读写操作  *4.关闭流  */ //字节流(写操作) public static void main(String[] args) { String messageString = "hello world";  byte[] bytes = me

关于hadoop处理大量小文件情况的解决方法

小文件是指那些size比HDFS的block size(默认64m)小的多的文件.任何一个文件,目录和bolck,在HDFS中都会被表示为一个object存储在namenode的内存中,每一个object占用150bytes的内存空间.所以,如果有10milion个文件,每一个文件对应一个block,那么就会消耗namenode 3G来保存这些block的信息.如果规模再大一点,那么将会超出现阶段计算机硬件所能满足的极限. 控制小文件的方法有: 1应用程序自己控制 2archieve 第一种是我

LOSF 海量小文件问题综述

1.LOSF问题概述 在互联网(尤其是移动互联网).物联网.云计算.大数据等高速发展的大背景下,数据呈现爆炸式地增长.根据IDC的预测,到2020年产生的数据量 将达到40ZB,而之前2011年6月的预测是35ZB.然而,社会化网络.移动通信.网络视频音频.电子商务.传感器网络.科学实验等各种应用产生的数 据,不仅存储容量巨大,而且还具有数据类型繁多.数据大小变化大.流动快等显著特点,往往能够产生千万级.亿级甚至十亿.百亿级的海量小文件,而且更多地 是海量大小文件混合存储.由于在元数据管理.访问

HDFS小文件合并问题的优化:copyMerge的改进

1.问题分析 用fsck命令统计 查看HDFS上在某一天日志的大小,分块情况以及平均的块大小,即 [[email protected] jar]$ hadoop fsck /wcc/da/kafka/report/2015-01-11 DEPRECATED: Use of this script to execute hdfs command is deprecated. Instead use the hdfs command for it. 15/01/13 18:57:23 WARN ut

Hadoop小文件问题及解决方案

1.概述 小文件是指文件size小于HDFS上block大小的文件.这样的文件会给hadoop的扩展性和性能带来严重问题.首先,在HDFS中,任何block,文件或者目录在内存中均以对象的形式存储,每个对象约占150byte,如果有1千万个小文件,每个文件占用一个block,则NameNode大约需要2G空间.如果存储一亿个文件,则NameNode需要20G空间.这样NameNode内存容量严重制约了集群的扩展.其次,访问大量小文件速度远远小于访问几个大文件.HDFS最初是为流式访问大文件开发的

海量小文件存储与Ceph实践

海量小文件存储(简称LOSF,lots of small files)出现后,就一直是业界的难题,众多博文(如[1])对此问题进行了阐述与分析,许多互联网公司也针对自己的具体场景研发了自己的存储方案(如taobao开源的TFS,facebook自主研发的Haystack),还有一些公司在现有开源项目(如hbase,fastdfs,mfs等)基础上做针对性改造优化以满足业务存储需求: 一. 通过对若干分布式存储系统的调研.测试与使用,与其它分布式系统相比,海量小文件存储更侧重于解决两个问题: 1.