TSM存储引擎的存储类tsdb.Store,蕴含索引区和数据区:
tsdb.Store //索引 -- map[string]*Index -- map[string]*measurement -- map[string]*series //数据 -- map[uint64]*Shard -- Engine // 形象接口,可插拔设计,目前是 tsm1 存储引擎 -- *WAL -- *Cache -- *Compactor -- *FileStore
索引区:map构造,databaseName-->Index构造;
- Index构造蕴含measurement和series元信息;
数据区:map构造,shardId-->Shard构造,一个shard能够了解为独自的tsm引擎,其中蕴含wal、tsm file等数据;
tsdb.Store整体构造
Store是存储的顶层构造,蕴含索引和数据:
//tsdb/store.gotype Store struct { path string // shared per-database indexes, only if using "inmem". indexes map[string]interface{} //key=databaseName, value理论是*Index //所有shards,key=shardId shards map[uint64]*Shard}
Store::indexes索引区
indexes定义为map[string]interface: key=databaseName,value=*Index。
该对象缓存了influxdb中所有的database、retention policy、measurement、series等元信息,若series设计不合理,容易导致内存占用偏高。
在influxdb启动时,将初始化该构造,从所有shards下的tsm file中加载index信息,获取其中的meaurement以及series信息,缓存到该构造中。
//tsdb/index/inmem/inmem.go// Index is the in memory index of a collection of measurements, time// series, and their tags.type Index struct { //数据库下measurementName-->*measurement measurements map[string]*measurement // measurement name to object and index //数据库下seriesKey-->*series series map[string]*series // map series key to the Series object database string //数据库名称}
measurement构造保留某个measurement下series、tags等信息:
- seriesByID:seriesId-->series;
seriesByTagKeyValue:
- 这个对象较为简单,它理论是tagKey-->tagValue-->[]uint64;
- 可通过tagKey查问到其tagValue、蕴含该tagKey的[]seriesId;
- 不便通过tagKey查问各种元信息;
//tsdb/index/inmem/meta.gotype measurement struct { Database string Name string `json:"name,omitempty"` fieldNames map[string]struct{} // in-memory index fields //seriesId-->*series seriesByID map[uint64]*series // lookup table for series by their id //tagKey-->tagValue-->[]seriesId //查问时,可依据tagKey找到seriesId,而后再找到相干的series seriesByTagKeyValue map[string]*tagKeyValue // map from tag key to value to sorted set of series ids sortedSeriesIDs seriesIDs // sorted list of series IDs in this measurement}type tagKeyValue struct { mu sync.RWMutex entries map[string]*tagKeyValueEntry}type tagKeyValueEntry struct { m map[uint64]struct{} // series id set}
series的构造很简略,蕴含serisId、key和tag信息:
// series belong to a Measurement and represent unique time series in a database.type series struct { // immutable ID uint64 Measurement *measurement //归属的measurement Key string Tags models.Tags}
Store::shards数据区
shard在TSM中的地位:
- influxdb依照数据的工夫戳范畴,创立不同的shard,每个shard负责管理一段时间内的数据;
- 每个shard都有本人的cache、wal、tsmfile和compactor;
- 能够通过工夫疾速定位到shard,减速查问;同时批量删除时,删除响应的shard目录即可;
每个shard能够了解为一个独自的底层数据引擎,由其中的engine负责和底层的文件打交道:
//tsdb/shard.gotype Shard struct { path string //shard在磁盘中的门路 walPath string //shard中的wal目录 id uint64 //shardId database string retentionPolicy string _engine Engine //存储引擎}
Engine是interface,InfluxDB应用tsm1实现了该接口:tsm1.Engine负责保护治理治理shard下的cache/wal/filestore/compactor对象
//tsdb/engine/tsm1/engine.gotype Engine struct { path string index tsdb.Index //索引信息 WAL *WAL //WAL文件对象 Cache *Cache //WAL文件在内容中的缓存 Compactor *Compactor //合并治理对象 CompactionPlan CompactionPlanner FileStore *FileStore //数据文件对象 //Cache超过肯定大小会被写入TSM文件,默认25M //配置文件:cache-snapshot-memory-size CacheFlushMemorySizeThreshold uint64 //Cache超过多久没有数据写入,将其写入TSM文件,默认30min //配置文件:cache-snapshot-write-cold-duration CacheFlushWriteColdDuration time.Duration}
每个Shard蕴含:Cache、WAL、Compactor、FileStore四大组件。
Cache
cache相当于LSM-Tree中的MemTable,内存中是一个map构造,key=seriesKey+分隔符+fieldName。
插入数据时,同时向cache和WAL写入数据,能够认为cache是wal在内存中的缓存;当influxdb启动时,会遍历所有的wal,从新结构cache,这样即便系统故障,也不会导致数据失落。
cache中的数据不会有限增长,当达到cache-snapshot-memory-size(默认25M)时,将cache进行快照,将快照中的数据写入tsm文件中;同时删除对应的wal文件。
WAL
wal文件内容与cache雷同,用于过程解体后,通过wal文件复原数据(复原到cache);
FileStore
FileStore具体是TSM File,单个TSM File最大2GB,用于寄存压缩后的时序数据,对不同的数据类型,应用不同的压缩算法;
- Timestamp: simple8B
- Floats: XOR
- Integers: ZigZag
- Strings: Snappy
Compactor
compactor相似于LSM-Tree中的低Level向高Level SSTable的合并。
compactor在后盾运行,每隔1s查看一次是否须要合并:
- cache中的数据大小达到阈值,进行快照,而后转存到一个tsm文件中;
- 合并tsm文件,将低level tsm合并到高level,缩小文件数量,同时进行数据的过期删除;
参考:
1.http://blog.fatedier.com/2016...
2.http://blog.fatedier.com/2016...
3.https://docs.influxdata.com/i...