InfluxDB架构设计和数据布局

原创 2018-07-20 11:44 阅读(347)次

InfluxDB架构设计和数据布局


作为专门针对时间序列数据的存储,InfluxDB在使用的时候也需要针对本身的特性结合需求来设计schema。
1. 针对tags和field的特性进行设计schema
tag 被索引,查询速度快。field没有做索引,查询需要scan,速度慢。
根据以上特性
常用来查询的数据存放在tags中
计划用来group by() 的数据,放在tags中
数据计划用InfluxQL function来处理的,放在fields中
数据需要表示为string以外的值,放在fields中。(tags始终表示为字符串)

2. 避免用InfluxQL的关键字作为标识符名字

这个约定在传统数据库中也是常见。标识符包括:数据库名称,保存策略名称,用户名,measurement名称,tag key和field key。
虽然这点在InfluxQL中不是强制的,但如果使用了关键字,编写查询的时候需要把标识符放在双引号中,增加了麻烦。

3. 不要有太多的series
tags包含类似UUID,hashes,随机字符串这种大量不重复的数据会导致数据库中出现大量series,称之高series基数,会造成数据库的内存高工作负载。
如果内存有限制,建议将高基数数据放在fields,而不是tags。

4.  不要把数据都集成到measurement name
InfluxDB查询的时候会合并同一个measurement的数据,用tags区分不同的数据要比把数据都集中起来要好。
我认为就是不希望把所有数据当成文本一样存在一个字段中。
例如:

Schema 1 - Data encoded in the measurement name
-------------
blueberries.plot-1.north temp=50.1 1472515200000000000
blueberries.plot-2.midwest temp=49.8 1472515200000000000
measurement name中的plot和region等信息进行编码将使数据更难查询。
如果要schema 1上计算plot1和plot2 的平均温度是不可能的。

采用schema 2
Schema 2 - Data encoded in tags
-------------
weather_sensor,crop=blueberries,plot=1,region=north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,plot=2,region=midwest temp=49.8 1472515200000000000
把数据分布到不同的tags
这样去查询平均值就要容易得多。
或许你会觉得使用正则表达式的方式在schema1上进行查询也是一种方式,但被证实正则表达式查询只会更复杂,甚至无法实现。
如下对比两种写法
# Schema 1 - Query for data encoded in the measurement name
> SELECT mean("temp") FROM /\.north$/


# Schema 2 - Query for data encoded in tags
> SELECT mean("temp") FROM "weather_sensor" WHERE "region" = 'north'
显然schema 2更适合大部分程序员。

5. 跟第4条类似,不要把太多信息放在同一个tag中
拆分会更容易简化查询,并减少正则的使用。

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


Schema 2 - Data encoded in multiple tags
-------------
weather_sensor,crop=blueberries,plot=1,region=north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,plot=2,region=midwest temp=49.8 1472515200000000000

自行比较一下在schema1和2上的InfluxQL写法

# Schema 1 - Query for multiple data encoded in a single tag
> SELECT mean("temp") FROM "weather_sensor" WHERE location =~ /\.north$/


# Schema 2 - Query for data encoded in multiple tags
> SELECT mean("temp") FROM "weather_sensor" WHERE region = 'north'


6. 分片组持续时间的选择
InfluxDB将数据存储在分片组(shard groups)中。 分片组按保存策略(RP)进行组织,根据数据的时间戳,将在特定时间间隔内的数据存储在一个shard中。 该时间间隔的长度称为分片组持续时间。
如果未提供分片组持续时间,则分片组持续时间由RP决定,在创建RP时同时确定持续时间。 默认值为:



RP Duration Shard Group Duration
< 2 days 1 hour
>= 2 days and <= 6 months 1 day
> 6 months 7 days
可以另行配置。
选择分片组持续时间需要有如下考虑
分片持续时间越长,整体性能越好
分片持续时间越短,灵活性越好

原因如下:
长分片持续时间允许InfluxDB在同一个逻辑位置存储更多的数据。这减少了数据重复,提高了压缩效率,提供了更快速的查询。
短分片持续时间允许系统更有效地丢弃过期数据,记录增量备份。InfluxDB在强制执行RP的时候,会丢弃整个分片,而不是单独的记录point。即使单个point已经过了保存策略的时间,也不会单独删除。系统只会删除shard group。如果shard group中还有没有过期的point,不会删除这个分片组。
如:RP是1天,InfluxDB每小时丢弃一次过期数据,并且总的值有25个分片组。
因此建议使用默认的分片组持续时间。
但如果高吞吐量或者长期运行的实力,建议用更长一些的分片组持续时间。


参考如下:

RP Duration Shard Group Duration
<= 1 day 6 hours
> 1 day and <= 7 days 1 day
> 7 days and <= 3 months 7 days
> 3 months 30 days
infinite 52 weeks or longer

infinite表示数据不做过期删除的动作。

同时还需要考虑如下因素
分片组持续时间应该是查询的最大时间范围的两倍。我理解为是为了让一次查询尽量在单个shard中完成,减少跨shard。
分片组应该包含超过100000个point。
分片组中每个series应该包含1000个point。
另外,需要考虑回填分片组持续时间
bulk插入大量历史数据,跨越了大量时间的范围,会触发同一时间创建很多shards。这可能会瞬间耗尽内存,导致性能下降。这种情况强烈建议设置较长的分片组持续时间以减少创建过多分片。比如52weeks的持续时间适合回填数据。

本文完。

本站作品的版权皆为作品作者所有。

本站文字和内容为本站编辑或翻译,部分内容属本站原创,所以转载前务必通知本站并以超链接形式注明内容来自本站,否则以免带来不必要的麻烦。

本站内容欢迎分享,但拒绝有商业目的的转载!