Просмотров: 8065

MySQL: SQL или NoSQL - вот в чем вопрос. Введение в HandlerSocket


Это продолжение, начало этого материала смотрите здесь.

Итак, в конце 2010 года японский разработчик Ёсинори Мацунобу (Yoshinori Matsunobu) запустил свой, теперь уже чрезвычайно известный проект по созданию NoSQL-плагина для MySQL, который назвал HandlerSocket. Этот интерфейсный плагин позволяет клиентскому приложению подключаться напрямую к движку данных MySQL для устранения избыточной нагрузки, характерной для традиционных запросов через интерфейс SQL и неприемлемой для высоконагруженных БД.

Для чего нужен HandlerSocket (HS)?

Давайте поясним последнее ключевое утверждение. При традиционной работе через SQL-интерфейс, со стороны логики работы сервера часто наблюдается очень заметный оверхед (sql overhead).

Судите сами: каждый раз при поступлении любого запроса выполняется его лексический анализ, парсинг, обращение к схеме (чтобы узнать поля и индексы), блок работы с query cache, запускается оптимизатор, анализ связанных индексов, выборка стратегии запроса, открытие и блокировка таблиц, потом следует сам запрос к движку и его обслуживание, форматирование полученных данных, закрытие и разблокировка таблиц (на самом деле этот список слишком неполный, детали здесь я просто опускаю).

MySQL plugin плагин NoSQL HandlerSocket Memcached хранилище highload Drizzle NewSQL схема производительность замеры тест тесты скорость график таблица

Особенно эти накладные расходы становятся заметны при интенсивной работе с однотипными запросами характерными для движков CMS на более-менее популярных сайтах, которые выполняются, условно говоря, «много сотен раз в секунду».

Конечно, SQL позволяет отчасти нивелировать эту ситуацию. Например, можно использовать постоянное соединение (persistent connection) и подготавливать запросы (prepare cached), в этом случае, план запроса, план оптимизации и некоторые другие мероприятия выполняются всего 1 раз среди серии подобных монотонных запросов, то есть все последующие запросы после первого отработают почти мгновенно. Но, даже при такой «удачной раскладке» производительность MySQL оставляет желать лучшего — забегая чуть вперед, — HS позволяет получать эти же данные в среднем в 5-6 раз быстрее!

В связи с этим, возвращаясь к истории и причинам разработки HandlerSocket, его создатель с сожалением пишет, что даже после выхода версии MySQL 5.5, где быстродействие сервера было существенно улучшено (для чего решены многие хронические проблемы с мьютексами), необходимый ему уровень производительности так и не был достигнут.

Яшинори рассказывает, что работая в DeNA (крупнейшая японская социальная сеть с игровой составляющей), он имеет дело с частотой запросов к MySQL колеблющихся в диапазоне от 200 000 до 500 000 запросов в секунду, что, конечно же, классический MySQL выдержать даже теоретически неспособен.

MySQL plugin плагин NoSQL HandlerSocket Memcached хранилище highload Drizzle NewSQL
Яшинори Мацунобу,
автор HandlerSocket NoSQL plugin for MySQL

Самостоятельный анализ узких мест работы MySQL привел к тому, что этот исследователь фактически «вычленил» SQL из работы БД, разработав свой собственный NoSQL-протокол доступа. Основная причина, по которой выбор сделан именно в пользу NoSQL — очень быстрый поиск по первичному ключу и возможность избавиться от наиболее «тормознутого участка» во всем MySQL — его SQL-подсистемы.

Особенности HandlerSocket

Теперь давайте перейдем к более конкретному рассмотрению HandlerSocket.

