Use new Prometheus text format parser

This commit is contained in:
Fabian Reinartz 2017-01-16 21:29:53 +01:00
parent dd0b69fe1b
commit 5fb01d41aa
3 changed files with 29 additions and 57 deletions

View file

@ -1,9 +1,9 @@
build: build:
@go build . @go1.8rc1 build .
bench: build bench: build
@echo ">> running benchmark" @echo ">> running benchmark"
@./tsdb bench write --metrics=$(NUM_METRICS) testdata.100k @./tsdb bench write --metrics=$(NUM_METRICS) testdata.1m
@go tool pprof -svg ./tsdb benchout/cpu.prof > benchout/cpuprof.svg @go tool pprof -svg ./tsdb benchout/cpu.prof > benchout/cpuprof.svg
@go tool pprof -svg ./tsdb benchout/mem.prof > benchout/memprof.svg @go tool pprof -svg ./tsdb benchout/mem.prof > benchout/memprof.svg
@go tool pprof -svg ./tsdb benchout/block.prof > benchout/blockprof.svg @go tool pprof -svg ./tsdb benchout/block.prof > benchout/blockprof.svg

View file

@ -9,15 +9,14 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"runtime/pprof" "runtime/pprof"
"sort"
"sync" "sync"
"time" "time"
"unsafe"
"github.com/fabxc/tsdb" "github.com/fabxc/tsdb"
"github.com/fabxc/tsdb/labels" "github.com/fabxc/tsdb/labels"
dto "github.com/prometheus/client_model/go" promlabels "github.com/prometheus/prometheus/pkg/labels"
"github.com/prometheus/common/expfmt" "github.com/prometheus/prometheus/pkg/textparse"
"github.com/prometheus/common/model"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -97,7 +96,7 @@ func (b *writeBenchmark) run(cmd *cobra.Command, args []string) {
} }
b.storage = st b.storage = st
var metrics []model.Metric var metrics []labels.Labels
measureTime("readData", func() { measureTime("readData", func() {
f, err := os.Open(args[0]) f, err := os.Open(args[0])
@ -133,23 +132,11 @@ func (b *writeBenchmark) run(cmd *cobra.Command, args []string) {
}) })
} }
func (b *writeBenchmark) ingestScrapes(metrics []model.Metric, scrapeCount int) error { func (b *writeBenchmark) ingestScrapes(lbls []labels.Labels, scrapeCount int) error {
var wg sync.WaitGroup var wg sync.WaitGroup
var mu sync.Mutex var mu sync.Mutex
var total uint64 var total uint64
lbls := make([]labels.Labels, 0, len(metrics))
for _, m := range metrics {
lset := make(labels.Labels, 0, len(m))
for k, v := range m {
lset = append(lset, labels.Label{Name: string(k), Value: string(v)})
}
sort.Sort(lset)
lbls = append(lbls, lset)
}
for i := 0; i < scrapeCount; i += 50 { for i := 0; i < scrapeCount; i += 50 {
lbls := lbls lbls := lbls
for len(lbls) > 0 { for len(lbls) > 0 {
@ -305,44 +292,30 @@ func measureTime(stage string, f func()) {
fmt.Printf(">> completed stage=%s duration=%s\n", stage, time.Since(start)) fmt.Printf(">> completed stage=%s duration=%s\n", stage, time.Since(start))
} }
func readPrometheusLabels(r io.Reader, n int) ([]model.Metric, error) { func readPrometheusLabels(r io.Reader, n int) ([]labels.Labels, error) {
dec := expfmt.NewDecoder(r, expfmt.FmtProtoText) b, err := ioutil.ReadAll(r)
if err != nil {
var mets []model.Metric
fps := map[model.Fingerprint]struct{}{}
var mf dto.MetricFamily
var dups int
for i := 0; i < n; {
if err := dec.Decode(&mf); err != nil {
if err == io.EOF {
break
}
return nil, err return nil, err
} }
for _, m := range mf.GetMetric() { p := textparse.New(b)
met := make(model.Metric, len(m.GetLabel())+1) i := 0
met["__name__"] = model.LabelValue(mf.GetName()) var mets []labels.Labels
hashes := map[uint64]struct{}{}
for _, l := range m.GetLabel() { for p.Next() && i < n {
met[model.LabelName(l.GetName())] = model.LabelValue(l.GetValue()) m := make(labels.Labels, 0, 10)
} p.Metric((*promlabels.Labels)(unsafe.Pointer(&m)))
if _, ok := fps[met.Fingerprint()]; ok {
dups++ h := m.Hash()
} else { if _, ok := hashes[h]; ok {
mets = append(mets, met) continue
fps[met.Fingerprint()] = struct{}{}
} }
mets = append(mets, m)
hashes[h] = struct{}{}
i++ i++
} }
} return mets, p.Err()
if dups > 0 {
fmt.Println("dropped duplicate metrics:", dups)
}
fmt.Println("read metrics", len(mets[:n]))
return mets[:n], nil
} }
func exitWithError(err error) { func exitWithError(err error) {

View file

@ -427,7 +427,6 @@ func (h *headBlock) create(hash uint64, lset labels.Labels) *memSeries {
lset: lset, lset: lset,
ref: uint32(len(h.series)), ref: uint32(len(h.series)),
} }
fmt.Println("create", lset)
// Allocate empty space until we can insert at the given index. // Allocate empty space until we can insert at the given index.
h.series = append(h.series, s) h.series = append(h.series, s)