Введение в интерфейс Мemcached для MySQL InnoDB

В предыдущих статьях серии:

В MySQL 5.6 появилось memcache-совместимое хранилище ключ-значение на базе движка Innodb.

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

С помощью mysqlnd_memcache, вы можете прозрачно направлять ваши запросы к такому memcache-совместимому интерфейсу.

Установка

Стандартные пакеты MySQL 5.6, которые поставляются Ubuntu (Trusty), не включают в себя плагин memcache. Для использования этого плагина вам потребуется установить его из официальных apt-репозиториев MySQL-я (для Debian 7.x Wheezy, Ubuntu 12.04 Precise и Ubuntu 14.04 Trusty).

После того как вы установили MySQL 5.6 (или выше), необходимо войти в MySQL под суперпользователем и выполнить следующее:

SOURCE /usr/share/mysql/innodb_memcached_config.sql;
INSTALL PLUGIN daemon_memcached SONAME "libmemcached.so";

Скрипт innodb_memcached_config.sql делает несколько вещей, и первое, что он делает – это создаёт базу данных innodb_memcache, которая содержит три таблицы:

  1. cache_policies: в этой таблице хранятся правила, как выполняются команды GET, SET, DELETE и FLUSH.
  2. containers: эта таблица содержит список ваших таблиц, к которым возможен доступ с помощью memcache
  3. config_options — в этой таблице хранятся настройки memcache, а именно — разделитель многоколоночных значений – separator (по умолчанию вертикальная черта “|”) и разделитель обращения к таблицам table_map_delimiter (по умолчанию точка “.”)

Второе, что выполняет скрипт – загружает сам плагин и запускает memcache демона внутри MySQL.

Теперь всё готово, чтобы использовать этот плагин.

Создание memcache хранилища

Так как движок memcache устанавливает некоторые требования к таблицам, то не каждая innodb таблица может быть автоматически использована в качестве такого хранилища. Для использования вы должны настроить так называемую коллекцию.

Каждая коллекция имеет название, которое используется для обращения к ней через memcache, а также содержит ряд столбцов:

  • name: название для обращения к коллекции через memcache
  • db_schema: название базы данных
  • db_table: название таблицы
  • key_columns: название столбца, содержащего ключ (пусть вас не смущает множественное число, это один столбец)
  • value_columns: названия столбцов, указанные через запятую, которые содержат значение. В memcache-значении все значения этих столбцов будут разделены вертикальной чертой (как указано в таблице config_options)
  • flags: какие флаги memcache установить
  • cas_column: название столбца для CAS-значения, устанавливаемого memcache-ем
  • expire_time_column: название столбца, в котором хранится время “протухания” (в секундах) или 0 если не “протухает” никогда
  • unique_idx_name_on_key: название индекса, который накладывает ограничение UNIQUE на столбец ключа. Если столбец ключа является первичным ключом, укажите PRIMARY

Для того чтобы организовать наше хранилище, мы создадим новую базу данных kv_data и таблицу kv_store в ней:

CREATE DATABASE kv_data;
USE kv_data;

CREATE TABLE kv_store (
    `key` VARCHAR(255),
    `value` VARCHAR(1024),
    `flags` INT, 
    `cas` BIGINT UNSIGNED, 
    `exp` INT,
    primary key(`key`)
) ENGINE = INNODB;

Далее, мы сообщим плагину о нашем хранилище, создав контейнер:

INSERT INTO innodb_memcache.containers(
    name, 
    db_schema, 
    db_table, 
    key_columns, 
    value_columns, 
    flags, 
    cas_column,
    expire_time_column,
    unique_idx_name_on_key
) VALUES (
    'kv_data',
    'kv_data',
    'kv_store',
    'key',
    'value',
    'flags',
    'cas',
    'exp',
    'PRIMARY'
);

После того как вы это сделали, вам нужно немного подождать, чтобы это вступило в силу или перезапустить MySQL.

Использование memcache интерфейса

Теперь, когда у вас запущен и работает memcache интерфейс innodb, вы можете вставлять (insert) данные также как в обычную таблицу БД или, конечно же, посредством протокола memcache, — что можно осуществить с помощью telnet-а.

При использовании протокола memcache — по умолчанию и минимальное — количество операций перед тем, как данные будут сброшены в innodb, является 32, как указано в настройке daemon_memcached_w_batch_size. Это означает, что данные становятся видны в MySQL каждые 32 операции. Такова плата за производительность. Исключением из правил является использование binlog-репликации, в том случае, если она постоянно установлена в 1.

Для того чтобы MySQL изменения были сразу доступны через memcache, вы должны выполнить:

SET TRANSACTION ISOLATION TO READ-UNCOMMITTED;

Для использования memcache интерфейса с помощью telnet, используйте его следующим образом:

$ telnet localhost 11211

telnet> set test.key 0 0 11
Hello World
STORED

