Actualmente, la E/S de disco remota y la CPU pueden planificarse con el método descrito. Para límites de memoria flexibles, consulte memory overcommit
Configuración del disco
storage_configuration del servidor:
Para habilitar la planificación de E/S para un disco específico, debe especificar read_resource y/o write_resource en la configuración de almacenamiento. Esto le indica a ClickHouse qué recurso debe usar para cada solicitud de lectura y escritura de ese disco. El recurso de lectura y el de escritura pueden referirse al mismo nombre de recurso, lo que resulta útil para Local SSD o HDD. Varios discos distintos también pueden referirse al mismo recurso, lo que resulta útil para discos remotos si desea permitir un reparto equitativo del ancho de banda de red entre, por ejemplo, las cargas de trabajo de “producción” y “desarrollo”.
Ejemplo:
Marcado de carga de trabajo
workload para distinguir distintas cargas de trabajo. Si no se establece workload, se usa el valor “default”. Tenga en cuenta que también puede especificar otro valor mediante perfiles de configuración. Las restricciones de configuración pueden usarse para hacer que workload sea constante si desea que todas las consultas de un usuario se marquen con un valor fijo para la configuración workload.
Es posible asignar una configuración workload a las actividades en segundo plano. Las fusiones y mutaciones usan las configuraciones del servidor merge_workload y mutation_workload, respectivamente. Estos valores también pueden anularse para tablas específicas mediante las configuraciones de MergeTree merge_workload y mutation_workload
Consideremos un ejemplo de un sistema con dos cargas de trabajo diferentes: “production” y “development”.
Jerarquía de planificación de recursos
inflight_limit(restricción) - bloquea si el número de solicitudes simultáneas en curso superamax_requestso si su coste total superamax_cost; debe tener un único hijo.bandwidth_limit(restricción) - bloquea si el ancho de banda actual superamax_speed(0 significa ilimitado) o si la ráfaga superamax_burst(de forma predeterminada, es igual amax_speed); debe tener un único hijo.fair(política) - selecciona la siguiente solicitud que se atenderá de uno de sus nodos hijos según la equidad max-min; los nodos hijos pueden especificarweight(el valor predeterminado es 1).priority(política) - selecciona la siguiente solicitud que se atenderá de uno de sus nodos hijos según prioridades estáticas (un valor menor significa una prioridad más alta); los nodos hijos pueden especificarpriority(el valor predeterminado es 0).fifo(cola) - hoja de la jerarquía capaz de contener solicitudes que superan la capacidad del recurso.
inflight_limit. Tenga en cuenta que un valor bajo de max_requests o max_cost podría hacer que el recurso no se utilice por completo, mientras que valores demasiado altos podrían dejar colas vacías dentro del planificador, lo que a su vez hará que se ignoren las políticas (falta de equidad o de prioridad) en el subárbol. Por otro lado, si desea proteger los recursos frente a una utilización excesiva, debe usar bandwidth_limit. Este limita el uso cuando la cantidad de recurso consumido en duration segundos supera max_burst + max_speed * duration bytes. Se pueden usar dos nodos bandwidth_limit sobre el mismo recurso para limitar el ancho de banda pico durante intervalos cortos y el ancho de banda medio durante intervalos más largos.
El siguiente ejemplo muestra cómo definir las jerarquías de programación de E/S que se muestran en la imagen:
Clasificadores de cargas de trabajo
workload especificada por una consulta a las colas hoja que deben usarse para recursos específicos. Por el momento, la clasificación de cargas de trabajo es sencilla: solo está disponible la asignación estática.
Ejemplo:
Jerarquía de cargas de trabajo
CREATE RESOURCE comparten la misma estructura jerárquica, aunque pueden diferir en algunos aspectos. Cada carga de trabajo creada con CREATE WORKLOAD mantiene varios nodos de planificación creados automáticamente para cada recurso. Se puede crear una carga de trabajo hija dentro de otra carga de trabajo padre. A continuación se muestra el ejemplo que define exactamente la misma jerarquía que la configuración XML anterior:
SETTINGS workload = 'name'.
Para personalizar la carga de trabajo, se pueden usar las siguientes opciones de configuración:
priority- las cargas de trabajo hermanas se atienden según valores de prioridad estáticos (un valor menor significa una prioridad más alta).weight- las cargas de trabajo hermanas con la misma prioridad estática comparten los recursos según sus pesos.max_io_requests- el límite del número de solicitudes de E/S concurrentes en esta carga de trabajo.max_bytes_inflight- el límite del total de bytes en curso para las solicitudes concurrentes en esta carga de trabajo.max_bytes_per_second- el límite de la tasa de lectura o escritura de bytes de esta carga de trabajo.max_burst_bytes- el número máximo de bytes que la carga de trabajo puede procesar sin que se limite su tasa (para cada recurso de forma independiente).max_concurrent_threads- el límite del número de hilos para las consultas de esta carga de trabajo.max_concurrent_threads_ratio_to_cores- lo mismo quemax_concurrent_threads, pero normalizado según el número de núcleos de CPU disponibles.max_cpus- el límite del número de núcleos de CPU para atender consultas en esta carga de trabajo.max_cpu_share- lo mismo quemax_cpus, pero normalizado según el número de núcleos de CPU disponibles.max_burst_cpu_seconds- el número máximo de segundos de CPU que la carga de trabajo puede consumir sin que se limite su tasa debido amax_cpus.
max_bytes_per_second = 10485760 tendrá un límite de ancho de banda de 10 MB/s para cada recurso de lectura y escritura, de forma independiente. Si se requiere un límite común para lectura y escritura, considere usar el mismo recurso para el acceso READ y WRITE.
No hay forma de especificar distintas jerarquías de cargas de trabajo para diferentes recursos. Pero sí hay una manera de especificar un valor distinto de configuración de la carga de trabajo para un recurso específico:
CREATE OR REPLACE WORKLOAD.
La configuración de la carga de trabajo se convierte en un conjunto adecuado de nodos de planificación. Para obtener más detalles, consulta la descripción de los tipos y opciones de los nodos de planificación.
Planificación de la CPU
- Hilo maestro — el primer hilo que empieza a trabajar en una consulta o en una actividad en segundo plano, como una fusión o una mutación.
- Hilo de trabajo — los hilos adicionales que el maestro puede generar para trabajar en tareas intensivas en CPU.
max_threads. En ese caso, las consultas entrantes tendrán que bloquearse y esperar a que haya un slot de CPU para que su hilo maestro pueda empezar a ejecutarse. Para evitarlo, podría usarse la siguiente configuración:
cpu_slot_preemption. Si está habilitada, cada hilo renueva su slot de CPU periódicamente (según la configuración del servidor cpu_slot_quantum_ns). Esa renovación puede bloquear la ejecución si la CPU está sobrecargada. Cuando la ejecución permanece bloqueada durante un tiempo prolongado (consulte la configuración del servidor cpu_slot_preemption_timeout_ms), la consulta reduce dinámicamente el número de hilos en ejecución concurrente. Tenga en cuenta que la equidad en el tiempo de CPU está garantizada entre cargas de trabajo, pero entre consultas dentro de la misma carga de trabajo podría no cumplirse en algunos casos extremos.
La declaración del recurso de CPU desactiva el efecto de los ajustes
concurrent_threads_soft_limit_num y concurrent_threads_soft_limit_ratio_to_cores. En su lugar, se usa el ajuste de carga de trabajo max_concurrent_threads para limitar el número de CPU asignadas a una carga de trabajo específica. Para lograr el comportamiento anterior, cree únicamente el recurso WORKER THREAD, establezca max_concurrent_threads para la carga de trabajo all con el mismo valor que concurrent_threads_soft_limit_num y use el ajuste de consulta workload = "all". Esta configuración corresponde al ajuste concurrent_threads_scheduler establecido con el valor “fair_round_robin”.Hilos vs. CPU
- Límite del número de hilos:
max_concurrent_threadsymax_concurrent_threads_ratio_to_cores - Limitación de CPU:
max_cpus,max_cpu_shareymax_burst_cpu_seconds
max_threads. La segunda limita el consumo de CPU de la carga de trabajo mediante el algoritmo de cubo de tokens. No afecta directamente al número de hilos, pero sí limita el consumo total de CPU de todos los hilos de la carga de trabajo.
La limitación mediante cubo de tokens con max_cpus y max_burst_cpu_seconds significa lo siguiente. Durante cualquier intervalo de delta segundos, no se permite que el consumo total de CPU de todas las consultas de la carga de trabajo supere max_cpus * delta + max_burst_cpu_seconds segundos de CPU. Limita el consumo medio a max_cpus a largo plazo, pero este límite puede superarse a corto plazo. Por ejemplo, dado max_burst_cpu_seconds = 60 y max_cpus=0.001, se permite ejecutar 1 hilo durante 60 segundos, o 2 hilos durante 30 segundos, o 60 hilos durante 1 segundo, sin que se aplique limitación. El valor predeterminado de max_burst_cpu_seconds es 1 segundo. Valores más bajos pueden provocar un infraaprovechamiento de los núcleos permitidos por max_cpus cuando hay muchos hilos concurrentes.
Mientras mantiene un slot de CPU, un hilo puede estar en uno de estos tres estados principales:
- En ejecución: Consume efectivamente recursos de CPU. El tiempo que pasa en este estado se contabiliza en la limitación de CPU.
- Listo: Esperando a que una CPU esté disponible. No se contabiliza en la limitación de CPU.
- Bloqueado: Realizando operaciones de E/S u otras llamadas al sistema bloqueantes (por ejemplo, esperando un mutex). No se contabiliza en la limitación de CPU.
max_cpu_share, tiene un límite del 70% de los recursos totales de CPU. Por su parte, aunque la ingestión se queda con una garantía de al menos 0.8 * 0.25 = 20%, no tiene límite superior.
Si desea maximizar el uso de CPU en su servidor ClickHouse, evite usar
max_cpus y max_cpu_share para la carga de trabajo raíz all. En su lugar, establezca un valor más alto para max_concurrent_threads. Por ejemplo, en un sistema con 8 CPU, establezca max_concurrent_threads = 16. Esto permite que 8 hilos ejecuten tareas de CPU mientras otros 8 pueden encargarse de operaciones de E/S. Los hilos adicionales generarán presión sobre la CPU, lo que garantiza que se apliquen las reglas de planificación. En cambio, establecer max_cpus = 8 nunca generará presión sobre la CPU porque el servidor no puede superar las 8 CPU disponibles.Planificación de slots de consulta
max_concurrent_queries limita la cantidad de consultas concurrentes que pueden ejecutarse simultáneamente para una carga de trabajo determinada. Es análoga a la configuración de consulta max_concurrent_queries_for_all_users y a la configuración del servidor max_concurrent_queries. Las consultas con async insert y algunas consultas específicas, como KILL, no cuentan para este límite.
Las configuraciones de carga de trabajo max_queries_per_second y max_burst_queries limitan la cantidad de consultas de la carga de trabajo mediante un limitador de tasa de tipo token bucket. Esto garantiza que, durante cualquier intervalo de tiempo T, no se iniciará la ejecución de más de max_queries_per_second * T + max_burst_queries consultas nuevas.
La configuración de carga de trabajo max_waiting_queries limita la cantidad de consultas en espera para la carga de trabajo. Cuando se alcanza el límite, el servidor devuelve un error SERVER_OVERLOADED.
Las consultas bloqueadas esperarán indefinidamente y no aparecerán en
SHOW PROCESSLIST hasta que se cumplan todas las restricciones.Almacenamiento de cargas de trabajo y recursos
CREATE WORKLOAD y CREATE RESOURCE, se almacenan de forma persistente, ya sea en disco, en workload_path, o en ZooKeeper, en workload_zookeeper_path. Se recomienda el almacenamiento en ZooKeeper para garantizar la consistencia entre los nodos. Como alternativa, se puede usar la cláusula ON CLUSTER junto con el almacenamiento en disco.
Cargas de trabajo y recursos basados en la configuración
Formato de la configuración
CREATE WORKLOAD y CREATE RESOURCE. Todas las consultas deben ser válidas.
Recomendaciones de uso
- Definir la carga de trabajo raíz y los recursos de E/S de red en la configuración para establecer los límites de la infraestructura
- Configurar
throw_on_unknown_workloadpara hacer cumplir estos límites - Crear
CREATE WORKLOAD default IN allpara aplicar automáticamente los límites a todas las consultas (ya que el valor predeterminado de la configuración de consultaworkloades ‘default’) - Permitir que los usuarios creen cargas de trabajo adicionales dentro de la jerarquía configurada
Acceso estricto a los recursos
throw_on_unknown_workload. Si se establece en true, cada consulta deberá usar una configuración de consulta workload válida; de lo contrario, se lanzará la excepción RESOURCE_ACCESS_DENIED. Si se establece en false, esa consulta no usará el planificador de recursos; es decir, tendrá acceso ilimitado a cualquier RESOURCE. La configuración de consulta use_concurrency_control = 0 permite que la consulta omita el planificador de CPU y obtenga acceso ilimitado a la CPU. Para imponer la planificación de CPU, cree una restricción de configuración que mantenga use_concurrency_control como un valor constante de solo lectura.
No establezca
throw_on_unknown_workload en true a menos que se haya ejecutado CREATE WORKLOAD default. Esto podría causar problemas durante el inicio del servidor si, en ese momento, se ejecuta una consulta sin la configuración explícita workload.Véase también
- system.scheduler
- system.workloads
- system.resources
- merge_workload configuración de MergeTree
- merge_workload configuración global del servidor
- mutation_workload configuración de MergeTree
- mutation_workload configuración global del servidor
- workload_path configuración global del servidor
- workload_zookeeper_path configuración global del servidor
- cpu_slot_preemption configuración global del servidor
- cpu_slot_quantum_ns configuración global del servidor
- cpu_slot_preemption_timeout_ms configuración global del servidor