From 41d9bb55031142cd550c053782d0957ab2a6f583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Reynard?= Date: Wed, 22 Jan 2025 16:51:30 +0100 Subject: [PATCH] Force DuplicatePolicy for Redis TS created programmatically by Cosmotech API. Depending on target deployment environment, Redis TS can have DUPLICATE_POLICY set to BLOCK. Until now, Redis TS created by Cosmotech API relied on target environment (without override the default value) As we log every API calls, when API is flooded, it can lead to HTTP errors 500 when Redis is deployed with DUPLICATE_POLICY set to BLOCK (https://redis.io/docs/latest/develop/data-types/timeseries/configuration/#duplicate_policy). To prevent that, every Redis TS will be created now with DUPLICATE_POLICY set to MAX. Doing that, will not lead to HTTP 500 error and if X Redis TS will be created with the same timestamp, only the TS with the maximum value will be kept. Note: You should delete all previously created one. A Redis TS cannot be changed/upgraded --- .../cosmotech/metrics/MetricsServiceImpl.kt | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/metrics/src/main/kotlin/com/cosmotech/metrics/MetricsServiceImpl.kt b/metrics/src/main/kotlin/com/cosmotech/metrics/MetricsServiceImpl.kt index 957ed8d4b..1a4a7b3bd 100644 --- a/metrics/src/main/kotlin/com/cosmotech/metrics/MetricsServiceImpl.kt +++ b/metrics/src/main/kotlin/com/cosmotech/metrics/MetricsServiceImpl.kt @@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory import org.springframework.context.event.EventListener import org.springframework.stereotype.Service import redis.clients.jedis.UnifiedJedis +import redis.clients.jedis.timeseries.DuplicatePolicy import redis.clients.jedis.timeseries.TSAlterParams import redis.clients.jedis.timeseries.TSCreateParams @@ -58,7 +59,12 @@ class MetricsServiceImpl( val metricLabels = getMetricLabels(commonLabels) logger.debug( "Creating Redis TS: $key with retention: $metricRetention and ${metricLabels.count()} labels") - unifiedJedis.tsCreate(key, TSCreateParams().retention(metricRetention).labels(metricLabels)) + unifiedJedis.tsCreate( + key, + TSCreateParams() + .retention(metricRetention) + .labels(metricLabels) + .duplicatePolicy(DuplicatePolicy.MAX)) if (metric.downSampling || csmPlatformProperties.metrics.downSamplingDefaultEnabled) { val downSamplingKey = getDownSamplingKey(metric) val downSamplingMetricLabels = getDownSamplingMetricLabels(commonLabels) @@ -69,7 +75,10 @@ class MetricsServiceImpl( "and ${downSamplingMetricLabels.count()} labels") unifiedJedis.tsCreate( downSamplingKey, - TSCreateParams().retention(downSamplingRetention).labels(downSamplingMetricLabels)) + TSCreateParams() + .retention(downSamplingRetention) + .labels(downSamplingMetricLabels) + .duplicatePolicy(DuplicatePolicy.MAX)) logger.debug( "Creating Redis DownSampling TS rule: from $key to $downSamplingKey, " + "aggregation: ${metric.downSamplingAggregation.value}, bucketDuration: $downSamplingBucketDuration") @@ -89,7 +98,12 @@ class MetricsServiceImpl( logger.debug( "Redis TS library cannot get current labels so it is not possible to check if labels changed") val metricLabels = getMetricLabels(commonLabels) - unifiedJedis.tsAlter(key, TSAlterParams().retention(metricRetention).labels(metricLabels)) + unifiedJedis.tsAlter( + key, + TSAlterParams() + .retention(metricRetention) + .labels(metricLabels) + .duplicatePolicy(DuplicatePolicy.MAX)) } else {} } }