目录
series cardinality
tag和field的比较
在把一个值设置为tag或者field之前,需要考虑以下问题:
Batch Points
Down-sample Your Data
存储策略
持续查询
Condense Like Data, Separate Unlike Data
Be Precise
influxdb性能调优
series是influxdb种共享tag集合,measurement,存储策略的数据集合。
series cardinality是一个数据库中唯一series的统计。
举个例子:
你运行了一个web 程序,使用influxdb作为中心数据库用来记录响应时间(当然可能还有一些其他指标)。再每个响应的时间指标里面,你会得到以下信息(item):
1.客户端ip
2.server ip
3.程序的版本version
4.当前请求的响应时间
5.http响应码
现在打算把数据存到influxdb里面,关键的是你要决定每个item里面你打算存储的潜在的基数(cardinality)或者是可能的值,并且还要决定是否当前这个item应该以tag还是field得方式存储。
influxdb为内存中得每个series存储一个反向索引(inverted index),在内存中就表现得相对紧凑,该索引值的大小直接影响查询性能,并且将决定处理该程序的机器的大小。
1.tag在内存中被索引,在查询和分组的时候能够提供非常高性能的查找。但是如果用来太多不同的tag,那么内存和硬件要求就会更高。
2.field在内存中不会被索引,但是能够被用来存储“类型化”的值,并且还可用作数学计算。field对series cardinality也没有影响。
1.这个值的基数高吗?如果高,那么假设它将被用作field
2.在where子句中是否会经常引用这个指标?如果是,那就意味着这个值需要被索引,因此应该以tag存储
3.在group by子句中是否会被引用?如果是,则必须以tag存储,因为field不能在group by中被引用
4.是否要把这个值用在数学函数中(mean(), seddev(),percentile()等)?如果是,那么必须以field存储。
5.是否需要存储一个值的类型(比如int, float, bool, string)?如果是,那么必须以field存储
总之,field用来作为高基数值,可以用在数学函数里面,或者说需要作为特定类型存储的值。使用tag时需要用在group by, where子句的。
客户端ip,代表着终端用户,这个值可能会很大,因此会以field存储。
server ip,这个值取决于操作规模,如果有10个程序服务器,由于基数小,就没必要作为field,当需要查询数据来源于哪个server的时候使用group by就会很有效,因此以tag存储。
程序版本version,这个值基数不会太大,很多程序都不可能有成千上万个版本的,而且在以后按照版本来收集程序性能特征的时候使用group by会很有效,因此以tag存储。
请求响应时间(毫秒),这个值基数会很大,而且在后续逻辑中可能会用来做相关计算,因此以field存储。
http响应码,这个值有明确的基数,也不需要用来计算,用tag存储。
为了避免存储高基数的值作为tag,应该尽可能的限制tag key和tag value的大小。tag key和tag value值越大,所需的内存占用也就越多。
批量,意味着你在同一个http请求或者连接的时候发送多个points。
推荐的起点是每批5000,后续则根据硬件和程序需要进行调整。
长期存储原始数据可能对查询性能和磁盘空间要求很高,应该尽可能的将数据进行采样和聚合。
每个point的存储策略决定了influxdb会保存多长时间。当新建数据库的时候默认的策略是永不删除。
在给定的时间内自动执行的查询。
由于TSM保存和检索数据的方式,仅仅简单的重构数据模式是几乎不会有性能提高的。
1.把相似的数据放到相同的measurement里,容易被压缩和查询。
2.分离不相似的数据到不同的数据库,在一个给定的时间内,只有一个程序负责把数据写入到一个shard里,因此越能将shard分离出来(拆分为不同的数据库),同时发生的写入就越多。
influxdb能够处理从纳秒到小时级别的时间精度。
纳秒(ns)
是最小也是最精确的
微秒(u)
毫秒(ms)
秒(s)
分钟和小时(m/h)
1.不应该选择比收集间隔(collection interval)更小的精度,否则会浪费空间和导致更大的性能开销
2.有规律的间隔点会带来更高效的压缩。(如每隔10秒)。
查询少量的近期数据的性能也优于查询长时间内的大量数据。shard默认是7天,shard越多,查询需要的时间就越长。