05月17, 2018

influxdb介绍

InfluxDB 是一个时间序列数据库,用于处理海量写入与负载查询。InfluxDB旨在用作涉及大量时间戳数据的任何用例(包括DevOps监控,应用程序指标,物联网传感器数据和实时分析)的后端存储。

特点

  • 为时间序列数据专门编写的自定义高性能数据存储。 TSM引擎具有高性能的写入和数据压缩
  • Golang编写,没有其它的依赖
  • 提供简单、高性能的写入、查询 http api
  • 插件支持其它数据写入协议,例如 graphite、collectd、OpenTSDB
  • 支持类sql查询语句
  • tags可以索引序列化,提供快速有效的查询
  • Retention policies自动处理过期数据
  • Continuous queries自动聚合,提高查询效率

设计理念

  • 同一时间点多次写入同样的数据被认为是重复写入
  • 极少出现删除数据的情况,删除数据基本都是清理过期数据
  • 极少更新已有数据且不会出现有争议的更新,时间序列数据总是新数据
  • 绝大多数写入是针对最新时间戳的数据,并且数据按时间升序添加
  • 数据的规模会非常大,必须能够处理大量的读写操作
  • 能够写入和查询数据会比强一致性更重要
  • 很多time series非常短暂的存在,所以time series 数量比较大
  • 没有哪个point是过于重要的

概念

Line protocol

在 InfluxDB 中,我们可以粗略的将要存入的一条数据看作一个虚拟的 key 和其对应的 value(field value),格式如下:

cpu_idle,host=k0614v,region=us-west value=83.13 1524730697000000000

虚拟的 key 包括以下几个部分:database, retention policy, measurement, tag sets, field name, timestamp ,database和retention policy在上面的数据中并没有体现,通常在插入数据时在 http 请求的相应字段中指定。

  • database

    InfluxDB 中可以创建多个数据库,不同数据库中的数据文件是隔离存放的,存放在磁盘上的不同目录。

  • retention policy

    存储策略,用于设置数据保留的时间、集群中存放副本数量以及shard group覆盖的时间范围。每个数据库刚开始会自动创建一个默认的存储策略 autogen,数据保留时间为永久,副本数量为1,shard group持续时间为7天,之后用户可以自己设置。InfluxDB 会定期清除过期的数据。

  • measurement

    measurement作为tags,fields和time列的容器,measurement也是存储在相关字段中的数据的描述

  • tag sets

    tags 在 InfluxDB 中会按照字典序排序,不管是 tag key 还是 tag value,只要不一致就分别属于两个 key,例如 host=k0614v,region=us-west 和 host=k0615v,region=us-west 就是两个不同的 tag sets

  • field name

    例如上面数据中的 value 就是 fieldName,InfluxDB 中支持一条数据中插入多个fieldName,这其实是一个语法上的优化,在实际的底层存储中,是当作多条数据来存储。

  • timestamp

    每一条数据都需要指定一个时间戳,在 TSM 存储引擎中会特殊对待,以为了优化后续的查询

Point

InfluxDB 中单条插入语句的数据结构,series + timestamp 可以用于区别一个 point,也就是说一个 point 可以有多个 field name 和 field value。

Series

series 相当于是 InfluxDB 中一些数据的集合,在同个 database 中,retention policy、measurement、tag完全相同的数据同属于一个 series,同个series的数据在物理上会按照时间顺序排列存储在一起。 series的key为measurement + 所有 tags 的序列化字符串,这个key在之后会经常用到。

Shard

shard是在 tsm 存储引擎之上的一个概念。在 InfluxDB 中按照数据的时间戳所在的范围,会去创建不同的 shard,每一个 shard 都有自己的 cache、wal、tsm file 以及 compactor,这样做的目的就是为了可以通过时间来快速定位到要查询数据的相关资源,加速查询的过程,并且也让之后的批量删除数据的操作变得非常简单且高效。

每个shard有且只有一个shard group。 单个shard group中可能存在多个shard。 每个shard包含特定的series集合。

Shard duration

Shard duration决定了每个shard group的时间跨度。具体由retention policy的SHARD DURATION决定

Shard group

shard group按照time、retention policy进行组织。每个包含数据的retention policy至少有一个关联的shard group。给定的shard group包含时间区间内所有shard数据。 每个shard group跨越的间隔是shard duration。

