La exploración de la nube móvil usando JuiceFS para admitir Apache HBase para aumentar la eficiencia y reducir los costos

Sobre el autor: Chen Haifeng, desarrollador de Apache HBase, una base de datos móvil en la nube, tiene un gran interés en Apache HBase, RBF y Apache Spark.

antecedentes

Apache HBase es un servicio de almacenamiento de datos distribuido, escalable y a gran escala en el ecosistema Apache Hadoop. También es una base de datos NoSQL. Está diseñado para proporcionar consultas aleatorias, altamente consistentes y en tiempo real para miles de millones de filas de registros que contienen millones de columnas. De forma predeterminada, los datos de HBase se almacenarán en HDFS, y HBase ha realizado muchas optimizaciones para HDFS para garantizar la estabilidad y el rendimiento. Sin embargo, el mantenimiento de HDFS en sí mismo no es nada fácil. Requiere monitoreo, operación y mantenimiento continuos, ajuste, expansión de capacidad, recuperación ante desastres, etc., y el costo de construir HDFS en la nube pública también es bastante alto. Para ahorrar dinero y reducir los costos de mantenimiento, algunos usuarios usan S3 (u otro almacenamiento de objetos) para almacenar datos de HBase. El uso de S3 ahorra el problema de monitorear la operación y el mantenimiento, y también realiza la separación del almacenamiento y la computación, lo que facilita la expansión y reducción de HBase.

Sin embargo, el acceso de datos HBase al almacenamiento de objetos no es una tarea fácil. Por un lado, el almacenamiento de objetos tiene funciones y rendimiento limitados debido a sus propias características. Una vez que los datos se escriben en el almacenamiento de objetos, el objeto de datos no se puede cambiar. Por otro lado, el uso de la semántica del sistema de archivos para acceder al almacenamiento de bloques tiene limitaciones naturales. Cuando se utiliza el cliente de AWS nativo de Hadoop para acceder al almacenamiento de objetos, la operación de cambio de nombre del directorio recorrerá todo el directorio para copiar y eliminar archivos, y el rendimiento es muy bajo. Además, la operación de cambio de nombre también causará problemas de atomicidad, es decir, la operación de cambio de nombre original se descompone en dos operaciones de copia y eliminación, lo que es propenso a la incoherencia de las vistas de datos de usuario en casos extremos. De manera similar, también hay una consulta del tamaño total de todos los archivos en un directorio.El principio es obtener secuencialmente toda la información de archivo de un directorio a través de la iteración transversal. Si hay una gran cantidad de subdirectorios y archivos en el directorio, consultar el tamaño total de todos los archivos en el directorio es más complicado y tiene un peor rendimiento.

Selección de esquema

Después de mucha investigación de soluciones y seguimiento de problemas de la comunidad, actualmente hay tres soluciones para el almacenamiento de objetos de acceso a datos HBase en la nube.

La primera es que HBase utiliza el cliente de AWS nativo de Hadoop para acceder al almacenamiento de objetos , a saber, S3AFileSystem. El código del kernel de HBase solo necesita cambios menores para usar S3AFileSystem. Un problema que debe resolverse en esta solución de almacenamiento de objetos de acoplamiento directo de HBase es el cambio de nombre del directorio. HBase implica el cambio de nombre de directorio en la administración de archivos Hlog, MemStore Flush, creación de tablas, compactación de regiones y división de regiones. La comunidad ha optimizado StoreFIle para resolver algunos de los problemas de rendimiento del cambio de nombre. Para resolver por completo el problema del rendimiento de las operaciones de directorio, se requieren cambios drásticos en el código fuente del kernel de HBase.

La segunda solución es introducir Alluxio como una aceleración de caché , que no solo mejora en gran medida el rendimiento de lectura y escritura, sino que también introduce la gestión de metadatos de archivos, lo que resuelve por completo el problema del bajo rendimiento de las operaciones de directorio. El final aparentemente feliz tiene muchas limitaciones detrás. Cuando Alluxio está configurado para usar solo memoria, el tiempo necesario para las operaciones de directorio es de ms. Si el UFS de Alluxio está configurado, la manipulación de metadatos en Alluxio tiene dos pasos: el primer paso es modificar el estado del maestro de Alluxio y el segundo paso es enviar una solicitud a UFS. Como puede ver, la operación de metadatos aún no es atómica y su estado es impredecible cuando la operación se está ejecutando o se produce algún error. Alluxio se basa en UFS para las operaciones de metadatos, como cambiar el nombre de un archivo, que se convierte en una operación de copia y eliminación. Los datos en HBase deben colocarse en el disco y Alluxio no puede resolver el problema de rendimiento de las operaciones de directorio.