Преимущества

  • Поддержка сразу нескольких шаблонов запросов (например, поиск по первичному и уникальному ключу, поиск по неуникальному ключу, поддерживается указание диапазона и пределов выборки), поддержка CRUD;
  • Обработка почти неограниченного количества конкурентных подключений;
  • Рекордное среди решений для MySQL быстродействие;
  • mysqld и HandlerSocket работают в одинаковых процессах, с очень маленьким временем доступа к общим данным. Как дополнительное следствие этого доступен мониторинг через Nagios и т.д. Работа HS также видна через обычные команды MySQL: SHOW GLOBAL STATUS, SHOW ENGINE INNODB STATUS, SHOW PROCESSLIST и так далее.
  • Протокол HandlerSocket существенно более компактный, чем mysql/libmysql, что порождает минимальные по размеру сетевые пакеты;
  • Группировка ответов на клиентские запросы в консолидированный пакет. Пакетная группировка дополнительно ускоряет работу, снижая нагрузку на сеть и процессор;
  • Сокращается количество «дорогих» вызовов fsync() ;
  • Уменьшаются задержки в репликации данных;
  • Всё богатство инструментов доступных для MySQL (репликация, обслуживание и т.д.) автоматически доступно и для HandlerSocket (в силу физически общей БД);
  • Устраняется проблема несоответствие данных и устаревание кэша;
  • Не нужно пересобирать или как-то модифицировать MySQL;
  • Таблицы БД постоянно свободны (неблокирующий I/O);
  • Все запросы и ответы этого плагина фиксируются в binlogs (записи начинаются строчками «Begin; multiple DMLs(row format); »)

Ограничения

  • Нет никакой безопасности (авторизация не предусмотрена).
  • Необходимость учиться новому протоколу/API.
  • Сортировка записей не предусмотрена.
  • Операции, не использующие ключи — не поддерживаются.

Установка HandlerSocket

Приведу короткий, принципиальный алгоритм установки HandlerSocket, за подробностями отсылаю к официальной документации:

1. Загружаем исходный код HandlerSocket и собираем его:

./configure —with-mysql-source=... —with-mysql-bindir=... ; make; make install

2. Заходим в командную строку как root и активируем плагин HandlerSocket в MySQL:

mysql> INSTALL PLUGIN ’HandlerSocket’ soname ’HandlerSocket.so’;

3. После этого будут собраны и установлены как серверный (handlersocket plugin), так и клиентский (libhsclient) код. Теперь желательно убедиться в том, что установка прошла успешно и плагин запущен, сделать это можно через ’show processlist ’:

mysql> SHOW PROCESSLIST;
+----+---------+------+-------------------------------------------+
| Id | Command | Time | State                                     | 
+----+---------+------+-------------------------------------------+
|  1 | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | 
|  2 | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | 
...
| 16 | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | 
| 17 | Connect | NULL | handlersocket: mode=wr, 0 conns, 0 active |

Особенности установки HandlerSocket

Протокол HandlerSocket является плагином с интерфейсом демона, который поддерживается в MySQL начиная с версии 5.1, соответственно, нужен сервер БД как минимум этой версии или выше. При самостоятельной сборке HandlerSocket не придется изменять исходные коды сервера, но должны быть доступны как исходные (путь к ним указывается в ключе —with-mysql-source ), так и бинарные коды MySQL (ключ —with-mysql-bindir ). Частый источник таинственных проблем — несовпадения версий дистрибутива и исходных кодов при этой процедуре. Дополнительно нужно проверить доступность портов 9998 и 9999 из внешнего мира (или измените их дефолтные значения в файле конфигурации my.cnf ). Как вариант, можно использовать Percona Server (форк MySQL), где этот протокол изначально интегрирован в дистрибутив.

Текущая версия HandlerSocket реализована только под Linux, версия под Windows не планируется. На данный момент имеются готовые классы для следующих ведущих языков программирования: C++, PHP, Python, Ruby, Java, JavaScript/Node.js. Доступны модули для веб-серверов, например для Nginx, который обращается к данным MySQL через протокол HandlerSocket и отдает данные клиенту в формате JSON.

Архитектура HandlerSocket

Будем считать, что установка успешно завершена. Но перед тем как мы начнем экскурс в устройство команд HandlerSocket, следует сразу уяснить его некоторые архитектурные особенности этого хранилища/протокола типа ключ-значение, а именно — наличие двух разных типов потоков: для доступа клиентов по чтению и по записи.

