LoginSignup
6

More than 5 years have passed since last update.

MySQL InnoDB memcached Pluginを試してみた

Last updated at Posted at 2018-02-12

はじめに

MySQL 5.6から InnoDB memcached Plugin というのが導入されました。これは memcached プロトコルおよびクライアントライブラリを利用して、MySQLのInnoDBテーブルにアクセスできるようにするプラグインです。

本記事では、簡単な動作検証を通じて本プラグインの概要を調査します。

前提

  • Dockerのmysql:5.7 を利用して検証する
    • インストールされるバージョンは 5.7.20

導入方法

導入方法は本家マニュアルに沿って行いますが、至って簡単。

  1. source /usr/share/mysql/innodb_memcached_config.sql のSQL文を実行
  2. INSTALL PLUGIN daemon_memcached soname "libmemcached.so"; を実行
    • 一度プラグインをインストールしたら、MySQLサーバーを再起動するたびに自動的にプラグインは有効になります。
mysql> source /usr/share/mysql/innodb_memcached_config.sql
Query OK, 1 row affected (0.00 sec)

Database changed
Query OK, 0 rows affected (0.03 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 1 row affected (0.01 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.01 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
Query OK, 0 rows affected (0.02 sec)

Query OK, 1 row affected (0.00 sec)

mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
Query OK, 0 rows affected (0.01 sec)

導入はこれで終わりですが、innodb_memcached_config.sql で何が実行されたのか気になるところです。次にこのSQLファイルについて見ていきましょう。

innodb_memcached_config.sql は何をするのか?

innodb_memcached_config.sql の全文は以下です。このSQLファイルでは以下を実施します。

  1. innodb_memcache データベースの作成
    • cache_policies テーブルの作成
    • containers テーブルの作成
    • config_options テーブルの作成
  2. test.demo_test テーブルをInnoDB Memcacheのバックエンドとして利用する設定を登録
  3. test データベースの作成
    • demo_test テーブルの作成
    • テスト用レコードを登録
innodb_memcached_config.sql
create database innodb_memcache;

use innodb_memcache;


-- ------------------------------------------------------------------------
-- Following are set of "configuration tables" that used to configure
-- the InnoDB Memcached.
-- ------------------------------------------------------------------------

-- ------------------------------------------------------------------------
-- Table `cache_policies`
--
-- Each record in this table represents a named caching policy, specifying:
--  * How the memcache GET command is executed, including whether to get
--    records from local cache only, from InnoDB only, from local cache if
--    present (treating InnoDB as a backing store), or not at all.
--  * Similarly, how memcache SET commands are executed.
--  * How memcache DELETE commands are executed.
--  * Whether flushing the cache should cause a mass delete from NDB.
--
-- ------------------------------------------------------------------------
CREATE  TABLE IF NOT EXISTS `cache_policies` (
        `policy_name` VARCHAR(40) PRIMARY KEY,
        `get_policy` ENUM('innodb_only', 'cache_only', 'caching','disabled')
         NOT NULL ,
        `set_policy` ENUM('innodb_only', 'cache_only','caching','disabled')
         NOT NULL ,
        `delete_policy` ENUM('innodb_only', 'cache_only', 'caching','disabled')
         NOT NULL,
        `flush_policy` ENUM('innodb_only', 'cache_only', 'caching','disabled')
         NOT NULL
) ENGINE = innodb;


-- ------------------------------------------------------------------------
-- Table `containers`
--
-- A container record describes an InnoDB table used for data storage by
-- InnoDB Memcache.
-- There must be a unique index on the `key column`, and unique index name
-- is specified in the `unique_idx_name_on_key` column of the table
-- `value_columns` are comma-separated lists of the columns that make up
-- the memcache key and value. Each column width is defined such that they
-- are in consistent with NDB memcached.
-- ------------------------------------------------------------------------

CREATE  TABLE IF NOT EXISTS `containers` (
        `name` varchar(50) not null primary key,
        `db_schema` VARCHAR(250) NOT NULL,
        `db_table` VARCHAR(250) NOT NULL,
        `key_columns` VARCHAR(250) NOT NULL,
        `value_columns` VARCHAR(250),
        `flags` VARCHAR(250) NOT NULL DEFAULT "0",
        `cas_column` VARCHAR(250),
        `expire_time_column` VARCHAR(250),
        `unique_idx_name_on_key` VARCHAR(250) NOT NULL
) ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `config_options` (
        `name` varchar(50) not null primary key,
        `value` varchar(50)) ENGINE = InnoDB;

-- ------------------------------------------------------------------------
-- This is an example
-- We create a InnoDB table `demo_test` is the `test` database
-- and insert an entry into contrainers' table to tell InnoDB Memcache
-- that we has such InnoDB table as back store:
-- c1 -> key
-- c2 -> value
-- c3 -> flags
-- c4 -> cas
-- c5 -> exp time
-- PRIMARY -> use primary key to search
-- ------------------------------------------------------------------------

INSERT INTO containers VALUES ("aaa", "test", "demo_test",
                               "c1", "c2",  "c3", "c4", "c5", "PRIMARY");

INSERT INTO cache_policies VALUES("cache_policy", "innodb_only",
                                  "innodb_only", "innodb_only", "innodb_only");

INSERT INTO config_options VALUES("separator", "|");
INSERT INTO config_options VALUES("table_map_delimiter", ".");

CREATE DATABASE IF NOT EXISTS test;
USE test

-- ------------------------------------------------------------------------
-- Key (c1) must be VARCHAR or CHAR type, memcached supports key up to 255
-- Bytes
-- Value (c2) must be VARCHAR or CHAR type
-- Flag (c3) is a 32 bits integer
-- CAS (c4) is a 64 bits integer, per memcached define
-- Exp (c5) is again a 32 bits integer
-- ------------------------------------------------------------------------
CREATE TABLE demo_test (c1 VARCHAR(32),
                        c2 VARCHAR(1024),
                        c3 INT, c4 BIGINT UNSIGNED, c5 INT, primary key(c1))
ENGINE = INNODB;

INSERT INTO demo_test VALUES ("AA", "HELLO, HELLO", 8, 0, 0);

innodb_memcacheデータベースは何か

詳細についてはマニュアルにまとまっているのでそちらをご確認ください。本項では、そのマニュアルから簡単に各テーブルの用途を説明します。

mysql> use innodb_memcache;
Database changed
mysql> show tables;
+---------------------------+
| Tables_in_innodb_memcache |
+---------------------------+
| cache_policies            |
| config_options            |
| containers                |
+---------------------------+
3 rows in set (0.00 sec)

cache_policiesテーブル

get, set, delete及びflush操作時の個々のポリシーが設定できると説明されている。つまり、InnoDBテーブルに保存するか、通常のmemcachedとしてかの挙動設定であると思われる。

mysql> select * from cache_policies;
+--------------+-------------+-------------+---------------+--------------+
| policy_name  | get_policy  | set_policy  | delete_policy | flush_policy |
+--------------+-------------+-------------+---------------+--------------+
| cache_policy | innodb_only | innodb_only | innodb_only   | innodb_only  |
+--------------+-------------+-------------+---------------+--------------+
1 row in set (0.00 sec)

config_optionsテーブル

memcached関連の設定値格納テーブルです。現状の設定値のままで問題ないと思います。

mysql> select * from config_options;
+---------------------+-------+
| name                | value |
+---------------------+-------+
| separator           | |     |
| table_map_delimiter | .     |
+---------------------+-------+
2 rows in set (0.00 sec)

containersテーブル

このテーブルが一番重要です。このテーブルで、どのInnoDBテーブルとmemcachedをマッピングするかを設定します。

mysql> select * from containers;
+------+-----------+------------+-------------+---------------+-------+------------+--------------------+------------------------+
| name | db_schema | db_table   | key_columns | value_columns | flags | cas_column | expire_time_column | unique_idx_name_on_key |
+------+-----------+------------+-------------+---------------+-------+------------+--------------------+------------------------+
| aaa  | test      | demo_test  | c1          | c2            | c3    | c4         | c5                 | PRIMARY                |
+------+-----------+------------+-------------+---------------+-------+------------+--------------------+------------------------+

TelnetでMemcachedにアクセスして動作検証

データ取得

demo_test テーブルには innodb_memcached_config.sql 実行時に登録されたテスト用レコードが1件登録されています。

mysql> select * from demo_test;
+----+--------------+------+------+------+
| c1 | c2           | c3   | c4   | c5   |
+----+--------------+------+------+------+
| AA | HELLO, HELLO |    8 |    0 |    0 |
+----+--------------+------+------+------+
1 row in set (0.00 sec)

telnetを利用してローカルホストのmemcachedに接続し、GETコマンドでAA キーを指定することで、HELLO, HELLOの値を取得することができました。

root@7dbca47d81fc:/# telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get AA
VALUE AA 8 12
HELLO, HELLO
END

データの格納

SETコマンドを利用してデータの格納もできました。確かにmemcachedプロトコルを利用して、MySQLのInnoDBテーブルにアクセスできています。

set HOGE 0 0 4
FUGA
STORED
mysql> select * from demo_test;
+------+--------------+------+------+------+
| c1   | c2           | c3   | c4   | c5   |
+------+--------------+------+------+------+
| AA   | HELLO, HELLO |    8 |    0 |    0 |
| HOGE | FUGA         |    0 |    1 |    0 |
+------+--------------+------+------+------+
2 rows in set (0.00 sec)

疑問

簡単な動作検証を通じて導入方法と使い方は理解できたが、いくつかの疑問がふつふつ湧いてきた。

memcachedのインストールは不要?

答えは libmemcached.so という MySQL に対する memcached デーモンプラグインが同梱されているため、memcached のインストールは不要でした。

root@7dbca47d81fc:/# ls -la /usr/lib/mysql/plugin/ | grep libmemcached
-rw-r--r-- 1 root root  185128 Sep 14 02:10 libmemcached.so

InnoDB memcachedを有効中に、memcachedデーモンを起動したどうなるか

答えは memcachedデーモンを同じポート番号で起動しようとした場合は起動できない。/var/log/memcached.logに以下が出力されていた。

failed to listen on TCP port 11211: Address already in use

なので、memcachedデーモンのポート番号を11211以外にすれば起動することはできました。

複数のInnoDBテーブルを使い分けることはできるのか

最初に作成した demo_test と同じテーブル設計で demo_test2 テーブルを作成して、このテーブルの情報をmemcached経由で取得するにはどうすればいいのか?

mysql> select * from test.demo_test2;
+----+--------------+------+------+------+
| c1 | c2           | c3   | c4   | c5   |
+----+--------------+------+------+------+
| BB | WORLD, WORLD |    8 |    0 |    0 |
+----+--------------+------+------+------+
1 row in set (0.01 sec)

まず始めに demo_test2 を InnoDB memcachedで利用する設定を containers テーブルに登録をします。

INSERT INTO containers VALUES ("bbb", "test", "demo_test2",
                               "c1", "c2",  "c3", "c4", "c5", "PRIMARY");

以下のようになります。

mysql> select * from containers;
+------+-----------+------------+-------------+---------------+-------+------------+--------------------+------------------------+
| name | db_schema | db_table   | key_columns | value_columns | flags | cas_column | expire_time_column | unique_idx_name_on_key |
+------+-----------+------------+-------------+---------------+-------+------------+--------------------+------------------------+
| aaa  | test      | demo_test  | c1          | c2            | c3    | c4         | c5                 | PRIMARY                |
| bbb  | test      | demo_test2 | c1          | c2            | c3    | c4         | c5                 | PRIMARY                |
+------+-----------+------------+-------------+---------------+-------+------------+--------------------+------------------------+
2 rows in set (0.00 sec)

その状態で、demo_testdemo_test2 のデータ取得をどのように実現するのか?

mysql> select * from test.demo_test;
+------+--------------+------+------+------+
| c1   | c2           | c3   | c4   | c5   |
+------+--------------+------+------+------+
| AA   | HELLO, HELLO |    8 |    0 |    0 |
| HOGE | FUGA         |    0 |    1 |    0 |
+------+--------------+------+------+------+
2 rows in set (0.00 sec)

mysql> select * from test.demo_test2;
+----+--------------+------+------+------+
| c1 | c2           | c3   | c4   | c5   |
+----+--------------+------+------+------+
| BB | WORLD, WORLD |    8 |    0 |    0 |
+----+--------------+------+------+------+
1 row in set (0.00 sec)

答えは、@@name を利用することでアクセスができました。これはマニュアルにも記載があります。

get @@bbb.BB
VALUE @@bbb.BB 8 12
WORLD, WORLD
END

また今まで get AAdemo_test側の情報が取得できていたのが、demo_test2の設定を追加したことで出来なくなりました。今まで出来ていたのは、demo_testしか設定がなかったので、デフォルト扱いされていたのだと思われます。

get AA
END

AAの情報を取得するにはもちろん @@aaa.AA で取得出来ました。

get @@aaa.AA
VALUE @@aaa.AA 8 12
HELLO, HELLO
END

InnoDB memcached pluginを通じて複数テーブルを使う場合は、気をつけないといけないかもしれません。

サンプルコード

本件で作成したサンプルコードはこちらにあります。

おわりに

タイトル通り InnoDB memcached Pluginのお試しとして動作検証を行いました。このプラグインを有効にすることで、InnoDBテーブルにアクセスすることができるmemcachedデーモンを起動することができ、KVSとしてMySQLを利用できることが分かりました。メリットとしては、InnoDB memcached pluginに乗り換える場合にアプリケーションコードの変更は無しに利用できることです。但し、バックエンドはMySQLでありディスクへの書き込みも発生するので、全くmemcachedと同じパフォーマンスが得られるかは不明です。次にInnoDB memcached Pluginの導入を見越した設定項目、パフォーマンスについて調査したいと思います。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6