WHMCS es una solución todo en uno de gestión de clientes, facturación y soporte para empresas de alojamiento web. Es uno de los líderes en el mundo de la automatización del alojamiento que se utiliza junto con el propio panel de control del alojamiento. WHMCS se ejecuta en una pila LAMP, con MySQL/MariaDB como proveedor de base de datos. Por lo general, WHMCS se instala como una instancia independiente (aplicación y base de datos) de forma independiente siguiendo la guía de instalación de WHMCS o mediante herramientas de instalación de software como cPanel Site Software o Softaculous. La base de datos puede tener una alta disponibilidad migrando a un Galera Cluster de 3 nodos.
En esta publicación de blog, le mostraremos cómo migrar la base de datos WHMCS desde un servidor MySQL independiente (proporcionado por el propio servidor WHM/cPanel) a un clúster MariaDB Galera externo de tres nodos para mejorar la disponibilidad de la base de datos. La aplicación WHMCS en sí se mantendrá ejecutándose en el mismo servidor cPanel. También le daremos algunos consejos de ajuste para optimizar el rendimiento.
Implementación del clúster de base de datos
- Instalar ClusterControl:
Siga las instrucciones correspondientes hasta que se complete la instalación. Luego, vaya a http://192.168.55.50/clustercontrol (192.168.55.50 es la dirección IP del host de ClusterControl) y registre un usuario superadministrador con la contraseña y otros detalles requeridos.$ whoami root $ wget https://severalnines.com/downloads/cmon/install-cc $ chmod 755 install-cc $ ./install-cc
- Configure SSH sin contraseña desde ClusterControl a todos los nodos de la base de datos:
$ whoami root $ ssh-keygen -t rsa # Press enter on all prompts $ ssh-copy-id 192.168.55.51 $ ssh-copy-id 192.168.55.52 $ ssh-copy-id 192.168.55.53
- Configure la implementación de la base de datos para nuestro clúster MariaDB Galera de 3 nodos. Vamos a utilizar la última versión compatible MariaDB 10.3: Asegúrese de obtener todas las marcas verdes después de presionar 'Enter' al agregar los detalles del nodo. Espere hasta que se complete el trabajo de implementación y debería ver que el clúster de la base de datos aparece en ClusterControl.
- Implemente un nodo ProxySQL (lo ubicaremos junto con el nodo ClusterControl) yendo a Administrar -> Equilibrador de carga -> ProxySQL -> Implementar ProxySQL . Especifique los siguientes detalles obligatorios: En "Agregar usuario de base de datos", puede pedirle a ClusterControl que cree un nuevo usuario de ProxySQL y MySQL mientras se configura , así ponemos al usuario como "portal_whmcs", asignado con TODOS LOS PRIVILEGIOS sobre la base de datos "portal_whmcs.*". Luego, marque todas las casillas para "Incluir" y finalmente elija "falso" para "¿Está usando transacciones implícitas?".
Una vez finalizada la implementación, debería ver algo como esto en la vista de topología:
Resources relacionados El principal proveedor de alojamiento de Australia aprovecha ClusterControl para ofrecer una experiencia de clase mundial a sus usuarios Balance de carga de base de datos para MySQL y MariaDB con ProxySQL - Tutorial MySQL de alta disponibilidad en cPanel con Galera ClusterLa implementación de nuestra base de datos ya está completa. Tenga en cuenta que no cubrimos la redundancia del nivel del balanceador de carga en esta publicación de blog. Puede lograrlo agregando un balanceador de carga secundario y encadenándolos con Keepalived. Para obtener más información al respecto, consulte los Tutoriales de ProxySQL en el capítulo "4.2. Alta disponibilidad para ProxySQL".
Instalación de WHMCS
Si ya tiene WHMCS instalado y ejecutándose, puede omitir este paso.
Tenga en cuenta que WHMCS requiere una licencia válida que debe comprar de antemano para poder utilizar el software. No proporcionan una licencia de prueba gratuita, pero ofrecen una garantía de devolución de dinero de 30 días sin preguntas, lo que significa que siempre puede cancelar la suscripción antes de que caduque la oferta sin que se le cobre.
Para simplificar el proceso de instalación, utilizaremos el software del sitio cPanel (puede optar por la instalación manual de WHMCS) en uno de nuestros subdominios, selfportal.mytest.io. Después de crear la cuenta en WHM, vaya a cPanel> Software> Software del sitio> WHMCS e instalar la aplicación web. Inicie sesión como usuario administrador y active la licencia para comenzar a usar la aplicación.
En este punto, nuestra instancia de WHMCS se ejecuta como una configuración independiente, conectándose al servidor MySQL local.
ClusterControlConsola única para toda su infraestructura de base de datosDescubra qué más hay de nuevo en ClusterControlInstale ClusterControl GRATISMigración de la base de datos WHMCS a MariaDB Galera Cluster
Ejecutar WHMCS en un servidor MySQL independiente expone la aplicación a un único punto de falla (SPOF) desde el punto de vista de la base de datos. MariaDB Galera Cluster proporciona redundancia a la capa de datos con funciones de agrupación en clúster integradas y soporte para arquitectura multimaestro. Combine esto con un balanceador de carga de base de datos, por ejemplo ProxySQL, y podemos mejorar la disponibilidad de la base de datos WHMCS con cambios mínimos en la aplicación misma.
Sin embargo, hay una serie de mejores prácticas que WHMCS (u otras aplicaciones) deben seguir para trabajar de manera eficiente en Galera Cluster, especialmente:
- Todas las tablas deben ejecutarse en el motor de almacenamiento InnoDB/XtraDB.
- Todas las tablas deben tener una clave principal definida (se admite la clave principal de varias columnas, la clave única no cuenta).
Según la versión instalada, en nuestra instalación del entorno de prueba (cPanel/WHM 11.78.0.23, WHMCS 7.6.0 a través de Site Software), los dos puntos anteriores no cumplieron con el requisito. La configuración predeterminada de cPanel/WHM MySQL viene con la siguiente línea dentro de /etc/my.cnf:
default-storage-engine=MyISAM
Lo anterior provocaría la creación de tablas adicionales administradas por los módulos adicionales de WHMCS en formato de motor de almacenamiento MyISAM si esos módulos están habilitados. Este es el resultado del motor de almacenamiento después de haber habilitado 2 módulos (Nuevos TLD y Tablón de anuncios para el personal):
MariaDB> SELECT tables.table_schema, tables.table_name, tables.engine FROM information_schema.tables WHERE tables.table_schema='whmcsdata_whmcs' and tables.engine <> 'InnoDB';
+-----------------+----------------------+--------+
| table_schema | table_name | engine |
+-----------------+----------------------+--------+
| whmcsdata_whmcs | mod_enomnewtlds | MyISAM |
| whmcsdata_whmcs | mod_enomnewtlds_cron | MyISAM |
| whmcsdata_whmcs | mod_staffboard | MyISAM |
+-----------------+----------------------+--------+
El soporte de MyISAM es experimental en Galera, lo que significa que no debe ejecutarlo en producción. En algunos casos peores, podría comprometer la consistencia de los datos y causar fallas en la replicación del conjunto de escritura debido a su naturaleza no transaccional.
Otro punto importante es que toda tabla debe tener definida una clave primaria. Según el procedimiento de instalación de WHMCS que haya realizado (en cuanto a nosotros, usamos el software del sitio cPanel para instalar WHMCS), algunas de las tablas creadas por el instalador no vienen con la clave principal definida, como se muestra en el siguiente resultado:
MariaDB [information_schema]> SELECT TABLES.table_schema, TABLES.table_name FROM TABLES LEFT JOIN KEY_COLUMN_USAGE AS c ON (TABLES.TABLE_NAME = c.TABLE_NAME AND c.CONSTRAINT_SCHEMA = TABLES.TABLE_SCHEMA AND c.constraint_name = 'PRIMARY' ) WHERE TABLES.table_schema <> 'information_schema' AND TABLES.table_schema <> 'performance_schema' AND TABLES.table_schema <> 'mysql' and TABLES.table_schema <> 'sys' AND c.constraint_name IS NULL;
+-----------------+------------------------------------+
| table_schema | table_name |
+-----------------+------------------------------------+
| whmcsdata_whmcs | mod_invoicedata |
| whmcsdata_whmcs | tbladminperms |
| whmcsdata_whmcs | tblaffiliates |
| whmcsdata_whmcs | tblconfiguration |
| whmcsdata_whmcs | tblknowledgebaselinks |
| whmcsdata_whmcs | tbloauthserver_access_token_scopes |
| whmcsdata_whmcs | tbloauthserver_authcode_scopes |
| whmcsdata_whmcs | tbloauthserver_client_scopes |
| whmcsdata_whmcs | tbloauthserver_user_authz_scopes |
| whmcsdata_whmcs | tblpaymentgateways |
| whmcsdata_whmcs | tblproductconfiglinks |
| whmcsdata_whmcs | tblservergroupsrel |
+-----------------+------------------------------------+
Como nota al margen, Galera aún permitiría que existan tablas sin clave principal. Sin embargo, las operaciones DELETE no son compatibles con esas tablas y, además, lo expondría a problemas mucho mayores, como el bloqueo del nodo, la degradación del rendimiento de la certificación del conjunto de escritura o las filas pueden aparecer en un orden diferente en diferentes nodos.
Para superar esto, nuestro plan de migración debe incluir el paso adicional para reparar el motor de almacenamiento y la estructura del esquema, como se muestra en la siguiente sección.
Plan de Migración
Debido a las restricciones explicadas en el capítulo anterior, nuestro plan de migración tiene que ser algo así:
- Habilitar el modo de mantenimiento WHMCS
- Realice copias de seguridad de la base de datos whmcs utilizando una copia de seguridad lógica
- Modifique los archivos de volcado para cumplir con los requisitos de Galera (motor de conversión de almacenamiento)
- Inicie uno de los nodos de Galera y deje que los nodos restantes se apaguen
- Restaurar al nodo Galera elegido
- Corregir la estructura del esquema para cumplir con el requisito de Galera (faltan claves principales)
- Arranca el clúster desde el nodo de Galera elegido
- Inicie el segundo nodo y deje que se sincronice
- Inicie el tercer nodo y deje que se sincronice
- Cambie la base de datos que apunta al punto final apropiado
- Deshabilitar el modo de mantenimiento de WHMCS
La nueva arquitectura se puede ilustrar de la siguiente manera:
El nombre de nuestra base de datos WHMCS en el servidor cPanel es "whmcsdata_whmcs" y vamos a migrar esta base de datos a un clúster MariaDB Galera externo de tres nodos implementado por ClusterControl. Además del servidor de la base de datos, tenemos un ProxySQL (co-ubicado con ClusterControl) ejecutándose para actuar como el balanceador de carga de MariaDB, proporcionando el punto final único para nuestra instancia de WHMCS. El nombre de la base de datos en el clúster se cambiará a "portal_whmcs", para que podamos distinguirlo fácilmente.
En primer lugar, habilite el Modo de mantenimiento en todo el sitio yendo a WHMCS> Configuración> Configuración general> General> Modo de mantenimiento> Marque para habilitar:impide el acceso al área del cliente cuando está habilitado . Esto garantizará que no haya actividad del usuario final durante la operación de copia de seguridad de la base de datos.
Dado que tenemos que hacer ligeras modificaciones a la estructura del esquema para que encaje bien en Galera, es una buena idea crear dos archivos de volcado separados. Uno solo con el esquema y otro solo para datos. En el servidor WHM, ejecute el siguiente comando como root:
$ mysqldump --no-data -uroot whmcsdata_whmcs > whmcsdata_whmcs_schema.sql
$ mysqldump --no-create-info -uroot whmcsdata_whmcs > whmcsdata_whmcs_data.sql
Luego, tenemos que reemplazar todas las ocurrencias de MyISAM en el archivo de volcado de esquema con 'InnoDB':
$ sed -i 's/MyISAM/InnoDB/g' whmcsdata_whmcs_schema.sql
Verifique que ya no tengamos líneas MyISAM en el archivo de volcado (no debería devolver nada):
$ grep -i 'myisam' whmcsdata_whmcs_schema.sql
Transfiera los archivos de volcado del servidor WHM a mariadb1 (192.168.55.51):
$ scp whmcsdata_whmcs_* 192.168.55.51:~
Cree la base de datos MySQL. Desde ClusterControl, vaya a Administrar -> Esquemas y usuarios -> Crear base de datos y especifique el nombre de la base de datos. Aquí usamos un nombre de base de datos diferente llamado "portal_whmcs". De lo contrario, puede crear manualmente la base de datos con el siguiente comando:
$ mysql -uroot -p
MariaDB> CREATE DATABASE 'portal_whmcs';
Cree un usuario de MySQL para esta base de datos con sus privilegios. Desde ClusterControl, vaya a Administrar -> Esquemas y usuarios -> Usuarios -> Crear nuevo usuario y especifique lo siguiente:
En caso de que elija crear el usuario de MySQL manualmente, ejecute las siguientes instrucciones:
$ mysql -uroot -p
MariaDB> CREATE USER 'portal_whmcs'@'%' IDENTIFIED BY 'ghU51CnPzI9z';
MariaDB> GRANT ALL PRIVILEGES ON portal_whmcs.* TO [email protected]'%';
Tenga en cuenta que el usuario de la base de datos creado debe importarse a ProxySQL para permitir que la aplicación WHMCS se autentique con el balanceador de carga. Vaya a Nodos -> elija el nodo ProxySQL -> Usuarios -> Importar usuarios y seleccione "portal_whmcs"@"%", como se muestra en la siguiente captura de pantalla:
En la siguiente ventana (Configuración de usuario), especifique Hostgroup 10 como el grupo de host predeterminado:
Ahora la etapa de preparación de la restauración está completa.
En Galera, restaurar una gran base de datos a través de mysqldump en un clúster de un solo nodo es más eficiente y esto mejora significativamente el tiempo de restauración. De lo contrario, cada nodo en el clúster tendría que certificar cada declaración de la entrada de mysqldump, lo que llevaría más tiempo para completarse.
Dado que ya tenemos un clúster MariaDB Galera de tres nodos en ejecución, detengamos el servicio MySQL en mariadb2 y mariadb3, un nodo a la vez para lograr una reducción ordenada. Para cerrar los nodos de la base de datos, desde ClusterControl, simplemente vaya a Nodos -> Acciones de nodo -> Detener nodo -> Continuar . Esto es lo que vería en el panel de control de ClusterControl, donde el tamaño del clúster es 1 y el estado de db1 es Sincronizado y Primario:
Luego, en mariadb1 (192.168.55.51), restaure el esquema y los datos según corresponda:
$ mysql -uportal_whmcs -p portal_whmcs < whmcsdata_whmcs_schema.sql
$ mysql -uportal_whmcs -p portal_whmcs < whmcsdata_whmcs_data.sql
Una vez importada, tenemos que corregir la estructura de la tabla para agregar la columna "id" necesaria (excepto para la tabla "tblafiliates"), así como agregar la clave principal en todas las tablas a las que les ha faltado alguna:
$ mysql -uportal_whmcs -p
MariaDB> USE portal_whmcs;
MariaDB [portal_whmcs]> ALTER TABLE `tblaffiliates` ADD PRIMARY KEY (id);
MariaDB [portal_whmcs]> ALTER TABLE `mod_invoicedata` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tbladminperms` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tblconfiguration` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tblknowledgebaselinks` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tbloauthserver_access_token_scopes` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tbloauthserver_authcode_scopes` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tbloauthserver_client_scopes` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tbloauthserver_user_authz_scopes` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tblpaymentgateways` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tblproductconfiglinks` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
MariaDB [portal_whmcs]> ALTER TABLE `tblservergroupsrel` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
O bien, podemos traducir las declaraciones repetidas anteriores usando un bucle en un script bash:
#!/bin/bash
db_user='portal_whmcs'
db_pass='ghU51CnPzI9z'
db_whmcs='portal_whmcs'
tables=$(mysql -u${db_user} "-p${db_pass}" information_schema -A -Bse "SELECT TABLES.table_name FROM TABLES LEFT JOIN KEY_COLUMN_USAGE AS c ON (TABLES.TABLE_NAME = c.TABLE_NAME AND c.CONSTRAINT_SCHEMA = TABLES.TABLE_SCHEMA AND c.constraint_name = 'PRIMARY' ) WHERE TABLES.table_schema <> 'information_schema' AND TABLES.table_schema <> 'performance_schema' AND TABLES.table_schema <> 'mysql' and TABLES.table_schema <> 'sys' AND c.constraint_name IS NULL;")
mysql_exec="mysql -u${db_user} -p${db_pass} $db_whmcs -e"
for table in $tables
do
if [ "${table}" = "tblaffiliates" ]
then
$mysql_exec "ALTER TABLE ${table} ADD PRIMARY KEY (id)";
else
$mysql_exec "ALTER TABLE ${table} ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST";
fi
done
En este punto, es seguro iniciar los nodos restantes para sincronizarlos con mariadb1. Comience con mariadb2 yendo a Nodos -> seleccione db2 -> Acciones de nodo -> Iniciar nodo . Supervise el progreso del trabajo y asegúrese de que mariadb2 esté en estado Sincronizado y Primario (supervise la página Descripción general para obtener más detalles) antes de iniciar mariadb3.
Finalmente, cambie la base de datos que apunta al host ProxySQL en el puerto 6033 dentro del archivo de configuración de WHMCS, como en nuestro caso se encuentra en /home/whmcsdata/public_html/configuration.php:
$ vim configuration.php
<?php
$license = 'WHMCS-XXXXXXXXXXXXXXXXXXXX';
$templates_compiledir = 'templates_c';
$mysql_charset = 'utf8';
$cc_encryption_hash = 'gLg4oxuOWsp4bMleNGJ--------30IGPnsCS49jzfrKjQpwaN';
$db_host = 192.168.55.50;
$db_port = '6033';
$db_username = 'portal_whmcs';
$db_password = 'ghU51CnPzI9z';
$db_name = 'portal_whmcs';
$customadminpath = 'admin2d27';
No olvide deshabilitar el modo de mantenimiento de WHMCS yendo a WHMCS> Configuración> Configuración general> General> Modo de mantenimiento> desmarque "Marque para habilitar - impide el acceso al área del cliente cuando está habilitado" . Nuestro ejercicio de migración de base de datos ya está completo.
Pruebas y ajustes
Puede verificar si observa las entradas de consulta de ProxySQL en Nodos -> ProxySQL -> Consultas principales :
Para las consultas de solo lectura más repetidas (puede ordenarlas por recuento de estrellas), puede almacenarlas en caché para mejorar el tiempo de respuesta y reducir la cantidad de visitas a los servidores back-end. Simplemente desplácese a cualquier consulta y haga clic en Consulta de caché y aparecerá la siguiente ventana emergente:
Lo que debe hacer es elegir solo el grupo de host de destino y hacer clic en "Agregar regla". A continuación, puede verificar si la consulta almacenada en caché se vio afectada en la pestaña "Reglas":
A partir de la regla de consulta en sí, podemos decir que las lecturas (todo SELECT excepto SELECT .. PARA ACTUALIZAR) se reenvían al grupo de host 20, donde las conexiones se distribuyen a todos los nodos, mientras que las escrituras (que no sean SELECT) se reenvían al grupo de host 10, donde las conexiones se reenvían a un solo nodo de Galera. Esta configuración minimiza el riesgo de interbloqueos que pueden ser causados por una configuración multimaestro, lo que mejora el rendimiento de la replicación en general.
Eso es todo por ahora. ¡Feliz agrupamiento!