La tercera opción es introducir el sistema de archivos compartidos JuiceFS entre HBase y el almacenamiento de objetos . Al usar JuiceFS para almacenar datos, los datos en sí se conservarán en el almacenamiento de objetos (por ejemplo, EOS en la nube móvil), y los metadatos correspondientes se pueden conservar en Redis, MySQL y otras bases de datos según sea necesario. En esta solución, la operación de directorio se completa en el motor de metadatos, sin interacción con el almacenamiento de objetos, y el tiempo de operación está en el nivel de ms, lo que puede resolver el problema del acceso de datos HBase al almacenamiento de objetos. Sin embargo, dado que el kernel de JuiceFS está escrito en lenguaje Go, presenta ciertos desafíos para el ajuste de rendimiento posterior y el mantenimiento de rutina.

Después de sopesar los pros y los contras de las tres soluciones anteriores, finalmente se adopta JuiceFS como la solución para que HBase en la nube admita el almacenamiento de objetos. Lo siguiente se centra en la práctica y el ajuste del rendimiento de JuiceFS en el almacenamiento de objetos compatible con HBase en la nube.

Una introducción

Primero, presentemos la arquitectura de JuiceFS. JuiceFS consta de dos partes principales: el servicio de metadatos de JuiceFS y el almacenamiento de objetos. JuiceFS Java SDK es totalmente compatible con HDFS API y también proporciona un montaje de cliente basado en FUSE, totalmente compatible con POSIX. Como sistema de archivos, JuiceFS procesará los datos y sus metadatos correspondientes por separado, los datos se almacenarán en el almacenamiento de objetos y los metadatos se almacenarán en el motor de metadatos. En términos de almacenamiento de datos, JuiceFS admite casi todos los almacenamientos de objetos en la nube pública, así como OpenStack Swift, Ceph, MinIO y otros almacenamientos de objetos de código abierto que admiten la implementación privada. En términos de almacenamiento de metadatos, JuiceFS adopta un diseño de varios motores y actualmente es compatible con Redis, TiKV, MySQL/MariaDB, PostgreSQL, SQLite, etc. como motores de servicio de metadatos.

Cualquier archivo almacenado en JuiceFS se dividirá en "fragmentos" de tamaño fijo, con un límite de tamaño predeterminado de 64 MiB. Cada Chunk consta de uno o más "Segmentos", y la longitud de los segmentos no es fija, dependiendo de cómo se escriba el archivo. Cada Slice se divide aún más en "Bloques" de tamaño fijo, que por defecto son 4 MiB. Finalmente, estos Bloques se almacenan en el almacén de objetos. Al mismo tiempo, JuiceFS almacenará cada archivo y sus fragmentos, segmentos, bloques y otra información de metadatos en el motor de metadatos.

Con JuiceFS, los archivos finalmente se dividen en trozos, secciones y bloques para almacenarlos en el almacenamiento de objetos. Por lo tanto, los archivos de origen almacenados en JuiceFS no se pueden encontrar en la plataforma de almacenamiento de objetos, y solo hay un directorio de fragmentos y un montón de directorios y archivos numerados numéricamente en el depósito.

Se requiere la siguiente configuración para que los componentes de HBase usen JuiceFS. Primero coloque el SDK de cliente compilado en el classpath de HBase. A continuación, escriba la configuración relacionada con JuiceFS en el archivo de configuración core-site.xml, como se muestra en la siguiente tabla. Finalmente, formatee el sistema de archivos usando el cliente juicefs.

elemento de configuración valores predeterminados describir
fs.jfs.impl io.juicefs.JuiceFileSystem Especifica la implementación de almacenamiento a usar, por defecto es jfs://
fs.AbstractFileSystem.jfs.impl io.juicefs.JuiceFS
jugofs.meta Especifica la dirección del motor de metadatos del sistema de archivos JuiceFS creado previamente.

En términos de almacenamiento de metadatos, MySQL se utiliza como almacenamiento de metadatos. El comando del sistema de archivos de formato es el siguiente. Se puede ver que formatear el sistema de archivos requiere la siguiente información:

  • --storage: establezca el tipo de almacenamiento, como la nube móvil EOS;
  • --bucket: establezca la dirección del punto final del almacenamiento de objetos;
  • --access-key: establezca la clave de acceso a la API de almacenamiento de objetos ID de clave de acceso;
  • --secret-key: establezca el secreto de la clave de acceso a la API de almacenamiento de objetos.
