当前位置: 首页 > ds >正文

【influxdb】InfluxDB 2.x 线性写入详解

1. 什么是线性写入

线性写入(Line Protocol)是 InfluxDB 的数据写入格式,它是一种文本格式,用于将时间序列数据高效地写入数据库。

2. 线性协议格式

基本语法

measurement,tag_key=tag_value field_key=field_value timestamp

完整格式

measurement,tag_set field_set timestamp

示例:cpu,host=server01,region=us-west usage=0.64,idle=0.36 1434055562000000000

3. 各个组成部分详解

3.1 Measurement(测量)

  • 作用:数据的主分类,相当于表名

  • 要求:必须存在,不能为空

  • 示例cpumemoryvirtualUsers

3.2 Tag Set(标签集)

  • 格式key=value 键值对,多个用逗号分隔

  • 特点

    • 用于索引和过滤数据

    • 应该是相对静态的元数据

    • 值通常是字符串类型

  • 示例host=server01,region=us-west

3.3 Field Set(字段集)

  • 格式key=value 键值对,多个用逗号分隔

  • 特点

    • 存储实际的数值数据

    • 支持多种数据类型:float, integer, string, boolean

    • 用于查询和聚合操作

  • 示例usage=0.64,idle=0.36

3.4 Timestamp(时间戳)

  • 格式:Unix 时间戳(纳秒精度)

  • 可选:如果省略,InfluxDB 会使用服务器时间

  • 精度:可以在写入时指定(ns, μs, ms, s, m, h)

4. 数据类型表示

字段值数据类型

# 浮点数 (默认)
temperature=23.5# 整数 (数值后加 i)
count=42i# 字符串 (用双引号)
status="running"# 布尔值
active=true

标签值

# 总是字符串类型,不需要引号
host=server01,env=production

5. 特殊字符转义

需要转义的字符

# 逗号、空格、等号需要转义
measurement\,with=comma tag\ key=tag\,value field\ key="field\,value"# 实际写入:measurement,with=comma 的标签键值对

转义规则

  • 逗号\,

  • 空格\

  • 等号\=

6. 写入方式

6.1 HTTP API 写入

curl -i -XPOST "http://localhost:8086/write?db=mydb&precision=s" \
--data-binary '
cpu,host=server01 usage=0.64 1434055562
cpu,host=server01 usage=0.73 1434055563'

6.2 使用客户端库写入

// Java 示例
Point point = Point.measurement("cpu").addTag("host", "server01").addField("usage", 0.64).time(1434055562, WritePrecision.S);writeApi.writePoint(point);

7. 性能优化技巧

7.1 批量写入

// 批量写入多个数据点
List<Point> points = Arrays.asList(Point.measurement("cpu").addTag("host", "server01").addField("usage", 0.64).time(1434055562),Point.measurement("cpu").addTag("host", "server01").addField("usage", 0.73).time(1434055563)
);writeApi.writePoints(points);

7.2 数据排序

按时间顺序写入可以提高压缩效率:

points.sort(Comparator.comparing(Point::getTime));

7.3 适当的批量大小

// 推荐批量大小:5000-10000 个点
int batchSize = 5000;
if (points.size() >= batchSize) {writeApi.writePoints(points);points.clear();
}

7.4 使用 Gzip 压缩

influxDBClient.enableGzip(); // 启用 Gzip 压缩

8. 最佳实践

8.1标签设计原则
// 好的标签:有限的可取值
addTag("region", "us-west")    // 可选值有限
addTag("status", "active")     // 可选值有限// 不好的标签:无限的可取值  
addTag("request_id", "uuid-123") // 每个值都不同,会导致序列爆炸8.2字段设计原则
// 数值数据放在字段中
addField("response_time", 150.5)  // 正确
addField("error_count", 2)        // 正确// 不要将数值数据作为标签
addTag("response_time", "150.5")  // 错误!会导致序列爆炸8.3时间戳管理
// 使用相同的时间精度
WritePrecision precision = WritePrecision.MS;// 客户端时间 vs 服务器时间
.time(System.currentTimeMillis(), precision) // 客户端时间
// 或者不设置时间戳,让服务器分配时间

9. 错误处理

9.1 常见的写入错误