telnet> get test.key
VALUE test.key 0 11
Hello World
END

Использование нескольких коллекций

По умолчанию данные сохраняются либо в коллекции под названием default или, если она не существует, в первую коллекцию в таблице коллекций.

Для доступа к данным другой коллекции у вас есть два варианта:

Первый наиболее близок к MySQL-евскому оператору USE. Вы просто обращаетесь к самой коллекции и далее любые запросы оперируют с этой коллекцией, пока она не будет изменена на другую.

Перед именем коллекции, для отличия от ключей, ставится префикс — два знака @:

telnet> get @@kv_data
VALUE @@kv_data 0 16
kv_data/kv_store
END

Второй — это использовать полное имя. В этом случае как раз вступает в игру table_map_delimeter, посредством чего мы просто ставим перед коллекцией префикс @@collection и после table_map_delimeter. Таким образом, обращение к test.key становится  @@kv_data.test.key

telnet> get @@kv_data.test.key
VALUE @@kv_data.test.key 0 11
Hello World
END

Я рекомендую всегда использовать такой синтаксис, т. к. вы можете случайно сменить коллекцию в каком-нибудь вызванном участке кода без возврата к предыдущей коллекции.

Использование плагина mysqlnd_memcache

Теперь вы можете просто обращаться к вашим данным через интерфейс memcache, используя PHP расширение memcached или memcache (memcached extension, memcache extension). В том числе, вы можете настроить ваш обработчик сессий использовать этот подход. А также вы можете использовать обычные SQL запросы. Однако, с плагином mysqlnd_memcache вы можете прозрачно перенаправлять SQL запросы на memcache интерфейс, когда это необходимо.

По умолчанию запросы сопоставляются с регулярным выражением, указанном в константе MYSQLND_MEMCACHE_DEFAULT_REGEXP:

/^\s*SELECT\s*(.+?)\s*FROM\s*`?([a-z0-9_]+)`?\s*WHERE\s*`?([a-z0-9_]+)`?\s*=\s*(?(?=["'])["']([^"']*)["']|([0-9e\.]*))\s*$/is

Если запрос соответствует, далее плагин проверяет, что в настройках коллекции перечисленны только поля из таблицы и что в секции WHERE только одно условие с простым сравнением по ключу.

Для нашего примера этому условию будет соответствовать вот такой запрос:

SELECT `value` FROM kv_store WHERE `key` = 'test.key';

Однако ни один из таких не будет:

SELECT * FROM kv_store WHERE `key` = 'test.key';
SELECT `value` FROM kv_store WHERE `key` = `test.key` AND value LIKE '%foo%';
SELECT `key` FROM kv_store WHERE value LIKE '%foo%';

Такие запросы могут быть выполнены с помощью механизмов одного из расширений: mysql, mysqli или pdo, и будут перехвачены незаметно для вас.

Плагин mysqlnd_memcache не обрабатывает запросы на запись.

Несмотря на это ограничение, его использование может определённо улучшить ваш код (тем, что вам не требуется реализовывать обращение к memcache/memcached API) и получить большой выигрыш в производительности при незначительных изменениях.

Запись, Репликация и пул Memcache

Memcached известен своей простой настройкой пула memcached-ов для балансировки нагрузки и отказоустойчивости, но как обстоят дела с memcache-интерфейсом для InnoDB? В некотором роде похожий обработчик присутствует в MySQL репликации, тем, что каждый слейв может быть использован как сервер Memcache-а в режиме только-для-чтения, впрочем, те же правила для разделения чтения и записи применимы и при работе с Memcache-ем.

Вы должны убедиться, что вы используете только плагин mysqlnd_memcache для доступа к вашему пулу и связать его с плагином mysqlnd_ms для организации разделения чтения и записи. Однако это означает, что вы упустите возможность воспользоваться высоко производительным иинтерфейсом Memcache-а на запись.

Так как нет способа указать memcache(d) расширению, что сервера используются в режиме только-на-чтение, то невозможно использовать стандартную топологию репликации master+slaves в качестве пула memcached-ов.

Заключение

Memcached интерфейс для InnoDB — это намного более быстрый способ использования MySQL для простых хранилищ ключ-значение, но при этом имеет все преимущества великолепного движка InnoDB.

Хотя он и не является настолько быстрым, как сам memcached, он позволяет вам устранить “ещё один шарнир” в вашей инфраструктуре, при этом являясь простой заменой для memcached.

Кроме того, были некоторые радикальные улучшения производительности memcached движка для innodb в предстоящем релизе MySQL 5.7 в особенности для больших мультиядерных систем.

В следующей статье этой серии мы рассмотрим кеширование запросов для дальнейшего повышения производительности.

Источник: https://phpprofi.ru/blogs/post/27

Be the first to comment

Leave a Reply

Your email address will not be published.


*