Gorilla: A Fast, Scalable, In-Memory Time Series Database
- 特性
分布式,全内存,一致性要求不高,底层有ODS, -
背景需求
10M写入,4万读取,ms级别读取(我们的读取40ms,这个要求太高,1ms),数据全内存26hours,16G每个,容错。- opentsdb 基于hbase,远程磁盘。query速度不满足
- whisper,graphite. 本地底盘,RRD数据(要求时间有序),
- influxdb,基于opentsdb,支持更richer的数据,
总之以上三个都是因为磁盘,query时间不满足。
内存结构
unordered_map+范围vector。
ts数据读写spinlock。open data block追加,2Hours后固定为closed blosks。比较简单
数据压缩
全内存重点就是数据压缩,可以说是时序数据很有价值的参考。
时间压缩:delta-delta。
block头存起始时间点,2小时窗口
第一个时间戳t0,存delta(差值)。后续的都是delta-delta的值,计算方法:
数据压缩:浮点XOR,64位精度
这里补了下浮点数的存储。嗯,浮点数第一个表示符号,后面11位是指数(值+1023),其他是值。要将十进制整数和小数分别计算出二进制,再表示为科学计数法,再对应到64位表示。比如12.125,整数(再不要蠢蠢的从高位计算了=。=):12%2=0,6%2=0,3%2=1,1%2=1 =>1100。0.125*2=0.25(取整数是0) 0,0.25*2=0,0.5*2=1 => 001
因此为1100.001 表示为科学计算法 1.1000001*2^3
转为64位是
0 3+1023 1100000100000……
0 100 0000 0010 1100 0001 0000 …… =》0x402c100000000000
这个压缩算法是前后做XOR之后,如果后面的数比在前面有意义数字长度内,直接存有意义数据(前后的0一定是相同的)。否则存前面0个数,有意义数长度5byte,有意义数,后面0就不需要存了。
比如图中的0x0010000……。11代表是第二种情况,0的个数是11个(01011),然后是值1长度为1,然后是值1。