#php #mysql
#php #mysql
Вопрос:
Я хочу загружать запросы баланса на 2 сервера mysql в моем приложении.
Каков был бы наилучший способ сделать это, чтобы каждый запрос отправлялся на другой сервер БД?
Я подумываю о том, чтобы иметь глобальный счетчик, который увеличивается каждый раз при установлении соединения, модифицируйте счетчик с помощью моих серверов БД, чтобы получить хост, к которому я должен подключиться. Однако вышеупомянутый процесс должен быть атомарным, чтобы никакие 2 запроса не видели один и тот же счетчик.
Как мне это сделать? Использовать блокировку семафора, mysql’s get_lock()?
псевдокод
counter = 0
hosts = array('192.168.1.1:3306', '192.168.1.2:3306')
//the below code needs to be atomic
GET A GLOBAL LOCK
counter = counter 1
RELEASE THE LOCK
host = hosts[counter % len(hosts)]
Спасибо
Ответ №1:
Лучший способ?
Используйте прокси MySQL… Это автоматически компенсирует неработоспособность серверов. Кроме того, вы можете написать правила, которые указывают, куда отправляется каждый запрос (либо по циклическому выбору, либо на определенный сервер для лучшей привязки к кэшу). Кроме того, он может автоматически направлять все записи на главный сервер…
Я бы не стал пытаться реализовать это в вашем приложении. Причина в том, что намного сложнее иметь дело с глобальными блокировками в нескольких экземплярах, и сложнее обеспечить обнаружение ошибок, которое не приводит к значительному снижению производительности…
Комментарии:
1. Привет, прокси Mysql все еще бета-версия, если я прав. В любом случае, мне это нужно в логике приложения
2. Технически это альфа-версия. Зачем вам это нужно в логике приложения? Что это даст вам такого, чего не даст использование прокси?
3. Это для целей тестирования. Есть также HAProxy, который мог бы выполнить эту работу, но пока я просто хочу протестировать его в логике приложения
4. Ну, как я уже сказал, будет довольно сложно обрабатывать все граничные случаи. Я бы лично использовал файл блокировки (используя
flock
) для управления счетчиком (заблокируйте его, прочитайте и увеличьте счетчик, запишите увеличенное число, снимите блокировку). Но будьте осторожны, это может быть опасно, поскольку является узким местом для вашего приложения… И почему так важно, чтобы это было атомарным? Кого волнует, что два последовательных процесса попадают на один и тот же сервер БД? Пока средний случай делится 50 на 50, действительно ли это имеет значение?
Ответ №2:
почему бы просто не использовать подход rand?
$this->read_host = $this->prod_slaves_array[rand(0,(count($this->prod_slaves_array)-1))];
преимущества в том, что он не имеет блокировки, и хотя это не полностью 50/50, действительно ли это необходимо?