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

【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.dtcms.com/a/360498.html

相关文章:

  • 层次分析法
  • Redis实现短信登录
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘SQLModel’问题
  • 37. 解数独
  • 解锁Tensor Core性能:深入探索CUDA Warp矩阵操作
  • Dify构建AI应用
  • FART 主动调用组件深度解析:破解 ART 下函数抽取壳的终极武器
  • #Datawhale 组队学习#8月-工作流自动化n8n入门-3
  • 第七章 使用角色和Asible内容集合简化Playbook
  • 4.4 光照(4) - 高光反射
  • 硬件工程师成长之路:从入门到精通的技术旅程
  • [Plecs基础知识系列]建立自定义模块/子系统(Subsystem)
  • C++ 面试高频考点 力扣 69. x 的平方根 二分查找 题解 每日一题
  • Linux网络socket套接字(中)
  • 切片语法[::-1]及其可用的类型
  • 基于单片机智能鞋柜/智能鞋橱/智能鞋盒
  • Linux - #操作系统概念 #权限
  • 获取某天的零点日期
  • Java 异常处理全解析:从基础到实践
  • Rust 登堂 之 枚举和整数(八)
  • OpenCL C++ 平台与设备
  • 集合-单列集合(Collection)
  • DrissionPage 实战:动态 IP 代理与百度翻译 API 数据抓取
  • LeetCode算法日记 - Day 27: 计算右侧小于当前元素的个数、翻转对
  • Linux wlan 之网络问题定位分析 实例一
  • 如何确定虚拟机的IP
  • Qt QML连接数据库如何解决重复创建连接问题
  • 【嵌入式】【电机控制】基础知识列表
  • K8s调度核心:从Pod分配到节点优化
  • MATLAB R2010b系统环境(四)MATLAB帮助系统