Surveillance et alertes ClickHouse
ClickHouse lui-même et son sidecar de sauvegarde exposent chacun des métriques Prometheus, désactivées par défaut. Le sidecar de sauvegarde mérite l'attention plus poussée décrite ci-dessous : sa boucle de surveillance retente une sauvegarde échouée au prochain tick planifié au lieu de s'arrêter, si bien qu'un échec persistant ne fait jamais planter le conteneur ni n'apparaît dans le statut du pod (voir Fraîcheur des sauvegardes).
Le ServiceMonitor propre à ClickHouse et celui du sidecar de sauvegarde produisent chacun une ressource ServiceMonitor. Si les CRD de Prometheus Operator ne sont pas installés dans le cluster, l'activation de l'un ou l'autre fait échouer l'installation de la release : laissez les deux sur false tant qu'ils ne le sont pas.
Métriques du serveur ClickHouse
Les métriques propres à ClickHouse (performance des requêtes, utilisation des ressources) sont exposées sur le port standard http-metrics. Deux paramètres contrôlent cela, tous deux sur false par défaut :
clickhouse-server:
metrics:
enabled: true
serviceMonitor:
enabled: true
metrics.enabled active le endpoint de métriques lui-même ; metrics.serviceMonitor.enabled livre en plus un ServiceMonitor correspondant : les deux sont nécessaires pour obtenir une cible scrapée.
Métriques clés
ClickHouse expose plusieurs métriques ; celles ci-dessous sont celles qui correspondent directement à un garde-fou que ce chart configure par défaut (voir Planification et fiabilité et Autres garde-fous), si bien qu'un dépassement ici signifie qu'un seuil spécifique et connu a été atteint, et non un symptôme à interpréter à partir de zéro.
| Métrique | Type | Signification |
|---|---|---|
ClickHouseErrorMetric_TOO_MANY_SIMULTANEOUS_QUERIES | Counter | Une requête a été rejetée d'emblée pour avoir dépassé MAX_CONCURRENT_QUERIES (32 par défaut). ClickHouseMetrics_Query (gauge) suit le nombre de requêtes concurrentes actuel si vous souhaitez surveiller la tendance avant d'y arriver. |
ClickHouseErrorMetric_TIMEOUT_EXCEEDED | Counter | Une requête a été interrompue pour avoir dépassé MAX_EXECUTION_TIME (55 secondes par défaut). |
ClickHouseMetrics_MemoryTracking / ClickHouseErrorMetric_MEMORY_LIMIT_EXCEEDED | Gauge (octets) / Counter | Mémoire actuellement suivie à l'échelle du serveur, et nombre de fois qu'une requête a été interrompue pour avoir dépassé MAX_SERVER_MEMORY_USAGE_TO_RAM_RATIO (0.9 de la limite mémoire du pod par défaut). |
ClickHouseAsyncMetrics_MaxPartCountForPartition | Gauge | Le nombre de parts actives de la partition la plus critique parmi toutes les tables. PARTS_TO_DELAY_INSERT/PARTS_TO_THROW_INSERT (1000/3000 par défaut) le vérifient avant d'accepter un insert dans cette partition. Recommandation propre de ClickHouse : des valeurs supérieures à 300 indiquent déjà une surcharge. |
ClickHouseProfileEvents_DelayedInserts / ClickHouseProfileEvents_RejectedInserts | Counter | Avertissement précoce (un insert a été artificiellement ralenti) vs. échec dur (un insert a été rejeté avec Too many parts) pour les mêmes garde-fous de parts par partition ci-dessus. |
ClickHouseProfileEvents_ExternalAggregationCompressedBytes / ExternalSortCompressedBytes | Counter (octets) | Données cumulées déversées sur le disque parce que le GROUP BY/ORDER BY d'une requête a franchi MAX_BYTES_RATIO_BEFORE_EXTERNAL_GROUP_BY/_SORT (0.4 par défaut). Un taux croissant signifie que les requêtes recourent de plus en plus au chemin plus lent de déversement disque. |
ClickHouseAsyncMetrics_DiskAvailable_default | Gauge (octets) | Espace libre sur le volume de métadonnées. Contrairement au cache de système de fichiers, ce volume ne se dégrade pas gracieusement s'il se remplit (voir Ce qui se passe si ce volume se remplit). |
Traité séparément dans Cache de système de fichiers : ClickHouseProfileEvents_CachedReadBufferReadFromCacheHits/...Misses (les mêmes counters derrière la requête SQL de cette page) et ClickHouseMetrics_FilesystemCacheSize/...SizeLimit pour connaître le niveau de remplissage actuel du cache.
Une croissance soutenue de ExternalAggregationCompressedBytes/...SortCompressedBytes ou une augmentation de MEMORY_LIMIT_EXCEEDED indiquent toutes deux que la RAM, et non le CPU, est le véritable goulot d'étranglement de votre charge d'agrégation. Voir Recommandations matérielles pour savoir quand passer du ratio RAM/cœur généraliste de ClickHouse à leur ratio dédié aux entrepôts de données.
Seuils clés
Ceux-ci supposent les valeurs de garde-fous par défaut du chart ci-dessus ; ajustez les nombres littéraux si vous avez personnalisé clickhouse.serverConfig. Critical signifie qu'une requête ou un insert a déjà échoué à cause de cela ; warning signifie que vous tendez vers un tel échec.
| Condition | Basé sur | Seuil suggéré | Sévérité |
|---|---|---|---|
| Une requête a été rejetée pour trop de requêtes concurrentes | ClickHouseErrorMetric_TOO_MANY_SIMULTANEOUS_QUERIES | Toute augmentation | Critical |
| Une requête a été interrompue pour une exécution trop longue | ClickHouseErrorMetric_TIMEOUT_EXCEEDED | Toute augmentation | Critical |
| Une requête a été interrompue pour avoir dépassé sa limite mémoire | ClickHouseErrorMetric_MEMORY_LIMIT_EXCEEDED | Toute augmentation | Critical |
Un insert a été rejeté d'emblée (Too many parts) | ClickHouseProfileEvents_RejectedInserts | Toute augmentation | Critical |
| Un insert est ralenti, mais pas encore rejeté | ClickHouseProfileEvents_DelayedInserts | Toute augmentation | Warning |
| Une partition approche du seuil de retardement des inserts | ClickHouseAsyncMetrics_MaxPartCountForPartition | Au-dessus de 80 % de PARTS_TO_DELAY_INSERT (800 par défaut) pendant 15 minutes | Warning |
| Les requêtes se déversent de plus en plus sur le disque | Taux de ExternalAggregationCompressedBytes + ExternalSortCompressedBytes | Taux non nul soutenu pendant 30 minutes | Warning |
| Le volume de métadonnées est censé se remplir | ClickHouseAsyncMetrics_DiskAvailable_default | predict_linear(...[1d]) < 0 (censé atteindre zéro dans les 24 h) | Critical |
Alertes recommandées
Un exemple implémentant les seuils ci-dessus sous forme de PrometheusRule de Prometheus Operator :
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: clickhouse-server
namespace: <namespace>
labels:
release: <your-prometheus-operator-release-label>
spec:
groups:
- name: clickhouse-server
rules:
- alert: ClickHouseTooManyConcurrentQueries
expr: increase(ClickHouseErrorMetric_TOO_MANY_SIMULTANEOUS_QUERIES[5m]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: 'A query was rejected for exceeding the concurrent query limit'
description: 'MAX_CONCURRENT_QUERIES (32 by default) was hit. ClickHouseMetrics_Query shows the current concurrent count if you want to confirm the trend.'
- alert: ClickHouseQueryTimeout
expr: increase(ClickHouseErrorMetric_TIMEOUT_EXCEEDED[5m]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: 'A query was killed for exceeding MAX_EXECUTION_TIME'
description: 'MAX_EXECUTION_TIME is 55 seconds by default. Check slow query logs for what ran long.'
- alert: ClickHouseQueryMemoryLimitExceeded
expr: increase(ClickHouseErrorMetric_MEMORY_LIMIT_EXCEEDED[5m]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: 'A query was killed for exceeding the server memory limit'
description: 'MAX_SERVER_MEMORY_USAGE_TO_RAM_RATIO is 0.9 by default. ClickHouseMetrics_MemoryTracking shows the server-wide trend leading up to this.'
- alert: ClickHouseInsertRejected
expr: increase(ClickHouseProfileEvents_RejectedInserts[5m]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: "An insert was rejected with 'Too many parts'"
description: 'PARTS_TO_THROW_INSERT (3000 by default) was hit for at least one partition. ClickHouseAsyncMetrics_MaxPartCountForPartition shows the worst-case partition if you want to confirm which one.'
- alert: ClickHouseInsertDelayed
expr: increase(ClickHouseProfileEvents_DelayedInserts[5m]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: 'Inserts are being throttled due to a high part count'
description: 'PARTS_TO_DELAY_INSERT (1000 by default) was hit for at least one partition. Not yet a rejection, but merges are falling behind inserts. Left unaddressed, this trends toward ClickHouseInsertRejected.'
- alert: ClickHouseMaxPartCountApproachingLimit
expr: ClickHouseAsyncMetrics_MaxPartCountForPartition > 800
for: 15m
labels:
severity: warning
annotations:
summary: 'A partition is approaching the insert-delay threshold'
description: 'Above 80% of PARTS_TO_DELAY_INSERT (1000 by default). Sustained high insert rate outpacing background merges. Consider batching inserts at the source.'
- alert: ClickHouseExternalSpillIncreasing
expr: rate(ClickHouseProfileEvents_ExternalAggregationCompressedBytes[30m]) > 0 or rate(ClickHouseProfileEvents_ExternalSortCompressedBytes[30m]) > 0
for: 30m
labels:
severity: warning
annotations:
summary: 'Queries are spilling GROUP BY/ORDER BY to disk'
description: 'MAX_BYTES_RATIO_BEFORE_EXTERNAL_GROUP_BY/_SORT (0.4 by default) is being crossed repeatedly, a sign these queries are memory-constrained relative to their data volume.'
- alert: ClickHouseMetadataDiskWillFillUp
expr: predict_linear(ClickHouseAsyncMetrics_DiskAvailable_default[1d], 86400) < 0
for: 10m
labels:
severity: critical
annotations:
summary: 'The metadata volume is projected to fill up within 24 hours'
description: 'Unlike the filesystem cache, this volume does not degrade gracefully when full: inserts and merges fail outright. See Metadata volume in the sizing guide.'
ClickHouseInsertRejected et ses choix de seuils reproduisent les règles d'alerte de référence de clickhouse-operator d'Altinity (ClickHouseRejectedInsert/ClickHouseDelayedInsertThrottling/ClickHouseMaxPartCountForPartition), et le motif predict_linear de ClickHouseMetadataDiskWillFillUp reproduit leur règle ClickHouseDiskUsage. Les deux sont ici restreints aux paramètres que ce chart configure réellement. La plupart des autres règles d'Altinity (retard de réplica, sessions ZooKeeper/Keeper, Kafka, tables Distributed) ne s'appliquent pas : ce chart exécute ClickHouse en nœud unique, sans réplication, Kafka ni sharding.
Métriques du sidecar de sauvegarde
Une sauvegarde échouée ne fait pas planter le conteneur, ne redémarre pas le pod et ne fait passer au rouge aucun indicateur de santé au niveau de Kubernetes. Le pod clickhouse peut afficher Running/Ready avec 0 redémarrage alors que les sauvegardes échouent depuis des jours. La seule façon fiable de le savoir est de mettre en place des alertes sur les métriques Prometheus ci-dessous.
Endpoint de métriques
Le sidecar de sauvegarde expose des métriques au format Prometheus sur sa propre API REST, sur le port backup-rest (7171), à /metrics. Comme toute autre route de cette API, elle nécessite les mêmes identifiants HTTP Basic Auth que le reste de l'API de sauvegarde (API_USERNAME/API_PASSWORD, voir Prérequis) : un scrape non authentifié reçoit un 401.
Pour le vérifier manuellement avant de brancher Prometheus : API_USERNAME/API_PASSWORD sont déjà injectés dans le conteneur clickhouse-backup lui-même (il en a besoin pour appliquer cette même authentification sur les requêtes entrantes), il n'est donc pas nécessaire de les récupérer séparément depuis le secret :
kubectl exec -n <namespace> <clickhouse-pod> -c clickhouse-backup -- \
sh -c 'curl -s -u "$API_USERNAME:$API_PASSWORD" http://localhost:7171/metrics'
Scraper avec Prometheus Operator
Définissez clickhouse.backup.metrics.enabled: true pour que le chart livre automatiquement un ServiceMonitor correspondant au port backup-rest : il récupère à la fois le nom d'utilisateur et le mot de passe depuis le même secret clickhouse-credentials déjà utilisé ailleurs (voir Prérequis) :
clickhouse:
backup:
metrics:
enabled: true
Métriques clés
Chaque tick planifié (complet ou incrémental) s'exécute comme une opération create_remote, que la sauvegarde complète de ce jour déclenche ou non aussi un rebase (voir Comprendre le planning de sauvegarde) :
| Métrique | Type | Signification |
|---|---|---|
clickhouse_backup_last_create_remote_status | Gauge | 0=échec, 1=succès, 2=inconnu. Le résultat de la plus récente tentative de sauvegarde planifiée, complète ou incrémentale. |
clickhouse_backup_last_create_remote_finish | Gauge (timestamp unix) | Timestamp de la tentative la plus récente, succès ou échec. Une valeur qui devient obsolète signifie que la boucle de surveillance elle-même a cessé de tourner, et pas seulement qu'une sauvegarde a échoué. |
clickhouse_backup_successful_create_remotes / clickhouse_backup_failed_create_remotes | Counter | Compteurs cumulatifs, utiles pour une alerte de taux d'échec sur une fenêtre glissante. |
clickhouse_backup_last_rebase_status / clickhouse_backup_last_rebase_finish | Gauge | Même forme, pour l'étape hebdomadaire rebase qui s'exécute après une sauvegarde complète dès qu'une chaîne précédente existe déjà. Reste non défini pendant environ les 2 premières semaines après une nouvelle installation, car full_type: rebase ne s'applique qu'à partir du deuxième cycle complet. |
clickhouse_backup_in_progress_commands | Gauge | Nombre d'opérations de sauvegarde actuellement en cours. Bloqué au-dessus de 0 bien plus longtemps qu'une sauvegarde ne le prend normalement signifie généralement une opération figée. |
clickhouse_backup_number_backups_remote / clickhouse_backup_last_backup_size_remote | Gauge | Nombre de chaînes et taille actuellement sur le stockage distant, un contrôle de cohérence basique confirmant que le nombre/la taille des chaînes ne se sont pas effondrés de façon inattendue. |
Seuils clés
Ces seuils sont agnostiques de la métrique : ils s'appliquent quelle que soit la façon dont les métriques ci-dessus sont collectées, que ce soit Prometheus, Datadog, Grafana Cloud ou toute autre solution de surveillance. Ils supposent le planning par défaut du chart (create_remote quotidien, rebase hebdomadaire) ; ajustez-les si vous avez personnalisé WATCH_SCHEDULES.
| Condition | Basé sur | Seuil suggéré | Sévérité |
|---|---|---|---|
| Aucune tentative de sauvegarde (complète ou incrémentale) récemment | Temps écoulé depuis clickhouse_backup_last_create_remote_finish | Plus de 36 heures (1,5x la cadence quotidienne par défaut) | Critical |
| La dernière tentative de sauvegarde a échoué | clickhouse_backup_last_create_remote_status | Égal à 0 (échec) pendant 15 minutes d'affilée | Critical |
| Aucun rebase de sauvegarde complète hebdomadaire récemment | Temps écoulé depuis clickhouse_backup_last_rebase_finish | Plus de 10 jours (n'a de sens qu'une fois un deuxième cycle complet exécuté, attendez-vous à ce que ce soit obsolète pendant les deux premières semaines après une nouvelle installation) | Warning |
| Une opération de sauvegarde tourne depuis trop longtemps | clickhouse_backup_in_progress_commands | Supérieur à 0 pendant 2 heures d'affilée | Warning |
| La sauvegarde distante la plus récente rapporte une taille de zéro | clickhouse_backup_last_backup_size_remote et clickhouse_backup_number_backups_remote | Taille égale à 0 alors qu'au moins une sauvegarde existe déjà à distance | Critical |
Alertes recommandées
Un exemple implémentant les seuils ci-dessus sous forme de PrometheusRule de Prometheus Operator :
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: clickhouse-backup
namespace: <namespace>
labels:
release: <your-prometheus-operator-release-label>
spec:
groups:
- name: clickhouse-backup
rules:
- alert: ClickHouseBackupStalled
expr: time() - clickhouse_backup_last_create_remote_finish > 36 * 3600
for: 10m
labels:
severity: critical
annotations:
summary: 'No backup attempt (full or incremental) in over 36 hours'
description: 'The clickhouse-backup sidecar has not attempted a backup in more than 36 hours (1.5x the default daily cadence). The watch loop may have stopped, or its config may be invalid. Pod status will not show this: check the sidecar logs directly.'
- alert: ClickHouseBackupFailing
expr: clickhouse_backup_last_create_remote_status == 0
for: 15m
labels:
severity: critical
annotations:
summary: 'The last backup attempt failed'
description: 'clickhouse_backup_last_create_remote_status is 0 (failed). Check the sidecar logs for the error; clickhouse-backup retries on the next scheduled tick, it does not stop or crash on its own.'
- alert: ClickHouseFullBackupStalled
expr: time() - clickhouse_backup_last_rebase_finish > 10 * 24 * 3600
for: 10m
labels:
severity: warning
annotations:
summary: 'No weekly full-backup rebase in over 10 days'
description: 'Only meaningful once a second full cycle has run. Expect this to be stale for the first two weeks after a fresh install, since full_type: rebase only applies from the second full backup onward.'
- alert: ClickHouseBackupStuck
expr: clickhouse_backup_in_progress_commands > 0
for: 2h
labels:
severity: warning
annotations:
summary: 'A backup operation has been running for over 2 hours'
description: 'clickhouse_backup_in_progress_commands has stayed above 0 for 2 hours straight, longer than a scheduled full or incremental backup normally takes. Check the sidecar logs for a hung operation. Raise the threshold if your data volume makes 2 hours a normal backup duration.'
- alert: ClickHouseBackupSizeZero
expr: clickhouse_backup_last_backup_size_remote == 0 and clickhouse_backup_number_backups_remote > 0
for: 10m
labels:
severity: critical
annotations:
summary: 'The most recent remote backup reports a size of zero'
description: 'At least one backup exists on remote storage, but the most recent one reports 0 bytes, likely a broken or empty backup rather than a real one. Check the sidecar logs and verify the backup with `clickhouse-backup list remote`.'
La fenêtre de 36 heures de ClickHouseBackupStalled est délibérément généreuse (1,5x la cadence par défaut de 24 heures) pour éviter les oscillations sur un unique tick retardé, ce qui correspond à la convention utilisée par les mainteneurs de clickhouse-backup eux-mêmes dans leurs règles d'alerte de référence pour ClickHouse Operator. ClickHouseBackupSizeZero reproduit la règle ClickHouseRemoteBackupSizeZero du même ensemble de règles de référence.