@ -27,9 +27,9 @@ import (
"time"
)
// t ieredStorage both persists samples and generates materialized views for
// T ieredStorage both persists samples and generates materialized views for
// queries.
type t ieredStorage struct {
type T ieredStorage struct {
appendToDiskQueue chan model . Samples
appendToMemoryQueue chan model . Samples
diskFrontier * diskFrontier
@ -51,36 +51,13 @@ type viewJob struct {
err chan error
}
// Provides a unified means for batch appending values into the datastore along
// with querying for values in an efficient way.
type Storage interface {
// Enqueues Samples for storage.
AppendSamples ( model . Samples ) error
// Enqueus a ViewRequestBuilder for materialization, subject to a timeout.
MakeView ( request ViewRequestBuilder , timeout time . Duration ) ( View , error )
// Starts serving requests.
Serve ( )
// Stops the storage subsystem, flushing all pending operations.
Drain ( )
Flush ( )
Close ( )
// Get all label values that are associated with the provided label name.
GetAllValuesForLabel ( model . LabelName ) ( model . LabelValues , error )
// Get all of the metric fingerprints that are associated with the provided
// label set.
GetFingerprintsForLabelSet ( model . LabelSet ) ( model . Fingerprints , error )
// Get the metric associated with the provided fingerprint.
GetMetricForFingerprint ( model . Fingerprint ) ( m * model . Metric , err error )
}
func NewTieredStorage ( appendToMemoryQueueDepth , appendToDiskQueueDepth , viewQueueDepth uint , flushMemoryInterval , writeMemoryInterval , memoryTTL time . Duration , root string ) ( storage Storage , err error ) {
func NewTieredStorage ( appendToMemoryQueueDepth , appendToDiskQueueDepth , viewQueueDepth uint , flushMemoryInterval , writeMemoryInterval , memoryTTL time . Duration , root string ) ( storage * TieredStorage , err error ) {
diskStorage , err := NewLevelDBMetricPersistence ( root )
if err != nil {
return
}
storage = & t ieredStorage{
storage = & TieredStorage {
appendToDiskQueue : make ( chan model . Samples , appendToDiskQueueDepth ) ,
appendToMemoryQueue : make ( chan model . Samples , appendToMemoryQueueDepth ) ,
diskStorage : diskStorage ,
@ -94,7 +71,8 @@ func NewTieredStorage(appendToMemoryQueueDepth, appendToDiskQueueDepth, viewQueu
return
}
func ( t tieredStorage ) AppendSamples ( s model . Samples ) ( err error ) {
// Enqueues Samples for storage.
func ( t TieredStorage ) AppendSamples ( s model . Samples ) ( err error ) {
if len ( t . draining ) > 0 {
return fmt . Errorf ( "Storage is in the process of draining." )
}
@ -104,7 +82,8 @@ func (t tieredStorage) AppendSamples(s model.Samples) (err error) {
return
}
func ( t tieredStorage ) Drain ( ) {
// Stops the storage subsystem, flushing all pending operations.
func ( t TieredStorage ) Drain ( ) {
log . Println ( "Starting drain..." )
drainingDone := make ( chan bool )
if len ( t . draining ) == 0 {
@ -114,7 +93,8 @@ func (t tieredStorage) Drain() {
log . Println ( "Done." )
}
func ( t * tieredStorage ) MakeView ( builder ViewRequestBuilder , deadline time . Duration ) ( view View , err error ) {
// Enqueus a ViewRequestBuilder for materialization, subject to a timeout.
func ( t TieredStorage ) MakeView ( builder ViewRequestBuilder , deadline time . Duration ) ( view View , err error ) {
if len ( t . draining ) > 0 {
err = fmt . Errorf ( "Storage is in the process of draining." )
return
@ -148,7 +128,7 @@ func (t *tieredStorage) MakeView(builder ViewRequestBuilder, deadline time.Durat
return
}
func ( t * t ieredStorage) rebuildDiskFrontier ( i leveldb . Iterator ) ( err error ) {
func ( t * T ieredStorage) rebuildDiskFrontier ( i leveldb . Iterator ) ( err error ) {
begin := time . Now ( )
defer func ( ) {
duration := time . Since ( begin )
@ -163,7 +143,8 @@ func (t *tieredStorage) rebuildDiskFrontier(i leveldb.Iterator) (err error) {
return
}
func ( t * tieredStorage ) Serve ( ) {
// Starts serving requests.
func ( t TieredStorage ) Serve ( ) {
flushMemoryTicker := time . NewTicker ( t . flushMemoryInterval )
defer flushMemoryTicker . Stop ( )
writeMemoryTicker := time . NewTicker ( t . writeMemoryInterval )
@ -193,7 +174,7 @@ func (t *tieredStorage) Serve() {
}
}
func ( t * t ieredStorage) reportQueues ( ) {
func ( t T ieredStorage) reportQueues ( ) {
queueSizes . Set ( map [ string ] string { "queue" : "append_to_disk" , "facet" : "occupancy" } , float64 ( len ( t . appendToDiskQueue ) ) )
queueSizes . Set ( map [ string ] string { "queue" : "append_to_disk" , "facet" : "capacity" } , float64 ( cap ( t . appendToDiskQueue ) ) )
@ -204,7 +185,7 @@ func (t *tieredStorage) reportQueues() {
queueSizes . Set ( map [ string ] string { "queue" : "view_generation" , "facet" : "capacity" } , float64 ( cap ( t . viewQueue ) ) )
}
func ( t * t ieredStorage) writeMemory ( ) {
func ( t * T ieredStorage) writeMemory ( ) {
begin := time . Now ( )
defer func ( ) {
duration := time . Since ( begin )
@ -222,11 +203,11 @@ func (t *tieredStorage) writeMemory() {
}
}
func ( t t ieredStorage) Flush ( ) {
func ( t T ieredStorage) Flush ( ) {
t . flush ( )
}
func ( t t ieredStorage) Close ( ) {
func ( t T ieredStorage) Close ( ) {
log . Println ( "Closing tiered storage..." )
t . Drain ( )
t . diskStorage . Close ( )
@ -239,7 +220,7 @@ func (t tieredStorage) Close() {
}
// Write all pending appends.
func ( t t ieredStorage) flush ( ) ( err error ) {
func ( t T ieredStorage) flush ( ) ( err error ) {
// Trim any old values to reduce iterative write costs.
t . flushMemory ( )
t . writeMemory ( )
@ -330,7 +311,7 @@ func (f memoryToDiskFlusher) Close() {
}
// Persist a whole bunch of samples to the datastore.
func ( t * t ieredStorage) flushMemory ( ) {
func ( t * T ieredStorage) flushMemory ( ) {
begin := time . Now ( )
defer func ( ) {
duration := time . Since ( begin )
@ -353,7 +334,7 @@ func (t *tieredStorage) flushMemory() {
return
}
func ( t * t ieredStorage) renderView ( viewJob viewJob ) {
func ( t T ieredStorage) renderView ( viewJob viewJob ) {
// Telemetry.
var err error
begin := time . Now ( )
@ -482,7 +463,7 @@ func (t *tieredStorage) renderView(viewJob viewJob) {
return
}
func ( t * t ieredStorage) loadChunkAroundTime ( iterator leveldb . Iterator , frontier * seriesFrontier , fingerprint model . Fingerprint , ts time . Time ) ( chunk model . Values ) {
func ( t T ieredStorage) loadChunkAroundTime ( iterator leveldb . Iterator , frontier * seriesFrontier , fingerprint model . Fingerprint , ts time . Time ) ( chunk model . Values ) {
var (
targetKey = & dto . SampleKey {
Fingerprint : fingerprint . ToDTO ( ) ,
@ -558,7 +539,8 @@ func (t *tieredStorage) loadChunkAroundTime(iterator leveldb.Iterator, frontier
return
}
func ( t * tieredStorage ) GetAllValuesForLabel ( labelName model . LabelName ) ( values model . LabelValues , err error ) {
// Get all label values that are associated with the provided label name.
func ( t TieredStorage ) GetAllValuesForLabel ( labelName model . LabelName ) ( values model . LabelValues , err error ) {
diskValues , err := t . diskStorage . GetAllValuesForLabel ( labelName )
if err != nil {
return
@ -579,7 +561,9 @@ func (t *tieredStorage) GetAllValuesForLabel(labelName model.LabelName) (values
return
}
func ( t * tieredStorage ) GetFingerprintsForLabelSet ( labelSet model . LabelSet ) ( fingerprints model . Fingerprints , err error ) {
// Get all of the metric fingerprints that are associated with the provided
// label set.
func ( t TieredStorage ) GetFingerprintsForLabelSet ( labelSet model . LabelSet ) ( fingerprints model . Fingerprints , err error ) {
memFingerprints , err := t . memoryArena . GetFingerprintsForLabelSet ( labelSet )
if err != nil {
return
@ -599,7 +583,8 @@ func (t *tieredStorage) GetFingerprintsForLabelSet(labelSet model.LabelSet) (fin
return
}
func ( t * tieredStorage ) GetMetricForFingerprint ( f model . Fingerprint ) ( m * model . Metric , err error ) {
// Get the metric associated with the provided fingerprint.
func ( t TieredStorage ) GetMetricForFingerprint ( f model . Fingerprint ) ( m * model . Metric , err error ) {
m , err = t . memoryArena . GetMetricForFingerprint ( f )
if err != nil {
return