ATS读大文件(命中)

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

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

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

CacheVC::handleRead: 获取偏移量(dir_get_offset)。 在内存中查询(vol->ram_cache->get函数会根据records.config中的配置项proxy.config.cache.ram_cache.algorithm指向不同的函数)。如果查询没有命中,生成一个iobufferdata buf(可以理解为内存中开了一块空间),生成一个char*变量指向buf的data。将磁盘中的内容memcpy到内存中。会有两种情况,一种是ramhit会执行CacheVC::handleReadDone,另一种是memhit,直接执行CacheVC::openReadStartHead,区别不大,这里讨论memhit情况。将回调函数POP掉,POP之后的回调函数变为在Cache::open_read设置的Cache::openReadStartHead,最终返回EVENT_RETURN一直向上直到Cache::open_read。

CacheVC::openReadStartHead: 函数确定了是大文件还是小文件。挑选了一个alternate,将选定的alternate的key赋值给Cache::key,判断alternate的key和doc->key是否相等。由于大文件的doc只存了一些信息,所以alternate的key和第一个存content的fragment的doc->key。函数最后将buf赋值为NULL,之后将回调函数设置为CacheVC::openReadStartEarliest并且执行。

CacheVC::openReadStartEarliest: 如果hit状态,一般会执行两次。但是如果出于正在下载状态,这个函数会执行若干次,但是获取锁不会成功。按照顺序来讲,CacheVC::openReadStartHead已经获取到了第一个存储content的fragment的key。通过dir_probe函数根据key得到earliest_dir。

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

CacheVC::handleRead: 获取偏移量(dir_get_offset)。 在内存中查询(vol->ram_cache->get函数会根据records.config中的配置项proxy.config.cache.ram_cache.algorithm指向不同的函数)。将回调函数设置为CacheVC::handleReadDone,返回EVENT_CONT一直向上给Cache::open_read,事件结束。

CacheVC::handleReadDone: 将回调函数POP掉,之后回调函数变为CacheVC::openReadStartEarliest,之后执行回调函数。

CacheVC::openReadStartEarliest: 这次之行时buf已经不是NULL了,计算next_key,设置回调函数为CacheVC::openReadMain并且执行。

CacheVC::openReadMain: 判断客户端请求的range最开始的位置位于哪个fragment,调整offset和doc_pos到合适的位置,offset是整个响应的offset不包含doc所占的72字节,doc_pos是单个fragment的postion包括72字节。这个函数会进入若干次,直到东西全都发完了。最后一次执行的时候,根据CacheVC::openReadStartEarliest计算得到的key,通过dir_probe的到对应的dir,设置回调函数为CacheVC::openReadReadDone,执行CacheVC::do_read_call,最后返回EVENT_CONT。到这里就进入了一个循环,一片一片的读文件发文件,直到请求结束。

CacheVC::handleReadDone: 进入循环之后这个函数由事件出发,将回调函数POP掉之后的回调函数变为CacheVC::openReadReadDone,执行回调函数。

CacheVC::openReadReadDone: fragment数量加1,计算next_key。将回调函数设置为CacheVC::openReadMain并且执行。

时间: 2024-08-11 01:36:27

ATS读大文件(命中)的相关文章

ATS读小文件(磁盘命中)

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

ATS读小文件(内存命中)

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

读大文件到mysql

起初使用java读文件处理格式后存入数据库,运行后发现,效率太低太低,4G文本,4000多万行,估计需要30天左右才能完成处理. 数据格式: 每行->  XXXX ||| XXXXXXX ||| XXXXXXXXXXXXXXXXX 数据是严格结构化的,因此查询到一种直接从文件导入mysql的方法: Load Data infile 参考文章:http://hunan.iteye.com/blog/752606 使用的指令如下: load data infile '/home/lenovo/文档/

POI 读大文件日志

POI的三个目录 usermodel 包含很多类,方便用户使用,但是占用内存大 eventusermodel 使用xml的SAX事件解析,XSSFReader创建时必须使用OPCPackage,pkg这个对象是通过OPCPackage.open(File或者inputStream)创建出来的, 这个过程是将excel文件解析成了xml文档(?),对于一个50M的excel占用内存达到500M左右. 后面解析这个xml时才用到SAX事件, 原文地址:https://www.cnblogs.com/

java读写文件,读超大文件

一直在处理爬虫,经常能遇到读写文件的操作,很多时候都是读写超大文件,记录如下: 一.读文件 import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;

Java NIO内存映射---上G大文件处理

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果. 一.java中的内存映射IO和内存映射文件是什么? 内存映射文件非常特别,它允许Java程序直接从内存中读取文件内容,通过将整个或部分文件映射到内存,由操作系统来处理加载请求和写入文件,应用只需要和内存打交道,这使得IO操作非常快.加载内存映射文件所使用的内存在Java堆区之外.Java编程语言

Java NIO内存映射---上G大文件处理(转)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果. 一.java中的内存映射IO和内存映射文件是什么? 内存映射文件非常特别,它允许Java程序直接从内存中读取文件内容,通过将整个或部分文件映射到内存,由操作系统来处理加载请求和写入文件,应用只需要和内存打交道,这使得IO操作非常快.加载内存映射文件所使用的内存在Java堆区之外.Java编程语言

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

php使用file函数、fseek函数读取大文件效率分析

php读取大文件可以使用file函数和fseek函数,但是二者之间效率可能存在差异,本文章向大家介绍php file函数与fseek函数实现大文件读取效率对比分析,需要的朋友可以参考一下. 1. 直接采用file函数来操作 由于 file函数是一次性将所有内容读入内存,而PHP为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的 memory_limit = 16M 来进行设置,这个值如果设置-1,