Problemas de latencia en replicación MySQL en páginas wp-admin
Tengo un entorno ejecutando WP 3.0.1 con una base de datos Maestro y dos esclavos. Estoy usando HyperDB para forzar que todas las escrituras vayan al Maestro, y todas las lecturas se hagan desde los dos esclavos.
Estoy experimentando varios problemas en las páginas wp-admin donde los datos se escriben en el maestro, y WordPress intenta leer desde un esclavo cuando los datos aún no han llegado al esclavo. Un ejemplo de esto es cuando engancho 'dbx_post_advanced' para establecer previamente algunas categorías y términos de taxonomía personalizada en nuevas entradas. He verificado que cuando configuro HyperDB para leer y escribir solo desde el Maestro, el hook 'dbx_post_advanced' funciona correctamente.
Actualmente estoy considerando las siguientes opciones para resolver este problema:
- Dedicar solo un servidor web a todo el tráfico wp-admin
- Configurar ese servidor para leer y escribir solo en la base de datos Maestro
- Configurar el balanceador de carga para redirigir todas las URLs /wp-admin a ese servidor web
- Configurar HyperDB para leer/escribir solo contra el Maestro para las páginas wp-admin
- Configurar Replicación Semisincrónica de MySQL
- http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html
- Esta solución probablemente no funcionará, porque la replicación semisincrónica solo espera hasta que UN esclavo complete sus escrituras, no ambos esclavos en mi caso
Házme saber si tienes algún consejo para este problema.
Gracias, Dave
No mencionaste una revisión de HyperDB, así que asumiré que es la versión trunk @337290.
La función SRTM de HyperDB (enviar lecturas al master) funciona de dos maneras. Primero, realiza un seguimiento de qué tablas han recibido escrituras durante el script actual y envía todas las lecturas posteriores de esas tablas al master. Segundo, te proporciona una forma de forzar todas las lecturas al master.
En el primer caso, todavía es posible que una lectura llegue al slave después de una escritura en la misma tabla. Si la lectura es una consulta JOIN u otro tipo de consulta que puede colocar nombres de tabla lejos del principio de la consulta, podría pasar desapercibida. Si puedes inspeccionar la consulta que está yendo incorrectamente al slave, verifica si ese es el caso. Si es así, intenta aumentar la longitud del substr
aquí:
if ( preg_match($pattern, substr($query, 0, 1000)) )
Es importante entender que la función SRTM solo realiza un seguimiento durante un script. Entonces, si escribes un registro (en el 1er script) y luego te redirigen (ahora en el 2do script) e intentas leer ese registro nuevamente de la base de datos, probablemente estarás leyendo desde el slave en ese segundo script.
Por último, permíteme abordar la idea de is_admin()
. Es una buena idea, simple y efectiva. Agrega algo como esto a tu archivo db-config:
if ( is_admin() )
$wpdb->send_reads_to_masters();

Te recomendaría que despliegues otra copia de tu sitio con diferentes detalles de conexión en http://admin.example.com/ Esta área de administración utilizaría los detalles de conexión maestra y realizaría lecturas y escrituras en el servidor maestro, evitando cualquier problema de datos no disponibles. Puedes forzar que la URL de administración sea diferente configurando banderas en el wp-config.
define('WP_SITEURL', 'http://admin.example.com');
define('WP_CONTENT_URL', 'http://admin.example.com');
El sitio frontend http://example.com/ funcionaría como lo hace actualmente.

Eso requeriría mucho más trabajo. Después de un tiempo, tu URL admin.example.com comenzaría a difundirse. Necesitarías agregar muchos filtros para cambiar la URL y tendrías que asegurarte de que tu plantilla use URLs canónicas, tuviera metadatos noindex adecuados / reglas en robots.txt para admin.example.com, etc. Podría ser peligroso desde una perspectiva de SEO y desastroso si la URL se hiciera pública y los visitantes comenzaran a acceder a esa URL (evitando tus réplicas de lectura, etc.).

admin.example.com estaría configurado para solo mostrar wp-admin y nunca servir una página real, necesitas modificar el DocumentRoot pero es posible. Si las URLs en el frontend nunca enlazaran de vuelta a admin.example.com, podrías colocar admin.example.com detrás de una autenticación HTTP básica para mayor seguridad y evitar el rastreo.

No lo recomendaría. He estado en ese camino y descubrí que causaba muchos dolores de cabeza. Estaba mucho más satisfecho después de simplemente crear algunas reglas en nginx para redirigir solicitudes de wp-admin
a otro servidor.

¿Has investigado la replicación de MySQL basada en Tungsten Replicator http://code.google.com/p/tungsten-replicator/? Mejora la replicación nativa de MySQL y reduce el retraso del esclavo, entre otros aspectos http://vbtechsupport.com/1318/.
Un maravilloso libro de recetas con configuraciones de ejemplo para empezar en http://code.google.com/p/tungsten-replicator/wiki/TungstenReplicatorCookbook
