From a3bf2efdd5ecfc7a81de1fe19385fefa8e4a325d Mon Sep 17 00:00:00 2001 From: "Matt T. Proud" Date: Wed, 7 Aug 2013 12:07:35 +0200 Subject: [PATCH 1/2] Replace index writes with wrapped interface. This commit is the first of several and should not be regarded as the desired end state for these cleanups. What this one does it, however, is wrap the query index writing behind an interface type that can be injected into the storage stack and have its lifecycle managed separately as needed. It also would mean we can swap out underlying implementations to support remote indexing, buffering, no-op indexing very easily. In the future, most of the individual index interface members in the tiered storage will go away in favor of agents that can query and resolve what they need from the datastore without the user knowing how and why they work. --- storage/metric/index.go | 187 +++++++++++++++++++++++++++++--- storage/metric/leveldb.go | 219 +++++--------------------------------- storage/metric/tiered.go | 2 + 3 files changed, 197 insertions(+), 211 deletions(-) diff --git a/storage/metric/index.go b/storage/metric/index.go index 89f5d9734..0ae2ca443 100644 --- a/storage/metric/index.go +++ b/storage/metric/index.go @@ -25,6 +25,7 @@ import ( "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/storage/raw" "github.com/prometheus/prometheus/storage/raw/leveldb" + "github.com/prometheus/prometheus/utility" ) type FingerprintMetricMapping map[clientmodel.Fingerprint]clientmodel.Metric @@ -211,20 +212,20 @@ func NewLevelLabelNameFingerprintIndex(o *LevelDBLabelNameFingerprintIndexOption }, nil } -type LabelSetFingerprintMapping map[LabelPair]clientmodel.Fingerprints +type LabelPairFingerprintMapping map[LabelPair]clientmodel.Fingerprints -type LabelSetFingerprintIndex interface { +type LabelPairFingerprintIndex interface { raw.ForEacher raw.Pruner - IndexBatch(LabelSetFingerprintMapping) error + IndexBatch(LabelPairFingerprintMapping) error Lookup(*LabelPair) (m clientmodel.Fingerprints, ok bool, err error) Has(*LabelPair) (ok bool, err error) State() *raw.DatabaseState Size() (s uint64, present bool, err error) } -type LevelDBLabelSetFingerprintIndex struct { +type LevelDBLabelPairFingerprintIndex struct { p *leveldb.LevelDBPersistence } @@ -232,7 +233,7 @@ type LevelDBLabelSetFingerprintIndexOptions struct { leveldb.LevelDBOptions } -func (i *LevelDBLabelSetFingerprintIndex) IndexBatch(m LabelSetFingerprintMapping) error { +func (i *LevelDBLabelPairFingerprintIndex) IndexBatch(m LabelPairFingerprintMapping) error { batch := leveldb.NewBatch() defer batch.Close() @@ -256,7 +257,7 @@ func (i *LevelDBLabelSetFingerprintIndex) IndexBatch(m LabelSetFingerprintMappin return i.p.Commit(batch) } -func (i *LevelDBLabelSetFingerprintIndex) Lookup(p *LabelPair) (m clientmodel.Fingerprints, ok bool, err error) { +func (i *LevelDBLabelPairFingerprintIndex) Lookup(p *LabelPair) (m clientmodel.Fingerprints, ok bool, err error) { k := &dto.LabelPair{ Name: proto.String(string(p.Name)), Value: proto.String(string(p.Value)), @@ -281,7 +282,7 @@ func (i *LevelDBLabelSetFingerprintIndex) Lookup(p *LabelPair) (m clientmodel.Fi return m, true, nil } -func (i *LevelDBLabelSetFingerprintIndex) Has(p *LabelPair) (ok bool, err error) { +func (i *LevelDBLabelPairFingerprintIndex) Has(p *LabelPair) (ok bool, err error) { k := &dto.LabelPair{ Name: proto.String(string(p.Name)), Value: proto.String(string(p.Value)), @@ -290,35 +291,35 @@ func (i *LevelDBLabelSetFingerprintIndex) Has(p *LabelPair) (ok bool, err error) return i.p.Has(k) } -func (i *LevelDBLabelSetFingerprintIndex) ForEach(d storage.RecordDecoder, f storage.RecordFilter, o storage.RecordOperator) (bool, error) { +func (i *LevelDBLabelPairFingerprintIndex) ForEach(d storage.RecordDecoder, f storage.RecordFilter, o storage.RecordOperator) (bool, error) { return i.p.ForEach(d, f, o) } -func (i *LevelDBLabelSetFingerprintIndex) Prune() (bool, error) { +func (i *LevelDBLabelPairFingerprintIndex) Prune() (bool, error) { i.p.Prune() return false, nil } -func (i *LevelDBLabelSetFingerprintIndex) Close() { +func (i *LevelDBLabelPairFingerprintIndex) Close() { i.p.Close() } -func (i *LevelDBLabelSetFingerprintIndex) Size() (uint64, bool, error) { +func (i *LevelDBLabelPairFingerprintIndex) Size() (uint64, bool, error) { s, err := i.p.Size() return s, true, err } -func (i *LevelDBLabelSetFingerprintIndex) State() *raw.DatabaseState { +func (i *LevelDBLabelPairFingerprintIndex) State() *raw.DatabaseState { return i.p.State() } -func NewLevelDBLabelSetFingerprintIndex(o *LevelDBLabelSetFingerprintIndexOptions) (*LevelDBLabelSetFingerprintIndex, error) { +func NewLevelDBLabelSetFingerprintIndex(o *LevelDBLabelSetFingerprintIndexOptions) (*LevelDBLabelPairFingerprintIndex, error) { s, err := leveldb.NewLevelDBPersistence(&o.LevelDBOptions) if err != nil { return nil, err } - return &LevelDBLabelSetFingerprintIndex{ + return &LevelDBLabelPairFingerprintIndex{ p: s, }, nil } @@ -326,7 +327,7 @@ func NewLevelDBLabelSetFingerprintIndex(o *LevelDBLabelSetFingerprintIndexOption type MetricMembershipIndex interface { raw.Pruner - IndexBatch([]clientmodel.Metric) error + IndexBatch(FingerprintMetricMapping) error Has(clientmodel.Metric) (ok bool, err error) State() *raw.DatabaseState Size() (s uint64, present bool, err error) @@ -338,11 +339,11 @@ type LevelDBMetricMembershipIndex struct { var existenceIdentity = new(dto.MembershipIndexValue) -func (i *LevelDBMetricMembershipIndex) IndexBatch(ms []clientmodel.Metric) error { +func (i *LevelDBMetricMembershipIndex) IndexBatch(b FingerprintMetricMapping) error { batch := leveldb.NewBatch() defer batch.Close() - for _, m := range ms { + for _, m := range b { k := new(dto.Metric) dumpMetric(k, m) batch.Put(k, existenceIdentity) @@ -391,3 +392,155 @@ func NewLevelDBMetricMembershipIndex(o *LevelDBMetricMembershipIndexOptions) (*L p: s, }, nil } + +// MetricIndexer indexes facets of a clientmodel.Metric. +type MetricIndexer interface { + // IndexMetric makes no assumptions about the concurrency safety of the + // underlying implementer. + IndexMetrics(FingerprintMetricMapping) error +} + +// TotalIndexer is a MetricIndexer that indexes all standard facets of a metric +// that a user or the Prometheus subsystem would want to query against: +// +// "