Бэкенд mysql_cluster нужен для использования Django в схеме с master-slave репликацией MySQL. Он умеет переключать глобальное соединение Джанго с БД между мастером и slave-репликами, и тем самым позволяет использовать стандартный ORM.
Скачать версия 1.0
УСТАНОВКА
Поставить mysql_cluster в питоновский путь (обычный способ "python setup.py install" работает).
Указать в настройках название бэкенда и хосты с портами мастера и реплики:
DATABASE_ENGINE = 'mysql_cluster' DATABASE_HOST = 'master.db' DATABASE_PORT = '' DATABASE_SLAVE_HOST = 'slave.db' DATABASE_SLAVE_PORT = DATABASE_PORT(Настройки DATABASE_SLAVE_* обязательны.)
Если используются джанговские сессии с хранением в БД, то почти без вариантов имеет смысл указать в качестве движка сессий класс из mysql_cluster. Он полностью совместим со стандартным, просто явно использует для доступа к сессиям мастер-соединение.
SESSION_ENGINE = 'mysql_cluster.sessions'
ИСПОЛЬЗОВАНИЕ
Mysql_cluster устроен так, что переключение между мастером и репликами должно делаться явно, оно не происходит автоматически в зависимости от типа SQL-запроса или доступа к какой-то определенной таблицы и т.д. Поэтому на голову программиста ложится ответственность за то, чтобы следить за тем, что
- write-операции происходят тогда, когда активно мастер-соединение
- слейв-соединение активируется для тех read-операций, для которых это имеет смысл
Тем не менее, на практике все не так сложно.
Middleware
Если ваш проект строится в соответствие с принципами HTTP, где GET-запросы не производят изменений в данных системе (за исключением всяких сторонних эффектов), то большая часть работы делается включением middleware из пакета:
MIDDLEWARE_CLASSES = [
# ...
'mysql_cluster.middleware.ReplicationMiddleware',
# ...
]
Фактически оно включает на время выполнения GET-запросов слейв-соединение, а на POST (а также PUT, DELETE и все другое) — мастер-соединение. Этого обычно достаточно для большинства случаев.
Но есть случаи, когда доступ в БД случается не в рамках основной логики. Например создание сессиий, запись какой-нибудь статистики, прозрачная регистрация пользователя где-нибудь внутри системы. Это может случаться в произвольные моменты времени, в том числе и при GET-запросах. Решается это так:
Если второстепенные записи делаются в какой-то другой middleware, то достаточно поставить ее в списке MIDDLEWARE_CLASSES перед ReplicationMiddleware. В этом случае работа вашей middleware будет происходить до логики переключения через соединение по умолчанию — мастер.
Иначе всегда можно явно переключить бэкенд в мастер-соединение (см. "Ручное управление" дальше).
Декораторы
Помимо ReplicationMiddleware, работающей для всех запросов, в пакете есть еще декораторы для отдельных view, которые позволяют явно сказать, что конкретная view работает с мастером или с репликой. Используются просто:
from mysql_cluster.decorators import use_master, use_slave
@use_master
def my_view(request, ...):
# используется мастер-соединение для все операций с БД на время
# работы view (если явно не переопределено).
@use_slave
def my_view(request, ...):
# то же для реплик
GET после POST
Есть отдельный момент в работе с репликацией в том, что реплики при обновлениях могут слегка отставать от мастера. На практике это выливается в то, что после сабмита POST-формы, которая возвращает HTTP-редирект на страницу с обновленными данными, эта страница может считаться из еще не обновленной реплики, и пользователь увидит, что его действие не сработало.
Для борьбы с этим эффектом и ReplicationMiddleware, и декораторы поддерживают специальную логику, по которой обслуживание следующего GET'а после POST'а с редиректом явно заворачивается в мастер.
Ручное управление
Любой код, который пишет в БД, но при этом выполняется в непредсказуемые моменты времени, можно явно завернуть в мастер соединение. Делается это так:
from django.db import connection
connection.use_master()
try:
# запись в БД
finally:
connection.revert()
Или, если вы используете Питон версии от 2.5 и новее, то короче:
from django.db import connection
with connection.use_master():
# запись в БД
Статистика
В отладочном режиме к стандартной статистике выполненных запросов бэкенд добавляет еще один параметр "db", который может иметь значения "master" или "slave".
from django.db import connection
print connection.queries[-1]['db']
Его удобно использовать во время разработки, когда база данных на самом деле одна, чтобы смотреть, какие запросы куда идут.