juicefs format --storage eos \
--bucket https://myjfs.eos-wuxi-1.cmecloud.cn \
--access-key ABCDEFGHIJKLMNopqXYZ \
--secret-key ZYXwvutsrqpoNMLkJiHgfeDCBA \
mysql://username:password@(ip:port)/database NAME

Verificación y optimización del esquema

Después de presentar cómo usar Juicefs, comience a probar. En el entorno de prueba se seleccionó un servidor con 48 núcleos y 187G de memoria. En el clúster de HBase, hay un HMaster, un RegionServer y tres zookeepers. El MySQL de tres nodos con replicación maestro-esclavo se usa en el motor de metadatos. El almacenamiento de objetos utiliza el EOS de almacenamiento de objetos en la nube móvil, y la estrategia de red adopta la red pública. Juicefs configura el tamaño del fragmento en 64 M, el tamaño del bloque de almacenamiento físico en 4 M, sin caché y 300 M para MEM. Construimos dos conjuntos de clústeres HBase, uno es HBase colocado directamente en el almacenamiento de objetos en la nube móvil, el otro es la introducción de Juicefs entre HBase y el almacenamiento de objetos en la nube móvil. La escritura secuencial y la lectura aleatoria son dos indicadores clave de rendimiento del clúster HBase, y las herramientas de prueba de PE se utilizan para probar estos dos indicadores de rendimiento. El rendimiento de lectura y escritura de prueba se muestra en la siguiente tabla.

Entorno de clúster

Entorno de clúster HBase-juicefs-EOS (fila/s) Entorno de clúster HBase-EOS (fila/s)
escribir secuencialmente 79465 33343
lectura aleatoria 6698 6476

De acuerdo con los resultados de la prueba, al usar la solución de Juicefs, el rendimiento de escritura secuencial del clúster mejora significativamente, pero el rendimiento de lectura aleatoria no mejora. El motivo es que la solicitud de escritura se puede devolver escribiendo en el búfer de memoria del cliente, por lo que, en términos generales, la latencia de escritura de JuiceFS es muy baja (decenas de microsegundos). Cuando JuiceFS procesa una solicitud de lectura, generalmente lee el almacenamiento de objetos de acuerdo con el método de alineación de bloques de 4M para lograr una determinada función de prelectura.Al mismo tiempo, los datos leídos se escribirán en el directorio de caché local para su uso posterior. Durante la lectura secuencial, las solicitudes posteriores accederán a los datos obtenidos de antemano y la tasa de aciertos de la memoria caché es muy alta, por lo que el rendimiento de lectura del almacenamiento de objetos también se puede utilizar por completo. Sin embargo, durante la lectura aleatoria, la eficiencia previa al almacenamiento en caché de JuiceFS no es alta, pero la utilización real de los recursos del sistema se reducirá debido a la amplificación de lectura y las frecuentes escrituras y desalojos de la memoria caché local.

Para mejorar el rendimiento de la lectura aleatoria, se pueden considerar dos direcciones. Una es aumentar la capacidad general de la caché tanto como sea posible, para lograr el efecto de almacenar en caché casi por completo los datos requeridos.En el escenario de uso de datos masivos, esta dirección de optimización no es factible. Otra dirección es cultivar profundamente el kernel de JuiceFS y optimizar la lógica de lectura de datos.

En la actualidad, las optimizaciones que hemos realizado incluyen: 1) Desactivar el mecanismo de prelectura y la función de caché para simplificar la lógica de lectura de datos; 2) Evitar almacenar en caché todos los datos del bloque tanto como sea posible y utilizar más los datos de solicitud de Range HTTP; 3) Establecer un tamaño de bloque más pequeño; 4) Mejorar el rendimiento de lectura del almacenamiento de objetos tanto como sea posible. Después de las pruebas en el entorno de I+D, el rendimiento de la lectura aleatoria mejora en aproximadamente un 70 % después de la optimización.

En combinación con el trabajo de prueba anterior, después de usar el almacenamiento de objetos como sistema de almacenamiento de datos subyacente, HBase en la nube logra el mismo rendimiento de lectura y escritura que los datos almacenados en HDFS, pero el usuario gasta menos de la mitad de los datos almacenados en HDFS. el almacenamiento de objetos es una práctica de investigación y desarrollo que tiene tanto el pastel como la pata.

Si es útil, ¡siga nuestro proyecto Juicedata/JuiceFS ! (0ᴗ0✿)

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/5389802/blog/5533644
Recomendado
Clasificación