La conversación se repite: alguien cambia los discos de su clúster por otros más rápidos y el rendimiento apenas se mueve. Entonces empieza la caza del cuello de botella —la red, la CPU, el firmware, el kernel— y casi nunca se mira el sitio donde de verdad se decide: el planificador de operaciones que cada OSD lleva dentro, y el número que ese planificador cree que tu disco es capaz de dar.
Operamos Proxmox VE con Ceph en producción en varios datacenters, así que esto lo decimos con el cariño de quien se lo ha comido: en Ceph, el rendimiento que ves no lo firma el fabricante del disco. Lo firma un reparto interno que se configuró solo, con una medición que hizo tu OSD el día que arrancó y que probablemente nadie ha vuelto a mirar. Los números que siguen no son nuestros: son los que trae la documentación de Ceph y los que vas a encontrar en tu clúster si lo miras. De cosecha propia va el orden en que los miramos y qué hacemos con ellos.
El planificador que llegó en Quincy y casi nadie configuró
Dentro de un OSD compiten cuatro clases de trabajo: las operaciones del cliente (tus VM), la recuperación y el backfill, el scrub y las tareas de mantenimiento. Hasta Ceph Pacific ese reparto lo hacía una cola de prioridades ponderada (wpq). Con Quincy, el planificador por defecto de los OSD BlueStore pasó a ser mclock_scheduler, y con él cambió la forma de repartir: en vez de prioridades relativas, mClock asigna a cada clase una reserva (mínimo garantizado), un peso y un límite sobre la capacidad total del OSD.
El perfil activo por defecto se llama balanced —lo es desde la 17.2.7 y la 18.2.0; en las Quincy anteriores venía puesto high_client_ops— y hace exactamente lo que promete: reserva un 50 % para el cliente y un 50 % para la recuperación (más un 5 % para el resto). Los otros dos perfiles integrados mueven ese equilibrio: high_client_ops deja 60/40 a favor del cliente y high_recovery_ops lo invierte a 30/70 para que un clúster degradado se cure antes.
Hasta aquí, razonable. El problema no es el reparto: es sobre qué se reparte.
315 IOPS: el número que gobierna tu clúster y no pusiste tú
Para repartir porcentajes, mClock necesita saber cuál es el 100 %. Ese techo vive en osd_mclock_max_capacity_iops_hdd y osd_mclock_max_capacity_iops_ssd, y lo determina el propio OSD ejecutando un benchmark la primera vez que arranca; el resultado se guarda en la configuración centralizada de los monitores y se reutiliza en arranques posteriores. Si esa medición nunca llegó a hacerse o se descartó, quedan en pie los valores por defecto de la documentación:
- •315 IOPS para un disco mecánico (
osd_mclock_max_capacity_iops_hdd). - •21.500 IOPS para uno de estado sólido (
osd_mclock_max_capacity_iops_ssd). - •Y, al margen del benchmark, un ancho de banda secuencial que no se mide nunca y siempre es fijo:
osd_mclock_max_sequential_bandwidth_hdd= 150Mi yosd_mclock_max_sequential_bandwidth_ssd= 1200Mi. mClock lo usa para calcular el coste de cada operación, no el techo.
Y aquí está la parte que sorprende a más de uno. La medición del arranque no se acepta a ciegas: si el resultado se sale de la horquilla que Ceph considera creíble, lo descarta y vuelve al valor por defecto, dejando un aviso en el log del OSD. Por arriba, osd_mclock_iops_capacity_threshold_hdd = 500 y osd_mclock_iops_capacity_threshold_ssd = 80.000. Por abajo funciona igual, y es la mitad que nadie cuenta: osd_mclock_iops_capacity_low_threshold_hdd = 50 y osd_mclock_iops_capacity_low_threshold_ssd = 1.000. Una medida demasiado buena y una demasiado mala acaban en el mismo sitio: la capacidad válida anterior o, si no la hay, el valor de fábrica.
Traducido a la vida real: puedes tener un NVMe empresarial que en su ficha promete cientos de miles de IOPS, y que el planificador de tu OSD esté repartiendo, tan tranquilo, sobre 21.500. El disco no miente y la ficha tampoco; simplemente nadie le ha dicho a Ceph que le crea.
Cómo saber qué se cree tu clúster (cinco minutos)
Esto no requiere ventana de mantenimiento ni parar nada. Se mira y ya:
# ¿Qué planificador está activo? ceph config show-with-defaults osd.0 | grep op_queue # ¿Qué techo de IOPS se cree cada OSD? ceph config show-with-defaults osd.0 | grep mclock_max_capacity # Medir de verdad ese OSD (4 KiB aleatorio, como manda la doc) y fijar el valor ceph tell osd.0 cache drop ceph tell osd.0 bench 12288000 4096 4194304 100 ceph config set osd.0 osd_mclock_max_capacity_iops_ssd <valor>
Si prefieres que el OSD lo vuelva a medir solo, existe osd_mclock_force_run_benchmark_on_init (por defecto false), pensado precisamente para cuando el hardware de debajo ha cambiado: se activa de forma temporal, se reinicia el OSD para que refresque su capacidad y después se quita. Ojo con dos cosas: el benchmark escribe, así que no es algo que se lance en hora punta a la vez en todos los OSD; y la medida es una foto de ese momento, hecha por una máquina que en ese instante no está sirviendo a tus VMs.
Los parámetros que llevabas años tocando ya no hacen nada
Esta es la segunda sorpresa, y la que más tiempo hace perder. Con un perfil integrado de mClock activo, la documentación de Ceph es explícita: estas opciones se sobrescriben con los valores de mClock.
- ✗
osd_max_backfills,osd_recovery_max_active,osd_recovery_max_active_hddyosd_recovery_max_active_ssd: sobrescritos. - ✗Con cualquier perfil activo, incluido
custom, las esperas se desactivan (se ponen a cero):osd_recovery_sleepy sus variantes,osd_scrub_sleep,osd_delete_sleepyosd_snap_trim_sleep.
Con dos matices que da la propia documentación, y que conviene decir para no vender la moto. El primero: esos límites sí se pueden tocar, pero solo activando antes osd_mclock_override_recovery_settings (por defecto false); si no lo activas y los cambias igual, Ceph revierte tu valor al suyo y deja un aviso en el log del clúster. No es que se ignore tu ajuste: es que se te deshace, y queda por escrito. El segundo: los valores a los que revierte coinciden con los históricos —osd_max_backfills 1, osd_recovery_max_active_hdd 3, _ssd 10—, así que en la mayoría de clústeres el efecto neto es el mismo que no haber tocado nada. Lo que se pierde es la ilusión de estar controlándolo.
El wiki de Proxmox lo dice sin rodeos: los métodos antiguos para controlar cuánto rendimiento se dedica al backfill y a la recuperación son ignorados por mClock. Así que si alguien copió de un manual de 2019 un osd_recovery_sleep_hdd generoso para que el clúster no se ahogue durante una reconstrucción, ese ajuste hoy no está haciendo absolutamente nada. Y ese mismo wiki avisa de un detalle que rompe recetas viejas: hasta la 17.2.6 los valores res y lim del perfil custom se expresaban en IOPS; desde la 17.2.7 y la 18.2.0 son una fracción de la capacidad de IOPS del OSD, de 0,0 a 1,0. La misma línea copiada de un foro significa dos cosas distintas según tu versión.
El scrub no tiene ventana horaria por defecto
Ceph verifica sus datos por su cuenta, y eso está muy bien: es una de las razones por las que confiamos en él. Pero conviene saber cuándo lo hace. Por defecto, el scrub ligero se plantea a partir de un día (osd_scrub_min_interval) y el deep scrub —que lee los datos, no solo los metadatos— cada siete días (osd_deep_scrub_interval). Cada OSD admite hasta tres scrubs simultáneos (osd_max_scrubs). Y la ventana horaria, osd_scrub_begin_hour y osd_scrub_end_hour, viene con 0 y 0: sin restricción, a cualquier hora.
En un clúster de NVMe eso pasa desapercibido. En uno de discos mecánicos con la nómina cerrándose un martes por la mañana, no. La opción sensata no es apagar el scrub —quien lo hace acaba descubriendo la corrupción el día del restore— sino ponerle horario y aceptar que la verificación es parte del coste de tener los datos sanos. Y aquí hay una palanca que sí funciona: mClock te ha puesto osd_scrub_sleep a cero, pero las horas de inicio y fin, sus equivalentes por día de la semana y osd_max_scrubs siguen siendo tuyos.
La red también es parte del disco
Una escritura de cliente en un pool replicado no termina cuando el disco primario la ha guardado: termina cuando la han guardado todas las réplicas. La latencia que ve la VM la marca, por tanto, el OSD más lento del grupo, no la media del clúster. Un solo disco enfermo —o con su medición mal puesta— arrastra al resto.
Por eso la recomendación de red de la propia documentación de Ceph no es un capricho de fabricante de switches. Sus números: replicar 1 TiB por una red de 1 Gb/s cuesta tres horas; 10 TiB, treinta horas; ese mismo TiB a 10 Gb/s baja a veinte minutos. La recomendación es provisionar al menos 10 Gb/s, y avisa de que los nodos densos o de NVMe pueden saturar 10 GE e incluso 25 GE; para cargas de trabajo serias sugiere 25 Gb/s, y enlaces de 100 Gb/s cuando los nodos son densos. Esas treinta horas no son un dato de catálogo: son el tiempo que tu clúster pasa degradado después de perder un nodo, y durante el cual el perfil balanced le está reservando a la recuperación la mitad de cada OSD.
Cuánto tarda esa reconstrucción depende también del esquema del pool: recuperar una réplica es copiar, y recuperar un fragmento de erasure coding es leer varios trozos y reconstruir. Hicimos esa cuenta completa en réplica 3 frente a erasure coding, y las optimizaciones que cambian esa aritmética en la última rama las repasamos en Fast EC llega apagado.
Cuándo el disco SÍ es el problema
Sería deshonesto quedarse en "es el planificador". Hay dos casos en los que el hierro es exactamente el culpable, y la documentación de Ceph los señala sin diplomacia:
- 1SSD de consumo en un OSD. La documentación recomienda unidades de clase empresarial porque llevan protección ante pérdida de alimentación (PLP), y llama a las de gama baja o sin marca una falsa economía que puede sufrir cliffing: tras una ráfaga inicial, cuando se llena una caché limitada, el rendimiento sostenido se desploma. Sobre desgaste, avisa de que un disco de 0,3 DWPD puede valer para OSD dedicados a datos escritos en secuencial y leídos mucho más de lo que se escriben, pero no es buena elección para un pool RBD sirviendo a cientos de VM, y que la mayoría de despliegues de OSD no necesitan más de 1 DWPD: los mixed-use de 3 DWPD suelen ser excesivos y cuestan bastante más. Hasta aquí la documentación. Lo que ponemos nosotros: Ceph escribe pidiendo confirmación a disco constantemente, y sin PLP cada una de esas confirmaciones se paga en latencia.
- 2Discos mecánicos sin WAL/DB en flash, o con demasiados por unidad. La proporción que da la documentación es de cuatro o cinco OSD de disco mecánico por cada SSD SATA de WAL/DB, y hasta unos quince por NVMe. Pasarse de ahí convierte el dispositivo de metadatos en el nuevo cuello de botella —y en un dominio de fallo que se lleva por delante todos los OSD que dependen de él.
Lo que miramos nosotros, en este orden
- ✓El planificador activo y el perfil de mClock. Antes de tocar nada más.
- ✓El techo de IOPS de cada OSD, uno por uno. Un OSD con el valor por defecto entre veinte que sí se midieron es una anomalía que no aparece en ningún gráfico de uso.
- ✓Los avisos del log del OSD sobre el resultado del benchmark descartado. Ahí está escrito el problema, con fecha.
- ✓Qué ajustes heredados siguen escritos en la configuración sin efecto real, para borrarlos y dejar de razonar sobre humo.
- ✓La latencia por OSD, no la media del clúster. La media esconde justo al que manda.
En corto
Ceph reparte trabajo sobre una capacidad que se estimó sola, en un arranque, y que puede haberse quedado en un valor de manual. Antes de firmar la compra de unos discos más rápidos, vale la pena dedicar cinco minutos a preguntarle al clúster qué se cree que tiene. A veces la respuesta es que el hierro va justo y hay que comprar. Y a veces la respuesta es que el hierro nuevo iba a entrar por la misma puerta estrecha que el viejo.
Fuentes (verificadas el 13 de agosto de 2026 contra las ramas latest y reef de la documentación): perfiles, reservas, capacidad de IOPS, umbrales y opciones sobrescritas — mClock Config Reference; intervalos de scrub y recuperación — OSD Config Reference; PLP, DWPD, proporciones de WAL/DB y tiempos de replicación por red — Hardware Recommendations; confirmación de la escritura replicada por el OSD primario — Ceph Architecture; cambio de wpq a mclock en Quincy, ajustes ignorados y unidades de res/lim según versión — Proxmox VE Wiki: Ceph mClock Tuning.
¿Tu Ceph va lento y nadie sabe explicar por qué?
En everyWAN diseñamos y operamos almacenamiento distribuido con Ceph en producción. Miramos el clúster que ya tienes antes de recomendarte comprar nada: no vendemos licencias ni discos de nadie.
Hablar con everyWAN