Compare commits

...

2 Commits

Author SHA1 Message Date
Zakhar Bessarab
b819157995 docs: add vmanomaly docs about licensing
Signed-off-by: Zakhar Bessarab <z.bessarab@victoriametrics.com>
2023-08-11 20:35:36 +04:00
Zakhar Bessarab
783dc8fd88 wip
Signed-off-by: Zakhar Bessarab <z.bessarab@victoriametrics.com>
2023-08-08 10:59:55 +04:00
2 changed files with 68 additions and 6 deletions

View File

@@ -135,3 +135,59 @@ It is also possible to split up config into multiple files, just list them all i
```sh
python3 -m vmanomaly model_prophet.yaml io_csv.yaml scheduler_oneoff.yaml
```
### Licensing
Starting from v1.5.0 vmanomaly requires a license key to run. You can obtain a trial license
key [here](https://victoriametrics.com/products/enterprise/trial/).
The license key can be passed via the following command-line flags:
```
--license LICENSE See https://victoriametrics.com/products/enterprise/
for trial license
--license-file LICENSE_FILE
See https://victoriametrics.com/products/enterprise/
for trial license
--license-verify-offline LICENSE_VERIFY_OFFLINE
Force offline verification of license code
```
Usage example:
```
python3 -m vmanomaly --license-file /path/to/license_file.yaml config.yaml
```
In order to make it easier to monitor the license expiration date, the following metrics are exposed:
```
# HELP vm_license_expires_at When the license expires as a Unix timestamp in seconds
# TYPE vm_license_expires_at gauge
vm_license_expires_at 1.6963776e+09
# HELP vm_license_expires_in_seconds Amount of seconds until the license expires
# TYPE vm_license_expires_in_seconds gauge
vm_license_expires_in_seconds 4.886608e+06
```
You can find example alerts for [vmalert](https://docs.victoriametrics.com/vmalert.html):
```yaml
groups:
- name: vm-license
# note the `job` filter and update accordingly to your setup
rules:
- alert: LicenseExpiresInLessThan30Days
expr: vm_license_expires_in_seconds < 30 * 24 * 3600
labels:
severity: warning
annotations:
summary: "{{ $labels.job }} instance {{ $labels.instance }} license expires in less than 30 days"
description: "{{ $labels.instance }} of job {{ $labels.job }} license expires in {{ $value | humanizeDuration }}.
Please make sure to update the license before it expires."
- alert: LicenseExpiresInLessThan7Days
expr: vm_license_expires_in_seconds < 7 * 24 * 3600
labels:
severity: critical
annotations:
summary: "{{ $labels.job }} instance {{ $labels.instance }} license expires in less than 7 days"
description: "{{ $labels.instance }} of job {{ $labels.job }} license expires in {{ $value | humanizeDuration }}.
Please make sure to update the license before it expires."
```

View File

@@ -30,10 +30,16 @@ const defaultPartsToMerge = 15
// The 1.7 is good enough for production workloads.
const minMergeMultiplier = 1.7
// The maximum number of inmemory parts in the partition.
// The maximum number of inmemory parts in the partition created per second.
//
// If the number of inmemory parts reaches this value, then assisted merge runs during data ingestion.
const maxInmemoryPartsPerPartition = 20
const maxInmemoryPartsPerPartitionPerSecond = 6
func getMaxInmemoryPartsPerPartition(fi time.Duration) int {
sec := fi.Seconds()
return int(sec * maxInmemoryPartsPerPartitionPerSecond)
}
// datadb represents a database with log data
type datadb struct {
@@ -455,7 +461,7 @@ func (ddb *datadb) getDstPartType(pws []*partWrapper, isFinal bool) partType {
return partFile
}
dstPartSize := getCompressedSize(pws)
if dstPartSize > getMaxInmemoryPartSize() {
if dstPartSize > getMaxInmemoryPartSize(ddb.flushInterval) {
return partFile
}
if !areAllInmemoryParts(pws) {
@@ -515,7 +521,7 @@ func (ddb *datadb) mustAddRows(lr *LogRows) {
if len(ddb.inmemoryParts) > defaultPartsToMerge {
ddb.startMergeWorkerLocked()
}
for len(ddb.inmemoryParts) > maxInmemoryPartsPerPartition {
for len(ddb.inmemoryParts) > getMaxInmemoryPartsPerPartition(ddb.flushInterval) {
// limit the pace for data ingestion if too many inmemory parts are created
ddb.mergeDoneCond.Wait()
}
@@ -741,9 +747,9 @@ func (ddb *datadb) getFlushToDiskDeadline(pws []*partWrapper) time.Time {
return d
}
func getMaxInmemoryPartSize() uint64 {
func getMaxInmemoryPartSize(fl time.Duration) uint64 {
// Allocate 10% of allowed memory for in-memory parts.
n := uint64(0.1 * float64(memory.Allowed()) / maxInmemoryPartsPerPartition)
n := uint64(0.1 * float64(memory.Allowed()) / float64(getMaxInmemoryPartsPerPartition(fl)))
if n < 1e6 {
n = 1e6
}