MySQL Handlersocket

Thank you for reading this post, don't forget to subscribe!

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

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

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

Исполь­зо­ва­ние это­го про­то­ко­ла может зна­чи­тель­но уско­рить про­стые запро­сы типа:

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

Настройка

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

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

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

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

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

PHP и HandlerSocket

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

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

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

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

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

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

# Созда­ем таб­ли­цу test в базе дан­ных test

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

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

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

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

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

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

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

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

# Handlersoket быстрее

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

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

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

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

# Клас­си­че­ское кэши­ро­ва­ния запи­сей по пер­вич­но­му ключу

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

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

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

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

Флаги

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

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

Счетчики

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

# Уве­ли­чи­ва­ем колон­ку value в таб­ли­це counters на 1

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

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