先给出index文件的结构:
┌────────────────────────────┬─────────────────────┐
│ magic(0xBAAAD700) <4b> │ version(1) <1 byte> │
├────────────────────────────┴─────────────────────┤
│ ┌──────────────────────────────────────────────┐ │
│ │ Symbol Table │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Series │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Label Index 1 │ │
│ ├──────────────────────────────────────────────┤ │
│ │ ... │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Label Index N │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Postings 1 │ │
│ ├──────────────────────────────────────────────┤ │
│ │ ... │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Postings N │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Label Index Table │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Postings Table │ │
│ ├──────────────────────────────────────────────┤ │
│ │ TOC │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
假设:查询某一条series的所有时间点的数据,比如:
({name:http_requests}{job:api-server}{instance:0}),且时间为start/end的所有序列数据
先从选择Block开始,遍历所有Block的meta.json,找到具体的Block:
通过Labels找数据是通过倒排索引。我们的倒排索引是保存在index文件里面的。 那么怎么在这个单一文件里找到倒排索引的位置呢?这就引入了TOC(Table Of Content)
Posting offset table 以及 Posting实现了倒排索引机制。
posting中的ref就是偏移量,因为每条series的大小是固定的,因此固定大小乘上偏移量,就能在index文件中找到series
这里ref(series)的值是一个8字节的值,其中4个字节存储量series对应的chunk文件id,另外四个字节存储量其对应的时序数据在chunk文件中的偏移量
每个block中的chunk里面有很多小chunk,每个小chunk就是一堆时序数据,时序数据的存储大致上长这样:
chunk文件则是通过mmap来访问里面具体偏移量对应的时序数据,也就是sample:
查找过程中的label名字和值的具体字符串形式都是存在符号表的,然后通过下标来查询对应的值
block文件夹下的chunk文件夹是chunk文件的集合,里面每个chunk文件中又有很多的chunk结构,每个chunk结构就是某个series对应的时序数据。index文件中的series条目会记录其所有的chunk结构所在的chunk文件id以及在文件中的偏移量,以供查询