SSTable是一种拥有持久化,有序且不可变的的键值存储结构
它的key和value都是任意的字节数组,并且了提供了按指定key查找和指定范围的key区间迭代遍历的功能。
SSTable内部包含了一系列可配置大小的Block块,典型的大小是64KB,关于这些Block块的index存储在SSTable的尾部,用于帮助快速查找特定的Block。当一个SSTable被打开的时候,index会被加载到内存,然后根据key在内存index里面进行一个二分查找,查到该key对应的磁盘的offset之后,然后去磁盘把响应的块数据读取出来。当然如果内存足够大的话,可以直接把SSTable直接通过MMap的技术映射到内存中,从而提供更快的查找
先取出来Index,通过key进行二分查找,找到对应的offset(偏移量),然后把磁盘里对应的Block(块数据)取出来。
Memory(active memtable、immutable memtable、block cache)、Disk(sstable、WAL)
active memtable:活跃的内存表
immutable memtable:不变的内存表
block cache:缓存
sstable:有序表
WAL:预写日志
有序性
虽然sstable是有序的,但同一level中不同的sstable可能会出现key重叠,这取决于compaction策略。
size-tiered compaction:同一level的sstable会出现重叠
leveled compaction:level0以上的同一level的sstable不会出现重叠
key重叠会导致读变大
写:
参考:
https://blog.csdn.net/u010454030/article/details/90414063
https://www.jianshu.com/p/e89cd503c9ae?utm_campaign=hugo
tag与field区别
tag: 建立索引,不必须,常用作筛选条件
field:不建立索引,必须,不推荐用作筛选条件
InfluxDB 不是一个完整的 CRUD 数据库,而是更像一个 CR-ud,将创建和读取数据的性能优先于更新和销毁,并防止一些更新和销毁行为以使创建和读取性能更高:
要更新一个点,请插入一个具有相同测量值、标签集和时间戳的点。
您可以删除或删除一个系列,但不能基于字段值删除单个点。作为一种解决方法,您可以搜索字段值,检索时间,然后根据time字段删除。
您还不能更新或重命名标签 - 请参阅 GitHub 问题#4157了解更多信息。要修改一系列点的标记,请找到具有违规标记值的点,将值更改为所需的值,将点写回,然后删除具有旧标记值的系列。
您不能按标签键(而不是值)删除标签 - 请参阅 GitHub 问题#8604。
_time | _measurement | location | scientist | _field | _value |
---|---|---|---|---|---|
2019-08-18T00:00:00Z | census | klamath | anderson | bees | 23 |
2019-08-18T00:00:00Z | census | portland | mullen | ants | 30 |
2019-08-18T00:06:00Z | census | klamath | anderson | bees | 28 |
2019-08-18T00:06:00Z | census | portland | mullen | ants | 32 |
存储字段_time
,
每条数据都有的列,磁盘上存储精确到纳秒。
写入数据时,需要注意时间戳的精度
存储字段_measurement
,字符串格式
充当temstamp、tags、field的容器
注:便于理解,可以认为是一个表
必须
**)包括字段键_field
、和字段值_value
bees
和ants
是字段键bees
(蜜蜂数量)23和28,以及指定时间的ants
(蚂蚁数量)30和32。census bees=23i,ants=30i 1566086400000000000
census bees=28i,ants=32i 1566086760000000000
-----------------
Field set
非必须
**)标签包括存储为字符串和元数据的标记键和标记值。
样本数据中,列location、scientist都是标签
不建议讲包含高度可变信息(如 UUID、哈希和随机字符串)设置为标签,这样会导致high series cardinality
(高系列技术),会导致数据库内存负载大幅度增高
location = klamath, scientist = anderson
location = portland, scientist = anderson
location = klamath, scientist = mullen
location = portland, scientist = mullen
在InfluxDB云中,具有显式模式类型的bucket需要为每个度量提供显式模式。测量值包含标签、字段和时间戳。显式模式约束可写入该度量的数据的形状。
以下是measurement census的架构
name | type | data_type |
---|---|---|
time | timestamp | |
location | tag | string |
scientist | tag | string |
ants | field | integer |
bees | field | integer |
measurement
(共享测量值)、tag set
(标记集)和field key
(字段键)的点的集合(注意,不包括字段值)_measurement | tag set | _field |
---|---|---|
census | location=klamath,scientist=anderson | bees |
census | location=portland,scientist=mullen | ants |
# series key(系列键)
census,location=klamath,scientist=anderson bees
# series (系列)
2019-08-18T00:00:00Z 23
2019-08-18T00:06:00Z 28
一个点包括序列键、字段值和时间戳(其实就是一个系列的全值)。
例如2019-08-18T00:00:00Z census ants 30 portland mullen
所有 InfluxDB 数据都存储在存储桶中。
存储桶结合了数据库的概念和保留期(每个数据点保留的持续时间)。
一个桶属于一个组织。
InfluxDB组织是一组用户的工作空间。
所有仪表板、任务、存储桶和用户都属于一个组织。
系列键(series key):measurement、tag(key和value)、field(key)相同的集合
系列(serie):系列键下的集合,包括时间戳、field(value)
点(point):包括序列键、field(value)、时间戳; 其实就是一个系列的全值
InfluxDB actually looks like two databases in one, a time series data store and an inverted index for the measurement, tag, and field metadata.
InfluxDB看起来是两个数据库,一个时间序列数据存储,一个倒排索引(为了measurement、tag、field的元数据)
InfluxDb存储引擎包含四个组件:WAL、CACHE、TSM、TSI
influxdb基础TSM和TSI来提取数据,先从TSI查询series,再从TSM文件读取对应的points。
TSM和TSI主要充当存储引擎,类似于Innodb和Mysql的关系。
一个桶有多个分片组(按照时间范围划分)
一个分片组包含多个分片(按照集群的数据节点区分,这些分片的时间范围是一样的)
一个桶会有多个测量(按照数据维度划分)
一个测量会存储在多个分片里
一个分片会包含多个测量的数据
一份分片包含多个TSM文件
TSM Files:存储TimeSeries(measurement + tags,注意没有field key)一段时间内的所有point;
问题:类似于SSTable?
influxDB将数据存储到磁盘时,将数据组织成分片。每个分片都属于一个分片组。(正常单机程序一个分片组只有一个分片。在集群中,分片组包含分布在多个数据节点上的多个分片)
shard group duration(分片组持续时间):指定每个分片组的时间范围。
默认情况下influxDB会根据bucket(存储桶)的保留策略设置碎片组的持续时间。
|bucket retention period(存储桶保留时间) | Default shard group duration (默认分片组持续时间)|
| 两天内 | 1小时|
| 2天-6个月 | 1天|
| 六个月前 | 7天|
也就是说,桶保留时间越短,分片组的时间范围就越小。比如桶的数据只保留两天,那每个分片组就只存储1个小时的数据
分片组属于InfluxDB bucket,包含由碎片组持续时间 定义的特定时间范围的时间序列数据。
当分片组持续时间为1天时,那每分片组就包含一天的数据,
shard group是从时间上,对shard做一个逻辑上的分组注意这里说的是逻辑上,shard group只是一个逻辑概念,在存储的时候,这些shard是平铺开的,并不是一个shard group的shard 存储在一起。
预先创建shardgroup,避免临时创建
shardgroup的时间是完全连续的,并且开始和结束时间都是shard duration的倍数。按照shard duration对齐。
分片包含由 分片组持续时间 定义的给定时间范围的编码和压缩时间序列数据。
指定碎分组持续时间内的系列中的所有点都存储在同一个分片中。
单个分片包含磁盘上的多个series(系列)、一个或多个TSM文件,并且属于碎片组。
下例为:bucket保留时间为4天,分片组持续时间为1天的桶数据分布
需要截图:https://docs.influxdata.com/influxdb/v2.4/reference/internals/shards/#shard-group-duration
通常influxDB会把数据写入到最新的分片组(热分片),当分片不再被写入数据时会被压缩数据称为冷分片。
如果要回填历史数据,需要先把冷分片数据解压缩,回填结束后再重新压缩。
InfluxDB定期压缩分片内的数据来优化磁盘使用率。开启压缩功能后,每秒检查是否需要进行压缩。
分片的压缩分两种情况
compact-full-write-cold-duration
控制)内没有数据写入以下配置设置对于负载不规则的系统特别有用,因为它们在高使用率期间限制压缩,并在负载较低期间让压缩赶上:
storage-compact-full-write-cold-duration
storage-compact-throughput-burst
storage-max-concurrent-compactions
storage-max-index-log-file-size
storage-series-file-max-concurrent-snapshot-compactions
storage-series-file-max-concurrent-snapshot-compactions
在具有稳定负载的系统中,如果压缩会干扰其他操作,通常情况下,系统的负载过小,并且配置更改不会有太大帮助。
InfluxDB的保留强制服务会定期检查分片组是否早于其存储桶的保留期。一旦分片组的开始时间超过存储桶的保留期,InfluxDB 就会删除分片组和关联的分片和 TSM 文件。
在具有无限保留期的存储桶中,分片无限期地保留在磁盘上。
InfluxDB 只删除冷分片。如果回填数据超出存储桶的保留期,则回填数据将保留在磁盘上,直到发生以下情况:
分片返回冷状态。
保留强制服务删除分片组。
猜测:TSM里,每一个SSTable只存储一个field的value,其中,时间戳为key,field_value为value;格式如下: time1:value1;time2:value2;time3:value3