Когда приложение отправляет запрос на MySQL сервер, происходит две основные операции:
Движок 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 существует библиотека 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 библиотеки.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…