Continuous Query

CQ 是预先配置好的一些查询命令,定期自动执行这些命令并将查询结果写入指定的 measurement 中,这个功能主要用于数据聚合。

存储引擎(TSM)

InfluxDB存储引擎看起来非常类似于LSM树。它主要由cache、wal、tsm file、compactor组成

Cache

cache是当前存储在WAL中的所有数据的内存副本。point由metric,tag和唯一字段组成。每个字段保持其自己的时间有序范围。cache中的数据未被压缩。对存储引擎的查询将合并Cache和TSM中的数据。

当influxDB启动时,会遍历所有的wal文件,重新构造cache,这样即使系统出现故障,也不会导致数据的丢失。

Wal(Write Ahead Log)

wal的内容与cache相同,其作用就是为了持久化数据,当系统崩溃后可以通过wal文件恢复还没有写入到tsm文件中的数据。

由于数据是被顺序插入到wal文件中,所以写入效率非常高。但是如果写入的数据没有按照时间顺序排列,而是以杂乱无章的方式写入,数据将会根据时间路由到不同的shard中,每一个shard都有自己的wal文件,这样就不再是完全的顺序写入,对性能会有一定影响。官方社区有说后续会进行优化,只使用一个 wal,而不是为每一个shard 创建 wal。

wal单个文件达到一定大小后会进行分片,创建一个新的wal分片文件用于写入数据。

TSM file

TSM文件是内存映射的只读文件的集合。 这些文件的结构看起来与LevelDB或其他LSM树变体中的SSTable非常相似。

一个TSM文件由4个区域组成:header,blocks,index,footer

┌────────┬────────────────────────────────────┬─────────────┬──────────────┐
│ Header │               Blocks               │    Index    │    Footer    │
│5 bytes │              N bytes               │   N bytes   │   4 bytes    │
└────────┴────────────────────────────────────┴─────────────┴──────────────┘

Header

┌───────────────────┐
│      Header       │
├─────────┬─────────┤
│  Magic  │ Version │
│ 4 bytes │ 1 byte  │
└─────────┴─────────┘
  • Magic: 用于区分是哪一个存储引擎,默认引擎tsm1,MagicNumber 为0x16D116D1
  • Version: 默认引擎是tsm1,固定为1

Blocks

┌───────────────────────────────────────────────────────────┐
│                          Blocks                           │
├───────────────────┬───────────────────┬───────────────────┤
│      Block 1      │      Block 2      │      Block N      │
├─────────┬─────────┼─────────┬─────────┼─────────┬─────────┤
│  CRC    │  Data   │  CRC    │  Data   │  CRC    │  Data   │
│ 4 bytes │ N bytes │ 4 bytes │ N bytes │ 4 bytes │ N bytes │
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

Blocks 是一系列crc32和数据块组成。crc32可以用来恢复,确保data的完整性。block的长度保存在索引中。

Index

┌────────────────────────────────────────────────────────────────────────────┐
│                                   Index                                    │
├─────────┬─────────┬──────┬───────┬─────────┬─────────┬────────┬────────┬───┤
│ Key Len │   Key   │ Type │ Count │Min Time │Max Time │ Offset │  Size  │...│
│ 2 bytes │ N bytes │1 byte│2 bytes│ 8 bytes │ 8 bytes │8 bytes │4 bytes │   │
└─────────┴─────────┴──────┴───────┴─────────┴─────────┴────────┴────────┴───┘

索引由一系列索引条目组成,先按照 key 的字典序排序,再按照 time 排序。 每条索引都以key len、key开始,count是文件中块的数量。

以下部分为block索引,根据count数量重复出现。

  • Min Time
  • Max Time
  • Offset
  • Size

Footer

┌─────────┐
│ Footer  │
├─────────┤
│Index Ofs│
│ 8 bytes │
└─────────┘

最后是Footer,它主要是存放索引的开始位置。

Compactor

compactor是一个持续的过程,优化存储,提升查询性能,具体做以下几件事:

  • 将已关闭的WAL文件转换为TSM文件并删除已关闭的WAL文件
  • 将较小的TSM文件合并为较大的文件以提高压缩率
  • 删除series data
  • 写入最新的数据,确保TSM文件中point的唯一性。

本文链接:https://www.opsdev.cn/post/influxdb-introduce.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。