carbon-c-relay -f Config-File [ options ... ]
Carbon-C-Relay acepta, limpia, coincide, reescribe, reenvía y agrega métricas de grafito escuchando conexiones entrantes y transmitiendo los mensajes a otros servidores definidos en su configuración. La funcionalidad central es enrutar mensajes a través de reglas flexibles a los destinos deseados.
Carbon-C-Relay es un programa simple que lee su información de enrutamiento de un archivo. Los argumentos de la línea de comando permiten establecer la ubicación para este archivo, así como la cantidad de despachadores (subprocesos de trabajadores) para usar para leer los datos de las conexiones entrantes y pasarlos a los destino correctos. El archivo de ruta admite dos construcciones principales: grupos y coincidencias. Los primeros grupos definidos de hosts se pueden enviar métricas de datos, el último define qué métricas deben enviarse a qué clúster. Las reglas de agregación se consideran como coincidencias. Las reescrituras son acciones que afectan directamente la métrica en el punto en que aparecen en la configuración.
Por cada métrica recibida por el relé, se realiza la limpieza. Los siguientes cambios se realizan antes de cualquier coincidencia, la regla de agregado o reescritura ve la métrica:
[0-9a-zA-Z-_:#] , pero puede anularse en la línea de comandos. Tenga en cuenta que las etiquetas (cuando están presentes y permitidas) no se procesan de esta manera. Estas opciones controlan el comportamiento de carbono-C-Relay .
-v : Versión de impresión Cadena y salida.
-d : Habilitar el modo de depuración, esto imprime estadísticas en Stdout e imprime mensajes adicionales sobre algunas situaciones encontradas por el relé que normalmente sería demasiado detallado para estar habilitado. Cuando se combina con -t (modo de prueba), esto también imprime rutas de stub y contenido de anillo de cano consistente.
-s : Habilitar el modo de envío. En este modo, no se generan estadísticas internas. En cambio, se informan la presión de la cola y las métricas en Stdout. Este modo es útil cuando se usa como relé de envío, qué trabajo es solo reenviar (un conjunto de) relés principales. No se necesitan estadísticas sobre los relés de envío en este caso, y podrían causar fácilmente una inundación de métricas no deseadas, por ejemplo, cuando se usa en todos y cada uno de los host localmente.
-S : Habilite el modo similar a iostat donde se informa cada segundo el estado actual de las estadísticas. Esto implica modo de envío -s .
-t : modo de prueba. Este modo no realiza ningún enrutamiento en absoluto, sino que lee la entrada de Stdin e imprime qué acciones se tomarían dada la configuración cargada. Este modo es muy útil para probar rutas de retransmisión para la sintaxis de expresión regular, etc. También permite dar una idea de cómo se aplica el enrutamiento en configuraciones complejas, ya que muestra reescrituras y agregados que también tienen lugar. Cuando -t se repite, el relé solo probará la configuración para la validez y saldrá inmediatamente después. Cualquier salida estándar se suprime en este modo, lo que lo hace ideal para que los start-scripts prueben una configuración (nueva).
-f FILE de configuración : lea la configuración de config-fil . Una configuración consiste en grupos y rutas. Consulte la sintaxis de configuración para obtener más información sobre las opciones y la sintaxis de este archivo.
-l Log-File : use el archivo de registro para escribir mensajes. Sin esta opción, el relé escribe tanto a Stdout como a Stderr . Al iniciar sesión para archivar, todos los mensajes tienen prefijo MSG cuando fueron enviados a Stdout , y ERR cuando fueron enviados a Stderr .
-p Puerto : Escuche las conexiones en el puerto del puerto. El número de puerto se utiliza para los enchufes TCP , UDP y UNIX sockets . En el último caso, el archivo de socket contiene el número de puerto. El puerto predeterminado es 2003 , que también es utilizado por el carbon-cache.py original. Tenga en cuenta que esto solo se aplica a los valores predeterminados, cuando las directivas listen están en la configuración, se ignora esta configuración.
-w : use el número de trabajadores de hilos. El número predeterminado de trabajadores es igual a la cantidad de núcleos de CPU detectados. Tiene sentido reducir este número en máquinas de muchos núcleos, o cuando el tráfico es bajo.
-b BatchSize : establezca la cantidad de métricas que se envían a servidores remotos a la vez para lotear . Cuando el relé envía métricas a los servidores, recuperará las métricas batchsize de la cola pendiente de métricas que esperan ese servidor y los enviarán uno por uno. El tamaño del lote tendrá un impacto mínimo en el envío del rendimiento, pero controla la cantidad de contención de bloqueo en la cola. El valor predeterminado es 2500 .
-q Queuesize : cada servidor desde la configuración a la que el relé enviará métricas tiene una cola asociada con ella. Esta cola permite que se manejaran interrupciones y ráfagas. El tamaño de esta cola se establecerá en cola , lo que permite que esa cantidad de métricas se almacene en la cola antes de que se desborde, y el relé comienza a dejar caer métricas. Cuanto más grande sea la cola, se pueden absorber más métricas, pero el relé utilizará más memoria. El tamaño de cola predeterminado es 25000 .
-L puestos : establece el montaje máximo de puestos en puestos antes de que el relé comience a dejar caer métricas para un servidor. Cuando se llena una cola, el relé utiliza un mecanismo llamado Stalling para indicar al cliente (escritura al relé) de este evento. En particular, cuando el cliente envía una gran cantidad de métricas en muy poco tiempo (estallido), el estancamiento puede ayudar a evitar caer las métricas, ya que el cliente solo necesita reducir la velocidad por un poco, lo que en muchos casos es posible (por ejemplo, cuando ata a un archivo con nc (1)). Sin embargo, este comportamiento también puede obstruir, estancando artificialmente a escritores que no pueden detenerse fácilmente. Para esto, los puestos se pueden establecer de 0 a 15 , donde cada puesto puede tomar alrededor de 1 segundo en el cliente. El valor predeterminado se establece en 4 , que está dirigido al escenario ocasional de interrupción y un esfuerzo máximo para no perder métricas con la desaceleración moderada de los clientes.
-C CacertPath : lea certs de CA (para usar con conexiones TLS/SSL) de la ruta o archivo dado. Cuando no se dan, se utilizan las ubicaciones predeterminadas. Se realiza una estricta verdad del par, por lo que cuando se usa certificados autofirmados, asegúrese de incluir el certificado de CA en la ubicación predeterminada o proporcionar la ruta al certificado utilizando esta opción.
-T Tiempo de espera : Especifica el tiempo de espera IO en milisegundos utilizados para las conexiones del servidor. El valor predeterminado es de 600 milisegundos, pero puede necesitar aumentar cuando se usan enlaces WAN para los servidores de destino. Un valor relativamente bajo para el tiempo de espera de conexión permite que el retransmisión establezca rápidamente un servidor es inalcanzable, y como tales estrategias de conmutación por error se activan antes de que la cola se agote.
-c Chars : Define los caracteres que están al lado de [A-Za-z0-9] permitidos en métricas a Chars . Cualquier personaje que no esté en esta lista es reemplazado por el relé con _ (bajo). La lista predeterminada de caracteres permitidos es -_:# .
-m Longitud : limita los nombres métricos para que tengan una longitud de largo. Cualquier línea que contenga nombres métricas más grandes que esto se descartará.
-M Longitud Limita la entrada a líneas de la mayoría de los bytes de longitud . Cualquier exceso de líneas se descartará. Tenga en cuenta que -m debe ser más pequeño que este valor.
-H Name de host : anular el nombre de host determinado por una llamada a gethostname (3) con HostName . El nombre de host se utiliza principalmente en las métricas de estadísticas carbon.relays.<hostname>.<...>
-B Backlog : Establece la conexión TCP KIRCE Backlog en las conexiones de Backlog . El valor predeterminado es 32, pero en los servidores que reciben muchas conexiones concurrentes, esta configuración es probable que deba incrementarse para evitar errores rechazados de conexión a los clientes.
-U bufsize : Establece los tamaños de búfer de envío/recepción de socket en bytes, tanto para escenarios TCP como UDP. Cuando no se usa, se usa el valor predeterminado del sistema operativo. El máximo también está determinado por el sistema operativo. Los tamaños se establecen usando SetSockOpt con los indicadores SO_RCVBUF y SO_SNDBUF. Configuración de este tamaño puede ser necesario para escenarios de gran volumen, para los cuales también se puede aplicar -B . Verificar el RECV-Q y los valores de recepción de errores de NetStat ofrecen una buena pista sobre el uso del búfer.
-E : Desactivar la desconexión de las conexiones entrantes inactivas. Por defecto, el relé desconecta las conexiones del cliente inactivo después de 10 minutos. Hace esto para evitar que los recursos se obstruyan cuando un cliente defectuoso o malicioso sigue abriendo conexiones sin cerrarlos. Por lo general, evita quedarse sin descriptores de archivos. Sin embargo, para algunos escenarios, no es deseable que se desconecten las conexiones inactivas, por lo tanto, pasar esta bandera deshabilitará este comportamiento.
-D : Deamonise en el fondo después del inicio. Esta opción requiere los indicadores -l y -P para configurarse también.
-P PIDFILE : escriba el PID del proceso de retransmisión en un archivo llamado PIDFile . Esto es en particular útil cuando se demora en combinación con los gerentes de inicio.
-O Umbral : el número mínimo de reglas para encontrar antes de tratar de optimizar el conjunto de reglas. El valor predeterminado es 50 , para deshabilitar el optimizador, usar -1 , para ejecutar siempre el optimista use 0 . El optimista intenta agrupar las reglas para evitar pasar un tiempo excesivo en expresiones coincidentes.
El archivo de configuración admite la siguiente sintaxis, donde los comentarios comienzan con un carácter # y pueden aparecer en cualquier posición en una línea y suprimir la entrada hasta el final de esa línea:
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>
;
Se pueden definir múltiples grupos y no deben ser referenciados por una regla de coincidencia. Todos los grupos apuntan a uno o más hosts, excepto el clúster file que se escribe en archivos en el sistema de archivos local. host puede ser una dirección IPv4 o IPv6, o un nombre de host. Dado que el host es seguido por un puerto opcional : para que las direcciones IPv6 no se interpreten incorrectamente, se debe dar un puerto o la dirección IPv6 rodeada de soportes, por ejemplo, [::1] . Se pueden usar cláusulas transport opcional y proto para envolver la conexión en una capa de compresión o cifrado o especificar el uso de UDP o TCP para conectarse al servidor remoto. Cuando se omite, la conexión es predeterminada a una conexión TCP simple. type solo puede ser linemode en este momento, por ejemplo, el modo de encurtido de Python no es compatible.
Los nombres de host de DNS se resuelven a una sola dirección, de acuerdo con las reglas de preferencia en RFC 3484. Los grupos any_of , failover y forward tienen un indicador explícito useall que permite la expansión de los nombres de host en múltiples direcciones. Usando esta opción, cada dirección de cualquier tipo se convierte en un destino de clúster. Esto significa, por ejemplo, que se agregan direcciones IPv4 e IPv6.
Hay dos grupos de tipos de clúster, grupos de reenvío simples y grupos de hashing consistentes.
forward y file clústeres
Los grupos forward y file simplemente envían todo lo que reciben a los miembros definidos (direcciones o archivos de host). Cuando un clúster tiene múltiples miembros, todas las métricas entrantes se envían a todos los miembros, básicamente duplicando el flujo de métrica de entrada sobre todos los miembros.
any_of cluster
El clúster any_of es una pequeña variante del clúster forward , pero en lugar de enviar las métricas de entrada a todos los miembros definidos, envía cada métrica entrante a solo uno de los miembros definidos. El propósito de esto es un escenario de carga en el que cualquiera de los miembros puede recibir cualquier métrica. Como sugiere any_of , cuando cualquiera de los miembros se vuelve inalcanzable, los miembros disponibles restantes recibirán inmediatamente el flujo de entrada completo de las métricas. Esto significa específicamente que cuando se usan 4 miembros, cada uno recibirá aproximadamente el 25% de las métricas de entrada. Cuando un miembro no está disponible (por ejemplo, interrupción de la red, o un reinicio del servicio), los 3 miembros restantes recibirán alrededor del 25% / 3 = ~ 8% más de tráfico (33%). Alternativamente, recibirán 1/3 de la entrada total. Al diseñar la capacidad del clúster, uno debe tener en cuenta que en el caso más extremo, el miembro final restante recibirá todo el tráfico de entrada.
Un clúster any_of puede ser útil en particular cuando el clúster apunta a otros relés o cachés. Cuando se usa con otros relés, es efectivo los balances de carga y se adapta inmediatamente a la inhalación de los objetivos. Cuando se usa con cachés, hay un pequeño detalle sobre cómo any_of , eso lo hace muy adecuado. La implementación de este enrutador no es para round-roBin sobre los miembros disponibles, sino que utiliza una estrategia de hashing consistente para entregar las mismas métricas al mismo destino todo el tiempo. Esto ayuda a los cachés y facilita la recuperación de puntos de datos no comprometidos (de un solo caché), pero aún así permite un reinicio de los cachés. Cuando un miembro no está disponible, los destinos hash no cambian, sino que el tráfico destinado al nodo no disponible se extiende uniformemente sobre los nodos disponibles.
clúster failover
El clúster failover es como el clúster any_of , pero se adhiere al orden en que se definen los servidores. Esto es para implementar un escenario de conmutación por error puro entre los servidores. Todas las métricas se envían como máximo 1 miembro, por lo que no se está produciendo hash ni equilibrio. Por ejemplo, un clúster de failover con dos miembros solo enviará métricas al segundo miembro cuando el primer miembro no esté disponible. Tan pronto como el primer miembro regrese, todas las métricas se envían al primer nodo nuevamente.
clúster carbon_ch
El clúster carbon_ch envía las métricas al miembro que es responsable de acuerdo con el algoritmo de hash consistente que se usa en el relevo de pitón de carbono original. Múltiples miembros son posibles si la replicación se establece en un valor superior a 1. Cuando se establece dynamic , la falla de cualquiera de los servidores no da como resultado que las métricas se eliminen para ese servidor, sino que las métricas no entregables se envían a cualquier otro servidor en el clúster para que las métricas no se pierdan. Esto es más útil cuando la replicación es 1.
El cálculo del hashring, que define la forma en que se distribuyen las métricas, se basa en el host del servidor (o dirección IP) y en la instance opcional del miembro. Esto significa que usar carbon_ch dos objetivos en diferentes puertos, pero en el mismo host, se asignará al mismo hashkey, lo que significa que no se produce una distribución de métricas. La instancia se usa para remediar esa situación. Se adjunta una instancia al miembro después del puerto, y se separa por un signo igual, por ejemplo, 127.0.0.1:2006=a , por ejemplo, a . Las instancias son un concepto introducido por el hacacial de carbono Python original, y deben usarse de acuerdo con la configuración de ellos.
Los hashes consistentes son consistentes en el sentido de que la eliminación de un miembro del clúster no debe dar como resultado un re-mapeo completo de todas las métricas a los miembros, sino que solo agregue las métricas del miembro eliminado a todos los miembros restantes, aproximadamente cada uno recibe su parte justa. Al revés, cuando se agrega un miembro, cada miembro debe ver un subconjunto de sus métricas que ahora se dirigen al nuevo miembro. Esta es una ventaja importante sobre un hash normal, donde cada remoción o adición de miembros (también a través de EG, un cambio en su dirección IP o nombre de host) causaría un re-mapeo completo de todas las métricas sobre todas las métricas disponibles.
clúster fnv1a_ch
El clúster fnv1a_ch es una mejora incompatible a carbon_ch introducida por Carbon-C-Relay. Utiliza una técnica hash diferente (FNV1A) que es más rápida que el achicamiento MD5 utilizado por carbon_ch . Más importante aún, los clústeres fnv1a_ch usan tanto el host como el puerto para distinguir a los miembros. Esto es útil cuando múltiples objetivos viven en el mismo host recién separado por el puerto.
Dado que la propiedad instance ya no es necesaria con fnv1a_ch de esta manera, se usa para anular completamente la cadena del host: el puerto que se calculará el hashkey. Este es un aspecto importante, ya que el Hashkey define qué métricas recibe un miembro. Dicha anulación permite muchas cosas, incluida la disfrazamiento de direcciones IP antiguas, por ejemplo, cuando una máquina se migró a hardware más nuevo. Un ejemplo de esto sería 10.0.0.5:2003=10.0.0.2:2003 donde una máquina en la dirección 5 ahora recibe las métricas para una máquina que estaba en la dirección 2.
Si bien el uso de instancias de esta manera puede ser muy útil para realizar migraciones en los grupos existentes, para los grupos de configuración recién a configurar, las instancias permiten evitar este trabajo utilizando una instancia desde el primer día para separar la ubicación de la máquina de las métricas que recibe. Considere, por ejemplo, 10.0.0.1:2003=4d79d13554fa1301476c1f9fe968b0ac donde se usa un hash aleatorio como instancia. Esto permitiría cambiar el puerto y/o la dirección IP del servidor que recibe datos tantas veces sin tener que ver cualquier legado visible, suponiendo que se retiene el hash aleatorio. Tenga en cuenta que, dado que el nombre de la instancia se usa como entrada de hash completa, las instancias como a , b , etc. probablemente darán lugar a una distribución de hash deficiente, ya que sus hashes tienen muy poca entrada. Por esa razón, considere usar nombres de instancias más largos y principales como hash aleatorios como se usan en el ejemplo anterior para un mejor comportamiento de distribución de hash.
jump_fnv1a_ch cluster
El clúster jump_fnv1a_ch también es un clúster hash consistente como los dos anteriores, pero no tiene en cuenta el host del miembro, el puerto o la instancia. Esto significa que este tipo de clúster analiza el orden en que se definen los miembros, ver también a continuación para obtener más información sobre este orden. Si esto es útil para usted depende de su escenario. En contraste con los dos tipos de clúster de hash anteriores, el hash de salto tiene un equilibrio casi perfecto sobre los miembros definidos en el clúster. Sin embargo, esto se produce a expensas de no poder eliminar a ningún miembro, sino el último del clúster sin causar un re-mapeo completo de todas las métricas sobre todos los miembros. Lo que esto significa básicamente es que este hash es bueno de usar con grupos constantes o en constante crecimiento donde los nodos más antiguos nunca se eliminan, sino que se reemplazan.
Si tiene un clúster donde tiene lugar la eliminación de nodos viejos, el hash de salto no es adecuado para usted. Jump Hash funciona con los servidores en una lista ordenada. Dado que este pedido es importante, se puede hacer explícito utilizando la instancia utilizada en tipos de clúster anteriores. Cuando se da una instancia con los miembros, se usará como clave de clasificación. Sin esta instancia, el pedido será el dado en el archivo de configuración, que puede ser propenso a los cambios cuando por ejemplo, generado por algún software de administración de configuración. Como tal, probablemente sea una buena práctica arreglar el orden de los servidores con instancias de tal manera que sea explícito cuáles son los nodos correctos para el hash de salto. Uno puede usar números para estos, pero tenga en cuenta que la clasificación de 1, 2 y 10 da como resultado 1, 10, 2, por lo que es mejor usar algo como P0001, P0002, P0010.
Las reglas de coincidencia son la forma de dirigir las métricas entrantes a uno o más grupos. Las reglas de coincidencia se procesan de arriba a abajo, ya que se definen en el archivo. Es posible definir múltiples partidos en la misma regla. Cada regla de coincidencia puede enviar datos a uno o más grupos. Dado que las reglas de coincidencia "caen" a menos que se agregue la palabra clave stop , la expresión de coincidencia cuidadosamente elaborada se puede usar para dirigir múltiples grupos o agregaciones. Esta capacidad permite replicar métricas, así como enviar ciertas métricas a grupos alternativos con un orden cuidadoso y uso de la palabra clave stop . El clúster especial blackhole descarta cualquier métrica que se le envíe. Esto puede ser útil para eliminar las métricas no deseadas en ciertos casos. Debido a que tirar métricas de distancia no tiene sentido si otras coincidencias aceptarían los mismos datos, una coincidencia con como destino el clúster Blackhole, tiene una stop implícita. La cláusula validation agrega una verificación a los datos (lo que viene después de la métrica) en forma de expresión regular. Cuando esta expresión coincida, la regla de coincidencia se ejecutará como si no hubiera una cláusula de validación presente. Sin embargo, si falla, la regla del partido se aborta y no se enviarán métricas a los destinos, este es el comportamiento drop . Cuando se usa log , la métrica se registra en Stderr. Se debe tener cuidado con este último para evitar inundaciones de registro. Cuando hay una cláusula de validación, los destinos no necesitan estar presentes, esto permite aplicar una regla de validación global. Tenga en cuenta que las reglas de limpieza se aplican antes de que se realice la validación, por lo tanto, los datos no tendrán espacios duplicados. La route using la cláusula se utiliza para realizar una modificación temporal a la clave utilizada para la entrada a las rutinas de hashing consistentes. El propósito principal es enrutar el tráfico para que los datos apropiados se envíen a las instancias de agregación necesarias.
Reescribir las reglas toman una expresión regular como entrada para que coincidan con las métricas entrantes, y transformarlas en el nuevo nombre métrico deseado. En el reemplazo, las backreferencias pueden coincidir con los grupos de captura definidos en la expresión regular de entrada. Una coincidencia del server.(x|y|z). permite usar role.1. en la sustitución. Si es necesario, se puede usar una notación de g{n} en lugar de n donde la referencia de retroceso es seguida por un entero, como g{1}100 . Algunas advertencias se aplican a la implementación actual de las reglas de reescritura. Primero, su ubicación en el archivo de configuración determina cuándo se realiza la reescritura. La reescritura se realiza en el lugar, ya que tal regla de coincidencia antes de que la reescritura coincida con el nombre original, una regla de coincidencia después de que la reescritura ya no coincida con el nombre original. Se debe tener cuidado con el pedido, ya que pueden tener lugar múltiples reglas de reescritura en sucesión, por ejemplo, a se reemplaza por b y b es reemplazado por c en una regla de reescritura sucesiva. La segunda advertencia con la implementación actual es que los nombres de las métricas reescritas no se limpian, como lo son las métricas recientemente entrantes. Por lo tanto, pueden aparecer puntos dobles y caracteres peligrosos potenciales si la cadena de reemplazo está diseñada para producirlos. Es responsabilidad del escritor asegurarse de que las métricas estén limpias. Si este es un problema para el enrutamiento, uno puede considerar tener una instancia de reescritura solo que reenvía todas las métricas a otra instancia que hará el enrutamiento. Obviamente, la segunda instancia limpiará las métricas a medida que entran. La notación de referencia de retroceso permite minúsculas y superará la cadena de reemplazo con el uso de los símbolos inferior ( _ ) y corret ( ^ ) que siguen directamente después de la ventiladora. Por ejemplo, role._1. ya que la sustitución se minero el contenido de 1 . El punto ( . ) Se puede usar de manera similar, o seguido después del subrayador o el cariño para reemplazar puntos con subrayos en la sustitución. Esto puede ser útil para algunas situaciones en las que se envían métricas al grafito.
Las agregaciones definidas toman una o más métricas de entrada expresadas por una o más expresiones regulares, similares a las reglas de coincidencia. Las métricas entrantes se agregan durante un período de tiempo definido por el intervalo en segundos. Dado que los eventos pueden llegar un poco más adelante en el tiempo, el tiempo de vencimiento en segundos define cuándo las agregaciones deben considerarse finales, ya que ya no se permiten nuevas entradas. Además de una agregación, se pueden calcular múltiples agregaciones. Pueden ser de los mismos o diferentes tipos de agregación, pero deben escribir en una nueva métrica única. Los nombres métricos pueden incluir referencias posteriores como en las expresiones de reescritura, lo que permite reglas de agregación única poderosas que producen en muchas agregaciones. Cuando no se entrega send to , las métricas producidas se envían al relé como si se enviaran desde el exterior, por lo tanto, las reglas de coincidencia y agregación se aplican a las. Se debe tener cuidado de que los bucles se eviten de esta manera. Por esta razón, se alienta el uso de la cláusula send to para dirigir el tráfico de salida cuando sea posible. Al igual que para las reglas de coincidencia, es posible definir múltiples objetivos de clúster. Además, al igual que las reglas de coincidencia, la palabra clave stop se aplica para controlar el flujo de métricas en el proceso de coincidencia.
Las send statistics to la construcción están en desuso y se eliminarán en la próxima versión. Utilice la construcción statistics especiales en su lugar.
La construcción statistics puede controlar un par de cosas sobre las estadísticas (internas) producidas por el relé. El send to Target se puede utilizar para evitar bucles de enrutadores enviando las estadísticas a ciertos clúster de destino. Por defecto, las métricas tienen el prefijo carbon.relays.<hostname> , donde el nombre de host se determina en el inicio y se puede anular utilizando el argumento -H . Este prefijo se puede establecer utilizando el prefix with una cláusula similar a un objetivo de regla de reescritura. La coincidencia de entrada en este caso es la expresión regular preestablecida ^(([^.]+)(..*)?)$ En el nombre de host. Como tal, se puede ver que el prefijo predeterminado es establecido por carbon.relays..1 . Tenga en cuenta que esto utiliza la función de reemplazo reemplazar-con-withscore de las reglas de reescritura. Dada la expresión de entrada, los siguientes grupos de coincidencias están disponibles: 1 todo el nombre de host, 2 el nombre de host corto y 3 el nombre de dominio (con DOT líder). Puede tener sentido reemplazar el valor predeterminado por algo como carbon.relays._2 De manera predeterminada, las métricas se envían cada 60 segundos, esto se puede cambiar utilizando la cláusula submit every <interval> seconds para obtener un conjunto de valores más compatible a carbono-cache.py, use los reset counters after interval para hacer que los valores no son llamativos, es decir, informarán el cambio en comparación con el valor anterior.
Los puertos y los protocolos El relé debe escuchar las conexiones entrantes se puede especificar utilizando la Directiva listen . Actualmente, todos los oyentes deben ser de tipo linemode . Se puede especificar un envoltorio de compresión o cifrado opcional para el puerto y la interfaz opcional dada por la dirección IP, o unix socket por archivo. Cuando no se especifica la interfaz, se supone la interfaz de todos los protocolos IP disponibles. Si no hay una Directiva listen , el relé utilizará los oyentes predeterminados para Port 2003 en TCP y UDP, más el UNIX Socket /tmp/.s.carbon-c-relay.2003 . Esto generalmente se expande a 5 oyentes en un sistema habilitado para IPv6. El valor predeterminado coincide con el comportamiento de las versiones anteriores a V3.2.
En caso de que la configuración sea muy larga o se administra mejor en archivos separados, la Directiva include se puede usar para leer otro archivo. El archivo dado se leerá en su lugar y se agregará a la configuración del enrutador en el momento de la inclusión. El resultado final es una gran configuración de ruta. Se pueden usar múltiples declaraciones include en todo el archivo de configuración. El posicionamiento influirá en el orden de las reglas normales. Tenga en cuenta que se admite la inclusión recursiva ( include desde un archivo incluido), y actualmente no existen salvaguardas para un bucle de inclusión. Para lo que vale, esta característica probablemente se usa mejor con archivos de configuración simples (por ejemplo, no tener include en ellos).
Carbon-C-Relay evolucionó con el tiempo, las características crecientes a pedido ya que la herramienta demostró ser estable y ajustando bien el trabajo. A continuación, siga algunos ejemplos anotados de construcciones que se pueden usar con el relé.
Los grupos se pueden definir tanto como sea necesario. Reciben datos de las reglas de coincidencia, y su tipo define qué miembros del clúster finalmente obtienen los datos métricos. La forma de clúster más simple es un clúster forward :
cluster send-through
forward
10.1.0.1
;
Cualquier métrica enviada al clúster send-through simplemente se reenviaría al servidor en la dirección IPv4 10.1.0.1 . Si definimos múltiples servidores, todos esos servidores obtendrían la misma métrica, por lo tanto:
cluster send-through
forward
10.1.0.1
10.2.0.1
;
Lo anterior da como resultado una duplicación de métricas enviadas a ambas máquinas. Esto puede ser útil, pero la mayoría de las veces no lo es. El tipo de clúster any_of es como forward , pero envía cada métrica entrante a cualquiera de los miembros. El mismo ejemplo con dicho clúster sería:
cluster send-to-any-one
any_of 10.1.0.1:2010 10.1.0.1:2011;
Esto implementaría un escenario de múltiples trayes, donde se usan dos servidores, la carga entre ellos se extiende, pero si cualquiera de ellos falle, todas las métricas se envían al restante. Esto generalmente funciona bien para los relés aguas arriba, o para equilibrar los procesos de caché de carbono que se ejecutan en la misma máquina. Si algún miembro no está disponible, por ejemplo debido a un reinicio de Rolling, los otros miembros reciben el tráfico. Si es necesario tener un verdadero fracaso, donde el servidor secundario solo se usa si el primero está inactivo, lo siguiente implementaría eso:
cluster try-first-then-second
failover 10.1.0.1:2010 10.1.0.1:2011;
Estos tipos son diferentes de los dos tipos consistentes de clúster hash:
cluster graphite
carbon_ch
127.0.0.1:2006=a
127.0.0.1:2007=b
127.0.0.1:2008=c
;
Si un miembro en este ejemplo falla, todas las métricas que irían a ese miembro se mantienen en la cola, esperando que el miembro regrese. Esto es útil para los grupos de máquinas de caché de carbono donde es deseable que la misma métrica termine siempre en el mismo servidor. El tipo de clúster carbon_ch es compatible con el hash consistente de reclusión de carbono, y puede usarse para los grupos existentes poblados por el relajado de carbono. Sin embargo, para nuevos grupos, es mejor usar el tipo de clúster fnv1a_ch , ya que es más rápido, y permite equilibrar la misma dirección pero diferentes puertos sin un número de instancia, en construcción a carbon_ch .
Debido a que podemos usar múltiples grupos, también podemos replicar sin el uso del tipo de clúster forward , de una manera más inteligente:
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
;
En este ejemplo, todas las métricas entrantes se envían por primera vez a dc-old , luego dc-new1 y finalmente a dc-new2 . Tenga en cuenta que el tipo de clúster de dc-old es diferente. Cada métrica entrante se enviará a 2 miembros de los tres grupos, replicando así en un total de 6 destinos. Para cada clúster, los miembros de destino se calculan de forma independiente. El fracaso de los grupos o miembros no afecta a los demás, ya que todos tienen colas individuales. El ejemplo anterior también podría escribirse utilizando tres reglas de coincidencia para cada DC, o una regla de coincidencia para los tres DC. La diferencia está principalmente en el rendimiento, el número de veces la métrica entrante debe coincidir con una expresión. La regla stop en la regla de coincidencia de dc-new no es estrictamente necesaria en este ejemplo, porque ya no hay más reglas de coincidencia. Sin embargo, si la coincidencia se dirigiera a un subconjunto específico, por ejemplo ^sys. , y se definirían más grupos, esto podría ser necesario, como por ejemplo en el siguiente ejemplo abreviado:
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;
Como se puede ver, sin la stop en la regla del partido de DC2-Sys, todas las métricas comienzan con sys. También se enviaría a DC1-MISC y DC2-MISC. Puede ser que esto se desee, por supuesto, pero en este ejemplo hay un clúster dedicado para las métricas sys .
Supongamos que habría una métrica no deseada que desafortunadamente se genera, supongamos un software malo/antiguo. No queremos almacenar esta métrica. El grupo blackhole es adecuado para eso, cuando es más difícil en realidad todas las métricas queridas. Considere lo siguiente:
match
some_legacy1$
some_legacy2$
send to blackhole
stop;
Esto arrojaría todas las métricas que terminan con some_legacy , que de otro modo sería difícil de filtrar. Dado que el orden es importante, se puede usar en una construcción como esta:
cluster old ... ;
cluster new ... ;
match * send to old;
match unwanted send to blackhole stop;
match * send to new;
En este ejemplo, el viejo clúster recibiría la métrica que no está deseada para el nuevo clúster. Entonces, el orden en que ocurren las reglas es importante para la ejecución.
La validación se puede utilizar para garantizar que los datos de métricos sean los esperados. Una validación global para los valores de solo número (sin punto flotante) podría ser:
match *
validate ^[0-9]+ [0-9]+$ else drop
;
(Tenga en cuenta que el escape con barra inactividad del espacio, es posible que pueda usar s o [:space:] En cambio, esto depende de su implementación de regex configurada).
La cláusula de validación puede existir en cada regla de coincidencia, por lo que, en principio, lo siguiente es válido:
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;
Tenga en cuenta que el comportamiento es diferente en los dos ejemplos anteriores. Cuando no se especifica send to los clústeres, un error de validación hace que la coincidencia se comporte como si la palabra clave stop esté presente. Del mismo modo, cuando pasa la validación, el procesamiento continúa con la siguiente regla. 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.
conexión
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.