carbon-c-relay -f Config-File [ options ... ]
Carbon-C-Relay accepte, nettoie, correspond, réécrit, avance et agrégte les mesures de graphite en écoutant les connexions entrantes et en relayant les messages à d'autres serveurs définis dans sa configuration. La fonctionnalité principale consiste à acheminer les messages via des règles flexibles vers les destinations souhaitées.
Carbon-C-Relay est un programme simple qui lit ses informations de routage à partir d'un fichier. Les arguments de la ligne de commande permettent de définir l'emplacement de ce fichier, ainsi que la quantité de répartiteurs (threads de travail) à utiliser pour lire les données à partir de connexions entrantes et les transmettre sur la ou les bonnes destinations. Le fichier d'itinéraire prend en charge deux constructions principales: les clusters et les correspondances. Les premiers groupes définissent des métriques de données d'hôtes peuvent être envoyés, ces derniers définissent quelles mesures doivent être envoyées au cluster. Les règles d'agrégation sont considérées comme des correspondances. Les réécritures sont des actions qui affectent directement la métrique au point où elles apparaissent dans la configuration.
Pour chaque métrique reçue par le relais, le nettoyage est effectué. Les modifications suivantes sont effectuées avant toute règle de correspondance, d'agrégat ou de réécriture voit la métrique:
[0-9a-zA-Z-_:#] , mais peut être remplacé sur la ligne de commande. Notez que les balises (lorsqu'elles sont présentes et autorisées) ne sont pas traitées de cette façon. Ces options contrôlent le comportement de la répression de carbone-c .
-v : Imprimer la chaîne de version et quitter.
-d : Activer le mode de débogage, cela imprime des statistiques à STDOUT et imprime des messages supplémentaires sur certaines situations rencontrées par le relais qui serait normalement trop verbeux pour être activé. Lorsqu'il est combiné avec -t (mode test), cela imprime également les routes de stub et le contenu des anneaux cohérents.
-s : Activer le mode de soumission. Dans ce mode, les statistiques internes ne sont pas générées. Au lieu de cela, les baisses de pression et de métriques sont signalées sur STDOUT. Ce mode est utile lorsqu'il est utilisé comme relais de soumission dont le travail est juste à transmettre à (un ensemble de relais principaux). Les statistiques concernant les relais de soumission dans ce cas ne sont pas nécessaires et pourraient facilement provoquer un inondation de métriques non désiré, par exemple lorsqu'il est utilisé sur chaque hôte localement.
-S : Activez le mode de type IOSTAT où chaque seconde l'état actuel des statistiques est signalé. Cela implique le mode de soumission -s .
-t : Mode de test. Ce mode ne fait aucun routage du tout, mais lit plutôt les entrées de Stdin et imprime les actions qui seraient prises compte tenu de la configuration chargée. Ce mode est très utile pour tester les voies de relais pour la syntaxe d'expression régulière, etc. Il permet également de donner un aperçu de la façon dont le routage est appliqué dans des configurations complexes, car elle montre également des réécritures et des agrégats. Lorsque -t est répété, le relais ne testera que la configuration pour la validité et la sortie immédiatement après. Toute sortie standard est supprimée dans ce mode, ce qui le rend idéal pour les scripts de démarrage pour tester une (nouvelle) configuration.
-f Configation-File : Lire la configuration à partir de configuration . Une configuration se compose de clusters et de routes. Voir Syntaxe de configuration pour plus d'informations sur les options et la syntaxe de ce fichier.
-l Log-fichier : Utilisez le fichier de journaux pour écrire des messages. Sans cette option, le relais écrit à la fois sur stdout et stderr . Lors de la connexion dans le fichier, tous les messages sont préfixés avec MSG lorsqu'ils ont été envoyés à STDOUT et ERR lorsqu'ils ont été envoyés à Stderr .
-p PORT : Écoutez les connexions sur le port de port. Le numéro de port est utilisé pour les prises TCP , UDP et UNIX sockets . Dans ce dernier cas, le fichier de socket contient le numéro de port. Le port par défaut est en 2003 , qui est également utilisé par le carbon-cache.py d'origine. Notez que cela ne s'applique qu'aux valeurs par défaut, lorsque les directives listen sont dans la configuration, ce paramètre est ignoré.
-w travailleurs : utilisez le nombre de threads des travailleurs . Le nombre par défaut de travailleurs est égal à la quantité de noyaux de processe détectés. Il est logique de réduire ce nombre sur les machines à plusieurs noyaux, ou lorsque le trafic est faible.
-b BatchSize : Définissez la quantité de mesures qui ont envoyé des serveurs distants à la fois sur BatchSize . Lorsque le relais envoie des métriques aux serveurs, il récupérera les métriques batchsize à partir de la file d'attente en attente de mesures en attente de ce serveur et en envoie un par un. La taille du lot aura un impact minimal sur l'envoi de performances, mais il contrôle le montant de la contention de verrouillage sur la file d'attente. La valeur par défaut est 2500 .
-q Queuesize : chaque serveur de la configuration où le relais enverra des mesures, a une file d'attente qui lui est associée. Cette file d'attente permet de gérer les perturbations et les éclats. La taille de cette file d'attente sera définie sur la file d'attente, ce qui permet de stocker cette quantité de mesures dans la file d'attente avant qu'elle ne déborde, et le relais commence à abandonner les mesures. Plus la file d'attente est grande, plus de mesures peuvent être absorbées, mais plus de mémoire sera utilisée par le relais. La taille de la file d'attente par défaut est de 25000 .
-L stalles : Définit le support maximal des stalles sur les stalles avant que le relais ne commence à abandonner les mesures pour un serveur. Lorsqu'une file d'attente se remplit, le relais utilise un mécanisme appelé Stalling pour signaler le client (écrivant au relais) de cet événement. En particulier, lorsque le client envoie une grande quantité de métriques en très peu de temps (rafale), le décrochage peut aider à éviter de supprimer les mesures, car le client doit simplement ralentir un peu, ce qui, dans de nombreux cas, est possible (par exemple lors de la capture d'un fichier avec nc (1)). Cependant, ce comportement peut également obstruer, bloquant artificiellement les écrivains qui ne peuvent pas s'arrêter facilement. Pour cela, les stands peuvent être réglés de 0 à 15 , où chaque stand peut prendre environ 1 seconde sur le client. La valeur par défaut est définie sur 4 , qui vise le scénario de perturbation occasionnel et l'effort maximum pour ne pas perdre de mesures avec un ralentissement modéré des clients.
-C CacertPath : Lire CERS CA (pour une utilisation avec les connexions TLS / SSL) à partir du chemin ou du fichier donné. Lorsqu'ils ne sont pas donnés, les emplacements par défaut sont utilisés. Une verfication stricte du pair est effectuée, donc lorsque vous utilisez des certificats auto-signés, assurez-vous d'inclure le certificat CA dans l'emplacement par défaut ou fournissez le chemin vers le certificat à l'aide de cette option.
-T Timeout : Spécifie le délai d'EI en millisecondes utilisé pour les connexions du serveur. La valeur par défaut est de 600 millisecondes, mais peut nécessiter une augmentation lorsque les liens WAN sont utilisés pour les serveurs cibles. Une valeur relativement faible pour le délai d'expiration de connexion permet au relais d'établir rapidement un serveur est inaccessible et, en tant que telles stratégies de basculement, à déclencher avant que la file d'attente ne soit élevée.
-c Chars : définit les caractères qui sont à côté de [A-Za-z0-9] autorisés dans les métriques aux caractères . Tout caractère qui n'est pas dans cette liste est remplacé par le relais par _ (soulignement). La liste par défaut des caractères autorisés est -_: # .
-m longueur : limite les noms métriques à des octets au plus long . Toutes les lignes contenant des noms métriques plus grandes que celle-ci seront rejetées.
-M longueur limite l'entrée sur les lignes des octets au plus de longueur . Toute ligne excessive sera jetée. Notez que -m doit être plus petit que cette valeur.
-H Nom hostNe : remplacer le nom d'hôte déterminé par un appel à gethostname (3) avec le nom d'hôte . Le nom d'hôte est utilisé principalement dans les métriques statistiques carbon.relays.<hostname>.<...> envoyé par le relais.
-B backlog : Définit les connexions TCP Connection Écoutez le backlog dans le backlog . La valeur par défaut est de 32 mais sur les serveurs qui reçoivent de nombreuses connexions simultanées, ce paramètre doit probablement être augmenté pour éviter les erreurs refusées de connexion sur les clients.
-U BUFSIZE : Définit les tailles de tampon Send Send / Recevoir en octets, pour les scénarios TCP et UDP. Lorsqu'il est inférieur, la valeur par défaut du système d'exploitation est utilisée. Le maximum est également déterminé par le système d'exploitation. Les tailles sont définies à l'aide de setsockopt avec les drapeaux SO_RCVBUF et SO_SNDBUF. Le réglage de cette taille peut être nécessaire pour les scénarios de grand volume, pour lesquels -B peut également s'appliquer. La vérification des valeurs RECV-Q et des erreurs de réception de Netstat donne un bon indice sur l'utilisation du tampon.
-E : Désactiver la déconnexion des connexions inactives. Par défaut, le relais déconnecte les connexions du client inactif après 10 minutes. Cela fait cela pour empêcher les ressources de se obstruer lorsqu'un client défectueux ou malveillant continue d'ouvrir des connexions sans les fermer. Il empêche généralement les descripteurs de fichiers. Pour certains scénarios, cependant, il n'est pas souhaitable que les connexions inactives soient déconnectées, donc passer ce drapeau désactivera ce comportement.
-D : Deamonise en arrière-plan après le démarrage. Cette option nécessite également les indicateurs -l et -P .
-P pidfile : écrivez le PID du processus de relais dans un fichier appelé pidfile . Ceci est en particulier utile lorsqu'il est débrouillé en combinaison avec les gestionnaires INI.
-O Seuil : le nombre minimum de règles à trouver avant d'essayer d'optimiser l'ensemble de règles. La valeur par défaut est 50 , pour désactiver l'optimisateur, utiliser -1 , pour toujours exécuter l'optimisation Utiliser 0 . L'Optimiser essaie de regrouper les règles pour éviter de passer un temps excessif à faire correspondre les expressions.
Le fichier de configuration prend en charge la syntaxe suivante, où les commentaires commencent par un caractère # et peuvent apparaître à n'importe quelle position sur une ligne et supprimer l'entrée jusqu'à la fin de cette ligne:
cluster <name>
< <forward | any_of | failover> [useall] |
<carbon_ch | fnv1a_ch | jump_fnv1a_ch> [replication <count>] [dynamic] >
<host[:port][=instance] [proto <udp | tcp>]
[type linemode]
[transport <plain | gzip | lz4 | snappy>
[ssl | mtls <pemcert> <pemkey>]]> ...
;
cluster <name>
file [ip]
</path/to/file> ...
;
match
<* | expression ...>
[validate <expression> else <log | drop>]
send to <cluster ... | blackhole>
[stop]
;
rewrite <expression>
into <replacement>
;
aggregate
<expression> ...
every <interval> seconds
expire after <expiration> seconds
[timestamp at <start | middle | end> of bucket]
compute <sum | count | max | min | average |
median | percentile<%> | variance | stddev> write to
<metric>
[compute ...]
[send to <cluster ...>]
[stop]
;
send statistics to <cluster ...>
[stop]
;
statistics
[submit every <interval> seconds]
[reset counters after interval]
[prefix with <prefix>]
[send to <cluster ...>]
[stop]
;
listen
type linemode [transport <plain | gzip | lz4 | snappy>
[<ssl | mtls> <pemcert>
[protomin <tlsproto>] [protomax <tlsproto>]
[ciphers <ssl-ciphers>] [ciphersuites <tls-suite>]
]
]
<<interface[:port] | port> proto <udp | tcp>> ...
</ptah/to/file proto unix> ...
;
# tlsproto: <ssl3 | tls1.0 | tls1.1 | tls1.2 | tls1.3>
# ssl-ciphers: see ciphers(1)
# tls-suite: see SSL_CTX_set_ciphersuites(3)
include </path/to/file/or/glob>
;
Plusieurs clusters peuvent être définis et ne doivent pas être référencés par une règle de correspondance. Tous les clusters pointent vers un ou plusieurs hôtes, à l'exception du cluster file qui écrit aux fichiers du système de fichiers local. host peut être une adresse IPv4 ou IPv6, ou un nom d'hôte. Étant donné que l'hôte est suivi par un port facultatif : et pour que les adresses IPv6 ne soient pas interprétées à tort, un port doit être donné, soit l'adresse IPv6 entourée de supports, par exemple [::1] . Des clauses transport et proto en option peuvent être utilisées pour envelopper la connexion dans une couche de compression ou de chiffrement ou spécifier l'utilisation d'UDP ou de TCP pour se connecter au serveur distant. Lorsqu'il est omis, la connexion par défaut vers une connexion TCP simple. type ne peut être que linemode pour le moment, par exemple le mode Python de Python n'est pas pris en charge.
Les noms d'hôtes DNS sont résolus en une seule adresse, selon les règles de préférence dans RFC 3484. Les clusters any_of , failover et forward ont un drapeau useall explicite qui permet l'expansion pour les noms d'hôtes résolvant à plusieurs adresses. En utilisant cette option, chaque adresse de tout type devient une destination de cluster. Cela signifie par exemple que des adresses IPv4 et IPv6 sont ajoutées.
Il existe deux groupes de types de cluster, de clusters de transfert simples et de clusters de hachage cohérents.
grappes forward et file
Les grappes forward et file envoient simplement tout ce qu'ils reçoivent aux membres définis (adresses hôte ou fichiers). Lorsqu'un cluster a plusieurs membres, toutes les mesures entrantes sont envoyées à tous les membres, en double du flux de métrique d'entrée sur tous les membres.
cluster any_of
Le cluster any_of est une petite variante du cluster forward , mais au lieu d'envoyer les mesures d'entrée à tous les membres définis, il envoie chaque métrique entrante à un seul des membres définis. Le but de ceci est un scénario équilibré en charge dans lesquels l'un des membres peut recevoir n'importe quelle mesure. Comme any_of le suggère, lorsque l'un des membres devient inaccessible, les autres membres disponibles recevront immédiatement le flux complet de mesures d'entrée. Cela signifie spécifiquement que lorsque 4 membres sont utilisés, chacun recevra environ 25% des mesures d'entrée. Lorsqu'un membre devient indisponible (par exemple, interruption du réseau ou redémarrage du service), les 3 membres restants recevront chacun environ 25% / 3 = ~ 8% de trafic de plus (33%). Alternativement, ils recevront 1/3 de l'entrée totale. Lors de la conception de la capacité du cluster, il faut tenir compte du fait que dans le cas le plus extrême, le membre final restant recevra tout le trafic d'entrée.
Un cluster any_of peut en particulier être utile lorsque le cluster pointe vers d'autres relais ou caches. Lorsqu'il est utilisé avec d'autres relais, il se compare efficacement et s'adapte immédiatement à l'inavance des cibles. Lorsqu'il est utilisé avec des caches, il y a un petit détail sur le fonctionnement any_of , ce qui le rend très approprié. La mise en œuvre de ce routeur ne consiste pas à rabondir par rapport aux membres disponibles, mais il utilise plutôt une stratégie de hachage cohérente pour fournir les mêmes mesures à la même destination tout le temps. Cela aide les caches et facilite la récupération de points de données non engagés (à partir d'un seul cache), mais permet toujours un redémarrage de roulement des caches. Lorsqu'un membre devient indisponible, les destinations de hachage ne sont pas modifiées, mais à la place, le trafic destiné au nœud indisponible est réparti uniformément sur les nœuds disponibles.
cluster failover
Le cluster failover est comme le cluster any_of , mais s'en tient à l'ordre dans lequel les serveurs sont définis. Il s'agit d'implémenter un scénario de basculement pur entre les serveurs. Toutes les mesures sont envoyées au plus 1 membre, donc aucun hachage ou équilibre n'a lieu. Par exemple, un cluster failover avec deux membres n'enverra des mesures que au deuxième membre lorsque le premier membre deviendra indisponible. Dès que le premier membre revient, toutes les mesures sont à nouveau envoyées au premier nœud.
cluster carbon_ch
Le cluster carbon_ch envoie les mesures au membre qui est responsable en fonction de l'algorithme de hachage cohérent utilisé dans le relais de carbone Python d'origine. Plusieurs membres sont possibles si la réplication est définie sur une valeur supérieure à 1. Lorsque dynamic est définie, l'échec de l'un des serveurs n'entraîne pas la suppression des mesures pour ce serveur, mais à la place, les mesures non livrables sont envoyées à un autre serveur dans le cluster afin que les mesures ne se perdent pas. Ceci est très utile lorsque la réplication est 1.
Le calcul du hashring, qui définit la façon dont les mesures sont distribuées, est basée sur l'hôte du serveur (ou adresse IP) et l' instance facultative du membre. Cela signifie que l'utilisation de carbon_ch deux cibles sur différents ports, mais sur le même hôte ne mappera au même hachage, ce qui signifie qu'aucune distribution de mesures n'a lieu. L'instance est utilisée pour remédier à cette situation. Une instance est ajoutée au membre après le port, et séparée par un signe égal, par exemple 127.0.0.1:2006=a Par exemple a . Les instances sont un concept introduit par Python Carbon-Cache original et doivent être utilisés conformément à la configuration de ceux-ci.
Les hachages cohérents sont cohérents dans le sens où la suppression d'un membre du cluster ne doit pas entraîner un re-mappage complet de toutes les mesures aux membres, mais à la place, ajoutez uniquement les mesures du membre supprimé à tous les membres restants, chacun obtient sa juste part. Dans l'autre sens, lorsqu'un membre est ajouté, chaque membre devrait voir un sous-ensemble de ses mesures qui sont maintenant adressées au nouveau membre. Il s'agit d'un avantage important par rapport à un hachage normal, où chaque retrait ou ajout de membres (également via par exemple un changement dans leur adresse IP ou nom d'hôte) entraînerait un re-mappage complet de toutes les mesures sur toutes les mesures disponibles.
cluster fnv1a_ch
Le cluster fnv1a_ch est une amélioration incompatible pour carbon_ch introduit par Carbon-C-Relay. Il utilise une technique de hachage différente (FNV1A) qui est plus rapide que le MD5-Hashing utilisé par carbon_ch . Plus important encore, les grappes fnv1a_ch utilisent à la fois l'hôte et le port pour distinguer les membres. Ceci est utile lorsque plusieurs cibles vivent sur le même hôte juste séparées par le port.
Étant donné que la propriété instance n'est plus nécessaire avec fnv1a_ch de cette façon, elle est utilisée pour remplacer complètement la chaîne de port hôte: le hachage serait calculé. Il s'agit d'un aspect important, car le Hashkey définit les mesures qu'un membre reçoit. Une telle remplacement permet beaucoup de choses, notamment en faisant passer l'ancienne adresse IP, par exemple lorsqu'une machine a été migrée vers le matériel plus récent. Un exemple de cela serait de 10.0.0.5:2003=10.0.0.2:2003 où une machine à l'adresse 5 reçoit désormais les métriques d'une machine qui était à l'adresse 2.
Bien que l'utilisation des instances de cette façon peut être très utile pour effectuer des migrations dans des clusters existants, pour que les clusters de configuration nouvellement, les instances ne permettent d'éviter ce travail en utilisant une instance du premier jour pour détacher l'emplacement de la machine à partir des métriques qu'il reçoit. Considérez par exemple 10.0.0.1:2003=4d79d13554fa1301476c1f9fe968b0ac où un hachage aléatoire en instance est utilisé. Cela permettrait de modifier l'adresse du port et / ou IP du serveur qui reçoit des données autant de fois sans que ce soit un héritage visible, en supposant que le hachage aléatoire est conservé. Notez que puisque le nom de l'instance est utilisé comme entrée de hachage complète, les instances en tant que a , b , etc. entraîneront probablement une mauvaise distribution de hachage, car leurs hachages ont très peu d'entrée. Pour cette raison, envisagez d'utiliser des noms d'instance plus longs et principalement différents tels que les hachages aléatoires utilisés dans l'exemple ci-dessus pour un meilleur comportement de distribution de hachage.
jump_fnv1a_ch CLUSTER
Le cluster jump_fnv1a_ch est également un cluster de hachage cohérent comme les deux précédents, mais il ne prend pas du tout l'hôte, le port ou l'instance membre. Cela signifie que ce type de cluster examine l'ordre dans lequel les membres sont définis, voir également ci-dessous pour plus sur cette commande. Que cela vous soit utile dépend de votre scénario. Contrairement aux deux types de cluster de hachage cohérents précédents, le hachage de saut a un équilibre presque parfait sur les membres définis dans le cluster. Cependant, cela se fait au détriment de ne pas pouvoir supprimer aucun membre, mais le dernier du cluster sans provoquer un re-mappage complet de toutes les mesures par rapport à tous les membres. Ce que cela signifie essentiellement, c'est que ce hachage est bon à utiliser avec des grappes constantes ou en croissance où les nœuds plus anciens ne sont jamais retirés, mais remplacés à la place.
Si vous avez un cluster où la suppression des anciens nœuds a lieu, le hachage de saut ne vous convient pas. Jump Hash fonctionne avec des serveurs dans une liste ordonnée. Étant donné que cette commande est importante, elle peut être rendue explicite en utilisant l'instance telle qu'elle est utilisée dans les types de cluster précédents. Lorsqu'une instance est donnée avec les membres, il sera utilisé comme clé de tri. Sans cette instance, la commande sera celle donnée dans le fichier de configuration, qui peut être sujette à des modifications lorsque par EG généré par un logiciel de gestion de configuration. En tant que tel, il est probablement une bonne pratique de réparer l'ordre des serveurs avec des instances telles que c'est explicite quels sont les nœuds de droite pour le hachage de saut. On peut simplement utiliser des nombres pour ceux-ci, mais sachez que le tri de 1, 2 et 10 en résulte 1, 10, 2, donc mieux utiliser quelque chose comme P0001, P0002, P0010 à la place.
Les règles de correspondance sont le moyen de diriger les mesures entrantes à un ou plusieurs clusters. Les règles de correspondance sont traitées de haut en bas car elles sont définies dans le fichier. Il est possible de définir plusieurs correspondances dans la même règle. Chaque règle de correspondance peut envoyer des données à un ou plusieurs clusters. Étant donné que les règles de correspondance "tombent", sauf si le mot clé stop est ajouté, l'expression de correspondance soigneusement conçue peut être utilisée pour cibler plusieurs clusters ou agrégations. Cette capacité permet de reproduire les mesures, ainsi que d'envoyer certaines mesures à des clusters alternatifs avec une commande minutieuse et une utilisation du mot-clé stop . Le cluster spécial blackhole élimine toutes les mesures qui lui sont envoyées. Cela peut être utile pour éliminer les mesures indésirables dans certains cas. Parce que lancer des mesures est inutile si d'autres correspondances accepteraient les mêmes données, une correspondance avec la destination du cluster Blackhole, a un stop implicite. La clause validation ajoute un contrôle aux données (ce qui vient après la métrique) sous la forme d'une expression régulière. Lorsque cette expression correspond, la règle de correspondance s'exécutera comme si aucune clause de validation n'était présente. Cependant, s'il échoue, la règle de correspondance est interrompue et aucune mesure ne sera envoyée aux destinations, c'est le comportement drop . Lorsque log est utilisé, la métrique est enregistrée à STDERR. Il faut prendre soin de ce dernier pour éviter les inondations en rondins. Lorsqu'une clause de validation est présente, les destinations ne doivent pas être présentes, cela permet d'appliquer une règle de validation globale. Notez que les règles de nettoyage sont appliquées avant la validation, donc les données n'auront pas d'espaces en double. La clause route using est utilisée pour effectuer une modification temporaire de la clé utilisée pour l'entrée dans les routines de hachage cohérentes. L'objectif principal est d'acheter le trafic afin que les données appropriées soient envoyées aux instances d'agrégation nécessaires.
Les règles de réécriture prennent une expression régulière en entrée pour faire correspondre les mesures entrantes et les transformer en le nouveau nom métrique souhaité. Dans le remplacement, les rétro-références sont autorisées à faire correspondre les groupes de capture définis dans l'expression régulière d'entrée. Une correspondance de server.(x|y|z). permet d'utiliser role.1. dans la substitution. Si nécessaire, une notation de g{n} peut être utilisée à la place de n où le backreference est suivi d'un entier, tel que g{1}100 . Quelques mises en garde s'appliquent à la mise en œuvre actuelle des règles de réécriture. Tout d'abord, leur emplacement dans le fichier de configuration détermine quand la réécriture est effectuée. La réécriture est effectuée en place, car une telle règle de correspondance avant que la réécriture ne corresponde au nom d'origine, une règle de match après que la réécriture ne correspond plus au nom d'origine. Il faut prendre soin de l'ordre, car plusieurs règles de réécriture successivement peuvent avoir lieu, par exemple a est remplacé par b et b est remplacé par c dans une règle de réécriture suivante. La deuxième mise en garde avec l'implémentation actuelle, est que les noms métriques réécrits ne sont pas nettoyés, comme les métriques nouvellement entrantes. Ainsi, les points doubles et les caractères dangereux potentiels peuvent apparaître si la chaîne de remplacement est fabriquée pour les produire. Il est de la responsabilité de l'écrivain de s'assurer que les mesures sont propres. S'il s'agit d'un problème de routage, on peut considérer pour avoir une instance de réécriture uniquement qui transmet toutes les mesures à une autre instance qui fera le routage. _ toute ^ , la deuxième instance nettoiera les mesures à mesure qu'ils arrivent. Par exemple, role._1. car la substitution sera minuscule, le contenu de 1 . Le point ( . ) Peut être utilisé de manière similaire, ou suivi après le soulignement ou le caret pour remplacer les points par des soulignements dans la substitution. Cela peut être pratique pour certaines situations où les métriques sont envoyées au graphite.
Les agrégations définies prennent une ou plusieurs mesures d'entrée exprimées par une ou plusieurs expressions régulières, similaires aux règles de correspondance. Les métriques entrantes sont agrégées sur une période de temps définie par l'intervalle en secondes. Étant donné que les événements peuvent arriver un peu plus tard dans le temps, le temps d'expiration en secondes définit lorsque les agrégations doivent être considérées comme finales, car aucune nouvelle entrée ne peut être ajoutée. En plus d'une agrégation, plusieurs agrégations peuvent être calculées. Ils peuvent être des mêmes types d'agrégations ou différents, mais doivent écrire à une nouvelle métrique unique. Les noms métriques peuvent inclure des références en arrière comme dans les expressions de réécriture, permettant de puissantes règles d'agrégation unique qui donnent dans de nombreuses agrégations. Lorsqu'aucun send to la clause n'est donné, des mesures produites sont envoyées au relais comme s'ils étaient soumis de l'extérieur, donc les règles de correspondance et d'agrégation s'appliquent à celles-ci. Il faut veiller à ce que les boucles soient évitées de cette façon. Pour cette raison, l'utilisation de la clause send to est encouragée pour diriger le trafic de sortie dans la mesure du possible. Comme pour les règles de correspondance, il est possible de définir plusieurs cibles de cluster. En outre, comme les règles de correspondance, le mot clé stop s'applique pour contrôler le flux de mesures dans le processus de correspondance.
Les send statistics to construire sont obsolètes et seront supprimées dans la prochaine version. Utilisez plutôt la construction spéciale statistics .
La construction statistics peut contrôler quelques choses sur les statistiques (internes) produites par le relais. L' send to la cible peut être utilisé pour éviter les boucles de routeur en envoyant les statistiques à un ou des cluster de destination. Par défaut, les métriques sont préfixées avec carbon.relays.<hostname> , où le nom d'hôte est déterminé au démarrage et peut être remplacé à l'aide de l'argument -H . Ce préfixe peut être défini en utilisant le prefix with une clause similaire à une cible de règle de réécriture. La correspondance d'entrée dans ce cas est l'expression régulière prédéfinie ^(([^.]+)(..*)?)$ Sur le nom d'hôte. En tant que tel, on peut voir que le préfixe par défaut est défini par carbon.relays..1 . Notez que cela utilise la fonction Remplace-Dot-with-Underscore de remplacement à partir des règles de réécriture. Compte tenu de l'expression d'entrée, les groupes de correspondance suivants sont disponibles: 1 le nom d'hôte entier, 2 le nom d'hôte court et 3 le nom de domaine (avec le point de tête). Il peut être logique de remplacer la valeur par défaut par quelque chose comme carbon.relays._2 pour certains scénarios, pour toujours utiliser le nom d'hôte court classé inférieur, qui suivant l'expression ne contient pas de point. Par défaut, les métriques sont soumises toutes les 60 secondes, cela peut être modifié à l'aide de la clause submit every <interval> seconds pour obtenir un ensemble de valeurs plus compatible sur carbone-cache.py, utiliser les reset counters after interval pour rendre les valeurs non cumulatives, c'est-à-dire qu'ils rapporteront la modification par rapport à la valeur précédente.
Les ports et les protocoles que le relais doit écouter pour les connexions entrantes peut être spécifiée à l'aide de la directive listen . Actuellement, tous les auditeurs doivent être de type linemode . Une compression ou un emballage de cryptage facultatif peut être spécifié pour le port et l'interface facultative donnée par adresse IP, ou socket UNIX par fichier. Lorsque l'interface n'est pas spécifiée, aucune interface sur tous les protocoles IP disponibles est supposée. Si aucune directive listen n'est présente, le relais utilisera les écouteurs par défaut pour Port 2003 sur TCP et UDP, plus le socket UNIX /tmp/.s.carbon-c-relay.2003 . Cela s'étend généralement à 5 écouteurs sur un système compatible IPv6. La valeur par défaut correspond au comportement des versions avant V3.2.
Dans le cas où la configuration devient très longue ou est mieux gérée dans des fichiers séparés, la directive include peut être utilisée pour lire un autre fichier. Le fichier donné sera lu en place et ajouté à la configuration du routeur au moment de l'inclusion. Le résultat final est une grande configuration d'itinéraire. Plusieurs instructions include peuvent être utilisées dans le fichier de configuration. Le positionnement influencera l'ordre des règles comme d'habitude. Méfiez-vous que l'inclusion récursive ( include à partir d'un fichier incluse) est prise en charge, et actuellement aucune garantie n'existe pour une boucle d'inclusion. Pour ce qui vaut la peine, cette fonctionnalité est probablement mieux utilisée avec des fichiers de configuration simples (par exemple, ne pas y avoir include ).
Carbon-C-Relay a évolué au fil du temps, des fonctionnalités croissantes à la demande, car l'outil s'est avéré stable et a bien adapté le travail. Ci-dessous, suivez quelques exemples annotés de constructions qui peuvent être utilisées avec le relais.
Les clusters peuvent être définis autant que nécessaire. Ils reçoivent des données des règles de correspondance et leur type définit quels membres du cluster obtiennent enfin les données métriques. Le formulaire de cluster le plus simple est un cluster forward :
cluster send-through
forward
10.1.0.1
;
Toute métrique envoyée au cluster send-through serait simplement transmise au serveur à l'adresse IPv4 10.1.0.1 . Si nous définissons plusieurs serveurs, tous ces serveurs obtiendraient la même mesure, donc:
cluster send-through
forward
10.1.0.1
10.2.0.1
;
L'envoi ci-dessus se traduit par une duplication de mesures envoyées aux deux machines. Cela peut être utile, mais la plupart du temps, ce n'est pas le cas. Le type de cluster any_of est comme forward , mais il envoie chaque métrique entrante à l'un des membres. Le même exemple avec un tel cluster serait:
cluster send-to-any-one
any_of 10.1.0.1:2010 10.1.0.1:2011;
Cela implémenterait un scénario de trajets multiples, où deux serveurs sont utilisés, la charge entre eux est répartie, mais si l'un d'eux échoue, toutes les mesures sont envoyées à la restante. Cela fonctionne généralement bien pour les relais en amont, ou pour équilibrer les processus de cache en carbone fonctionnant sur la même machine. Si un membre devenait indisponible, par exemple en raison d'un redémarrage de roulement, les autres membres reçoivent le trafic. S'il est nécessaire d'avoir un véritable déchaînement, où le serveur secondaire n'est utilisé que si le premier est en baisse, ce qui suit implémenterait cela:
cluster try-first-then-second
failover 10.1.0.1:2010 10.1.0.1:2011;
Ces types sont différents des deux types de cluster de hachage cohérents:
cluster graphite
carbon_ch
127.0.0.1:2006=a
127.0.0.1:2007=b
127.0.0.1:2008=c
;
Si un membre de cet exemple échoue, toutes les mesures qui iraient à ce membre sont conservées dans la file d'attente, en attendant que le membre revienne. Ceci est utile pour les grappes de machines à cache carbone où il est souhaitable que la même métrique se retrouve toujours sur le même serveur. Le type de cluster carbon_ch est compatible avec le hachage cohérent de la relais en carbone et peut être utilisé pour les grappes existantes peuplées de relais de carbone. Pour les nouveaux clusters, cependant, il est préférable d'utiliser le type de cluster fnv1a_ch , car il est plus rapide, et permet d'équilibrer sur la même adresse mais différents ports sans numéro d'instance, en contraste à carbon_ch .
Parce que nous pouvons utiliser plusieurs clusters, nous pouvons également reproduire sans l'utilisation du type de cluster forward , de manière plus intelligente:
cluster dc-old
carbon_ch replication 2
10.1.0.1
10.1.0.2
10.1.0.3
;
cluster dc-new1
fnv1a_ch replication 2
10.2.0.1
10.2.0.2
10.2.0.3
;
cluster dc-new2
fnv1a_ch replication 2
10.3.0.1
10.3.0.2
10.3.0.3
;
match *
send to dc-old
;
match *
send to
dc-new1
dc-new2
stop
;
Dans cet exemple, toutes les métriques entrantes sont d'abord envoyées à dc-old , puis dc-new1 et enfin à dc-new2 . Notez que le type de cluster de dc-old est différent. Chaque métrique entrante sera envoyée à 2 membres des trois clusters, se reproduisant ainsi en 6 destinations. Pour chaque cluster, les membres de la destination sont calculés indépendamment. L'échec des grappes ou des membres n'affecte pas les autres, car tous ont des files d'attente individuelles. L'exemple ci-dessus pourrait également être écrit en utilisant trois règles de correspondance pour chaque DC, ou une règle de correspondance pour les trois CD. La différence est principalement dans les performances, le nombre de fois où la métrique entrante doit être appariée à une expression. La règle stop dans la règle dc-new Match n'est pas strictement nécessaire dans cet exemple, car il n'y a plus de règles de correspondance suivantes. Cependant, si la correspondance ciblerait un sous-ensemble spécifique, par exemple ^sys. et plus de clusters seraient définis, cela pourrait être nécessaire, comme par exemple dans l'exemple abrégé suivant:
cluster dc1-sys ... ;
cluster dc2-sys ... ;
cluster dc1-misc ... ;
cluster dc2-misc ... ;
match ^sys. send to dc1-sys;
match ^sys. send to dc2-sys stop;
match * send to dc1-misc;
match * send to dc2-misc stop;
Comme on peut le voir, sans l' stop de la règle de match de DC2-SYS, toutes les mesures commençant par sys. Serait également envoyé à DC1-MISC et DC2-MISC. Il se peut que cela soit souhaité, bien sûr, mais dans cet exemple, il existe un cluster dédié pour les métriques sys .
Supposons qu'il y aurait une métrique indésirable qui est malheureusement générée, supposons un logiciel mauvais / ancien. Nous ne voulons pas stocker cette métrique. Le cluster blackhole convient à cela, lorsqu'il est plus difficile de réellement la liste blanche toutes les mesures recherchées. Considérez ce qui suit:
match
some_legacy1$
some_legacy2$
send to blackhole
stop;
Cela jetterait toutes les mesures qui se termineraient par some_legacy , qui serait autrement difficile à filtrer. Étant donné que la commande compte, elle peut être utilisée dans une construction comme celle-ci:
cluster old ... ;
cluster new ... ;
match * send to old;
match unwanted send to blackhole stop;
match * send to new;
Dans cet exemple, l'ancien cluster recevrait la métrique indésirable pour le nouveau cluster. Ainsi, l'ordonnance dans laquelle les règles se produisent est importante pour l'exécution.
La validation peut être utilisée pour garantir que les données des mesures sont comme prévu. Une validation globale pour juste les valeurs du nombre (pas de point flottantes) pourraient être:
match *
validate ^[0-9]+ [0-9]+$ else drop
;
(Remarquez l'évasion avec BackSlash de l'espace, vous pourrez peut-être utiliser s ou [:space:] Au lieu de cela, cela dépend de votre implémentation Regex configurée.)
La clause de validation peut exister sur chaque règle de correspondance, donc en principe, ce qui suit est valide:
match ^foo
validate ^[0-9]+ [0-9]+$ else drop
send to integer-cluster
;
match ^foo
validate ^[0-9.e+-]+ [0-9.e+-]+$ else drop
send to float-cluster
stop;
Notez que le comportement est différent dans les deux exemples précédents. Lorsqu'aucun send to clusters n'est spécifié, une erreur de validation fait que le match se comporte comme le mot clé stop est présent. De même, lorsque la validation passe, le traitement se poursuit avec la règle suivante. When destination clusters are present, the match respects the stop keyword as normal. When specified, processing will always stop when specified so. However, if validation fails, the rule does not send anything to the destination clusters, the metric will be dropped or logged, but never sent.
The relay is capable of rewriting incoming metrics on the fly. This process is done based on regular expressions with capture groups that allow to substitute parts in a replacement string. Rewrite rules allow to cleanup metrics from applications, or provide a migration path. In it's simplest form a rewrite rule looks like this:
rewrite ^server.(.+).(.+).([a-zA-Z]+)([0-9]+)
into server._1.2.3.34
;
In this example a metric like server.DC.role.name123 would be transformed into server.dc.role.name.name123 . For rewrite rules hold the same as for matches, that their order matters. Hence to build on top of the old/new cluster example done earlier, the following would store the original metric name in the old cluster, and the new metric name in the new cluster:
rewrite ^server.(.+).(.+).([a-zA-Z]+)([0-9]+)
into server._1.2.3.34
;
rewrite ^server.(.+).(.+).([a-zA-Z]+)([0-9]+)
into server.g{_1}.g{2}.g{3}.g{3}g{4}
;
The alternate syntax for backreference notation using g{n} instead of n notation shown above. Both rewrite rules are identical.
match * send to old;
rewrite ... ;
match * send to new;
Note that after the rewrite, the original metric name is no longer available, as the rewrite happens in-place.
Aggregations are probably the most complex part of carbon-c-relay. Two ways of specifying aggregates are supported by carbon-c-relay. The first, static rules, are handled by an optimiser which tries to fold thousands of rules into groups to make the matching more efficient. The second, dynamic rules, are very powerful compact definitions with possibly thousands of internal instantiations. A typical static aggregation looks like:
aggregate
^sys.dc1.somehost-[0-9]+.somecluster.mysql.replication_delay
^sys.dc2.somehost-[0-9]+.somecluster.mysql.replication_delay
every 10 seconds
expire after 35 seconds
timestamp at end of bucket
compute sum write to
mysql.somecluster.total_replication_delay
compute average write to
mysql.somecluster.average_replication_delay
compute max write to
mysql.somecluster.max_replication_delay
compute count write to
mysql.somecluster.replication_delay_metric_count
;
In this example, four aggregations are produced from the incoming matching metrics. In this example we could have written the two matches as one, but for demonstration purposes we did not. Obviously they can refer to different metrics, if that makes sense. The every 10 seconds clause specifies in what interval the aggregator can expect new metrics to arrive. This interval is used to produce the aggregations, thus each 10 seconds 4 new metrics are generated from the data received sofar. Because data may be in transit for some reason, or generation stalled, the expire after clause specifies how long the data should be kept before considering a data bucket (which is aggregated) to be complete. In the example, 35 was used, which means after 35 seconds the first aggregates are produced. It also means that metrics can arrive 35 seconds late, and still be taken into account. The exact time at which the aggregate metrics are produced is random between 0 and interval (10 in this case) seconds after the expiry time. This is done to prevent thundering herds of metrics for large aggregation sets. The timestamp that is used for the aggregations can be specified to be the start , middle or end of the bucket. Original carbon-aggregator.py uses start , while carbon-c-relay's default has always been end . The compute clauses demonstrate a single aggregation rule can produce multiple aggregates, as often is the case. Internally, this comes for free, since all possible aggregates are always calculated, whether or not they are used. The produced new metrics are resubmitted to the relay, hence matches defined before in the configuration can match output of the aggregator. It is important to avoid loops, that can be generated this way. In general, splitting aggregations to their own carbon-c-relay instance, such that it is easy to forward the produced metrics to another relay instance is a good practice.
The previous example could also be written as follows to be dynamic:
aggregate
^sys.dc[0-9].(somehost-[0-9]+).([^.]+).mysql.replication_delay
every 10 seconds
expire after 35 seconds
compute sum write to
mysql.host.1.replication_delay
compute sum write to
mysql.host.all.replication_delay
compute sum write to
mysql.cluster.2.replication_delay
compute sum write to
mysql.cluster.all.replication_delay
;
Here a single match, results in four aggregations, each of a different scope. In this example aggregation based on hostname and cluster are being made, as well as the more general all targets, which in this example have both identical values. Note that with this single aggregation rule, both per-cluster, per-host and total aggregations are produced. Obviously, the input metrics define which hosts and clusters are produced.
With use of the send to clause, aggregations can be made more intuitive and less error-prone. Consider the below example:
cluster graphite fnv1a_ch ip1 ip2 ip3;
aggregate ^sys.somemetric
every 60 seconds
expire after 75 seconds
compute sum write to
sys.somemetric
send to graphite
stop
;
match * send to graphite;
It sends all incoming metrics to the graphite cluster, except the sys.somemetric ones, which it replaces with a sum of all the incoming ones. Without a stop in the aggregate, this causes a loop, and without the send to , the metric name can't be kept its original name, for the output now directly goes to the cluster.
When configuring cluster you might want to check how the metrics will be routed and hashed. That's what the -t flag is for. For the following configuration:
cluster graphite_swarm_odd
fnv1a_ch replication 1
host01.dom:2003=31F7A65E315586AC198BD798B6629CE4903D089947
host03.dom:2003=9124E29E0C92EB63B3834C1403BD2632AA7508B740
host05.dom:2003=B653412CD96B13C797658D2C48D952AEC3EB667313
;
cluster graphite_swarm_even
fnv1a_ch replication 1
host02.dom:2003=31F7A65E315586AC198BD798B6629CE4903D089947
host04.dom:2003=9124E29E0C92EB63B3834C1403BD2632AA7508B740
host06.dom:2003=B653412CD96B13C797658D2C48D952AEC3EB667313
;
match *
send to
graphite_swarm_odd
graphite_swarm_even
stop
;
Running the command: echo "my.super.metric" | carbon-c-relay -f config.conf -t , will result in:
[...]
match
* -> my.super.metric
fnv1a_ch(graphite_swarm_odd)
host03.dom:2003
fnv1a_ch(graphite_swarm_even)
host04.dom:2003
stop
You now know that your metric my.super.metric will be hashed and arrive on the host03 and host04 machines. Adding the -d flag will increase the amount of information by showing you the hashring
When carbon-c-relay is run without -d or -s arguments, statistics will be produced. By default they are sent to the relay itself in the form of carbon.relays.<hostname>.* . See the statistics construct to override this prefix, sending interval and values produced. While many metrics have a similar name to what carbon-cache.py would produce, their values are likely different. By default, most values are running counters which only increase over time. The use of the nonNegativeDerivative() function from graphite is useful with these.
The following metrics are produced under the carbon.relays.<hostname> namespace:
metricsReceived
The number of metrics that were received by the relay. Received here means that they were seen and processed by any of the dispatchers.
metricsSent
The number of metrics that were sent from the relay. This is a total count for all servers combined. When incoming metrics are duplicated by the cluster configuration, this counter will include all those duplications. In other words, the amount of metrics that were successfully sent to other systems. Note that metrics that are processed (received) but still in the sending queue (queued) are not included in this counter.
metricsDiscarded
The number of input lines that were not considered to be a valid metric. Such lines can be empty, only containing whitespace, or hitting the limits given for max input length and/or max metric length (see -m and -M options).
metricsQueued
The total number of metrics that are currently in the queues for all the server targets. This metric is not cumulative, for it is a sample of the queue size, which can (and should) go up and down. Therefore you should not use the derivative function for this metric.
metricsDropped
The total number of metric that had to be dropped due to server queues overflowing. A queue typically overflows when the server it tries to send its metrics to is not reachable, or too slow in ingesting the amount of metrics queued. This can be network or resource related, and also greatly depends on the rate of metrics being sent to the particular server.
metricsBlackholed
The number of metrics that did not match any rule, or matched a rule with blackhole as target. Depending on your configuration, a high value might be an indication of a misconfiguration somewhere. These metrics were received by the relay, but never sent anywhere, thus they disappeared.
metricStalls
The number of times the relay had to stall a client to indicate that the downstream server cannot handle the stream of metrics. A stall is only performed when the queue is full and the server is actually receptive of metrics, but just too slow at the moment. Stalls typically happen during micro-bursts, where the client typically is unaware that it should stop sending more data, while it is able to.
relations
The number of connect requests handled. This is an ever increasing number just counting how many connections were accepted.
disconnects
The number of disconnected clients. A disconnect either happens because the client goes away, or due to an idle timeout in the relay. The difference between this metric and connections is the amount of connections actively held by the relay. In normal situations this amount remains within reasonable bounds. Many connections, but few disconnections typically indicate a possible connection leak in the client. The idle connections disconnect in the relay here is to guard against resource drain in such scenarios.
dispatch_wallTime_us
The number of microseconds spent by the dispatchers to do their work. In particular on multi-core systems, this value can be confusing, however, it indicates how long the dispatchers were doing work handling clients. It includes everything they do, from reading data from a socket, cleaning up the input metric, to adding the metric to the appropriate queues. The larger the configuration, and more complex in terms of matches, the more time the dispatchers will spend on the cpu. But also time they do /not/ spend on the cpu is included in this number. It is the pure wallclock time the dispatcher was serving a client.
dispatch_sleepTime_us
The number of microseconds spent by the dispatchers sleeping waiting for work. When this value gets small (or even zero) the dispatcher has so much work that it doesn't sleep any more, and likely can't process the work in a timely fashion any more. This value plus the wallTime from above sort of sums up to the total uptime taken by this dispatcher. Therefore, expressing the wallTime as percentage of this sum gives the busyness percentage draining all the way up to 100% if sleepTime goes to 0.
server_wallTime_us
The number of microseconds spent by the servers to send the metrics from their queues. This value includes connection creation, reading from the queue, and sending metrics over the network.
dispatcherX
For each indivual dispatcher, the metrics received and blackholed plus the wall clock time. The values are as described above.
destinations.X
For all known destinations, the number of dropped, queued and sent metrics plus the wall clock time spent. The values are as described above.
aggregators.metricsReceived
The number of metrics that were matched an aggregator rule and were accepted by the aggregator. When a metric matches multiple aggregators, this value will reflect that. A metric is not counted when it is considered syntactically invalid, eg no value was found.
aggregators.metricsDropped
The number of metrics that were sent to an aggregator, but did not fit timewise. This is either because the metric was too far in the past or future. The expire after clause in aggregate statements controls how long in the past metric values are accepted.
aggregators.metricsSent
The number of metrics that were sent from the aggregators. These metrics were produced and are the actual results of aggregations.
Please report them at: https://github.com/grobian/carbon-c-relay/issues
Fabian Groffen <[email protected]>
All other utilities from the graphite stack.
This project aims to be a fast replacement of the original Carbon relay. carbon-c-relay aims to deliver performance and configurability. Carbon is single threaded, and sending metrics to multiple consistent-hash clusters requires chaining of relays. This project provides a multithreaded relay which can address multiple targets and clusters for each and every metric based on pattern matches.
There are a couple more replacement projects out there, which are carbon-relay-ng and graphite-relay.
Compared to carbon-relay-ng, this project does provide carbon's consistent-hash routing. graphite-relay, which does this, however doesn't do metric-based matches to direct the traffic, which this project does as well. To date, carbon-c-relay can do aggregations, failover targets and more.
This program was originally developed for Booking.com, which approved that the code was published and released as Open Source on GitHub, for which the author would like to express his gratitude. Development has continued since with the help of many contributors suggesting features, reporting bugs, adding patches and more to make carbon-c-relay into what it is today.