17 Gestión de datos almacenados #
El algoritmo CRUSH determina cómo se deben almacenar y recuperar los datos. Para ello, calcula las ubicaciones de almacenamiento. CRUSH aporta a los clientes de Ceph la capacidad de comunicarse con los OSD directamente, en lugar de hacerlo a través de un servidor centralizado o un intermediario. Con un método de almacenamiento y recuperación de datos determinado mediante un algoritmo, Ceph evita que haya un punto único de error, un cuello de botella de rendimiento y un límite físico a su capacidad de ampliación.
CRUSH requiere un mapa del clúster y usa el mapa de CRUSH para almacenar y recuperar de forma pseudoaleatoria los datos de los OSD con una distribución uniforme de los datos por el clúster.
Los mapas de CRUSH contienen una lista de los OSD, una lista de "depósitos" para agregar los dispositivos en ubicaciones físicas, y una lista de reglas que indican a CRUSH cómo se deben replicar los datos en los repositorios del clúster de Ceph. Al reflejar la organización física subyacente de la instalación, CRUSH puede modelar, y por lo tanto solucionar, causas potenciales de errores de dispositivo correlacionados. Las causas habituales suelen ser la proximidad física, una fuente de alimentación compartida y una red compartida. Mediante la codificación de esta información en un mapa del clúster, las directivas de colocación de CRUSH pueden separar las réplicas del objeto en dominios de fallo diferentes, al tiempo que se mantiene la distribución que se desea. Por ejemplo, para prepararse en caso de que se produzcan fallos simultáneos, puede ser conveniente asegurarse de que las réplicas de datos se encuentran en dispositivos que utilizan diferentes estantes, bastidores, fuente de alimentación, controladores o ubicaciones físicas.
Después de distribuir un clúster de Ceph, se genera un mapa de CRUSH por defecto. Resulta adecuado para el entorno de la zona protegida de Ceph. Sin embargo, si se distribuye un clúster de datos a gran escala, debe planificarse concienzudamente cómo desarrollar un mapa de CRUSH personalizado, ya que le ayudará a gestionar el clúster de Ceph, a mejorar el rendimiento y a garantizar la seguridad de los datos.
Por ejemplo, si falla un OSD, un mapa de CRUSH puede ayudarle a localizar el centro de datos físico, la sala, la fila y el bastidor del host donde se encuentra el OSD que ha fallado, en caso de que necesite asistencia técnica in situ o sustituir el hardware.
Del mismo modo, CRUSH puede ayudarle a identificar los errores más rápidamente. Por ejemplo, si todos los OSD en un bastidor determinado fallan al mismo tiempo, el error podría encontrarse en un conmutador de red o en la fuente de alimentación del bastidor, o en el conmutador de red, en lugar de estar en los propios OSD.
Un mapa de CRUSH personalizado también ayuda a identificar las ubicaciones físicas donde Ceph almacena las copias redundantes de los datos si los grupos de colocación (consulte la Sección 17.4, “Grupos de colocación”) asociados con un host que falla se encuentran en un estado degradado.
Hay tres secciones principales en un mapa de CRUSH.
Los Dispositivos OSD son cualquier dispositivo de almacenamiento de objetos correspondiente a un daemon
ceph-osd
.Los Depósitos son una agregación jerárquica de ubicaciones de almacenamiento (por ejemplo, filas, bastidores, hosts, etc.) y sus pesos asignados.
Los Conjuntos de reglas son una forma de seleccionar depósitos.
17.1 Dispositivos OSD #
Para asignar grupos de colocación a los OSD, un mapa de CRUSH requiere una lista de los dispositivos OSD (el nombre del daemon OSD). La lista de dispositivos aparece primero en el mapa de CRUSH.
#devices device NUM osd.OSD_NAME class CLASS_NAME
Por ejemplo:
#devices device 0 osd.0 class hdd device 1 osd.1 class ssd device 2 osd.2 class nvme device 3 osd.3 class ssd
Como regla general, un daemon OSD se asigna a un solo disco.
17.1.1 Clases de dispositivos #
La flexibilidad del mapa de CRUSH para controlar la colocación de los datos es uno de los puntos fuertes de Ceph. También es una de las partes más difíciles de gestionar del clúster. Las clases de dispositivos automatizan los cambios más comunes en los mapas de CRUSH que, antes, el administrador debía realizar manualmente.
17.1.1.1 El problema de la gestión de CRUSH #
Los clústeres de Ceph se crean con frecuencia con varios tipos de dispositivos de almacenamiento: discos duros, unidades SSD, NVMe o incluso con combinaciones de estos. Llamamos a estos diferentes tipos de dispositivos de almacenamiento clases de dispositivos, para evitar confusiones entre la propiedad type de las depósitos CRUSH (por ejemplo, host, bastidor o fila; consulte la Sección 17.2, “Depósitos” para obtener detalles). Los Ceph OSD respaldados por unidades SSD son mucho más rápidos que los respaldados por discos giratorios, por lo que son más adecuados para ciertas cargas de trabajo. Ceph facilita la creación de repositorios RADOS para diferentes conjuntos de datos o cargas de trabajo, así como para asignar las diferentes reglas de CRUSH que sirven para controlar la colocación de datos para esos repositorios.
Sin embargo, configurar las reglas de CRUSH para colocar datos solo en una determinada clase de dispositivo resulta tedioso. Las reglas funcionan en términos de la jerarquía de CRUSH, pero si los dispositivos se mezclan en los mismos hosts o bastidores (como en la jerarquía de ejemplo anterior), se mezclarán (por defecto) y aparecerán en los mismos subárboles de la jerarquía. Separarlos manualmente en árboles independientes implicaba crear varias versiones de cada nodo intermedio para cada clase de dispositivo en las versiones anteriores de SUSE Enterprise Storage.
17.1.1.2 Clases de dispositivos #
Una solución elegante que ofrece Ceph es añadir una propiedad denominada clase de dispositivo a cada OSD. Por defecto, los OSD definirán automáticamente sus clases de dispositivo como "hdd", "ssd" o "nvme", en función de las propiedades de hardware expuestas por el kernel de Linux. Estas clases de dispositivo se indican en una columna nueva del resultado del comando ceph osd tree
:
cephuser@adm >
ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 83.17899 root default
-4 23.86200 host cpach
2 hdd 1.81898 osd.2 up 1.00000 1.00000
3 hdd 1.81898 osd.3 up 1.00000 1.00000
4 hdd 1.81898 osd.4 up 1.00000 1.00000
5 hdd 1.81898 osd.5 up 1.00000 1.00000
6 hdd 1.81898 osd.6 up 1.00000 1.00000
7 hdd 1.81898 osd.7 up 1.00000 1.00000
8 hdd 1.81898 osd.8 up 1.00000 1.00000
15 hdd 1.81898 osd.15 up 1.00000 1.00000
10 nvme 0.93100 osd.10 up 1.00000 1.00000
0 ssd 0.93100 osd.0 up 1.00000 1.00000
9 ssd 0.93100 osd.9 up 1.00000 1.00000
Si se produce un error al detectar automáticamente la clase de dispositivo, por ejemplo porque el controlador del dispositivo no exponga correctamente la información sobre el dispositivo mediante /sys/block
, puede ajustar las clases de dispositivo desde la línea de comandos:
cephuser@adm >
ceph osd crush rm-device-class osd.2 osd.3 done removing class of osd(s): 2,3cephuser@adm >
ceph osd crush set-device-class ssd osd.2 osd.3 set osd(s) 2,3 to class 'ssd'
17.1.1.3 Definición de las reglas de colocación de CRUSH #
Las reglas de CRUSH pueden restringir la colocación a una clase de dispositivo específica. Por ejemplo, puede crear un repositorio "fast" (rápido) replicado que distribuya datos solo a través de discos SSD ejecutando el siguiente comando:
cephuser@adm >
ceph osd crush rule create-replicated RULE_NAME ROOT FAILURE_DOMAIN_TYPE DEVICE_CLASS
Por ejemplo:
cephuser@adm >
ceph osd crush rule create-replicated fast default host ssd
Cree un repositorio denominado "fast_pool" y asígnelo a la regla "fast":
cephuser@adm >
ceph osd pool create fast_pool 128 128 replicated fast
El proceso para crear reglas codificadas de borrado es ligeramente diferente. En primer lugar, cree un perfil codificado de borrado que incluya una propiedad para la clase de dispositivo deseada. A continuación, utilice ese perfil al crear el repositorio codificado de borrado:
cephuser@adm >
ceph osd erasure-code-profile set myprofile \ k=4 m=2 crush-device-class=ssd crush-failure-domain=hostcephuser@adm >
ceph osd pool create mypool 64 erasure myprofile
En caso de que necesite editar manualmente el mapa de CRUSH para personalizar la regla, la sintaxis se ha ampliado para permitir que se especifique la clase de dispositivo. Por ejemplo, la regla de CRUSH generada por los comandos anteriores tiene el siguiente aspecto:
rule ecpool {
id 2
type erasure
min_size 3
max_size 6
step set_chooseleaf_tries 5
step set_choose_tries 100
step take default class ssd
step chooseleaf indep 0 type host
step emit
}
La diferencia importante aquí es que el comando "take" incluye el sufijo adicional "class NOMBRE_CLASE".
17.1.1.4 Comandos adicionales #
Para mostrar las clases de dispositivo utilizadas en un mapa de CRUSH, ejecute:
cephuser@adm >
ceph osd crush class ls
[
"hdd",
"ssd"
]
Para mostrar las reglas de CRUSH existentes, ejecute:
cephuser@adm >
ceph osd crush rule ls
replicated_rule
fast
Para ver los detalles de la regla de CRUSH denominada "fast", ejecute:
cephuser@adm >
ceph osd crush rule dump fast
{
"rule_id": 1,
"rule_name": "fast",
"ruleset": 1,
"type": 1,
"min_size": 1,
"max_size": 10,
"steps": [
{
"op": "take",
"item": -21,
"item_name": "default~ssd"
},
{
"op": "chooseleaf_firstn",
"num": 0,
"type": "host"
},
{
"op": "emit"
}
]
}
Para mostrar los OSD que pertenecen a una clase "ssd", ejecute:
cephuser@adm >
ceph osd crush class ls-osd ssd
0
1
17.1.1.5 Migración de una regla de SSD heredada a las clases de dispositivos #
En versiones de SUSE Enterprise Storage anteriores a la 5 era necesario editar manualmente el mapa de CRUSH y mantener una jerarquía paralela para cada tipo de dispositivo especializado (como SSD) para poder escribir reglas que se aplicaran a esos dispositivos. Desde SUSE Enterprise Storage 5, la característica de clase de dispositivo hace que escribir esas reglas se pueda hacer de forma transparente.
Es posible transformar una regla y una jerarquía heredadas a las nuevas reglas basadas en clases mediante el comando crushtool
. Hay varios tipos de transformación posibles:
crushtool ‑‑reclassify‑root ROOT_NAME DEVICE_CLASS
Este comando toma todos los elementos de la jerarquía situados bajo ROOT_NAME (nombre de raíz) y ajusta las reglas que hacen referencia a esa raíz mediante
take ROOT_NAME
y las sustituya por
take ROOT_NAME class DEVICE_CLASS
Vuelve a numerar los depósitos para que los ID anteriores se utilicen para el "árbol paralelo" de la clase especificada. Como consecuencia, no se produce ningún movimiento de datos.
Ejemplo 17.1:crushtool ‑‑reclassify‑root
#Veamos la siguiente regla existente:
rule replicated_ruleset { id 0 type replicated min_size 1 max_size 10 step take default step chooseleaf firstn 0 type rack step emit }
Si reclasifica la raíz "default" como clase "hdd", la regla se convertirá en:
rule replicated_ruleset { id 0 type replicated min_size 1 max_size 10 step take default class hdd step chooseleaf firstn 0 type rack step emit }
crushtool ‑‑set‑subtree‑class BUCKET_NAME DEVICE_CLASS
Este método marca todos los dispositivos del subárbol enraizados en BUCKET_NAME con la clase de dispositivo especificada.
‑‑set-subtree-class
se utiliza normalmente junto con la opción‑‑reclassify-root
para garantizar que todos los dispositivos de esa raíz están etiquetados con la clase correcta. Sin embargo, algunos de esos dispositivos pueden tener una clase diferente de forma intencionada y, por lo tanto, no desea volver a etiquetarlos. En tales casos, excluya la opción‑‑set-subtree-class
. Tenga en cuenta que dicha reasignación no será perfecta, ya que la regla anterior se distribuye entre dispositivos de varias clases, pero las reglas ajustadas solo se asignan a los dispositivos de la clase de dispositivo especificada.crushtool ‑‑reclassify‑bucket MATCH_PATTERN DEVICE_CLASS DEFAULT_PATTERN
Este método permite combinar una jerarquía paralela específica de tipo con la jerarquía normal. Por ejemplo, muchos usuarios tienen mapas de CRUSH similares a los siguientes:
Ejemplo 17.2:crushtool ‑‑reclassify‑bucket
#host node1 { id -2 # do not change unnecessarily # weight 109.152 alg straw hash 0 # rjenkins1 item osd.0 weight 9.096 item osd.1 weight 9.096 item osd.2 weight 9.096 item osd.3 weight 9.096 item osd.4 weight 9.096 item osd.5 weight 9.096 [...] } host node1-ssd { id -10 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.80 weight 2.000 [...] } root default { id -1 # do not change unnecessarily alg straw hash 0 # rjenkins1 item node1 weight 110.967 [...] } root ssd { id -18 # do not change unnecessarily # weight 16.000 alg straw hash 0 # rjenkins1 item node1-ssd weight 2.000 [...] }
Esta función reclasifica cada depósito que coincide con un patrón determinado. El patrón puede ser de tipo
%sufijo
oprefijo%
. En el ejemplo anterior, se usaría el patrón%-ssd
. Para cada depósito coincidente, la parte restante del nombre que coincida con el comodín "%" especifica el depósito base. Todos los dispositivos del depósito coincidente se etiquetan con la clase de dispositivo especificada y, a continuación, se mueven al depósito base. Si el depósito base no existe (por ejemplo, si "node12-ssd" existe, pero "node12" no), se crea y se vincula debajo del depósito padre por defecto especificado. Los ID de depósito antiguos se conservan para los nuevos depósitos paralelos a fin de evitar que haya que mover datos. Las reglas con los pasostake
(tomar) que hagan referencia a depósitos antiguos se ajustan.crushtool ‑‑reclassify‑bucket BUCKET_NAME DEVICE_CLASS BASE_BUCKET
Puede utilizar la opción
‑‑reclassify-bucket
sin un comodín para asignar un solo depósito. Por ejemplo, en el ejemplo anterior, queremos que el depósito "ssd" se asigne al depósito por defecto.El comando final para convertir el mapa compuesto por los fragmentos anteriores sería el siguiente:
cephuser@adm >
ceph osd getcrushmap -o originalcephuser@adm >
crushtool -i original --reclassify \ --set-subtree-class default hdd \ --reclassify-root default hdd \ --reclassify-bucket %-ssd ssd default \ --reclassify-bucket ssd ssd default \ -o adjustedPara verificar que la conversión sea correcta, hay una opción
‑‑compare
que prueba una muestra cuantiosa de entradas al mapa de CRUSH y comprueba si vuelve a salir el mismo resultado. Estas entradas se controlan mediante las mismas opciones que se aplican a‑‑test
. Para el ejemplo anterior, el comando sería el siguiente:cephuser@adm >
crushtool -i original --compare adjusted rule 0 had 0/10240 mismatched mappings (0) rule 1 had 0/10240 mismatched mappings (0) maps appear equivalentSugerenciaSi hubiera diferencias, vería qué proporción de entradas se reasignan entre paréntesis.
Si el mapa de CRUSH ajustado es el que desea, puede aplicarlo al clúster:
cephuser@adm >
ceph osd setcrushmap -i adjusted
17.1.1.6 información adicional #
Encontrará más detalles sobre los mapas de CRUSH en la Sección 17.5, “Manipulación del mapa de CRUSH”.
Encontrará más detalles sobre los repositorios de Ceph en general en el Capítulo 18, Gestión de repositorios de almacenamiento.
Encontrará más detalles sobre los repositorios codificados de borrado en el Capítulo 19, Repositorios codificados de borrado.
17.2 Depósitos #
Los mapas de CRUSH contienen una lista de los OSD, que se pueden organizar en una estructura de árbol de los depósitos para agregar los dispositivos en ubicaciones físicas. Los OSD individuales forman las hojas del árbol.
0 |
osd |
Un dispositivo u OSD específico ( |
1 |
host |
El nombre de un host que contiene uno o más OSD. |
2 |
chassis |
Identificador del chasis del bastidor que contiene el |
3 |
rack |
El bastidor de un equipo. El valor por defecto es |
4 |
row |
Una fila de una serie de bastidores. |
5 |
pdu |
Abreviatura de "Power Distribution Unit", unidad de distribución de energía. |
6 |
pod |
Abreviatura de "Point of Delivery", punto de entrega. En este contexto, un grupo de PDU o un grupo de filas de bastidores. |
7 |
room |
Una sala que contiene filas de bastidores. |
8 |
datacenter |
Un centro de datos físico que contiene una o más salas. |
9 |
region |
Región geográfica del mundo (por ejemplo, NAM, LAM, EMEA, APAC, etc.). |
10 |
root |
El nodo raíz del árbol de depósitos OSD (normalmente definido como |
Puede modificar los tipos existentes y crear los suyos propios.
Las herramientas de distribución de Ceph generan un mapa de CRUSH que contiene un depósito para cada host y una raíz denominada "default", lo que resulta útil para el repositorio rbd
por defecto. El resto de tipos de depósitos ofrecen un medio para almacenar información acerca de la ubicación física de los nodos/depósitos, lo que facilita la administración del clúster cuando los OSD, los hosts, o el hardware de red funcionan erróneamente y el administrador necesita acceder al hardware físico.
Una depósito tiene un tipo, un nombre exclusivo (cadena), un ID único que se expresa como un número entero negativo, un peso relativo a la capacidad total dividida entre la capacidad de sus elementos, el algoritmo de depósito (por defecto, straw2
) y el hash (0
por defecto, que refleja el hash de CRUSH rjenkins1
). Un depósito puede tener uno o varios elementos. Los elementos pueden estar formados por otros depósitos o por OSD. Los elementos pueden tener un peso relativo.
[bucket-type] [bucket-name] { id [a unique negative numeric ID] weight [the relative capacity/capability of the item(s)] alg [the bucket type: uniform | list | tree | straw2 | straw ] hash [the hash type: 0 by default] item [item-name] weight [weight] }
En el siguiente ejemplo se muestra cómo se pueden utilizar depósitos para agregar un repositorio y ubicaciones físicas como un centro de datos, una sala, un bastidor y una fila.
host ceph-osd-server-1 { id -17 alg straw2 hash 0 item osd.0 weight 0.546 item osd.1 weight 0.546 } row rack-1-row-1 { id -16 alg straw2 hash 0 item ceph-osd-server-1 weight 2.00 } rack rack-3 { id -15 alg straw2 hash 0 item rack-3-row-1 weight 2.00 item rack-3-row-2 weight 2.00 item rack-3-row-3 weight 2.00 item rack-3-row-4 weight 2.00 item rack-3-row-5 weight 2.00 } rack rack-2 { id -14 alg straw2 hash 0 item rack-2-row-1 weight 2.00 item rack-2-row-2 weight 2.00 item rack-2-row-3 weight 2.00 item rack-2-row-4 weight 2.00 item rack-2-row-5 weight 2.00 } rack rack-1 { id -13 alg straw2 hash 0 item rack-1-row-1 weight 2.00 item rack-1-row-2 weight 2.00 item rack-1-row-3 weight 2.00 item rack-1-row-4 weight 2.00 item rack-1-row-5 weight 2.00 } room server-room-1 { id -12 alg straw2 hash 0 item rack-1 weight 10.00 item rack-2 weight 10.00 item rack-3 weight 10.00 } datacenter dc-1 { id -11 alg straw2 hash 0 item server-room-1 weight 30.00 item server-room-2 weight 30.00 } root data { id -10 alg straw2 hash 0 item dc-1 weight 60.00 item dc-2 weight 60.00 }
17.3 Conjuntos de reglas #
Los mapas de CRUSH admiten la noción de "reglas de CRUSH", que son las reglas que determinan la colocación de los datos de un repositorio. En clústeres de gran tamaño, es probable que cree muchos repositorios y que cada uno de ellos tenga sus propios conjuntos de reglas y reglas de CRUSH. El mapa de CRUSH por defecto tiene una regla para la raíz por defecto. Si desea más raíces y más reglas, debe crearlas más adelante o se crearán automáticamente cuando se creen nuevos repositorios.
En la mayoría de los casos, no será necesario modificar las reglas por defecto. Cuando se crea un repositorio nuevo, el conjunto de reglas por defecto es 0.
Una regla tiene el siguiente formato:
rule rulename { ruleset ruleset type type min_size min-size max_size max-size step step }
- ruleset
Un número entero. Clasifica una regla para que pertenezca a un conjunto de reglas. Se activa definiendo el conjunto de reglas en un repositorio. Esta opción es obligatoria. El valor por defecto es
0
.- type
Una cadena. Describe una regla para un repositorio codificado de réplica ("replicated)" o de borrado ("erasure"). Esta opción es obligatoria. El valor por defecto es
replicated
(replicada).- min_size
Un número entero. Si un grupo de repositorios realiza un número inferior de réplicas que el indicado por este número, CRUSH NO selecciona esta regla. Esta opción es obligatoria. El valor por defecto es
2
.- max_size
Un número entero. Si un grupo de repositorios realiza un número superior de réplicas que el indicado por este número, CRUSH NO selecciona esta regla. Esta opción es obligatoria. El valor por defecto es
10
.- step take bucket
Toma un depósito especificado por su nombre e inicia una iteración hacia abajo por el árbol. Esta opción es obligatoria. Para obtener una explicación acerca de la iteración por el árbol, consulte la Sección 17.3.1, “Iteración del árbol de nodos”.
- step targetmodenum type bucket-type
target puede ser
choose
ochooseleaf
. Si se define comochoose
, se seleccionan varios depósitos.chooseleaf
selecciona directamente los OSD (nodos hoja) del subárbol de cada depósito en el conjunto de depósitos.mode puede ser
firstn
oindep
. Consulte la Sección 17.3.2, “firstn e indep
”.
Selecciona el número de depósitos del tipo especificado. Donde N es el número de opciones disponibles, si num > 0 && < N, seleccione ese número de depósitos; si num < 0, significa N - num; y si num == 0, selecciona N depósitos (todos los disponibles). Se usa después de
step take
o astep choose
.- step emit
Devuelve el valor actual y vacía la pila. Se suele usar al final de una regla, pero también puede utilizarse para formar árboles diferentes en la misma regla. Se usa después de
step choose
.
17.3.1 Iteración del árbol de nodos #
La estructura definida con los depósitos se puede ver como un árbol de nodos. Los depósitos son nodos y los OSD son hojas de ese árbol.
Las reglas del mapa de CRUSH definen cómo se seleccionan los OSD del árbol. Una regla empieza con un nodo y se itera hacia abajo por el árbol para devolver un conjunto de OSD. No es posible definir la rama que se debe seleccionar. En su lugar, el algoritmo CRUSH garantiza que el conjunto de OSD cumple los requisitos de réplica y distribuye los datos de forma homogénea.
Con step take
bucket, la iteración por el árbol de nodos comienza en el depósito indicado (no en el tipo de depósito). Si se deben devolver OSD de todas las ramas del árbol, se debe indicar el depósito raíz. De lo contrario, la iteración de los pasos siguientes solo se producirá por un subárbol.
Después de step take
, se usan una o varias entradas step choose
en la definición de la regla. Cada step choose
elige un número definido de nodos (o ramas) del nodo superior seleccionado anteriormente.
Al final, los OSD seleccionados se devuelven con step emit
.
step chooseleaf
es una función de conveniencia que selecciona directamente los OSD de ramas de un depósito determinado.
En la Figura 17.2, “Árbol de ejemplo” se proporciona un ejemplo de cómo se usa step
para producir la iteración por un árbol. Las flechas naranjas y los números corresponden a example1a
y example1b
, mientras que las azules corresponden a example2
en las siguientes definiciones de regla.
# orange arrows rule example1a { ruleset 0 type replicated min_size 2 max_size 10 # orange (1) step take rack1 # orange (2) step choose firstn 0 host # orange (3) step choose firstn 1 osd step emit } rule example1b { ruleset 0 type replicated min_size 2 max_size 10 # orange (1) step take rack1 # orange (2) + (3) step chooseleaf firstn 0 host step emit } # blue arrows rule example2 { ruleset 0 type replicated min_size 2 max_size 10 # blue (1) step take room1 # blue (2) step chooseleaf firstn 0 rack step emit }
17.3.2
firstn e indep
#
Una regla de CRUSH define las sustituciones de los nodos o los OSD que fallan (consulte la Sección 17.3, “Conjuntos de reglas”). La palabra clave step
requiere el parámetro firstn
o indep
. En la Figura 17.3, “Métodos de sustitución de nodos” se muestra un ejemplo.
Con firstn
se añaden nodos de sustitución al final de la lista de nodos activos. En el caso de un nodo que ha fallado, los nodos en buen estado siguientes se desplazan a la izquierda para cubrir el hueco del nodo erróneo. Se trata del método por defecto, y el recomendado, para los repositorios replicados, ya que un nodo secundario ya tiene todos los datos y, por lo tanto, puede hacerse cargo de las tareas del nodo principal de inmediato.
Con indep
se seleccionan nodos de sustitución fijos para cada nodo activo. La sustitución de un nodo con fallos no cambia el orden de los nodos restantes. Este es el comportamiento recomendado para los repositorios codificados de borrado. En los repositorios codificados de borrado, los datos almacenados en un nodo dependen de su posición en la selección de nodos. Cuando se cambia el orden de los nodos, todos los datos de los nodos afectados deben recolocarse.
17.4 Grupos de colocación #
Ceph asigna objetos a los grupos de colocación. Los grupos de colocación son fragmentos de un repositorio de objetos lógicos que colocan objetos como un grupo en los OSD. Los grupos de colocación reducen la cantidad de metadatos por objeto cuando Ceph almacena los datos en los OSD. Disponer de un mayor número de grupos de colocación (por ejemplo, 100 por OSD) produce que haya un mejor equilibrio.
17.4.1 Uso de los grupos de colocación #
Un grupo de colocación (PG) agrega objetos dentro de un repositorio. La razón principal es que realizar un seguimiento de la ubicación de los objetos y de los metadatos de cada objeto es costoso desde el punto de vista computacional. Por ejemplo, un sistema con millones de objetos no puede realizar directamente un seguimiento de la ubicación de cada uno de esos objetos.
El cliente de Ceph calculará a qué grupo de colocación pertenecerá un objeto. Para ello, aplica el hash del ID de objeto y aplica una operación basada en el número grupos de colocación del repositorio definido y el ID del repositorio.
El contenido de un objeto situado dentro de un grupo de colocación se almacena en un conjunto de OSDs. Por ejemplo, en un repositorio replicado con un tamaño de dos, cada grupo de colocación almacenará objetos en dos OSD:
Si se produce un error en el OSD 2, otro OSD se asignará al grupo de colocación 1 y se rellenará con copias de todos los objetos de OSD 1. Si el tamaño del repositorio cambia de dos a tres, se asignará un OSD adicional al grupo de colocación y recibirá copias de todos los objetos del grupo de colocación.
Los grupos de colocación no son propietarios del OSD; lo comparten con otros grupos de colocación del mismo repositorio, o incluso con otros repositorios. Si se produce un error en el OSD 2, el grupo de colocación 2 también tendrá que restaurar copias de los objetos, mediante el OSD 3.
Cuando aumenta el número de grupos de colocación, se asignan OSD a los nuevos grupos de colocación. El resultado de la función CRUSH también cambia y algunos objetos de los grupos de colocación anteriores se copian en los nuevos grupos de colocación y se eliminan de los antiguos.
17.4.2 Determinación del valor de PG_NUM #
Desde Ceph Nautilus (v14.x), puede utilizar el módulo pg_autoscaler
de Ceph Manager para escalar automáticamente los grupos de colocación según sea necesario. Si desea habilitar esta función, consulte el Section 8.1.1.1, “Default PG and PGP counts”.
Al crear un repositorio nuevo, se puede elegir el valor de PG_NUM manualmente:
#
ceph osd pool create POOL_NAME PG_NUM
El valor de PG_NUM no se puede calcular automáticamente. A continuación se muestran algunos valores de uso común según el número de OSDs del clúster:
- Menos de 5 OSD:
En PG_NUM, defina el valor 128.
- Entre 5 y 10 OSD:
En PG_NUM, defina el valor 512.
- Entre 10 y 50 OSD:
En PG_NUM, defina el valor 1024.
A medida que aumenta el número de OSD, seleccionar el valor adecuado para PG_NUM se vuelve cada vez más importante. El valor de PG_NUM afecta considerablemente al comportamiento del clúster, así como a la durabilidad de los datos en caso de error del OSD.
17.4.2.1 Cálculo de los grupos de colocación para más de 50 OSD #
Si tiene menos de 50 OSD, utilice el valor preseleccionado descrito en la Sección 17.4.2, “Determinación del valor de PG_NUM”. Si tiene más de 50 OSD, se recomienda disponer de entre 50 y 100 grupos de colocación por OSD para equilibrar el uso de los recursos, la durabilidad de los datos y la distribución. Para un único repositorio de objetos, puede utilizar la siguiente fórmula para obtener una línea base:
total PGs = (OSDs * 100) / POOL_SIZE
Donde POOL_SIZE es el número de réplicas para repositorios replicados o la suma "k"+"m" para lo repositorios codificados de borrado, según el resultado del comando ceph osd erasure-code-profile get
. Debe redondear el resultado hasta la potencia más cercana de 2. Se recomienda redondear hacia arriba para que el algoritmo CRUSH equilibre uniformemente el número de objetos entre los grupos de colocación.
Por ejemplo, para un clúster con 200 OSD y un tamaño de repositorio de 3 réplicas, el número de grupos de colocación se calcularía de la siguiente manera:
(200 * 100) / 3 = 6667
La potencia más cercana de 2 es 8192.
Si se usan varios repositorios de datos para almacenar objetos, debe equilibrar el número de grupos de colocación por repositorio con el número de grupos de colocación por OSD. Se debe alcanzar un número total razonable de grupos de colocación que proporcione una varianza razonablemente baja por OSD sin que afecte negativamente a los recursos del sistema ni provocar que el proceso de emparejamiento sea demasiado lento.
Por ejemplo, un clúster de 10 repositorios, cada uno con 512 grupos de colocación en 10 OSD da un total de 5120 grupos de colocación repartidos en 10 OSD; es decir, 512 grupos de colocación por OSD. Tal configuración no utilizaría demasiados recursos. Sin embargo, si se crearan 1000 repositorios con 512 grupos de colocación cada uno, los OSD controlarían aproximadamente 50 000 grupos de colocación cada uno y requerirían muchos más recursos y tiempo para el emparejamiento.
17.4.3 Definición del número de grupos de colocación #
Desde Ceph Nautilus (v14.x), puede utilizar el módulo pg_autoscaler
de Ceph Manager para escalar automáticamente los grupos de colocación según sea necesario. Si desea habilitar esta función, consulte el Section 8.1.1.1, “Default PG and PGP counts”.
Si aún necesita especificar el número de grupos de colocación en un repositorio manualmente, deberá especificarlos en el momento en el que cree el repositorio (consulte la Sección 18.1, “Creación de un repositorio”). Después de haber establecido los grupos de colocación para un repositorio, puede aumentar el número de grupos de colocación ejecutando el comando siguiente:
#
ceph osd pool set POOL_NAME pg_num PG_NUM
Después de aumentar el número de grupos de colocación, también debe aumentar el número de grupos de colocación de la ubicación (PGP_NUM
) antes de que el clúster se reequilibre. El valor de PGP_NUM
será el número de grupos de colocación que el algoritmo CRUSH tendrá en cuenta para la colocación. Al aumentar el valor de PG_NUM
, se dividen los grupos de colocación, pero los datos no se migran a los grupos de colocación más recientes hasta que se aumenta este valor de PG_NUM
. El valor de PGP_NUM
debe ser igual al de PG_NUM
. Para aumentar el número de grupos de colocación de la ubicación, ejecute lo siguiente:
#
ceph osd pool set POOL_NAME pgp_num PGP_NUM
17.4.4 Obtención del número de grupos de colocación #
Para averiguar el número de grupos de colocación de un repositorio, ejecute el comando get
siguiente:
#
ceph osd pool get POOL_NAME pg_num
17.4.5 Obtención de estadísticas del grupo de colocación de un clúster #
Para obtener las estadísticas de los grupos de colocación del clúster, ejecute el comando siguiente:
#
ceph pg dump [--format FORMAT]
Los formatos válidos son "plain" (por defecto) y "json".
17.4.6 Obtención de estadísticas de los grupos de colocación atascados #
Para obtener las estadísticas de todos los grupos de colocación atascados en un estado especificado, ejecute lo siguiente:
#
ceph pg dump_stuck STATE \
[--format FORMAT] [--threshold THRESHOLD]
El valor de STATE puede ser "inactive" (inactivo, los grupos de colocación no pueden procesar lecturas ni escrituras porque están a la espera de que aparezca un OSD con los datos más actualizados), "unclean" (no limpio, los grupos de colocación contienen objetos que no se replican el número deseado de veces), "stale" (obsoleto, los grupos de colocación están en un estado desconocido: los OSD donde se alojan no han informado al clúster de supervisión en un intervalo de tiempo especificado por la opción mon_osd_report_timeout
, "undersized" (tamaño insuficiente) o "degraded" (degradado).
Los formatos válidos son "plain" (por defecto) y "json".
El umbral define el número mínimo de segundos que el grupo de colocación debe estar atascado antes de que se incluya en las estadísticas (300 segundos por defecto).
17.4.7 Búsqueda de un mapa de grupos de colocación #
Para obtener el mapa de un grupo de colocación determinado, ejecute lo siguiente:
#
ceph pg map PG_ID
Ceph devolverá el mapa del grupo de colocación, el grupo de colocación y el estado del OSD:
#
ceph pg map 1.6c
osdmap e13 pg 1.6c (1.6c) -> up [1,0] acting [1,0]
17.4.8 Obtención de estadísticas de los grupos de colocación #
Para recuperar estadísticas de un grupo de colocación determinado, ejecute lo siguiente:
#
ceph pg PG_ID query
17.4.9 Depuración de un grupo de colocación #
Para borrar de forma segura un grupo de colocación (Sección 17.6, “Depuración de grupos de colocación”), ejecute lo siguiente:
#
ceph pg scrub PG_ID
Ceph comprueba los nodos primario y de réplica, genera un catálogo de todos los objetos del grupo de colocación y los compara para asegurarse de que no falta ningún objeto, que no coinciden y que su contenido es coherente. Suponiendo que todas las réplicas coincidan, un barrido semántico final garantiza que todos los metadatos de objetos relacionados con instantáneas sean coherentes. Los errores se notifican a través de los registros.
17.4.10 Priorización de la reposición y la recuperación de los grupos de colocación #
Puede encontrarse con una situación en la que varios grupos de colocación requieran una recuperación o una reposición, y algunos grupos contienen datos más importantes que otros. Por ejemplo, unos grupos de colocación pueden contener datos para las imágenes utilizadas por las máquinas en ejecución, mientras que otros pueden ser utilizados por máquinas inactivas o contener datos menos relevantes. En este caso, es posible que desee dar prioridad a la recuperación de los primeros grupos para que el rendimiento y la disponibilidad de los datos almacenados en aquellos grupos se restaure antes. Para marcar grupos de colocación concretos como prioritarios durante la reposición o la recuperación, ejecute lo siguiente:
#
ceph pg force-recovery PG_ID1 [PG_ID2 ... ]#
ceph pg force-backfill PG_ID1 [PG_ID2 ... ]
Esto hará que Ceph lleve a cabo la recuperación o la reposición en los grupos de colocación especificados, antes que en los demás. No se interrumpen las operaciones de reposición o recuperación que haya en curso, sino que los grupos de colocación especificados se procesan lo antes posible. Si cambia de opinión o se equivoca de grupo para priorizar, puede cancelar la priorización:
#
ceph pg cancel-force-recovery PG_ID1 [PG_ID2 ... ]#
ceph pg cancel-force-backfill PG_ID1 [PG_ID2 ... ]
Los comandos cancel‑*
eliminan el indicador "force" de los grupos de colocación para que se procesen en el orden por defecto. Una vez más, esto no afecta a los grupos de colocación que ya se están procesando, solo a los que todavía están en cola. El indicador "force" se borra automáticamente después de que se realice la recuperación o la reposición del grupo.
17.4.11 Reversión de objetos perdidos #
Si el clúster ha perdido uno o más objetos y ha decidido abandonar la búsqueda de los datos perdidos, debe marcar los objetos no encontrados como "perdidos".
Si los objetos siguen perdidos después de haber consultado todas las ubicaciones posibles, es posible que deba darlos definitivamente por perdidos. Esto puede ocurrir si se da una combinación inusual de errores en la que se permite al clúster obtener información sobre las escrituras que se realizaron antes de que se recuperaran las escrituras en sí.
Actualmente, la única opción admitida es "revert", que revertirá a una versión anterior del objeto, o que se ignorará por completo en caso de un objeto nuevo. Para marcar los objetos "unfound" (no encontrados) como "lost" (perdidos), ejecute lo siguiente:
cephuser@adm >
ceph pg PG_ID mark_unfound_lost revert|delete
17.4.12 Habilitación del escalador automático de grupos de colocación #
Los grupos de colocación (PG) son un detalle de implementación interno de cómo Ceph distribuye los datos. Al habilitar pg-autoscaling, puede permitir que el clúster cree o ajuste automáticamente los grupos de colocación en función de cómo se utilice el clúster.
Cada repositorio del sistema tiene una propiedad pg_autoscale_mode
que se puede establecer en off
, on
o warn
:
El escalador automático se configura para cada repositorio y se puede ejecutar en tres modos:
- off
Inhabilita la escala automática para este repositorio. Depende del administrador elegir un número de grupos de colocación adecuado para cada repositorio.
- on
Habilita los ajustes automáticos del recuento de grupos de colocación para el repositorio indicado.
- warn
Genera alertas de estado que indican cuando se debe ajustar el recuento de grupos de colocación.
Para definir el modo escala automático para los repositorios existentes:
cephuser@adm >
ceph osd pool set POOL_NAME pg_autoscale_mode mode
También puede configurar la propiedad por defecto de pg_autoscale_mode
que se aplica a cualquier repositorio que se cree en el futuro con:
cephuser@adm >
ceph config set global osd_pool_default_pg_autoscale_mode MODE
Puede ver cada repositorio, su utilización relativa y los cambios sugeridos en el recuento de grupos de colocación con este comando:
cephuser@adm >
ceph osd pool autoscale-status
17.5 Manipulación del mapa de CRUSH #
En esta sección se describen formas para manipular de forma básica el mapa de CRUSH: por ejemplo, para editar un mapa de CRUSH; cambiar los parámetros del mapa de CRUSH y añadir, mover o eliminar un OSD.
17.5.1 Edición de un mapa de CRUSH #
Para editar un mapa de CRUSH existente, haga lo siguiente:
Obtenga un mapa de CRUSH. Para obtener el mapa de CRUSH de su clúster, ejecute lo siguiente:
cephuser@adm >
ceph osd getcrushmap -o compiled-crushmap-filenameCeph da como resultado (
-o
) un mapa de CRUSH compilado con el nombre de archivo que especifique. Puesto que el mapa de CRUSH está compilado, debe descompilarlo antes de que se pueda editar.Descompilación de un mapa de CRUSH. Para descompilar un mapa de CRUSH, ejecute lo siguiente:
cephuser@adm >
crushtool -d compiled-crushmap-filename \ -o decompiled-crushmap-filenameCeph descompilará (
-d
) el mapa de CRUSH compilado y lo obtendrá como resultado (‑o
) con el nombre de archivo que especifique.Edite al menos uno de los parámetros de dispositivos, depósitos o reglas.
Compile un mapa de CRUSH. Para hacerlo, ejecute lo siguiente:
cephuser@adm >
crushtool -c decompiled-crush-map-filename \ -o compiled-crush-map-filenameCeph almacenará un mapa de CRUSH compilado con el nombre de archivo que especifique.
Defina un mapa de CRUSH. Para definir el mapa de CRUSH de su clúster, ejecute lo siguiente:
cephuser@adm >
ceph osd setcrushmap -i compiled-crushmap-filenameCeph introducirá el mapa de CRUSH compilado con el nombre de archivo que ha especificado como el mapa de CRUSH del clúster.
Utilice un sistema de control de versiones, como git o svn, para los archivos de mapa de CRUSH exportados y modificados. Con ellos, una posible reversión es más sencilla.
Pruebe el nuevo mapa de CRUSH ajustado con el comando crushtool ‑‑test
y compárelo con el estado anterior a la aplicación del nuevo mapa de CRUSH. Encontrará útiles los siguientes conmutadores de comandos: ‑‑show‑statistics
, ‑‑show‑mappings
, ‑‑show‑bad‑mappings
, ‑‑show‑utilization
, ‑‑show‑utilization‑all
, ‑‑show‑choose‑tries
.
17.5.2 Adición o traslado de un OSD #
Para añadir o trasladar un OSD en el mapa de CRUSH de un clúster en ejecución, ejecute lo siguiente:
cephuser@adm >
ceph osd crush set id_or_name weight root=pool-name
bucket-type=bucket-name ...
- id
Un número entero. El ID numérico del OSD. Esta opción es obligatoria.
- name
Una cadena. El nombre completo del OSD. Esta opción es obligatoria.
- weight
Un valor doble. El peso de CRUSH para el OSD. Esta opción es obligatoria.
- root
Un par de clave y valor. Por defecto, la jerarquía de CRUSH contiene como raíz el repositorio por defecto. Esta opción es obligatoria.
- bucket-type
Pares clave-valor. Puede especificar la ubicación del OSD en la jerarquía de CRUSH.
El ejemplo siguiente añade osd.0
a la jerarquía, o traslada el OSD desde una ubicación anterior.
cephuser@adm >
ceph osd crush set osd.0 1.0 root=data datacenter=dc1 room=room1 \
row=foo rack=bar host=foo-bar-1
17.5.3 Diferencia entre ceph osd reweight
y ceph osd crush reweight
#
Hay dos comandos similares que cambian el "peso" de un Ceph OSD. El contexto en el que se usan es diferente y puede causar confusión.
17.5.3.1 ceph osd reweight
#
Uso:
cephuser@adm >
ceph osd reweight OSD_NAME NEW_WEIGHT
ceph osd reweight
define un peso de sustitución en el Ceph OSD. Este valor está en el intervalo entre 0 y 1 e impone a CRUSH que recoloque los datos que de otro modo estarían en esta unidad. No cambia los pesos asignados a los depósitos situados por encima del OSD. Se trata de una medida correctiva en caso de que la distribución normal de CRUSH no funcione del todo bien. Por ejemplo, si uno de los OSD está al 90 % y los demás están al 40 %, podría reducir este peso para tratar de compensarlos.
Tenga en cuenta que ceph osd reweight
no es un ajuste persistente. Cuando un OSD se excluye, su peso se define en 0, y cuando se incluye de nuevo, el peso cambia a 1.
17.5.3.2 ceph osd crush reweight
#
Uso:
cephuser@adm >
ceph osd crush reweight OSD_NAME NEW_WEIGHT
El valor ceph osd crush reweight
permite definir el peso de CRUSH del OSD. Este peso es un valor arbitrario (generalmente el tamaño del disco en TB) y controla la cantidad de datos que el sistema intenta asignar al OSD.
17.5.4 Eliminación de un OSD #
Para eliminar un OSD del mapa de CRUSH de un clúster en ejecución, ejecute lo siguiente:
cephuser@adm >
ceph osd crush remove OSD_NAME
17.5.5 Adición de un depósito #
Para añadir un depósito al mapa de CRUSH de un clúster en ejecución, ejecute el comando ceph osd crush add-bucket
:
cephuser@adm >
ceph osd crush add-bucket BUCKET_NAME BUCKET_TYPE
17.5.6 Traslado de un depósito #
Para trasladar un depósito a una ubicación diferente o colocarlo en la jerarquía del mapa de CRUSH, ejecute lo siguiente:
cephuser@adm >
ceph osd crush move BUCKET_NAME BUCKET_TYPE=BUCKET_NAME [...]
Por ejemplo:
cephuser@adm >
ceph osd crush move bucket1 datacenter=dc1 room=room1 row=foo rack=bar host=foo-bar-1
17.5.7 Eliminación de un depósito #
Para eliminar un depósito de la jerarquía del mapa de CRUSH, ejecute lo siguiente:
cephuser@adm >
ceph osd crush remove BUCKET_NAME
un depósito debe estar vacío para que se pueda eliminar de la jerarquía de CRUSH.
17.6 Depuración de grupos de colocación #
Además de realizar varias copias de los objetos, Ceph garantiza la integridad de los datos realizando un borrado seguro de los grupos de colocación (encontrará más información sobre los grupos de colocación en el Sección 1.3.2, “Grupos de colocación”). El borrado seguro de Ceph es análogo a ejecutar fsck
en la capa de almacenamiento de objetos. Para cada grupo de colocación, Ceph genera un catálogo de todos los objetos y compara cada objeto primario y sus réplicas para asegurarse de que no falta ningún objeto o que hay objetos que no coinciden. Un borrado seguro ligero diario comprueba el tamaño y los atributos del objeto, mientras que el borrado seguro profundo semanal lee los datos y utiliza sumas de comprobación para garantizar la integridad de los datos.
El borrado seguro es importante para mantener la integridad de los datos, pero puede reducir el rendimiento. Es posible ajustar los valores siguientes para aumentar o disminuir las operaciones de borrado seguro:
osd max scrubs
El número máximo de operaciones de borrado seguro simultáneas para un Ceph OSD. El valor por defecto es 1.
osd scrub begin hour
,osd scrub end hour
Las horas del día (de las 0 a 24) con las que se define una ventana temporal en la que se puede producir el borrado seguro. Por defecto, empieza a las 0 y termina a las 24.
ImportanteSi el intervalo de depuración del grupo de colocación supera el valor indicado en
osd scrub max interval
, el borrado seguro se producirá independientemente de la ventana temporal que se defina.osd scrub during recovery
Permite el borrado seguro durante la recuperación. Si se establece el valor "false" (falso), se inhabilita la programación de borrados seguros nuevos mientras haya una recuperación activa. Los borrados seguros que ya estén en ejecución continuarán. Esta opción resulta útil para reducir la carga en clústeres muy ocupados. El valor por defecto es "true" (verdadero).
osd scrub thread timeout
El tiempo máximo en segundos que debe transcurrir para que un hilo de borrado seguro llegue a su tiempo límite. El valor por defecto es 60.
osd scrub finalize thread timeout
El tiempo máximo en segundos que debe transcurrir para que un hilo de finalización de borrado seguro llegue a su tiempo límite. El valor por defecto es 60*10.
osd scrub load threshold
La carga máxima normalizada. Ceph no llevará a cabo un borrado seguro cuando la carga del sistema (como se define por el coeficiente de
getloadavg()
/número deCPUs en línea
) sea superior a este número. El valor por defecto es 0,5.osd scrub min interval
El intervalo mínimo en segundos para el borrado seguro de Ceph OSD cuando la carga del clúster de Ceph sea pequeña. Por defecto es 60*60*24 (una vez al día).
osd scrub max interval
El intervalo máximo en segundos para el borrado seguro del Ceph OSD, independientemente de la carga del clúster. Por defecto es 7*60*60*24 (una vez a la semana).
osd scrub chunk min
El número mínimo de porciones de almacenamiento de objetos que se deben borrar de forma segura durante una única operación. Ceph bloquea la escritura en una única porción durante el borrado seguro. El valor por defecto es 5.
osd scrub chunk max
El número máximo de porciones de almacenamiento de objetos que se deben borrar de forma segura durante una única operación. El valor por defecto es 25.
osd scrub sleep
El tiempo de reposo antes de realizar el borrado seguro en el siguiente grupo de porciones. Al aumentar este valor, se ralentiza toda la operación de borrado seguro, mientras que las operaciones del cliente se ven menos afectadas. El valor por defecto es 0.
osd deep scrub interval
El intervalo entre borrados seguros "profundos" (con lectura completa de todos los datos). La opción
osd scrub load threshold
no afecta a este valor. Por defecto es 60*60*24*7 (una vez a la semana).osd scrub interval randomize ratio
Añade un retraso aleatorio al valor
osd scrub min interval
cuando se programa la siguiente tarea de borrado seguro para un grupo de colocación. El retraso es un valor aleatorio menor que el resultado deosd scrub min interval
*osd scrub interval randomized ratio
. Por lo tanto, el valor por defecto difunde de forma prácticamente aleatoria los procesos de borrado seguro durante la ventana temporal permitida de [1, 1,5] *osd scrub min interval
. El valor por defecto es 0,5.osd deep scrub stride
El tamaño de lectura cuando se realiza un borrado seguro profundo. El valor por defecto es 524288 (512 kB).