Ressources
Par défaut, l’ordonnancement des charges de travail est désactivé. Pour l’activer, vous devez créer des ressources qui seront utilisées pour la planification, ainsi qu’au moins un workload. Toutes les ressources sont indépendantes et peuvent être combinées librement. Pour activer l’ordonnancement CPU, vous devez créer une ressource CPU pour les threads MASTER ou WORKER (voir ordonnancement CPU pour plus de détails) :- Ressources partagées dans le temps (CPU, IO, slots de requête) - gèrent les requêtes de ressources mises en file d’attente aux feuilles de la hiérarchie d’ordonnancement. Les requêtes sont ordonnancées selon les politiques et les contraintes définies par la hiérarchie. Les requêtes de ressources sont créées lorsqu’une requête accède à la ressource correspondante. Par exemple, lorsqu’une requête lit des données sur le disque ou utilise le CPU pour le traitement, des requêtes de ressources sont créées pour chaque quantum de travail effectué ou pour chaque quantité d’octets envoyés ou reçus via un socket.
- Ressources partagées dans l’espace (Memory) - gèrent les allocations de ressources aux feuilles de la hiérarchie d’ordonnancement. Les allocations peuvent être actives ou en attente. Les allocations en attente sont bloquées jusqu’à ce que suffisamment d’espace soit libéré ou qu’une autre allocation soit évincée (interrompue de force). Les décisions sont fondées sur les limites et les politiques définies par la hiérarchie. Il existe une correspondance un à un entre les allocations et les requêtes (ou les activités en arrière-plan). Une allocation est créée lorsqu’une requête commence son exécution et elle est libérée lorsqu’elle se termine. Les allocations en cours d’exécution peuvent augmenter ou diminuer leur taille de manière dynamique.
Hiérarchie des charges de travail
ClickHouse fournit une syntaxe SQL pratique pour définir la hiérarchie d’ordonnancement. Toutes les ressources sont réparties dans une hiérarchie de charges de travail commune. Les règles de répartition peuvent différer sur certains points selon les ressources, mais la hiérarchie reste la même. Chaque charge de travail comporte les nœuds d’ordonnancement nécessaires pour chaque ressource. Une charge de travail enfant peut être créée au sein de n’importe quelle charge de travail pour construire la hiérarchie. ClickHouse n’impose aucune structure spécifique ou prédéfinie pour la hiérarchie des charges de travail. Une charge de travail sans parent (sans clauseIN) est une charge de travail racine, et la hiérarchie peut en contenir autant que nécessaire — par exemple, une arborescence définie en SQL et une autre chargée depuis la configuration. Toutes les charges de travail racines sont les enfants d’une racine anonyme implicite (affichée au path / dans system.scheduler) ; elles sont donc ordonnancées les unes par rapport aux autres selon leurs paramètres weight, priority et precedence, exactement comme des charges de travail sœurs au sein d’une même arborescence.
Voici un exemple de hiérarchie qui répartit toutes les ressources entre les charges de travail “user” et “system”, avec une garantie respective de 90 % et 10 %. Notez que les poids définis pour les charges de travail sont utilisés pour l’équité max-min et ne fournissent donc qu’une garantie minimale au mieux (et non une limite ou un quota maximal). L’ordonnancement est effectué indépendamment sur chaque hôte et, par conséquent, les limites définies par les paramètres max_* s’appliquent à chaque hôte. La charge de travail “user” subdivise ses ressources entre les charges de travail “development” et “production”, “production” disposant de 3 fois plus de ressources que “development” :
SETTINGS workload = 'name'. Consultez Marquage des workloads pour plus de détails.
Pour personnaliser une charge de travail, les paramètres suivants peuvent être utilisés :
priority- (partagé dans le temps uniquement) les charges de travail sœurs sont servies selon des valeurs statiques (une valeur plus faible signifie une priorité plus élevée). Détermine la préemption.precedence- (partagé dans l’espace uniquement) les charges de travail sœurs sont admises selon des valeurs statiques (une valeur plus faible signifie une préséance plus élevée). Détermine l’éviction et l’admission.weight- les charges de travail sœurs ayant la même priorité statique ou la même préséance se partagent les ressources en fonction de leurs poids, de manière équitable. Affecte la préemption, l’éviction et l’admission.max_io_requests- la limite du nombre de requêtes d’IO concurrentes dans cette charge de travail.max_bytes_inflight- la limite du nombre total d’octets en cours de traitement pour les requêtes concurrentes dans cette charge de travail.max_bytes_per_second- la limite du débit en octets en lecture ou en écriture de cette charge de travail.max_burst_bytes- le nombre maximal d’octets pouvant être traités par la charge de travail sans être bridée (pour chaque ressource indépendamment).max_concurrent_threads- la limite du nombre de threads pour les requêtes dans cette charge de travail.max_concurrent_threads_ratio_to_cores- identique àmax_concurrent_threads, mais normalisé par rapport au nombre de cœurs CPU disponibles.max_cpus- la limite du nombre de cœurs CPU pour servir les requêtes dans cette charge de travail.max_cpu_share- identique àmax_cpus, mais normalisé par rapport au nombre de cœurs CPU disponibles.max_burst_cpu_seconds- le nombre maximal de secondes CPU pouvant être consommées par la charge de travail sans être bridée en raison demax_cpus.scheduler- (partagé dans le temps uniquement) l’algorithme d’ordonnancement appliqué aux requêtes de cette charge de travail :fifo(par défaut, premier arrivé, premier servi),fair(mise en file d’attente équitable pondérée),las(least-attained-service) oupriority(ordre strict selon le paramètre de requêteworkload_priority). Consultez Ordonnancement tenant compte des requêtes.max_memory- la limite de la mémoire totale réservée à cette charge de travail.
max_bytes_per_second = '10Mi' disposera d’une limite de débit de 10 Mo/s pour chaque ressource de lecture et d’écriture, de manière indépendante. Si une limite commune à la lecture et à l’écriture est nécessaire, envisagez d’utiliser la même ressource pour les accès READ et WRITE.
Il n’est pas possible de définir des hiérarchies de charges de travail différentes selon les ressources. Il est toutefois possible de définir une valeur de paramètre de charge de travail différente pour une ressource donnée :
CREATE OR REPLACE WORKLOAD.
Les paramètres de charge de travail sont convertis en un ensemble approprié de nœuds d’ordonnancement. Pour des détails de plus bas niveau, consultez la description des types et options des nœuds d’ordonnancement.
Marquage des workloads
Les requêtes peuvent être marquées à l’aide du paramètreworkload pour distinguer différents workloads. Si workload n’est pas défini, la valeur “default” est utilisée. Notez que vous pouvez également spécifier une autre valeur à l’aide de profils de paramètres. Des contraintes sur les paramètres peuvent être utilisées pour rendre workload constant si vous souhaitez que toutes les requêtes d’un utilisateur soient marquées avec une valeur fixe du paramètre workload.
workload aux activités en arrière-plan. Les merges et les mutations utilisent respectivement les paramètres serveur merge_workload et mutation_workload. Ces valeurs peuvent également être redéfinies pour des tables spécifiques à l’aide des paramètres MergeTree merge_workload et mutation_workload.
Ordonnancement du CPU
Pour activer l’ordonnancement du CPU pour les workloads, créez une ressource CPU et définissez une limite pour le nombre de threads concurrents :- Master thread — le premier thread qui commence à travailler sur une requête ou une activité en arrière-plan comme une merge ou une mutation.
- Worker thread — les threads supplémentaires que le master peut créer pour travailler sur des tâches gourmandes en CPU.
max_threads sont utilisées. Les requêtes entrantes doivent alors se bloquer et attendre qu’un slot CPU se libère pour que leurs master threads puissent commencer l’exécution. Pour éviter cela, la configuration suivante peut être utilisée :
cpu_slot_preemption. S’il est activé, chaque thread renouvelle périodiquement son slot CPU (selon le paramètre serveur cpu_slot_quantum_ns). Un tel renouvellement peut bloquer l’exécution si le CPU est surchargé. Lorsque l’exécution reste bloquée pendant une durée prolongée (voir le paramètre serveur cpu_slot_preemption_timeout_ms), la requête réduit alors sa capacité, et le nombre de threads exécutés en parallèle diminue dynamiquement. Notez que l’équité du temps CPU est garantie entre les workloads, mais qu’entre les requêtes d’un même workload, elle peut ne pas être respectée dans certains cas limites.
La déclaration d’une ressource CPU désactive l’effet des paramètres
concurrent_threads_soft_limit_num et concurrent_threads_soft_limit_ratio_to_cores. À la place, le workload setting max_concurrent_threads est utilisé pour limiter le nombre de CPU alloués à une charge de travail spécifique. Pour retrouver le comportement précédent, créez uniquement la ressource WORKER THREAD, définissez max_concurrent_threads pour la charge de travail all sur la même valeur que concurrent_threads_soft_limit_num, puis utilisez le paramètre de requête workload = "all". Cette configuration correspond au paramètre concurrent_threads_scheduler défini sur la valeur “fair_round_robin”.Ordonnancement tenant compte des requêtes
Les paramètres de charge de travailweight et priority répartissent les ressources entre les charges de travail. Pour contrôler la manière dont les requêtes au sein d’une même charge de travail se partagent une ressource partagée dans le temps, choisissez le scheduler de la charge de travail :
fifo(par défaut) — premier arrivé, premier servi, ce qui préserve le comportement historique. Ce mode exclut toute famine, mais n’offre aucune équité et ignoreweightainsi que les paramètres par requête associés.fair— mise en file d’attente équitable pondérée : chaque requête reçoit une part de la ressource proportionnelle à sonweight(un paramètre de requête,1par défaut), et aucune requête n’est privée de ressources.las— least-attained-service : la requête ayant consommé le moins de cette ressource jusqu’à présent est servie en premier (avec un regroupement par niveaux, de sorte qu’une requête descend d’un niveau chaque fois que sa consommation double). Ce mode minimise la latence des requêtes courtes dans les charges de travail mixtes, mais une requête de longue durée peut être privée de ressources par un flux continu de requêtes courtes. Privilégiezfairlorsqu’une garantie d’absence de famine est requise.priority— priorité stricte selon le paramètreworkload_priorityde la requête (unInt64; plus la valeur est faible, plus la priorité est élevée). Les requêtes sont servies par ordre de priorité, en FIFO à priorité égale. La valeur par défaut0sert de référence neutre ; une valeur négative fait passer une requête au-dessus de la priorité par défaut, une valeur positive la fait passer en dessous. Comme tout mécanisme à priorité stricte, ce mode peut priver de ressources les requêtes de faible priorité.
scheduler s’applique uniquement aux ressources partagées dans le temps (CPU et IO) et peut être défini par ressource avec la clause FOR <resource>. Le modifier sur une charge de travail existante remplace l’algorithme à chaud, sans interrompre les autres ressources.
Pour les ressources CPU, le scheduler et les paramètres par requête ci-dessous n’ont de sens qu’avec la préemption des slots CPU (cpu_slot_preemption = 1, valeur par défaut). Sans préemption, chaque slot CPU correspond à un coût fixe plutôt qu’à un temps CPU réel ; ces paramètres ne reflètent donc plus la consommation CPU effective.
Avec le scheduler fair, le poids effectif d’une requête peut être abaissé au fil de son exécution, afin que les requêtes plus courtes ou plus récentes obtiennent une part plus importante. Ce comportement est contrôlé par des paramètres par requête (tous désactivés par défaut) :
Threads vs. CPU
Il existe deux façons de contrôler la consommation de CPU d’une charge de travail :- Limite du nombre de threads :
max_concurrent_threadsetmax_concurrent_threads_ratio_to_cores - Bridage du CPU :
max_cpus,max_cpu_shareetmax_burst_cpu_seconds
max_threads. La seconde bride la consommation de CPU de la charge de travail à l’aide de l’algorithme du seau à jetons. Elle n’affecte pas directement le nombre de threads, mais bride la consommation totale de CPU de tous les threads de la charge de travail.
Le bridage par seau à jetons avec max_cpus et max_burst_cpu_seconds signifie ce qui suit. Sur tout intervalle de delta secondes, la consommation totale de CPU de toutes les queries de la charge de travail ne doit pas dépasser max_cpus * delta + max_burst_cpu_seconds secondes CPU. Cela limite la consommation moyenne à max_cpus sur le long terme, mais cette limite peut être dépassée à court terme. Par exemple, avec max_burst_cpu_seconds = 60 et max_cpus=0.001, il est possible d’exécuter soit 1 thread pendant 60 secondes, soit 2 threads pendant 30 secondes, soit 60 threads pendant 1 seconde sans bridage. La valeur par défaut de max_burst_cpu_seconds est de 1 seconde. Des valeurs plus faibles peuvent entraîner une sous-utilisation des cœurs autorisés par max_cpus en présence de nombreux threads concurrents.
Lorsqu’il détient un slot CPU, un thread peut se trouver dans l’un de ces trois états principaux :
- Running: consomme effectivement des ressources CPU. Le temps passé dans cet état est pris en compte par le bridage du CPU.
- Ready: attend qu’un CPU devienne disponible. Le temps passé dans cet état n’est pas pris en compte par le bridage du CPU.
- Blocked: effectue des opérations d’IO ou d’autres appels système bloquants (par exemple, en attente d’un mutex). Le temps passé dans cet état n’est pas pris en compte par le bridage du CPU.
max_cpu_share, d’une limite de 70 % des ressources CPU totales. Quant à l’ingestion, si elle conserve une garantie d’au moins 0.8 * 0.25 = 20 %, elle n’a pas de limite supérieure.
Si vous souhaitez maximiser l’utilisation du CPU sur votre serveur ClickHouse, évitez d’utiliser
max_cpus et max_cpu_share pour le workload racine all. Définissez plutôt une valeur plus élevée pour max_concurrent_threads. Par exemple, sur un système avec 8 CPU, définissez max_concurrent_threads = 16. Cela permet à 8 threads d’exécuter des tâches CPU pendant que 8 autres threads peuvent gérer des opérations d’E/S. Des threads supplémentaires créeront une pression sur le CPU, ce qui garantit l’application des règles d’ordonnancement. À l’inverse, définir max_cpus = 8 ne créera jamais de pression sur le CPU, car le serveur ne peut pas dépasser les 8 CPU disponibles.Réservations de mémoire
La planification des réservations de mémoire est expérimentale. Elle ne prend effet que lorsqu’une ressource
MEMORY RESERVATION existe, et sa syntaxe SQL ainsi que son comportement peuvent évoluer dans les versions futures. Elle n’est pas encore prise en charge pour les merge et les mutations, et l’éviction d’une requête en cours s’effectue au mieux : elle prend effet au prochain point de synchronisation mémoire de la requête, et non instantanément.reserve_memory supérieur à zéro, l’allocation est alors créée à l’état en attente. Une allocation en attente réserve la quantité de mémoire demandée dans la hiérarchie des workloads. S’il n’y a pas assez de mémoire disponible, l’allocation reste en attente jusqu’à ce qu’une quantité suffisante de mémoire soit libérée ou que d’autres allocations soient évincées (tuées). Lorsque l’allocation est acceptée, elle passe à l’état d’exécution. Une allocation en cours d’exécution peut augmenter ou diminuer dynamiquement en taille en fonction de la consommation mémoire de la requête. Le cycle de vie d’une allocation peut être représenté par le diagramme d’état suivant :
Les allocations en attente d’un workload feuille sont admises selon l’ordre FIFO. Lorsque plusieurs workloads ont des allocations en attente, elles sont admises selon les paramètres de préséance et de pondération. Les workloads de préséance plus élevée sont servis en premier. Les workloads frères ayant la même préséance se partagent la mémoire selon leurs pondérations, de façon équitable selon le principe max-min, ce qui signifie que le workload dont l’utilisation mémoire normalisée est la plus faible (utilisation actuelle plus augmentation demandée, divisée par la pondération) est servi en premier. La logique inverse s’applique lors de l’éviction. Lorsqu’il faut libérer de la mémoire, les workloads de préséance plus faible et dont l’utilisation mémoire normalisée est plus élevée sont évincés en premier.
Notez que les ressources partagées dans le temps utilisent la priorité, tandis que les ressources partagées dans l’espace utilisent la préséance. Ce sont des paramètres indépendants, qui peuvent donc être définis sur des valeurs différentes. Une priorité plus élevée implique une préemption non destructive (retard ou limitation), tandis qu’une préséance plus élevée peut impliquer une éviction destructive (arrêt avec une erreur). Un workload peut avoir une priorité élevée pour l’ordonnancement CPU, tout en conservant la même préséance pour la réservation mémoire afin d’éviter d’évincer d’autres workloads et de perdre le travail qu’ils ont déjà effectué.
Tout workload avec une limite max_memory garantit que la mémoire totale allouée dans son sous-arbre ne dépasse pas cette limite. Si une allocation en attente ou en cours d’augmentation dépasse cette limite, une procédure d’éviction est lancée pour libérer de la mémoire. La procédure d’éviction sélectionne une victime à tuer. Le workload correspondant au plus proche ancêtre commun du killer et de la victime empêche l’éviction dans les situations suivantes :
- Une allocation en attente ne peut pas évincer des allocations en cours dans le même workload. (Les workloads du killer et de la victime coïncident).
- Une allocation en attente de préséance plus faible ne tue jamais un workload de préséance plus élevée.
- Une allocation en attente ne peut pas tuer une allocation de même préséance. Notez que des allocations en cours de même préséance peuvent s’évincer mutuellement en fonction de l’utilisation mémoire normalisée. Si l’éviction est empêchée ou ne libère pas assez de mémoire, la nouvelle allocation est bloquée jusqu’à ce qu’une quantité suffisante de mémoire soit libérée. Ces règles permettent la mise en file d’attente des requêtes excessives en fonction de la pression mémoire et offrent un moyen pratique d’éviter les erreurs MEMORY_LIMIT_EXCEEDED.
Les limites de workload sont indépendantes des autres moyens de limiter la consommation de mémoire, comme le paramètre de requête max_memory_usage. Elles peuvent être utilisées ensemble pour mieux contrôler la consommation de mémoire. Il est possible de définir des limites mémoire indépendantes en fonction des utilisateurs (et non des workloads). Cette approche est moins flexible et n’offre pas de fonctionnalités comme la réservation de mémoire et la mise en file d’attente des requêtes en attente. Voir Memory overcommit
max_waiting_queries limite le nombre d’allocations en attente pour le workload. Lorsque la limite est atteinte, le serveur renvoie une erreur SERVER_OVERLOADED. Notez que max_waiting_queries n’est pas hérité par les workloads enfants et n’a de sens que pour les workloads feuille.
L’ordonnancement de la réservation de mémoire n’est pas encore pris en charge pour les merge et les mutations.
Seules les requêtes dont le paramètre reserve_memory est supérieur à zéro peuvent être bloquées dans l’attente d’une réservation de mémoire. Cependant, les requêtes pour lesquelles reserve_memory vaut zéro sont elles aussi prises en compte dans l’empreinte mémoire de leur workload, et elles peuvent être évincées si nécessaire afin de libérer de la mémoire pour d’autres allocations en attente ou en augmentation. Les requêtes sans marquage de workload approprié ne sont pas soumises à l’ordonnancement de la réservation de mémoire et ne peuvent pas être évincées par le planificateur.
Pour fournir à une requête une réservation de mémoire non élastique, définissez les paramètres de requête reserve_memory et max_memory_usage à la même valeur. Dans ce cas, la requête réservera une quantité fixe de mémoire et ne pourra pas augmenter dynamiquement son allocation. Notez qu’une réservation de mémoire élastique peut être augmentée au-delà de reserve_memory, jusqu’à max_memory_usage, sans être arrêtée, sauf en cas de pression mémoire. En revanche, elle ne peut pas être réduite en dessous de reserve_memory, même lorsque la consommation réelle est inférieure.
Prenons un exemple de configuration :
Ordonnancement des slots de requête
Pour activer l’ordonnancement des slots de requête pour les workloads, créez la ressource QUERY et définissez une limite sur le nombre de requêtes simultanées ou de requêtes par seconde :max_concurrent_queries limite le nombre de requêtes concurrentes pouvant s’exécuter simultanément pour un workload donné. Il s’agit de l’équivalent du paramètre de requête max_concurrent_queries_for_all_users et du paramètre du serveur max_concurrent_queries. Les requêtes async insert et certaines requêtes spécifiques, comme KILL, ne sont pas comptabilisées dans cette limite.
Les paramètres de workload max_queries_per_second et max_burst_queries limitent le nombre de requêtes pour le workload à l’aide d’un mécanisme de limitation de débit de type token bucket. Cela garantit que, sur tout intervalle de temps T, pas plus de max_queries_per_second * T + max_burst_queries nouvelles requêtes ne commenceront à s’exécuter.
Le paramètre de workload max_waiting_queries limite le nombre de requêtes en attente pour le workload. Lorsque la limite est atteinte, le serveur renvoie une erreur SERVER_OVERLOADED. Notez que max_waiting_queries n’est pas hérité par les workloads enfants et n’a de sens que pour les workloads feuilles.
Les requêtes bloquées attendent indéfiniment et n’apparaissent pas dans
SHOW PROCESSLIST tant que toutes les contraintes ne sont pas satisfaites.Stockage des workloads et des ressources
Les définitions de tous les workloads et de toutes les ressources, sous la forme de requêtesCREATE WORKLOAD et CREATE RESOURCE, sont stockées de manière persistante soit sur le disque dans workload_path, soit dans ZooKeeper dans workload_zookeeper_path. Le stockage dans ZooKeeper est recommandé pour garantir la cohérence entre les nœuds. Sinon, la clause ON CLUSTER peut être utilisée avec le stockage sur disque.
Charges de travail et ressources définies par configuration
En plus des définitions basées sur SQL, les charges de travail et les ressources peuvent être prédéfinies dans le fichier de configuration du serveur. Cela est utile dans les environnements cloud, où certaines restrictions sont imposées par l’infrastructure, tandis que d’autres limites peuvent être modifiées par les clients. Les entités définies par configuration ont priorité sur celles définies en SQL et ne peuvent pas être modifiées ni supprimées à l’aide de commandes SQL.Format de la configuration
CREATE WORKLOAD et CREATE RESOURCE. Toutes les requêtes doivent être valides.
Recommandations d’utilisation
Pour les environnements cloud, une configuration typique peut inclure :- Définir le workload racine et les ressources d’E/S réseau dans la configuration afin de fixer les limites de l’infrastructure
- Définir
throw_on_unknown_workloadpour faire respecter ces limites - Créer un
CREATE WORKLOAD default IN allpour appliquer automatiquement les limites à toutes les requêtes (puisque la valeur par défaut du paramètre de requêteworkloadest ‘default’) - Autoriser les utilisateurs à créer des workloads supplémentaires dans la hiérarchie configurée
Accès strict aux ressources
Pour obliger toutes les requêtes à respecter les politiques d’ordonnancement des ressources, il existe un paramètre du serveurthrow_on_unknown_workload. S’il est défini sur true, chaque requête doit utiliser un paramètre de requête workload valide, faute de quoi l’exception RESOURCE_ACCESS_DENIED est levée. S’il est défini sur false, une telle requête n’utilise pas l’ordonnanceur de ressources, c’est-à-dire qu’elle bénéficie d’un accès illimité à n’importe quelle RESOURCE. Le paramètre de requête ‘use_concurrency_control = 0’ permet à une requête de contourner l’ordonnanceur CPU et d’obtenir un accès illimité au CPU. Pour imposer l’ordonnancement CPU, créez une contrainte de paramètre afin que ‘use_concurrency_control’ reste une valeur constante en lecture seule.
Ne définissez pas
throw_on_unknown_workload sur true tant que CREATE WORKLOAD default n’a pas été exécuté. Cela peut entraîner des problèmes au démarrage du serveur si une requête sans paramètre workload explicite est exécutée pendant le démarrage.Hiérarchie des nœuds d’ordonnancement
Du point de vue du sous-système d’ordonnancement, chaque ressource correspond à une hiérarchie de nœuds d’ordonnancement. ClickHouse crée automatiquement tous les nœuds d’ordonnancement nécessaires à partir des définitions WORKLOAD et RESOURCE. Les nœuds d’ordonnancement sont des détails d’implémentation de bas niveau, accessibles dans la table system.scheduler.inflight_limit(contrainte) - bloque si le nombre de requêtes simultanément en vol dépassemax_requests, ou si leur coût total dépassemax_cost; doit avoir un seul enfant.bandwidth_limit(contrainte) - bloque si le débit actuel dépassemax_speed(0 signifie illimité) ou si la rafale dépassemax_burst(par défaut, égal àmax_speed) ; doit avoir un seul enfant.fair(politique) - sélectionne la prochaine requête à traiter dans l’un de ses nœuds enfants selon l’équité max-min ; les nœuds enfants peuvent spécifierweight(la valeur par défaut est 1).priority(politique) - sélectionne la prochaine requête à traiter dans l’un de ses nœuds enfants selon des priorités statiques (une valeur plus faible signifie une priorité plus élevée) ; les nœuds enfants doivent spécifierpriority(la valeur par défaut est 0).queue- feuille de la hiérarchie capable de contenir des requêtes qui dépassent la capacité des ressources.
limit- garantit que l’allocation totale de l’enfant ne dépasse jamais une limite et déclenche, si nécessaire, une procédure d’éviction dans un sous-arbre ; doit avoir un seul enfant.fair_allocation- applique l’éviction selon l’équité max-min ; une allocation en attente n’évince jamais une allocation en cours d’exécution ; les nœuds enfants peuvent spécifierweight(la valeur par défaut est 1).precedence_allocation- applique l’éviction selon une préséance statique (une valeur plus faible signifie une préséance plus élevée) ; une allocation en attente de préséance plus élevée évince les allocations de préséance plus faible ; les nœuds enfants doivent spécifierprecedence(la valeur par défaut est 0).queue- feuille de la hiérarchie capable de contenir des allocations en cours d’exécution et en attente.
Sauvegarde et restauration
Les workloads et ressources définis en SQL peuvent être inclus dans une sauvegarde ClickHouse :<resources_and_workloads> dans le fichier de configuration du serveur) ne sont pas inclus : ils font partie de la server configuration, qui doit être sauvegardée séparément.
Sauvegardez et restaurez toujours system.workloads et system.resources ensemble, dans une même commande. Un workload peut référencer une ressource (via SETTINGS ... FOR <resource>) ainsi qu’un workload parent, et une sauvegarde de system.workloads seule n’inclut pas les définitions des ressources référencées. La restauration d’un workload dont la ressource référencée n’est ni présente dans la sauvegarde ni déjà présente sur le server target échoue.
Pour restaurer des workloads et des ressources à partir d’une sauvegarde :
CREATE WORKLOAD et CREATE RESOURCE. Par défaut, les entités existantes sont conservées telles quelles (sémantique if not exists) ; le paramètre create_workloads_and_resources ci-dessous détermine la façon dont une entité déjà existante est traitée. Si le serveur utilise le stockage ZooKeeper (workload_zookeeper_path), une seule réplique du cluster créera chaque entité ; les autres répliques récupèrent la modification via le mécanisme de réplication ordinaire.
Pour les configurations répliquées, les deux tables peuvent être sauvegardées et restaurées avec ON CLUSTER :
create_workloads_and_resources détermine la façon dont un workload ou une ressource déjà existant est traité lors de sa restauration (il n’active ni ne désactive la restauration de ces entités). Il accepte :
if not exists(valeur par défaut) — conserver une entité existante telle quelle et créer uniquement celles qui manquent ;create— faire échouer la restauration si l’une des entités restaurées existe déjà ;replace— écraser une entité existante avec la définition issue du backup (cela requiert en outre le privilègeDROP WORKLOAD/DROP RESOURCE). :::
Voir aussi
- system.scheduler
- system.workloads
- system.resources
- merge_workload paramètre de MergeTree
- merge_workload paramètre global du serveur
- mutation_workload paramètre de MergeTree
- mutation_workload paramètre global du serveur
- workload_path paramètre global du serveur
- workload_zookeeper_path paramètre global du serveur
- cpu_slot_preemption paramètre global du serveur
- cpu_slot_quantum_ns paramètre global du serveur
- cpu_slot_preemption_timeout_ms paramètre global du serveur