如何将数据插入Prometheus时间序列数据库
前言
在上一篇文章中,作者详细介绍了描述了Prometheus时序数据库在内存和磁盘中的存储结构。有了前面的铺垫,作者就可以解释一下本文中的数据插入过程了。
监控数据的插入
这里作者不讨论Promtheus从各个Endpoint抓取数据的过程。相反,我将仅详细说明如何将数据插入到 Prometheus 中。对应方法:
func (a *headAppender) Add(lset labels.Labels, t int64, v float64) (uint64, error) { ... // 如果lset对应的系列不存在,则建造一个。同时,将新创建的Series放入倒排的Posting映射中,created := a.head.getOrCreate(lset.Hash(), lset) if created { // 如果创建了新的,则放入新的进入 a.在 .series 中 a.series =append(a.series, record.RefSeries{ Ref: s.ref, 标签: lset, }) 到 p>app.Add(labels.FromStrings("foo", "bar "), 0, 0)第一个是getOrCreate,顾名思义,如果不存在就创建一个。创建过程包括seriesHashMap/Postings(倒排索引)/LabelIndex的维护。如下图所示:
然后AddFast方法
func (a *headAppender) AddFast(ref uint64, t int64, v float64) 报错{ / 取出对应的ing memSeries s := a.head.series.getByID(ref) ……s.pendingCommit = True …… // 对于事务的概念,放在TEMP存储中,然后写入Memseries a。 Samples = APPEND(A.SAMPLES, Record.Refsample {Ref, T: T: T: t, v: v,}) //}Prometheus ADD数据点时并不直接添加到Memseries中(即 Query 使用的结构),而是将其添加到一个临时的临时样本切片内。同时,该数据点对应的memSeries被同步到另一个sampleSeries。
交易可见性
我们为什么要这样做?就是实现commit语义,数据只有commit后才可见(可以查询)。否则看不到数据。 commit动作主要是WAL(Write Ahead Log),将headerAppender.samples数据写入到其对应的memSeries中。这样数据就对查询可见了,如下图:
WAL
Si由于Prometheus的最新数据保存在内存中,并不能防止服务器崩溃和丢失数据。它在提交之前写入日志 WAL。当服务重启时,会从WAL日志中获取信息并重放。
为了性能,Prometheus使用另一个goroutine对文件进行同步操作,因此不能保证WAL不会丢失。此外,也不保证监控数据不会丢失。这也是由监控业务的特点决定的。
编写的代码为:
commit() |=> func (a *headAppender) log() error { ... 。系列信息 if len(a.series) > 0 { rec = enc.Series(a.series, buf) buf = rec[:0] if err := a.head.wal.Log(rec); err != nil { 返回错误。Wrap(错误,“日志系列”) ; R=ENC.SAMPLES(A.SAMPLES, BUF) buf=R/REC[:0] if err:=a.Head.Wal.log(REC);呃! = Nil {ReturnErrors.wrap(err, "日志样本")}}对应的WAL日志格式为:
系列记录
<前> ────────────────────────────────────────────── ──────────────────────────────────────────────────── ┐ │ 类型 = 1 <1b> ────────────────────────────────┤ │ ┌── ──── ────┬──────────────────────────┐ │ │ │ id <8b> │ n = len(标签)│ │ │ ├────────┴────────────┬────── ────────────┤ │ │ │ len(str_1) │ str_1 <字节> │ │ │ ├────────────────────────┴──────────── ────┤ │ │ │ ... ──────┬──────────────┤ │ │ │ len(str_2n) │ str_2n <字节> │ │ │ │──────── ───────────────┴──────────────┘ │ │ bsp; │ ────────────────────────────────────────────────── ─┘
样本记录
┌──────────────────── ────────────────────────────────────────────┐ │ 类型 = 2 <1b > │ ├──────────────────────────────────────────────── ────────────────┤ │ ┌──────────────────┬──────── ──── ──────────────┐ bsp; 」 ──────┬──────────┐ ││ │ id_delta│ timestamp_delta │ value <8b> │ │ │ └──────── ────────────┴────────── ──────────────────┴──────────────┘│ │ └──────────── ──────────────────────────────────────────────────── ┘
参见Prometheus WAL.md
下载存储
前面描述的所有数据都写入内存。最终的实现是通过compator例程将每两个小时的数据打包成一个Block。
至此,相信大家对“如何向Prometheus时序数据库插入数据”有了更深入的了解,那么不妨这样做实践中吧!这是网站。更多相关内容,您可以进入相关渠道进行查询。关注我们并继续学习!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > 如何将数据插入Prometheus时间序列数据库