try {writeApi.writePoints(points);
} catch (Exception e) {// 处理写入错误if (e.getMessage().contains("field type conflict")) {// 字段类型冲突} else if (e.getMessage().contains("points beyond retention policy")) {// 数据超过保留策略}
}

9.2 重试机制

int maxRetries = 3;
int retryCount = 0;while (retryCount < maxRetries) {try {writeApi.writePoints(points);break; // 成功则退出循环} catch (Exception e) {retryCount++;Thread.sleep(1000 * retryCount); // 指数退避}
}

10. 实际应用示例

10.1 虚拟用户监控数据

public void writeVirtualUserStats(String testName, String nodeName, String runId, int minThreads, int maxThreads, double meanThreads,int started, int finished) {Point point = Point.measurement(VirtualUsersMeasurement.MEASUREMENT_NAME).addTag(VirtualUsersMeasurement.Tags.NODE_NAME, nodeName).addTag(VirtualUsersMeasurement.Tags.TEST_NAME, testName).addTag(VirtualUsersMeasurement.Tags.RUN_ID, runId).addField(VirtualUsersMeasurement.Fields.MIN_ACTIVE_THREADS, minThreads).addField(VirtualUsersMeasurement.Fields.MAX_ACTIVE_THREADS, maxThreads).addField(VirtualUsersMeasurement.Fields.MEAN_ACTIVE_THREADS, meanThreads).addField(VirtualUsersMeasurement.Fields.STARTED_THREADS, started).addField(VirtualUsersMeasurement.Fields.FINISHED_THREADS, finished).time(System.currentTimeMillis(), WritePrecision.MS);collectData(point);
}

10.2 性能监控写入性能

long startTime = System.currentTimeMillis();
writeApi.writePoints(points);
long endTime = System.currentTimeMillis();LOGGER.info("写入 {} 个数据点,耗时 {} ms", points.size(), (endTime - startTime));// 监控写入速率,计算写入速率
double pointsPerSecond = points.size() / ((endTime - startTime) / 1000.0);
LOGGER.info("写入速率: {}/秒", String.format("%.2f", pointsPerSecond));

总结:线性写入是 InfluxDB 的核心功能,理解其格式和最佳实践对于构建高效的时间序列数据系统至关重要。正确的数据模型设计和写入策略可以显著提高性能和可维护性。

http://www.xdnf.cn/news/19603.html

相关文章:

  • 【IDE问题篇】新电脑安装Keil5,出现找不到arm 编译器版本5编译报错;改为版本6后旧代码编译是出现编译报错
  • 自然语言处理NLP:嵌入层Embedding中input_dim的计算——Tokenizer文本分词和编码
  • android中常见布局及其约束
  • 超越关键词:RAG系统如何破解用户查询的“模糊密码”
  • Redis 中的 Bitmap 与 Bitfield 及 Java 操作实践
  • 【LeetCode】18、四数之和
  • LeetCode 每日一题 2025/8/25-2025/8/31
  • SciPy
  • DrissionPage 实战:动态 IP 代理与百度翻译 API 数据抓取
  • 硬件开发_基于物联网的工厂环境监测系统
  • Qt Demo之 deepseek 帮我写的关于双目标定的小界面
  • redis----zset详解
  • Langflow Memory 技术深度分析
  • Langflow RAG 技术深度分析
  • 人工智能学习:机器学习相关面试题(二)
  • MySQL-视图与用户管理
  • Langchain指南-关键特性:如何流式传输可运行项
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘SQLModel’问题
  • 案例——从零开始搭建 ASP.NET Core 健康检查实例
  • 齿轮加工刀具材料漫谈:从高速钢到陶瓷的 “切削艺术”
  • 传统数据库out啦!KINGBASE ES V9R1C10 开启国产数据库“修仙”新纪元!
  • Day19_【机器学习—线性回归 (2)】
  • 正则表达式 Python re 库完整教程
  • 生存分析入门教程
  • 馈电油耗讲解
  • AssemblyLoadContext`的插件化架构
  • Qt libcurl的下载、配置及简单测试 (windows环境)
  • springboot项目启动时打印maven打包时间
  • [Mysql数据库] 知识点总结8
  • 计算机网络:(十六)TCP 的运输连接管理