スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQLでMemcachedプロトコルを使う

MySQL では 「InnoDB Memcached」プラグインを使うことで、Memcached プロトコルを使ってテーブルデータに直接アクセスすることができるようになります。

参考:MySQL :: MySQL 5.7 Reference Manual :: 14.20 InnoDB memcached Plugin

このシリーズではセットアップから基本的な使用方法、本家MemcachedとRedisとのベンチマーク比較、そしてSQLとMemcachedプロトコルのベンチマーク比較を行なっていきたいと思います。

Memcached プラグインの利点

MySQLのMemcachedプラグインを利用することの利点は主に以下の通りです。

InnoDB ストレージエンジンにSQLを介さずに直接アクセスするため高速です

SQLステートメントの場合、MySQLではクエリパーサーで解析処理が必要ですが、Memcachedプロトコルではその部分が不要になるため高速に動作します。

データはMySQLのデータベースとして保存されるため、クラッシュセーフ

本家Memcachedはデータはメモリ上にしかないため、停止するとデータは消えてしまいますが、Memcachedプラグインの場合、データは通常のテーブルに保存されているため、MySQLが停止してもデータは守られます。

データはSQLによる操作も可能です

Memcachedプロトコルで書き込まれたデータも、通常のテーブルに保存されているので、SQLを使ってアクセスすることも可能なので、他のテーブルとJOINして使うこともできます。

マスタースレーブによる高可用性構成も可能です

本家Memcachedではレプリカを持つような構成は組めませんが、Memcachedプロトコルでの書き込みはバイナリログに記録させることができるため、マスタースレーブ構成を組むことも可能です。

参考:MySQL :: MySQL 5.7 Reference Manual :: 14.20.1 Benefits of the InnoDB memcached Plugin

セットアップ

事前準備として、CentOS 7.3 上に MySQL 5.7.20 がインストール済とします。

Memcamedプラグインを動かすために必要なテーブルをセットアップするためのSQLがデフォルトでは /usr/share/mysql/innodb_memcached_config.sql に配置されているのでこれを実行します。

上記のSQLを実行すると、 innodb_memcache と test という2つのデータベースが作成されます。

innodb_memcache には以下の3つのテーブルが作成されています。

test データベースには demo_test テーブルが作成されます。

memcachedプラグインをインストールします。

公式ドキュメントのセットアップ手順には記載が無いですが、リッスンするポート番号を設定する必要があります。

MySQLを再起動します。

Memcachedプラグインの動作確認

初期設定では test.demo_test が動作するようになっているのでこれを使って動作確認を行なってみます。
また、Memcachedプロトコルでは特別なクライアントツールは不要で、telnetを使って操作することができます。

参考:memcachedプロトコルについて | さくらインターネット研究所

telnetをインストールします。

MySQLのMemcachedに接続します。

Memcachedプロトコル経由でデータを取得します。
ここでは既にデータが登録済の「AA」というキー名で取得します。

「HELLO,HELLO」という登録済データが取得できました。

Memcachedプロトコル経由でデータをセットします。

SQLでテーブルデータを確認すると、 demo_test にデータが格納されていることがわかります。

参考:MySQL :: MySQL 5.7 Reference Manual :: 14.20.3 Setting Up the InnoDB memcached Plugin

新しいテーブルをMemcachedで使えるようにする

初期設定ではMemcachedプロトコルで読み書きされるテーブルは demo_test ですが、新しくテーブルを追加したいと思います。

test データベースに以下の users テーブルを作成します。

memcache のデータストアとしてマッピングするには以下のカラムが必要になります。

  • PRIMARY KEY もしくは UNIQUE INDEX が付与された VARCHAR カラム
  • memcached が使用するフラグ INT カラム
  • memcached が使用する比較とスワップ値を格納する BIGINT カラム
  • memcached が使用する有効期限の値を格納する INT カラム

参考:14.18.7 InnoDB memcached プラグインの内部構造 ページ内「containers テーブルカラムの制約」箇所

users テーブルをmemcacheのテーブルとしてマッピングします。

設定値をリロードするにはMySQLの再起動か、以下のようにプラグインをアンインストールしてからインストールし直します。

操作するテーブルを指定する

containers テーブルに複数レコード設定されているときは、 name カラムに default が指定されているレコードのマッピングが使用されます。
それ以外のマッピングを利用してSETやGETを行う場合は、キー名を以下のように指定します。

複数のカラムに入力値を分割して格納する

複数のカラムに入力値を分割して格納したい場合は、value_columns に | で区切って指定してください。

入力値を | で区切る

分割されて格納されます

MySQL側の更新をMemcached経由で読み出す

SQLを使ったテーブルデータの更新情報はMemcachedでも反映されます。

SQLを使ってデータを挿入

Memcached経由でデータを取得する

デフォルトのMemcachedプロトコルの分離レベルは READ UNCOMMITTED

利用する上で注意が必要なのは、Memcachedプロトコルの分離レベルは READ UNCOMMITTED なので、他のトランザクション途中の更新データが見えてしまうことです。

MySQL側でデータを挿入する

この段階ではコミットしていないため、他のコネクションからはDは見えません。

Memcachedからは見えてしまいます。

ロールバックすると、

Memcachedからも見えなくなります。

これらの問題は、innodb_api_trx_level で分離レベルの変更は可能です。
my.cnf に以下の設定をすることで REPEATABLE READ に設定できます。

ただし、弊社の検証環境では、innodb_api_trx_level を変更するとMySQLが極端に不安定な状態になってしまいました。
もし変更する際は十分に検証を行った上で利用してください。

まとめ

Memcachedで読み書きするデータをMySQLでも利用したい場合など、本家Memcachedでは難しかった使い方や、Memcachedで課題になりやすい永続化の部分もMySQLそのままの機構に任せることができるなど利点も多いです。
次回はこのMemcachedプラグインと本家Memcached、最近キャッシュサーバーとしてよく利用されているRedisとのベンチマーク比較を行いたいと思います。


MySQL

 

Return Top