当前位置: 首页 > 科技观察

Prometheus时序数据库——数据插入

时间:2023-03-16 01:52:36 科技观察

前言在上一篇文章中,笔者详细阐述了Prometheus时序数据库在内存和磁盘的存储结构。有了前面的铺垫,笔者就可以把本文的数据插入过程解释清楚了。监控数据的插入就到这里,Promtheus从各个Endpoint抓取数据的过程笔者就不展开讨论了。相反,它仅详细说明了数据如何插入Prometheus的过程。对应方法:func(a*headAppender)Add(lsetlabels.Labels,tint64,vfloat64)(uint64,error){...//如果没有lset对应的series,则创建一个。同时,将新的series放入倒置的Postingmaps,created:=a.head.getOrCreate(lset.Hash(),lset)ifcreated{//如果有新的创建,则将新的放入a.在系列中a.series=append(a.series,record.RefSeries{Ref:s.ref,Labels:lset,})}returns.ref,a.AddFast(s.ref,t,v)}我们将使用下面以调用add函数为例:app.Add(labels.FromStrings("foo","bar"),0,0)首先getOrCreate,顾名思义,不存在就创建一个。创建过程包括维护seriesHashMap/Postings(倒排索引)/LabelIndex。如下图:然后就是AddFast方法func(a*headAppender)AddFast(refuint64,tint64,vfloat64)error{//取出对应的memSeries:=a.head.series.getByID(ref)......//设置为等待commit状态s.pendingCommit=true...//对于transaction的概念,先放入tempstorage,等待realcommit后再写入memSeriesa.samples=append(a.samples,record.RefSample{Ref:ref,T:t,V:v,})//}Prometheus在添加数据点时并没有直接添加到memSeries(即query使用的结构)中,而是添加到一个临时的samples中里面切片。同时将这个数据点对应的memSeries同步添加到另一个sampleSeries中。为什么交易可见性会这样做?就是实现commit语义,commit之后数据才可见(可以查询)。否则,数据是看不到的。commit的动作主要是WAL(WriteAheadLog)以及将headerAppender.samples数据写入到其对应的memSeries中。这样查询就可以看到数据了,如下图:WAL并不能防止服务器崩溃丢失数据,因为内存中存放的是Prometheus的最新数据。它在提交之前写入日志WAL。当服务重新启动时,从WAL日志中获取信息并重播。为了性能,Prometheus使用了另一个goroutine来做文件同步操作,所以不能保证WAL不会丢失。此外,也无法保证监控数据不会丢失。这也是由监控服务的特性决定的。写入代码为:commit()|=>func(a*headAppender)log()error{......//将对应的系列信息写入WALiflen(a.series)>0{rec=enc.系列(a.series,buf)buf=rec[:0]iferr:=a.head.wal.Log(rec);err!=nil{returnerrors.Wrap(err,"logseries")}}...。..//写真实样本iflen(a.samples)>0{rec=enc.Samples(a.samples,buf)buf=rec[:0]iferr:=a.head.wal.Log(rec);err!=nil{returnerrors.Wrap(err,"logsamples")}}}对应WAL日志格式:系列记录┌────────────────────────────────────────────────────────────────┐│type=1<1b>│├────────────────────────────────────────────────────────────────┤│┌──────────────────────────────────────────────────────────────────────────────┐│││id<8b>│n=len(labels)││├──────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│││len(str_1)│str_1.....││──────────────────────┬────────────────┤┤││Len(str_2n)│str_2n││└─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘││...│└──────────────────────────────────────────────────────┘样本记录┌──────────────────────────────────────────────────────────────────┐│type=2<1b>│├──────────────────────────────────────────────────────────────────┤│┌──────────────────────┬──────────────────────────┐│││id<8b>│时间戳<8b>│││└────────────────────┴────────────────────────────┘││┌────────────────────┬────────────────────────────┬────────────┐│││id_delta│timestamp_delta│value<8b>│││└────────────────────┴────────────────────────────┴──────────────┘││...│└────────────────────────────────────────────────────────────────┘见PrometheusWAL.md落盘存储之前描述的所有数据都在写组合器常规将里面落地将将将小时的的到到一个个个个个个个个个个个个个里面里面里面里面具体具体具体见笔者之前之前之前之前之前之前的的的的的的博客《Prometheus时序数据库-磁盘中的存储结构》《Prometheus时序数据库-磁盘中的存储结构》《Prometheus时序数据库-磁盘中的存储结构》《Prometheus时序数据库-磁盘中的存储结构》《Prometheus时序数据库-磁盘中的存储结构》《Prometheus时序数据库-磁盘中的存储结构》总结总结在总结总结总结总结总结总结在在在在Prometheus数据篇篇文章数据数据数据查询。本文自公众号公众号公众号公众号公众号「解解解解解之之之之」之路,可以可以可以可以可以通过

猜你喜欢