MySQL Handlersocket

Игорь Грегорченко

Когда приложение отправляет запрос на MySQL сервер, происходит две основные операции:

  • Разбор, анализ и подготовка плана выполнения для SQL запроса.
  • Выполнение нужных операций в движке таблицы и возврат результата.

Движок InnoDB позволяет включить специальный интерфейс для работы без использования SQL прослойки. Этот интерфейс называется HandlerSocket. Он предоставляет протокол работы с данными по принципу NoSQL.

Использование этого протокола может значительно ускорить простые запросы типа:
SELECT * FROM users WHERE id = 7

Протокол поддерживает базовые операции чтения/записи/обновления/удаления, а также ряд продвинутых (например, инкремент/декремент).

Настройка

Для установки необходимо поставить сборку Percona MySQL:

apt-get install percona-server-server-5.5

После этого, указать настройки портов протокола для чтения и записи данных в файле my.cnf:

loose_handlersocket_port = **9998**

loose_handlersocket_port_wr = **9999**

loose_handlersocket_threads = 16

loose_handlersocket_threads_wr = 1

open_files_limit = 65535

После перезагрузки сервера, нужно установить плагин:

mysql> install plugin handlersocket soname 'handlersocket.so';

Готово. Проверить установку можно с помощью команды:

mysql> show processlist;
+----+-------------+-----------------+---------------+---------+------+-------------------------------------------+------------------+-----------+---------------+-----------+
| Id | User        | Host            | db            | Command | Time | State                                     | Info             | Rows_sent | Rows_examined | Rows_read |
+----+-------------+-----------------+---------------+---------+------+-------------------------------------------+------------------+-----------+---------------+-----------+
|  1 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL             |         0 |             0 |         0 |
|  2 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL             |         0 |             0 |         0 |
|  3 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL             |         0 |             0 |         0 |
|  **4 | system user | connecting host | handlersocket | Connect | NULL | handlersocket: mode=wr, 0 conns, 0 active | NULL**             |         0 |             0 |         0 |
|  5 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL             |         0 |             0 |         0 |
|  6 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL             |         0 |             0 |         0 |
|  7 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL             |         0 |             0 |         0 |
|  8 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL             |         0 |             0 |         0 |
...

## Если плагин включен, он будет виден в процессах

PHP и HandlerSocket

Для работы из PHP существует библиотека php-handlersocket. Она устанавливается, как расширение:

wget https://php-handlersocket.googlecode.com/files/php-handlersocket-0.3.1.tar.gz
tar -xvf php-handlersocket-0.3.1.tar.gz
cd php-handlersocket-0.3.1
phpize
./configure
make
make install

После этого необходимо подключить расширение в php.ini:

extension=handlersocket.so

Проверить установку можно так:

root@sh:~# php -i | grep handlersocket
**handlersocket**

## Если расширение установлено, оно будет найдено в информации о php

Работа из приложения

HandlerSocket предоставляет работу с данными в движке InnoDB с помощью инициализации индекса и колонок, с которыми будут происходить манипуляции. Перед тем, как начать работу, необходимо подготовить таблицу:

CREATE TABLE `test` (

`id` int(11) NOT NULL,

`text` varchar(32) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB
## Создаем таблицу test в базе данных test

Запись данных

Запишем в эту таблицу данные:

# Вставляем данные

$hs->executeInsert(1, array(‘1’, ‘absde’));

Обратите внимание, что для записи используется порт, установленный в параметре loose_handlersocket_port_wr. Установленное значение можно проверить обычным SQL-запросом:

mysql> select * from test;
+----+-------+
| id | text  |
+----+-------+
|  1 | absde |
+----+-------+

Чтение данных

Прочитать данные из таблицы можно таким образом:

# выполняем операцию получения данных первичного ключа со значением 1

$data = $hs->executeSingle(1, ‘=’, array(‘1’), 1, 0);

print_r($data);

Производительность

Сравним два запроса на получение данных из таблицы – один через классический SQL, второй – через HandlerSocket:

$t = microtime(1);

for ( $i = 0; $i < 200000; $i++ )
{
$retval = $hs->executeSingle(1, ‘=’, array( mt_rand(1, 1000) ), 1, 0);

}

echo ‘Spent ‘ . (microtime(1) – $t) . ‘s’ . “n”;

# Отправляем 200 тыс. таких же запросов, только через SQL-интерфейс

mysql_connect(‘localhost’, ‘root’, ”);

$t = microtime(1);

for ( $i = 0; $i < 200000; $i++ )

{

$q = mysql_query(‘SELECT text FROM test.test WHERE id = ‘ . mt_rand(1, 1000));

$r = mysql_fetch_assoc($q);

}

echo ‘Spent ‘ . (microtime(1) – $t) . ‘s’ . “n”;

mysql_close();

Результаты на небольшом облачном сервере:

Spent **6.9966340065002s**
Spent 19.924588918686s

## Handlersoket быстрее

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

Применение на практике

Замена кэширования

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

$q = mysql_query('SELET name, age FROM users WHERE id = 7');

$data = mysql_fetch_assoc($q);

memcache_set(‘user7’, $data);
## Классическое кэширования записей по первичному ключу

Имеет смысл использовать HandlerSocket вместо SQL для получения таких данных. Тогда кэшировать их не понадобится:

$hs = new HandlerSocket('localhost', 9998);

$hs->openIndex(1, ‘db’, ‘users’, HandlerSocket::PRIMARY, ‘id,name,age’);

$data = $hs->executeSingle(1, ‘=’, array(‘7’), 1, 0);

## Получаем данные пользователя без SQL

Во втором случае мы:

  • уменьшим расход памяти, т.к. не будет необходимости сохранять данные в кэш
  • упростим код, т.к. данные будут храниться в едином месте, и не будет необходимости синхронизировать данные в кэше и базе
  • уменьшим риск резкого роста нагрузки при сбое кэширующих серверов

Флаги

Другой вариант применения – это работа с key-value данными. Например, различные флаги для пометки состояния пользователя:


$hs->executeInsert(1, array('1', 'is_moderator', 1));

Операция вставки не заменяет предыдущего значения, поэтому для обновления данных необходимо будет использовать операцию update.

Счетчики

Есть поддержка атомарных операций, в том числе инкремент/декремент:

$hs = new HandlerSocket('localhost', 9999);

$hs->openIndex(1, ‘test’, ‘counters’, ”, ‘**value**’);

$hs->executeSingle(1, ‘=’, array(‘1’), 1, 0, ‘+’, array(‘**1**’));
## Увеличиваем колонку value в таблице counters на 1

Эти операции удобно использовать для работы со счетчиками (например, подсчет количества просмотров у статьи).

Самое важное

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

Смотрите подробное описание протокола и PHP библиотеки.

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023