MySQL plugin плагин NoSQL HandlerSocket Memcached хранилище highload Drizzle NewSQL схема производительность замеры тест тесты скорость график таблица

Как можно увидеть в файле /etc/mysql/my.cnf , по-умолчанию стартует 16 читающих тредов (которые будут доступны клиентам на 9998 порту) и только 1 пишущий (доступный на 9999 порту).

Вот как выглядят все эти параметры по-умолчанию в конфигурационном файле:

loose_handlersocket_port = 9998
# номер порта, на котором ожидаются запросы на чтение
loose_handlersocket_port_wr = 9999
# номер порта, на котором ожидаются запросы на запись
loose_handlersocket_threads = 16
# количество рабочих потоков (для запросов по чтению) 
loose_handlersocket_threads_wr = 1
# количество рабочих потоков (для запросов по записи)
open_files_limit = 65535
# максимальное количество разрешенных конкурентных соединений

Если взглянуть выше ещё раз на вывод команды ’show processlist ’, то отчетливо видны как читающие треды (атрибут handlersocket: mode=rd), так и один пишущий (handlersocket: mode=wr). Естественно, в зависимости от специфики и интенсивности конкретной задачи вам предлагается самостоятельно сконфигурировать разумный баланс между количественными отношениям между этими потоками.

Теперь коснемся вопроса авторизации и безопасности доступа. Тут должен сразу предупредить, что сейчас я буду рассказывать вещи, которые противоречат тому, что написано в документации и на тысяче сайтов посвященных протоколу HandlerSocket. В самом деле, везде утверждается, что в этом протоколе отсутствует авторизация (я даже указал это в описании протокола выше для соответствия официальным источникам), но как любитель почитать код, хотел бы оспорить это утверждение.

Поэтому, как бы там ни было, просто описываю здесь эту недокументированную опцию, которая, несмотря на её малоизвестность, прекрасно работает на практике. Итак, следующие переменные (вносимые в конфигурационный файл my.cnf самостоятельно) ответственны за авторизацию в HandlerSocket:

handlersocket_plain_secret = YOUR_PASS
handlersocket_plain_secret_wr = YOUR_PASS

Соответственно, первая строчка отвечает за доступ читающих потоков, а вторая — за пишущие (здесь вместо параметра YOUR_PASS нужно вписать свой пароль, естественно, у разных типов потоков они могут не совпадать).

Аутенфикация в HandlerSocket реализована и действует в пределах текущей сессии, а не для каждой команды. И, наконец, вы можете разрешить отдельную авторизацию, например, только потокам ответственным за запись, — тогда просто удалите строчку handlersocket_plain_secret из конфигурационного файла, оставив заполненной handlersocket_plain_secret_wr . Подробное описание всех остальных параметров настройки HandlerSocket можно найти в официальной документации.

Посмотреть множество других фактов и дополнительные сведения об Handlersocket можно в этой презентации от компании Percona


~

Читать этот материал дальше. Оглавление этой серии статей — здесь.

Игорь Савчук ©  Системный Администратор, 2011
twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru ya.ru pikabu.ru blogger.com liveinternet.ru livejournal.ru google.com bobrdobr.ru yandex.ru del.icio.us

Подписка на обновления блога → через RSS, на e-mail, через Twitter
Теги: , , , , , , ,
Эта запись опубликована: Вторник, 20 марта 2012 в рубрике Unix'овоеПрограммирование.

Оставьте комментарий!

Не регистрировать/аноним

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Зарегистрировать/комментатор

Для регистрации укажите свой действующий email и пароль. Связка email-пароль позволяет вам комментировать и редактировать данные в вашем персональном аккаунте, такие как адрес сайта, ник и т.п. (Письмо с активацией придет в ящик, указанный при регистрации)

(обязательно)


⇑ Наверх
⇓ Вниз