Проблемы с задержкой репликации MySQL в страницах wp-admin
У меня настроена среда на WP 3.0.1 с мастер-базой и двумя репликами. Я использую HyperDB, чтобы все записи шли на мастер, а чтение - с двух реплик.
Я сталкиваюсь с различными проблемами в страницах wp-admin, где данные записываются на мастер, а WordPress пытается читать с реплики, когда данные ещё не успели туда попасть. Пример: когда я использую хук 'dbx_post_advanced' для предустановки некоторых категорий и пользовательских таксономий в новых записях. Я проверил, что если настроить HyperDB на чтение и запись только с мастера, хук 'dbx_post_advanced' работает корректно.
Сейчас я рассматриваю следующие варианты решения проблемы:
- Назначить только один веб-сервер для всего трафика wp-admin
- Настроить этот сервер на чтение и запись только с мастер-базы
- Настроить балансировщик нагрузки для маршрутизации всех URL /wp-admin на этот веб-сервер
- Настроить HyperDB для чтения/записи только с мастера для страниц wp-admin
- Настроить полусинхронную репликацию MySQL
- http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html
- Это решение, скорее всего, не сработает, так как полусинхронная репликация ждёт завершения записи только на ОДНОЙ реплике, а у меня их две
Дайте знать, если у вас есть советы по этой проблеме.
Спасибо, Дэйв
Вы не указали ревизию HyperDB, поэтому я предполагаю, что это trunk @337290.
Функция SRTM в HyperDB (отправка чтений на мастер) работает в двух направлениях. Во-первых, она отслеживает, какие таблицы получали записи во время текущего скрипта, и отправляет все последующие операции чтения для этих таблиц на мастер. Во-вторых, она предоставляет способ принудительно направлять все чтения на мастер.
В первом случае все еще возможно, что операция чтения попадет на слейв после записи в ту же таблицу. Если запрос на чтение является JOIN-запросом или другим типом запроса, где имена таблиц могут находиться далеко от начала запроса, он может проскочить. Если вы можете проанализировать запрос, который неправильно направляется на слейв, проверьте, так ли это. Если да, попробуйте увеличить длину substr
здесь:
if ( preg_match($pattern, substr($query, 0, 1000)) )
Важно понимать, что функция SRTM отслеживает записи только в пределах одного скрипта. Поэтому если вы записываете запись (в 1-м скрипте), затем происходит перенаправление (теперь 2-й скрипт), а затем вы пытаетесь прочитать эту запись из базы данных, скорее всего, чтение будет происходить со слейва во втором скрипте.
Наконец, позвольте мне прокомментировать идею с is_admin()
. Это хорошая идея, простая и эффективная. Добавьте что-то подобное в ваш db-config файл:
if ( is_admin() )
$wpdb->send_reads_to_masters();

Я бы рекомендовал развернуть еще одну копию вашего сайта с другими параметрами подключения по адресу http://admin.example.com/. Эта админ-зона будет использовать мастер-подключение для чтения и записи и не будет страдать от проблем с недоступностью данных. Вы можете принудительно задать другой URL для админки, установив флаги в wp-config.
define('WP_SITEURL', 'http://admin.example.com');
define('WP_CONTENT_URL', 'http://admin.example.com');
Публичная часть сайта http://example.com/ будет работать в текущем режиме.

Это потребует значительно больше работы. Со временем ваш URL admin.example.com начнет распространяться в интернете. Вам придется добавить множество фильтров для изменения URL, а также убедиться, что ваш шаблон использует канонические URL, имеет правильные метаданные noindex / правила robots.txt для admin.example.com и т.д. Это может быть опасно с точки зрения SEO и катастрофично, если URL станет публичным и посетители начнут обращаться к нему (обходя ваши read slaves и т.д.).

admin.example.com можно настроить так, чтобы он показывал только wp-admin и никогда не отдавал страницы - для этого нужно повозиться с DocumentRoot, но это возможно. Если URL на фронтенде никогда не будут ссылаться на admin.example.com, вы можете защитить admin.example.com с помощью HTTP Basic Auth для дополнительной безопасности и предотвращения индексации.

Я бы не рекомендовал этот подход. Я уже проходил этот путь и столкнулся с множеством проблем. Гораздо лучше просто создать правила в nginx для проксирования запросов к wp-admin
на другой сервер.

Вы рассматривали репликацию MySQL на основе Tungsten Replicator http://code.google.com/p/tungsten-replicator/? Этот инструмент улучшает встроенную репликацию MySQL и сокращает отставание реплик (slave lag) и другие проблемы http://vbtechsupport.com/1318/.
Отличная поваренная книга с примерами настроек для начала работы доступна по адресу http://code.google.com/p/tungsten-replicator/wiki/TungstenReplicatorCookbook
