app/vlstorage: add -retention.maxDiskSpaceUsageBytes command-line flag for limiting the retention at VictoriaLogs by disk space usage

This commit is contained in:
Aliaksandr Valialkin 2024-06-25 17:30:02 +02:00
parent 7d026b4655
commit dff5008392
No known key found for this signature in database
GPG key ID: 52C003EE2BCDB9EB
4 changed files with 128 additions and 21 deletions

View file

@ -20,10 +20,12 @@ import (
var ( var (
retentionPeriod = flagutil.NewDuration("retentionPeriod", "7d", "Log entries with timestamps older than now-retentionPeriod are automatically deleted; "+ retentionPeriod = flagutil.NewDuration("retentionPeriod", "7d", "Log entries with timestamps older than now-retentionPeriod are automatically deleted; "+
"log entries with timestamps outside the retention are also rejected during data ingestion; the minimum supported retention is 1d (one day); "+ "log entries with timestamps outside the retention are also rejected during data ingestion; the minimum supported retention is 1d (one day); "+
"see https://docs.victoriametrics.com/victorialogs/#retention") "see https://docs.victoriametrics.com/victorialogs/#retention ; see also -retention.maxDiskSpaceUsageBytes")
maxDiskSpaceUsageBytes = flagutil.NewBytes("retention.maxDiskSpaceUsageBytes", 0, "The maximum disk space usage at -storageDataPath before older per-day "+
"partitions are automatically dropped; see https://docs.victoriametrics.com/victorialogs/#retention-by-disk-space-usage ; see also -retentionPeriod")
futureRetention = flagutil.NewDuration("futureRetention", "2d", "Log entries with timestamps bigger than now+futureRetention are rejected during data ingestion; "+ futureRetention = flagutil.NewDuration("futureRetention", "2d", "Log entries with timestamps bigger than now+futureRetention are rejected during data ingestion; "+
"see https://docs.victoriametrics.com/victorialogs/#retention") "see https://docs.victoriametrics.com/victorialogs/#retention")
storageDataPath = flag.String("storageDataPath", "victoria-logs-data", "Path to directory with the VictoriaLogs data; "+ storageDataPath = flag.String("storageDataPath", "victoria-logs-data", "Path to directory where to store VictoriaLogs data; "+
"see https://docs.victoriametrics.com/victorialogs/#storage") "see https://docs.victoriametrics.com/victorialogs/#storage")
inmemoryDataFlushInterval = flag.Duration("inmemoryDataFlushInterval", 5*time.Second, "The interval for guaranteed saving of in-memory data to disk. "+ inmemoryDataFlushInterval = flag.Duration("inmemoryDataFlushInterval", 5*time.Second, "The interval for guaranteed saving of in-memory data to disk. "+
"The saved data survives unclean shutdowns such as OOM crash, hardware reset, SIGKILL, etc. "+ "The saved data survives unclean shutdowns such as OOM crash, hardware reset, SIGKILL, etc. "+
@ -49,12 +51,13 @@ func Init() {
logger.Fatalf("-retentionPeriod cannot be smaller than a day; got %s", retentionPeriod) logger.Fatalf("-retentionPeriod cannot be smaller than a day; got %s", retentionPeriod)
} }
cfg := &logstorage.StorageConfig{ cfg := &logstorage.StorageConfig{
Retention: retentionPeriod.Duration(), Retention: retentionPeriod.Duration(),
FlushInterval: *inmemoryDataFlushInterval, MaxDiskSpaceUsageBytes: maxDiskSpaceUsageBytes.N,
FutureRetention: futureRetention.Duration(), FlushInterval: *inmemoryDataFlushInterval,
LogNewStreams: *logNewStreams, FutureRetention: futureRetention.Duration(),
LogIngestedRows: *logIngestedRows, LogNewStreams: *logNewStreams,
MinFreeDiskSpaceBytes: minFreeDiskSpaceBytes.N, LogIngestedRows: *logIngestedRows,
MinFreeDiskSpaceBytes: minFreeDiskSpaceBytes.N,
} }
logger.Infof("opening storage at -storageDataPath=%s", *storageDataPath) logger.Infof("opening storage at -storageDataPath=%s", *storageDataPath)
startTime := time.Now() startTime := time.Now()

View file

@ -19,6 +19,8 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta
## tip ## tip
* FEATURE: add `-retention.maxDiskSpaceUsageBytes` command-line flag, which allows limiting disk space usage for [VictoriaLogs data](https://docs.victoriametrics.com/victorialogs/#storage) by automatic dropping the oldest per-day partitions if the storage disk space usage becomes bigger than the `-retention.maxDiskSpaceUsageBytes`. See [these docs](https://docs.victoriametrics.com/victorialogs/#retention-by-disk-space-usage).
## [v0.23.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.23.0-victorialogs) ## [v0.23.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.23.0-victorialogs)
Released at 2024-06-25 Released at 2024-06-25

View file

@ -77,6 +77,8 @@ For example, the following command starts VictoriaLogs with the retention of 8 w
/path/to/victoria-logs -retentionPeriod=8w /path/to/victoria-logs -retentionPeriod=8w
``` ```
See also [retention by disk space usage](#retention-by-disk-space-usage).
VictoriaLogs stores the [ingested](https://docs.victoriametrics.com/victorialogs/data-ingestion/) logs in per-day partition directories. VictoriaLogs stores the [ingested](https://docs.victoriametrics.com/victorialogs/data-ingestion/) logs in per-day partition directories.
It automatically drops partition directories outside the configured retention. It automatically drops partition directories outside the configured retention.
@ -101,6 +103,23 @@ For example, the following command starts VictoriaLogs, which accepts logs with
/path/to/victoria-logs -futureRetention=1y /path/to/victoria-logs -futureRetention=1y
``` ```
## Retention by disk space usage
VictoriaLogs can be configured to automatically drop older per-day partitions if the total size of partitions at [`-storageDataPath` directory](#storage)
becomes bigger than the given threshold at `-retention.maxDiskSpaceUsageBytes` command-line flag. For example, the following command starts VictoriaLogs,
which drops old per-day partitions if the total [storage](#storage) size becomes bigger than `100GiB`:
```sh
/path/to/victoria-logs -retention.maxDiskSpaceUsageBytes=100GiB
```
VictoriaLogs keeps at least two last days of data in order to guarantee that the logs for the last day can be returned in queries.
This means that the total disk space usage may exceed the `-retention.maxDiskSpaceUsageBytes` if the size of the last two days of data
exceeds the `-retention.maxDiskSpaceUsageBytes`.
See also [retention](#retention).
## Storage ## Storage
VictoriaLogs stores all its data in a single directory - `victoria-logs-data`. The path to the directory can be changed via `-storageDataPath` command-line flag. VictoriaLogs stores all its data in a single directory - `victoria-logs-data`. The path to the directory can be changed via `-storageDataPath` command-line flag.
@ -263,8 +282,11 @@ Pass `-help` to VictoriaLogs in order to see the list of supported command-line
Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . By default, metrics exposed at /metrics page aren't pushed to any remote storage Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . By default, metrics exposed at /metrics page aren't pushed to any remote storage
Supports an array of values separated by comma or specified via multiple flags. Supports an array of values separated by comma or specified via multiple flags.
Value can contain comma inside single-quoted or double-quoted string, {}, [] and () braces. Value can contain comma inside single-quoted or double-quoted string, {}, [] and () braces.
-retention.maxDiskSpaceUsageBytes size
The maximum disk space usage at -storageDataPath before older per-day partitions are automatically dropped; see https://docs.victoriametrics.com/victorialogs/#retention-by-disk-space-usage ; see also -retentionPeriod
Supports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB (default 0)
-retentionPeriod value -retentionPeriod value
Log entries with timestamps older than now-retentionPeriod are automatically deleted; log entries with timestamps outside the retention are also rejected during data ingestion; the minimum supported retention is 1d (one day); see https://docs.victoriametrics.com/victorialogs/#retention Log entries with timestamps older than now-retentionPeriod are automatically deleted; log entries with timestamps outside the retention are also rejected during data ingestion; the minimum supported retention is 1d (one day); see https://docs.victoriametrics.com/victorialogs/#retention ; see also -retention.maxDiskSpaceUsageBytes
The following optional suffixes are supported: s (second), m (minute), h (hour), d (day), w (week), y (year). If suffix isn't set, then the duration is counted in months (default 7d) The following optional suffixes are supported: s (second), m (minute), h (hour), d (day), w (week), y (year). If suffix isn't set, then the duration is counted in months (default 7d)
-search.maxConcurrentRequests int -search.maxConcurrentRequests int
The maximum number of concurrent search requests. It shouldn't be high, since a single request can saturate all the CPU cores, while many concurrently executed requests may require high amounts of memory. See also -search.maxQueueDuration (default 16) The maximum number of concurrent search requests. It shouldn't be high, since a single request can saturate all the CPU cores, while many concurrently executed requests may require high amounts of memory. See also -search.maxQueueDuration (default 16)
@ -276,7 +298,7 @@ Pass `-help` to VictoriaLogs in order to see the list of supported command-line
The minimum free disk space at -storageDataPath after which the storage stops accepting new data The minimum free disk space at -storageDataPath after which the storage stops accepting new data
Supports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB (default 10000000) Supports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB (default 10000000)
-storageDataPath string -storageDataPath string
Path to directory with the VictoriaLogs data; see https://docs.victoriametrics.com/victorialogs/#storage (default "victoria-logs-data") Path to directory where to store VictoriaLogs data; see https://docs.victoriametrics.com/victorialogs/#storage (default "victoria-logs-data")
-syslog.compressMethod.tcp array -syslog.compressMethod.tcp array
Compression method for syslog messages received at the corresponding -syslog.listenAddr.tcp. Supported values: none, gzip, deflate. See https://docs.victoriametrics.com/victorialogs/data-ingestion/syslog/ Compression method for syslog messages received at the corresponding -syslog.listenAddr.tcp. Supported values: none, gzip, deflate. See https://docs.victoriametrics.com/victorialogs/data-ingestion/syslog/
Supports an array of values separated by comma or specified via multiple flags. Supports an array of values separated by comma or specified via multiple flags.

View file

@ -45,7 +45,12 @@ type StorageConfig struct {
// Older data is automatically deleted. // Older data is automatically deleted.
Retention time.Duration Retention time.Duration
// FlushInterval is the interval for flushing the in-memory data to disk at the Storage // MaxDiskSpaceUsageBytes is an optional maximum disk space logs can use.
//
// The oldest per-day partitions are automatically dropped if the total disk space usage exceeds this limit.
MaxDiskSpaceUsageBytes int64
// FlushInterval is the interval for flushing the in-memory data to disk at the Storage.
FlushInterval time.Duration FlushInterval time.Duration
// FutureRetention is the allowed retention from the current time to future for the ingested data. // FutureRetention is the allowed retention from the current time to future for the ingested data.
@ -53,7 +58,8 @@ type StorageConfig struct {
// Log entries with timestamps bigger than now+FutureRetention are ignored. // Log entries with timestamps bigger than now+FutureRetention are ignored.
FutureRetention time.Duration FutureRetention time.Duration
// MinFreeDiskSpaceBytes is the minimum free disk space at storage path after which the storage stops accepting new data. // MinFreeDiskSpaceBytes is the minimum free disk space at storage path after which the storage stops accepting new data
// and enters read-only mode.
MinFreeDiskSpaceBytes int64 MinFreeDiskSpaceBytes int64
// LogNewStreams indicates whether to log newly created log streams. // LogNewStreams indicates whether to log newly created log streams.
@ -81,6 +87,11 @@ type Storage struct {
// older data is automatically deleted // older data is automatically deleted
retention time.Duration retention time.Duration
// maxDiskSpaceUsageBytes is an optional maximum disk space logs can use.
//
// The oldest per-day partitions are automatically dropped if the total disk space usage exceeds this limit.
maxDiskSpaceUsageBytes int64
// flushInterval is the interval for flushing in-memory data to disk // flushInterval is the interval for flushing in-memory data to disk
flushInterval time.Duration flushInterval time.Duration
@ -247,15 +258,16 @@ func MustOpenStorage(path string, cfg *StorageConfig) *Storage {
filterStreamCache := workingsetcache.New(mem / 10) filterStreamCache := workingsetcache.New(mem / 10)
s := &Storage{ s := &Storage{
path: path, path: path,
retention: retention, retention: retention,
flushInterval: flushInterval, maxDiskSpaceUsageBytes: cfg.MaxDiskSpaceUsageBytes,
futureRetention: futureRetention, flushInterval: flushInterval,
minFreeDiskSpaceBytes: minFreeDiskSpaceBytes, futureRetention: futureRetention,
logNewStreams: cfg.LogNewStreams, minFreeDiskSpaceBytes: minFreeDiskSpaceBytes,
logIngestedRows: cfg.LogIngestedRows, logNewStreams: cfg.LogNewStreams,
flockF: flockF, logIngestedRows: cfg.LogIngestedRows,
stopCh: make(chan struct{}), flockF: flockF,
stopCh: make(chan struct{}),
streamIDCache: streamIDCache, streamIDCache: streamIDCache,
streamTagsCache: streamTagsCache, streamTagsCache: streamTagsCache,
@ -305,6 +317,7 @@ func MustOpenStorage(path string, cfg *StorageConfig) *Storage {
s.partitions = ptws s.partitions = ptws
s.runRetentionWatcher() s.runRetentionWatcher()
s.runMaxDiskSpaceUsageWatcher()
return s return s
} }
@ -318,6 +331,17 @@ func (s *Storage) runRetentionWatcher() {
}() }()
} }
func (s *Storage) runMaxDiskSpaceUsageWatcher() {
if s.maxDiskSpaceUsageBytes <= 0 {
return
}
s.wg.Add(1)
go func() {
s.watchMaxDiskSpaceUsage()
s.wg.Done()
}()
}
func (s *Storage) watchRetention() { func (s *Storage) watchRetention() {
d := timeutil.AddJitterToDuration(time.Hour) d := timeutil.AddJitterToDuration(time.Hour)
ticker := time.NewTicker(d) ticker := time.NewTicker(d)
@ -360,6 +384,62 @@ func (s *Storage) watchRetention() {
} }
} }
func (s *Storage) watchMaxDiskSpaceUsage() {
d := timeutil.AddJitterToDuration(10 * time.Second)
ticker := time.NewTicker(d)
defer ticker.Stop()
for {
s.partitionsLock.Lock()
var n uint64
ptws := s.partitions
var ptwsToDelete []*partitionWrapper
for i := len(ptws) - 1; i >= 0; i-- {
ptw := ptws[i]
var ps PartitionStats
ptw.pt.updateStats(&ps)
n += ps.IndexdbSizeBytes + ps.CompressedSmallPartSize + ps.CompressedBigPartSize
if n <= uint64(s.maxDiskSpaceUsageBytes) {
continue
}
if i >= len(ptws)-2 {
// Keep the last two per-day partitions, so logs could be queried for one day time range.
continue
}
// ptws are sorted by time, so just drop all the partitions until i, including i.
i++
ptwsToDelete = ptws[:i]
s.partitions = ptws[i:]
// Remove reference to deleted partitions from s.ptwHot
for _, ptw := range ptwsToDelete {
if ptw == s.ptwHot {
s.ptwHot = nil
break
}
}
break
}
s.partitionsLock.Unlock()
for i, ptw := range ptwsToDelete {
logger.Infof("the partition %s is scheduled to be deleted because the total size of partitions exceeds -retention.maxDiskSpaceUsageBytes=%d",
ptw.pt.path, s.maxDiskSpaceUsageBytes)
ptw.mustDrop.Store(true)
ptw.decRef()
ptwsToDelete[i] = nil
}
select {
case <-s.stopCh:
return
case <-ticker.C:
}
}
}
func (s *Storage) getMinAllowedDay() int64 { func (s *Storage) getMinAllowedDay() int64 {
return time.Now().UTC().Add(-s.retention).UnixNano() / nsecPerDay return time.Now().UTC().Add(-s.retention).UnixNano() / nsecPerDay
} }