ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

InfluxDB实战指南:从数据模型到运维排坑的完整梳理

InfluxDB实战指南:从数据模型到运维排坑的完整梳理 得先聊一个很多人都会踩的坑。去年有个朋友找到我说他们的一套监控系统上线三个月MySQL里攒了几千万条监控数据查最近一个月CPU使用率要多长时间一条慢查询卡到十秒开外整个业务都跟着遭殃。我问他监控数据长什么样他说就是每台机器每十秒上报一次CPU、内存、磁盘IO外加几个业务接口的响应时间。我说你这就是典型的时序数据存储场景非要用关系型数据库硬扛早期数据量小看不出来问题等数据积累到一定程度查询要按时间范围做全表扫描索引再优化也扛不住。后来我把这套监控的数据迁到InfluxDB同样的查询从十几秒降到了几十毫秒存储占用还直接砍掉了一大截。这篇文章就是围绕这个话题展开的。InfluxDB是一款专门为时序数据设计的开源数据库核心解决的是“高频写入、海量时间维度数据、按时间范围聚合分析”这类场景应用范围覆盖监控系统、物联网设备数据采集、工业传感器数据、金融行情数据等。无论你是刚听说时序数据库这个概念还是已经在生产环境用着InfluxDB但想系统理一遍核心机制这篇文章都值得花时间看完。我会从数据模型、环境部署、写入查询、运维排坑到生态集成把整个知识框架完整串一遍重点是帮你看清楚InfluxDB为什么这么设计、在什么场景下选型合适、实际操作中又有哪些坑不能踩。1. InfluxDB到底是什么先搞清楚它和MySQL这类数据库的差别1.1 时序数据的痛点和InfluxDB的定位要理解InfluxDB先得理解一类特殊的数据时序数据。简单说就是每条数据都带着一个时间戳一旦写入基本不会更新后续主要是按时间范围做查询和统计。机器监控指标、App埋点日志、智能水表上报数据、股票买卖的报价记录这些都是典型的时序数据。这类数据有几个鲜明的特点。第一是写入极其频繁以监控为例一台机器每10秒上报一次指标1000台机器每秒就是100条写入一天下来就是近千万条记录。第二个特点是数据基本不做修改你很少会去改一条三天前的CPU监控数据。第三是查询模式固定大多数需求都是“最近一小时每5分钟的平均CPU”“过去一周磁盘空间的变化趋势”这类按时间范围聚合的操作。传统关系型数据库在这类场景下问题很明显。MySQL即便加了索引面对海量的时间范围查询还是会非常吃力而且每行数据都要存索引、做页分裂空间浪费严重。写入频繁还会带来锁竞争并发一高就会成为瓶颈。更麻烦的是如果你只是偶尔想查一下很久之前的数据这份成本依然得保留存储开销根本降不下来。InfluxDB的设计就是奔着这套场景去的。它使用自定义的列式存储和高效的压缩算法对时序数据做了大量针对性优化。单机版就能支撑每秒几十万到上百万的写入取决于硬件和Schema设计空间占用通常只有传统数据库的十分之一甚至更低。而且它还内置了持续聚合能力可以把原始数据自动降精度这样查“过去一年每小时的趋势”这种大范围查询也能秒级完成而不需要把昨天写库的明细数据都翻出来。所以你看MySQL和InfluxDB的核心区别不是谁比谁强而是适用场景不同。MySQL适合状态型数据比如用户信息、订单记录数据会持续更新需要复杂的关系查询和事务支持。InfluxDB适合事件型数据比如传感器读数、监控指标数据量大、只追加、按时间维度分析。很多人问“能不能用InfluxDB代替MySQL”这是个伪命题两个系统的设计起点完全不同硬要用InfluxDB去存用户账号密码反而会把自己坑得很惨。1.2 InfluxDB 1.x、2.x和3.x怎么选接触InfluxDB时很多人第一个困惑就是版本。目前社区和实际生产环境里1.8还在大量使用2.x已经比较成熟3.x也已经在逐步推进。这三个大版本在架构、查询语法和认证方式上都有不小差异选错了学习资料是相当痛苦的事情。1.x系列最经典用的是InfluxQL语法和SQL长得非常像SELECT、WHERE、GROUP BY这些写起来几乎没有学习成本。数据组织方式是database、measurement、tag、field配合retention policy来管理数据过期。很多人2018、2019年写的教程都是基于1.x的到今天依然有参考价值因为它真的简单稳定。2.x则在底层做了大改引入了bucket取代database和retention policy这对概念查询语言换成了Flux认证方式也改成token。这套改动灵活但学习曲线明显变陡Flux的语法又和SQL不太一样初次上手会觉得不太适应。那么生产环境到底选哪个我的建议很直接如果你的业务是2019年之前就用InfluxDB做的团队已经培养了基于InfluxQL的维护习惯升级诉求不大就继续用1.8版本毕竟稳定压倒一切。如果是全新项目、没有历史包袱建议直接用2.x或者3.x把Token机制、bucket和Flux这些新生态一次吃透。尤其现在InfluxDB官方在持续演进3.x版本新项目没必要在1.x上开个维护老摊子。很多教程一上来就讲InfluxQL然后突然跳到Flux读着读着就乱了。这篇文章后续的核心概念和运维部分我会把1.x和2.x的对应关系都点出来。你只要理解了一边另一边对照着看其实很好入门。2. 核心概念逐个拆measurement、tag、field、point别搞混2.1 数据模型每条“记录”到底长什么样InfluxDB的数据模型看着不难但初学阶段特别容易绕晕。我第一次接触时死活不明白为什么一条数据既叫measurement又有点还有tag和field的区分。后来我用一个生活化的类比才算真正理解你可以把InfluxDB的存储想象成一个带自动索引的时间轴笔记本每一条记录都是一个pointpoint上贴了几类标签一类是指标含义一类是标签属性一类是指标数值。拆开来看一个point由四部分组成time、measurement、tag set、field set。time就是这条数据产生的时间戳精确到纳秒。measurement表示你要存的是哪一类指标可以理解为关系型数据库里的表名比如叫cpu、memory、temperature。measurement后面跟着的tag set可以理解成额外用来过滤的维度属性比如host、region、device_id这些tag相当于数据库里带索引的字段查询时可以快速过滤。field set就是真正存储数值的字段可以是一个或多个比如usage_idle、usage_user这些它们不太适合用来做查询过滤条件更适合存实际的测量值。举个例子用InfluxDB的写入协议表示一条CPU监控数据是这样写的cpu_usage,hostweb01,regioncn-bj usage_idle87.6,usage_user10.2 1620000000000000000这条line protocol从左到右依次是测量名cpu_usage两个tag分别是host和region逗号分隔的多个field是usage_idle和usage_user最后跟的是纳秒级时间戳。这里面有个细节必须搞清楚tag是用索引且只能存字符串的field是值可以变化且类型多样的但field不做全文索引所以在查询里如果对field做大范围过滤性能不会太好。在实际使用中我强烈建议你对tag和field提前做好Schema规划。监控场景下host和region这种几十个可枚举值的维度设置为tag非常合适而CPU使用率、内存剩余量这类连续变化的数值设置成field。如果你把主机名这种高基数的tag塞进InfluxDB指tag组合的基数过大内存索引会直接爆掉这是我踩过最大的一个坑后文我会再单独展开。2.2 保留策略与桶数据生命周期管理时序数据最大的特点是永远在增长但是否所有数据都需要永久保存绝大多数场景不是这样。监控数据一个月前的明细可能价值就急剧下降只需要看个趋势而一年前的数据很多时候连趋势都不用看。InfluxDB提供了数据生命周期管理的机制1.x叫Retention Policy简称RP保留策略2.x则直接叫Bucket其实理念完全一样。保留策略最核心的配置就两个参数数据保留多久、分片多久落一次盘。一个典型的1.x建RP语句是这样的CREATE RETENTION POLICY rp_30d ON mydb DURATION 30d REPLICATION 1 DEFAULT;这句的意思是在这个数据库上创建一条30天过期的保留策略默认数据按这个策略来存。时间一到数据就会被自动删除更准确说是标记掉然后后台compaction清理掉磁盘空间。2.x里你只需要在创建bucket时指定一个retention period比如30天之后写入这个bucket的数据就会自动按这个时间窗管理。RP的价值不只是删除数据它能帮你做多级降采样。比如原始数据10秒一条保留7天7天内如果需要秒级分析直接用原始数据超过7天自动对原始数据做聚合按每分钟一条存进另一个宽口径的RP保留一年。这样既保留了数据的整体趋势又不会让存储无限膨胀。这个多级策略很多监控系统都在用配合下一节要说的持续查询或任务基本就是一套“自动水滴定期归档”的完整方案。2.3 连续查询与任务让系统自己帮你“瘦身”光有RP还不够因为数据过期只是删除并不解决“趋势分析要保留更长时间”的问题。这时候就要用持续查询Continuous Query1.x叫法或者任务Task2.x叫法来做自动降精度聚合。思想很简单系统每个固定的时间窗口比如每5分钟运行一次查询把这段时间内的原始数据做聚合求平均值、最大值、最小值然后将聚合结果写入到另一个measurement或bucket。这样你可以让原始10秒级数据只保留几天但分钟级聚合结果可以保留好几个月查询“过去一个月趋势”的速度还会更快。1.x里的连续查询长这样CREATE CONTINUOUS QUERY cq_1m_cpu ON mydb BEGIN SELECT mean(usage_user) AS usage_user_mean INTO cpu_usage_1m FROM cpu_usage GROUP BY time(1m), host END;这段查询会每分钟自动执行一次从cpu_usage这个measurement里取出前1分钟的原始数据按host分组把usage_user的均值写入到cpu_usage_1m这个新表。2.x引入了Flux语法和Task任务机制本质思路一样但表达更灵活可以一次处理多个数据源、做更复杂的窗口计算。Task还可以自定义调度间隔和延迟补偿实用性更强。我的经验是多级降精度策略最好在项目初始化时就定下来不要等数据量已经变大了再回头补否则原始数据堆积阶段磁盘膨胀很快补建任务时又要额外消耗计算资源去回填历史数据。3. 从零搭建一套最小可用的InfluxDB环境3.1 安装方式和目录规划部署InfluxDB其实非常简单官方提供了各大操作系统的安装包和静态二进制压缩包。以Linux环境为例你只需要下载压缩包、解压、改配置、启动这四步。但这里有一个很多人忽略的点InfluxDB会写不少落盘文件物理目录规划不好后续很容易遇到磁盘空间不足的问题。如果你用APT或YUM安装默认的数据目录是/var/lib/influxdb1.x和2.x略有差异。1.x版本数据目录下有meta、wal、data三个子目录meta存数据库元信息wal是预写日志data是最终存储数据2.x版本则使用bolt文件存储元数据和engine目录存储时序数据。生产环境下我建议把数据目录挂载到独立的、性能较好的磁盘上至少要和系统盘分开。这样万一数据量爆炸导致磁盘写满不会影响整个服务器如果条件允许用SSD做WAL目录也能明显降低写入延迟和抖动。InfluxDB本身对部署架构要求不高单机版已经能处理很高的写入速率这也是它相比很多分布式数据库在中小团队里更受欢迎的原因。分布式集群方案比如InfluxDB Enterprise能力和商业授权都有门槛一般团队用单机或者多节点副本就够了。启动完成后1.x默认不需要认证就能访问2.x则需要在浏览器里做一次初始化创建管理员账号、组织、bucket。如果是生产环境一定要立刻开启认证并创建专用的只读账号给监控面板用避免用admin token去写查询接口。配置项里把http.bind-address和auth-enabled改一下就够。3.2 写入第一条数据从命令行到写接口环境装好后最快体验写入数据的方式是直接用InfluxDB自带的CLI或者HTTP API。我个人习惯第一步先用命令行确认写入协议能跑通再做集成。以2.x为例可以先创建一个副本然后通过influx CLI写入数据influx write \ -b my_bucket \ -o my_org \ -t my_token \ -p sensor_data,device_iddev_001 temperature25.6,humidity58.3 1620000000000000000这条命令会把一个point写入到sensor_data measurement带上device_id这个tag以及temperature、humidity两个field时间戳是自定义的纳秒值。如果你不想指定时间戳InfluxDB会自动取当前系统时间。这个设计很常用因为很多数据源上报时并不带时间戳又想以到达时间作为记录时间此时只需要省去末尾时间戳即可。生产环境一般是通过HTTP API来写数据的POST请求的body就是line protocol文本比如curl -XPOST http://127.0.0.1:8086/api/v2/write?bucketmy_bucketprecisionns \ -H Authorization: Token my_token \ --data-binary sensor_data,device_iddev_001 temperature25.6 1620000000000000000这里有一个关键参数precision。它表示传输时间戳的精度可以是ns、us、ms、s。很多开发者在写Python代码时习惯性用int(time.time() * 1000)传毫秒却忘了在URL里把precision设成ms结果数据的时间戳被按纳秒理解一下子就变成1970年附近的日期了。这个坑我在对接第三方SDK时遇到过好几次排查过程特别折腾。建议在接入初期就固定好时间戳精度并在接口层做一层转义不要依赖上游的自觉。3.3 查询入门从InfluxQL到Flux查询这块1.x的InfluxQL和2.x的Flux差异很大但如果只做基础查询其实两者的学习成本都在半小时内。先说InfluxQL它的风格更接近SQLSELECT mean(usage_idle) AS avg_idle FROM cpu_usage WHERE host web01 AND time now() - 1h GROUP BY time(10m)这个查询的意思是从cpu_usage中取web01这台机器最近1小时的usage_idle数据按10分钟一个窗口做平均值计算返回最近6个聚合点。InfluxQL对新手非常友好理解GROUP BY time()这个语法以后常规的聚合分析都能写出来。2.x的Flux查询则是另一种风格它更像函数式管道。同样做最近一小时CPU平均值的查询Flux会写成from(bucket: my_bucket) | range(start: -1h) | filter(fn: (r) r._measurement cpu_usage and r.host web01) | filter(fn: (r) r._field usage_idle) | aggregateWindow(every: 10m, fn: mean)Flux最核心的思维是“每一步都在变换数据流”。from从bucket读数据range限定时间范围filter做维度过滤最后用aggregateWindow做窗口聚合。这套语法写复杂任务时非常灵活但如果你只是想要一条简单的监控趋势线确实会比InfluxQL绕一些。我的建议是1.x环境老老实实用InfluxQL2.x环境日常查询也可以用InfluxQL兼容层InfluxDB 2.x默认还支持InfluxQL查询复杂任务或数据转换再考虑Flux。不要为了用花活而用花活查询可维护性优先。4. 写入与查询的最佳实践这些设计和坑我都是踩过才懂的4.1 Tag、Field设计的基本法什么能当tag什么必须当fieldInfluxDB的Schema设计直接决定了数据库的性能上限这是时序数据库和关系型数据库一个很重要的不同点。关系型数据库的Schema设计主要考虑关系建模和索引优化而InfluxDB的Schema设计最核心的原则是控制tag的基数。什么叫基数就是某个tag字段所有不同取值的数量。比如host这个tag如果总共有20台机器那基数就是20如果统计用户上报的浏览器UA字符串那基数可能是几千甚至几万。InfluxDB会把所有的tag和维护在内存索引结构里用来快速过滤数据量基数越大内存占用就越高一旦基数爆炸比如超过百万级别内存会被直接占满查询、写入都会大幅卡顿甚至直接OOM崩溃。实际场景中最常见的高基数tag案例是什么机器ID、用户ID、订单号、URL地址。我见过一个团队把HTTP请求的完整URL当成tag每分钟几万次请求每个URL带不同的query参数几天下来tag基数突破几十万监控页面直接打不开。后来把所有URL参数从tag挪到field只把固定不变的路径部分做tag问题才解决。判断标准其实很简单**你查数据时是否常用某个维度做过滤这个维度的取值是否相对稳定和有限**回答“会过滤且取值有限”的就放tag剩下的、尤其是高基数的取值放field更安全。此外field是可以有类型的数值类型包括float、integer、unsigned、boolean、string写入时能明确类型就用明确的类型别让数据库反复推断。4.2 写入性能优化批量、测点命名和不必要的潮流用InfluxDB接入数据源时很多人的第一版代码是每条数据来了就发一次HTTP请求结果数据量稍微一上来写入吞吐就崩。InfluxDB的单条写入开销主要在HTTP请求和WAL fsync一条一条地请求完全浪费了服务端的批量写入能力。正确的做法是攒一批数据一次性写入批量大小建议在5000~10000条之间并适当牺牲一点实时性换取写入吞吐。除了批量测点命名也影响写入性能。这里涉及InfluxDB的底层存储机制数据会先写入内存中的缓存和预写日志WAL然后再定时合并落盘落盘的文件称为TSM文件。同一块数据点越集中、越连续压缩效果越好如果一条一条穿插着不同measurement的数据写入分片和压缩的收益就会下降。把同类的采集目标放到同一个measurement下面并保持固定的tag组合能让写入的连续性更友好。还有一点很多人忽略时间戳不要回退太多。InfluxDB内部会维护着一个时间窗口如果一个数据点的时间戳比当前时间落后太多比如补了一周前的老数据它会落到一个很老的shard上导致这个shard的压缩和合并频率提升长时间大量回填数据还会让查询性能出现抖动。所以代码里要尽量把实时数据用当前时间写入历史数据回填要做分批限速。4.3 查询性能优化为什么你的GROUP BY time()查得这么慢写完数据之后最影响体验的就是查询速度了慢查询在InfluxDB里通常由几个因素造成。第一个是每次都查原始数据做大范围扫描。比如你已经存了半年原始10秒级数据却每次查询“近三个月每天的聚合值”这时所有原始点都会参与计算。最佳实践仍然是前文提到的降精度策略把长时间粒度的查询尽量落到聚合表或聚合bucket上。第二个是time范围不写或者写得太宽。InfluxDB的查询引擎会根据时间范围筛选对应的分片文件时间范围太宽意味需要扫描的分片更多自然就慢。虽然InfluxDB是一个时间序列数据库但在查询时仍然要养成显式限制时间范围的意识不要默认查全量。第三个是field做过滤。前文说过field没有索引如果查询条件里有WHERE fieldxxx这种必然要做全文件扫描。比如你存了host、region、cpu、mem等多个指标在同一个measurement里然后想查cpu指标正确姿势是用tag做个标识或者在measurement层面直接就拆成cpu、mem不同的measurement让扫描文件的范围更小。如果在同一数据表中既有cpu又有mem靠field级别的过滤来查性能会明显差。另外还要关注是否开启了压缩存储。默认InfluxDB落盘的TSM文件是压缩的压缩可以在几乎不损失读取速度的情况下显著减少磁盘空间占用对查询时的磁盘IO也有正向影响。不要因为担心压缩影响性能就关掉这个开关很多情况下并不划算。5. 运维与问题排查这几类坑我基本都踩过5.1 “数据库死锁”和锁文件问题InfluxDB真会死锁吗热搜词里有“数据库死锁”这个词放在InfluxDB场景里其实很多人遇到的不是传统意义上的死锁而是服务启动失败或者写入卡住一段时间。最典型的现象是服务器异常断电或重启之后InfluxDB进程起不来日志里提示“timeout exceeded while waiting for lock on shard”这就是shard层面的锁释放问题。InfluxDB在写入和合并TSM文件时会对shard加锁如果进程被kill -9或服务器强制断电锁文件可能残留导致后续启动无法重新拿到锁。遇到这种情况的排查步骤通常是先看进程是否还活着没有的话查看数据目录下是否有遗留的.lock文件手动清理掉然后重启服务。这里要提醒一句清理锁文件前务必确认没有其他InfluxDB进程还在运行最好是先停服务再清理否则可能造成正在写入的WAL数据损坏。还有一种“卡死”的情况是Compaction压缩合并任务长时间卡在某个shard上导致同一shard的写入也变慢。此时可以先用influxd inspect工具检查具体是哪个shard一直处于compaction状态再决定是等待完成还是暂停压缩任务。总之InfluxDB的“死锁”不像MySQL那种事务锁冲突更多是文件锁和任务调度问题。运维上做好优雅停机和定时清理日志问题会少很多。5.2 磁盘占用暴涨为什么删除数据后空间没有立刻释放另一个高频问题是磁盘占用居高不下甚至删除了大量数据后空间却没有回来。原因和InfluxDB的存储引擎设计有关。InfluxDB不会因为你有RP就同步删除底层TSM文件删除动作是标记操作真正释放空间是靠后续的压缩合并流程把标记过的数据清理掉。如果写入压力很大、压缩任务来不及执行或者压缩被限定得很低那么磁盘空间就会迟迟不释放。遇到这种情况先检查压缩相关的配置比如1.x里cache-snapshot-memory-size、compact-throughput这些参数2.x里可以通过任务队列观察compaction状态。如果磁盘压力非常紧急可以考虑在线执行一次全量压缩任务InfluxDB提供了相关命令可以触发对特定shard的压缩。日常运维建议就是给磁盘空间留足冗余不要卡着90%的用量线才想起来清理因为大表重组期间所需的临时空间比你想的多。顺带提一下文件系统层面默认写时序数据时InfluxDB会产生很多小文件如果你的文件系统inode不够也会表现成“磁盘满了但du还显示没满”的诡异情况。用df -i看一下inode使用率这也是我踩过一次的坑。5.3 CPU、内存配置与“数据库只能使用多少核心”的误区有网友搜“数据库只能使用40个核心”这类问题在InfluxDB语境下其实是一个容易讲混的话题。InfluxDB的写入和查询大多是CPU密集型的压缩、聚合、合并这些环节都吃CPU理论上核心越多越好但并不是说把机器所有核心都直接喂给InfluxDB就是最优解。在1.x版本里InfluxDB内部并行压缩任务的并发数上限一般受runtime.GOMAXPROCS影响一些发行版默认可能不识别所有核心数。在2.x和3.x版本里你可以通过配置调度参数控制查询并发和合并任务的并行度。实际操作中我建议给InfluxDB预留一定的CPU余量不要把CPU干到100%否则写入时延会明显抖动。比如一台16核的机器可以考虑给查询并发和压缩任务各预留4个核心的余量让系统给你一定的弹性。内存方面InfluxDB会大量使用内存作为缓存和索引。这个缓存大小通常受配置上限控制如果你给的机器内存小又写了特别大的tag基数OOM的风险非常高反之如果内存很大但配置里没有把缓存上限调高内存利用率也不充分。比较合理的做法是先根据机器的物理内存确定cache上限比如32GB机器就留一半给InfluxDB作为内存上限然后持续观察内存压力。这些配置都需要结合自己的数据规模做微调没有一个万能模板。5.4 备份恢复与迁移同步怎么带数据搬家说到“数据库同步”“数据库迁移”InfluxDB的备份恢复机制在1.x和2.x上有明显差异这也是很多人在迁移时踩坑的地方。1.x版本常用influxd backup备份influxd restore恢复它们会生成一份meta和一份数据文件的备份。全量备份时要确保在备份期间没有写入操作或者要接受部分数据可能滞后。2.x版本的备份命令是influx backup需要指定token、org和bucket备份到的文件夹里包含元数据快照和数据文件。恢复也是对应的influx restore。注意备份文件的版本必须和目标实例匹配比如2.0版本备份的文件不能直接恢复到2.7版本尤其是元数据部分这会让你格式不兼容老版本没注意很容易白忙一场。如果要做跨实例的数据同步实现方案各不相同。简单场景下可以全量导出数据再用influx write或influx CLI导入到新库实时性要求高的话可以考虑在应用层做双写或者用Telegraf的execd插件做数据转发。InfluxDB本身在单机版没有提供原生的主从复制这一点跟MySQL的master-slave机制不一样也不是同一个产品定位。跨区域的多活容灾属于商业版和高可用方案的范畴如果你正在评估高可用架构要把这个预期先摆正。6. 与生态集成让InfluxDB真正跑在业务里6.1 用Telegraf采集系统指标InfluxDB配套最常用的采集器就是Telegraf它和InfluxDB同属一个技术栈采集、处理、转发时序数据非常顺手。一段最简单的Telegraf配置就能把系统的CPU、内存、磁盘、网络指标采集到InfluxDB[[inputs.cpu]] percpu true totalcpu true [[inputs.mem]] [[inputs.disk]] [[inputs.net]] [[outputs.influxdb_v2]] urls [http://127.0.0.1:8086] token your-token organization your-org bucket system_statsTelegraf采集到的数据会打上host这个tag来区分机器默认情况下它会自动在数据后追加上当前时间和一些统计信息。对比自己写采集脚本Telegraf的好处是插件生态丰富已经覆盖MySQL、Redis、Nginx、Kafka等几十种常见中间件的指标采集还有内置的聚合和过滤能力。集群部署时建议给Telegraf单独分配一个账号只授予写入权限避免密钥泄露后被拿来查询全量数据。我之前接手过一套自己写脚本上报数据的监控系统每次指标格式调整都要改采集脚本后来切到Telegraf之后新增采集项只是加一段配置的功夫维护成本下降特别多。如果你当前还在一行一行手写采集脚本建议尽早切到Telegraf上来。6.2 用Grafana做可视化告警InfluxDB自带了一个简单的UI但要说做出专业的监控大屏和告警Grafana是事实标准。Grafana可以很方便地添加InfluxDB数据源1.x选择InfluxQL2.x可以选择Flux数据源或InfluxQL兼容层然后在面板上写查询语句、配置时间范围、调整图例。监控大屏的做法网上教程很多这里我更想提醒一个实际运维中容易踩的坑多个面板同时查询大时间范围会把InfluxDB查询并发打爆。因为Grafana的每个面板都会独立发起查询请求如果你一屏放了十几个面板每个面板都查询“过去7天每秒的趋势”InfluxDB要同时执行十几条大范围查询压力非常大。解决办法是给面板配置不同的刷新频率或者利用Grafana的模板变量和缓存特性减少重复查询更彻底的做法是之前的降精度策略把长时间趋势查询落到聚合bucket上。监控大屏不是堆指标合理规划面板和查询范围才有真的大屏体验。6.3 应用侧接入SDK以Python为例快速上手如果你的业务系统需要自己上报业务指标InfluxDB官方提供了丰富的客户端SDKPython版用起来很顺手。PIP安装influxdb-client库之后写入数据一般分两步先创建写入API再用write方法写入一个点集合。from influxdb_client import InfluxDBClient, Point from influxdb_client.client.write_api import SYNCHRONOUS client InfluxDBClient(urlhttp://127.0.0.1:8086, tokenmy-token, orgmy-org) write_api client.write_api(write_optionsSYNCHRONOUS) point Point(order_metrics) \ .tag(region, cn-bj) \ .field(order_count, 100) \ .field(total_amount, 9980.5) write_api.write(bucketbusiness_stats, recordpoint)这段代码会把一个业务指标点写入order_metrics measurement包含region这个tag和两个field。需要注意的坑是SYNCHRONOUS模式是同步写入每条都会等服务器确认吞吐较低适合调试或低频场景生产高吞吐建议改用BATCH模式把多个点攒成批一次性发送官方Python库已经封装好了批量缓冲逻辑你只需要设置flush间隔或batch size。查询侧用Python库做聚合分析同样方便这里以InfluxQL为例query_api client.query_api() result query_api.query( SELECT mean(total_amount) AS avg_amount FROM order_metrics WHERE time now() - 1d GROUP BY time(10m), region ) for table in result: for record in table.records: print(record[region], record[_time], record[avg_amount])按区域和时间窗口统计日均金额和单量是业务侧非常有代表性的用法。后续如果要把这些聚合数据接进报表、推送到消息队列或者写回另一个存储都只是再加一步处理的功夫InfluxDB的数据链路在这里可以很自然地衔接到业务数据平台里。写到这里我觉得InfluxDB最有效率的打开方式其实是把它当作时序数据的“操作系统”来对待先把数据模型和理解清楚知道哪些场景适合它、哪些不适合再结合保留策略、降精度、查询优化这些手段让它自然地运行起来。前前后后我看过不少团队在时序数据存储上各种绕路要么用传统数据库硬扛到崩溃要么一上来就上重型分布式架构其实大部分场景下一台跑着InfluxDB的单机就已经能支撑很高的写入量和查询需求。做技术选型还是要回到业务本身的数据特征而不是沉迷于工具的复杂度。
返回列表