一、基础概念
1、存储桶(bucket)
bucket是存储时序数据的一个命名空间,相当于数据表。
每个bucket都必须设置数据保存的时长。存储桶属于某个组织。
翻译自:https://docs.influxdata.com/influxdb/v2.0/organizations/buckets/
2、组织(Organization)
每个组织创建时都必须关联一个存储桶(bucket),所以每个组织都至少有一个bucket,
单个InfluxDB OSS,建议存储桶不超过20,因此组织也不超过20个。
单个InfluxDB OSS,支持20个buckets以内的持续写入或者跨bucket或组织的持续查询。
3、成员(Member)(相当于用户)
每个成员都从属于组织。成员可以属于多个组织。
4、API令牌(token)
用户使用API token访问对应组织的数据。
bucket只是组织中的一类数据,组织中还有user、task等其他数据。
二、数据元素
翻译自:https://docs.influxdata.com/influxdb/v2.0/reference/key-concepts/data-elements/
数据组织模式(Schema):
InfluxDB schema包括: buckets, series, measurements, tag keys, tag values, and field keys。
每个bucket存储的数据结构 “示意” 如下表所示:
_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
其中:
_measurement:代表一个大类型的数据(包括某个类型的所有 _field 和 tags)。
一个bucket可以存储任意数量的measurement。每种measurement的tags可以不同。
field key 和 filed value:即 key-value,注意key是无索引的
tag:相当于索引信息,tag key为表头meta信息,tag value存储到每行数据中(string类型)。
tag value可以为空,但是tag字段作为索引,一般需要能对数据进行降维分类——tag要适合于分类,而不建议使用 UUIDs, hashes, and random strings这种会导致大量唯一的类型(称之为 high series cardinality:高维基数),高维基数是导致数据库内存占用巨大的罪魁祸首。
field set:即一组 time + key-value 的集合,例如
census bees=23i,ants=30i 1566086400000000000 census bees=28i,ants=32i 1566086760000000000 ----------------- Field set
tag set:即一组(可以有多个)tag key + tag value的集合,例如:
location = klamath, scientist = anderson location = portland, scientist = anderson location = klamath, scientist = mullen location = portland, scientist = mullen
Series(序列):把具有相同_measurement + tags k-v + _field key的数据(时间和field value)称之为一个序列。例如:
# series key census,location=klamath,scientist=anderson bees # series 2019-08-18T00:00:00Z 23 2019-08-18T00:06:00Z 28
点位(Point):一个点位包括了series key、field value 和 timestamp,例如:
2019-08-18T00:00:00Z census ants 30 portland mullen
注意(一),InfluxDB没有点位ID的概念,所有点位都是根据series key来确定的,而series key是 _measurement + tags k-v + _field key三者的组合。理论上tags可以没有,_measurement可以看做小表名称,所以field key可以近似的视为“点位ID”。
注意(二),避免过高的series:由于点位是由series key确定的,而seriers key又是由_measurement + tags k-v + _field key三者的组合确定的,所以设计时,建议降低series key的数量,即减少三者组合的个数。
数据写入使用行协议(Line protocol),包括4个部分:
measurement
field set
tag set(可选)
timestamp(可选)
例如:
measurementName,tagKey=tagValue fieldKey="fieldValue" 1465839830100400200 | | 1st space 2nd space # Measurement name with spaces my\ Measurement fieldKey="string value" # Double quotes in a string field value myMeasurement fieldKey="\"string\" within a string" # Tag keys and values with spaces myMeasurement,tag\ Key1=tag\ Value1,tag\ Key2=tag\ Value2 fieldKey=100 # Emojis myMeasurement,tagKey=🍭 fieldKey="Launch 🚀" 1556813561098000000
行协议具体定义参见:https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol
官方建议的数据组织方式:
1、避免在测量名称中编码数据
例如:
Schema 1 - Data encoded in the measurement name ------------- blueberries.plot-1.north temp=50.1 1472515200000000000 blueberries.plot-2.midwest temp=49.8 1472515200000000000
2、避免在一个标签中放置多于一条信息
例如:
Schema 1 - Multiple data encoded in a single tag ------------- weather_sensor,crop=blueberries,location=plot-1.north temp=50.1 1472515200000000000 weather_sensor,crop=blueberries,location=plot-2.midwest temp=49.8 1472515200000000000
这是因为,在InfluxDB中,tags的数量是不限制的,它从存储层面支持多列索引。(至于tags数量多了之后,是否影响存储和查询效率,暂且未知)
三、服务端关键配置
包括文件地址,查询连接池等,如下:
[root@influxdb2]# cat config.yml bolt-path: /home/data/.influxdbv2/influxd.bolt engine-path: /home/data/.influxdbv2/engine http-write-timeout: 65s http-read-timeout: 305s query-queue-size: 100 query-memory-bytes: 104857600 query-concurrency: 100
具体参见官方配置文档。
四、客户端关键配置(以Java为例)
生产使用,强烈建议配置HttpClient各项参数,通过测试和监控来设置合理的值。
例如压力测试时的配置如下:
Dispatcher dispatcher = new Dispatcher(); dispatcher.setMaxRequestsPerHost(1000); // 默认5 dispatcher.setMaxRequests(1000); // 默认64 OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder() .protocols(Collections.singletonList(Protocol.HTTP_1_1)) // 设置完成请求的超时;调用超时跨越整个调用:解析DNS、连接、写入请求、正文、服务器处理和读取响应正文。如果呼叫需要重定向或 // 所有重试都必须在一个超时时间内完成;默认为0,则不设置超时 .callTimeout(Duration.ZERO) // 建立连接(TCP 套接字)的超时时间;默认值是10S .connectTimeout(Duration.ofSeconds(100)) // 发起请求到读到响应数据的超时时间,默认是10S .readTimeout(Duration.ofSeconds(600)) // 发起请求并被⽬目标服务器器接受的超时时间,默认是10S .writeTimeout(Duration.ofSeconds(60)) // 默认连接池配置默认5,5 .connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES)).dispatcher(dispatcher); InfluxDBClientOptions options = InfluxDBClientOptions.builder().url("http://192.168.10.36:8086") .authenticateToken(token).org(org).bucket(bucket).okHttpClient(okHttpClient).build();
五、我对InfluxDB的测试及评价
1、开源版本不支持集群
不支持集群,性能和容量如何扩展,数据如何备份,需要谨慎评估。如果要买商业版另论。
如果研发能力强,也可以考虑一下自研InfluxDB HA方案及组件,最简单的是类似于sharding-jdbc这种分库分表方法,还有基于Raft的方案。
2、性能
单节点普通配置,同服务器下测试,写入性能达到6w/s左右,算是一流的。查询性能有3w/s,算比较好。相比之下,同样的环境和类似的程序测试下,HBase的查询性能可达300w/s。