MemSQLと共同で作成

前書き

MemSQLは、従来のデータベースよりも高速な読み取りと書き込みを提供できるメモリ内データベースの一種です。 新しいテクノロジーであるにもかかわらず、MySQLプロトコルを使用しているため、操作に非常に馴染みがあります。

MemSQLは、JSONサポートやデータの挿入機能などの最新機能を備えたMySQLの最新機能を採用しています。 MemSQLのMySQLに対する最大の利点の1つは、単一のクエリを「大規模並列処理」と呼ばれる複数のノードに分割できることです。これにより、読み取りクエリが大幅に高速化されます。

このチュートリアルでは、単一のUbuntu 14.04サーバーにMemSQLをインストールし、パフォーマンスベンチマークを実行し、コマンドラインMySQLクライアントを介してJSONデータを挿入します。

前提条件

このチュートリアルを実行するには、次のものが必要です。

ステップ1-MemSQLのインストール

このセクションでは、MemSQLをインストールするための作業環境を準備します。

MemSQLの最新バージョンは、http://www.memsql.com/download/ [ダウンロードページ]にリストされています。 MemSQL Opsをダウンロードしてインストールします。これは、MemSQLを正しく実行するためのサーバーのダウンロードと準備を管理するプログラムです。 執筆時点でのMemSQL Opsの最新バージョンは4.0.35です。

まず、MemSQLのインストールパッケージファイルをWebサイトからダウンロードします。

wget http://download.memsql.com/memsql-ops-4.0.35/memsql-ops-4.0.35.tar.gz

次に、パッケージを抽出します。

tar -xzf memsql-ops-4.0.35.tar.gz

パッケージを展開すると、 `+ memsql-ops-4.0.35 +`というフォルダーが作成されます。 フォルダー名にはバージョン番号があるため、このチュートリアルで指定したものより新しいバージョンをダウンロードすると、ダウンロードしたバージョンのフォルダーが作成されます。

ディレクトリをこのフォルダーに変更します。

cd memsql-ops-4.0.35

次に、抽出したインストールパッケージの一部であるインストールスクリプトを実行します。

sudo ./install.sh

スクリプトからの出力が表示されます。 しばらくすると、このホストのみにMemSQLをインストールするかどうかを尋ねられます。 将来のチュートリアルでは、複数のマシンにMemSQLをインストールする方法を検討します。 したがって、このチュートリアルでは、* y *と入力して「はい」と言います。

インストールスクリプトのプロンプトと出力

. . .
Do you want to install MemSQL on this host only? [y/N]

2015-09-04 14:30:38: Jd0af3b [INFO] Deploying MemSQL to 45.55.146.81:3306
2015-09-04 14:30:38: J4e047f [INFO] Deploying MemSQL to 45.55.146.81:3307
2015-09-04 14:30:48: J4e047f [INFO] Downloading MemSQL: 100.00%
2015-09-04 14:30:48: J4e047f [INFO] Installing MemSQL
2015-09-04 14:30:49: Jd0af3b [INFO] Downloading MemSQL: 100.00%
2015-09-04 14:30:49: Jd0af3b [INFO] Installing MemSQL
2015-09-04 14:31:01: J4e047f [INFO] Finishing MemSQL Install
2015-09-04 14:31:03: Jd0af3b [INFO] Finishing MemSQL Install
Waiting for MemSQL to start...

これで、UbuntuサーバーにMemSQLクラスターがデプロイされました! ただし、上記のログから、MemSQLが2回インストールされていることがわかります。

MemSQLは、アグリゲーターノードとリーフノードの2つの異なるロールとして実行できます。 MemSQLが2回インストールされた理由は、クラスターが動作するために少なくとも1つのアグリゲーターノードと少なくとも1つのリーフノードが必要だからです。

_aggregator node_は、MemSQLへのインターフェースです。 外の世界から見ると、MySQLによく似ています。同じポートでリッスンし、MySQLおよび標準のMySQLライブラリと通信することを期待するツールを接続できます。 アグリゲーターの仕事は、すべてのMemSQLリーフノードを把握し、MySQLクライアントを処理し、クエリをMemSQLに変換することです。

_leaf node_は実際にデータを保存します。 リーフノードは、アグリゲーターノードからデータの読み取りまたは書き込み要求を受信すると、そのクエリを実行し、結果をアグリゲーターノードに返します。 MemSQLを使用すると、複数のホスト間でデータを共有でき、各リーフノードにはそのデータの一部が含まれます。 (単一のリーフノードであっても、データはそのリーフノード内で分割されます。)

複数のリーフノードがある場合、アグリゲーターはMySQLクエリをそのクエリに関与するすべてのリーフノードに変換する責任があります。 次に、すべてのリーフノードからの応答を取得し、結果を1つのクエリに集約して、MySQLクライアントに返します。 これが並列クエリの管理方法です。

単一ホストのセットアップでは、アグリゲーターとリーフノードが同じマシンで実行されていますが、他の多くのマシンにさらに多くのリーフノードを追加できます。

ステップ2-ベンチマークの実行

MemSQLのインストールスクリプトの一部としてインストールされたMemSQL Opsツールを使用して、MemSQLがどれだけ速く動作するかを見てみましょう。

Webブラウザーで、「+ http://:9000+」に移動します

画像:https://assets.digitalocean.com/articles/memsql/img1.png [img]

MemSQL Opsツールを使用すると、クラスターの概要を確認できます。 マスターアグリゲーターとリーフノードの2つのMemSQLノードがあります。

単一マシンのMemSQLノードで速度テストを行ってみましょう。 左側のメニューから[速度テスト]をクリックし、[テストの開始]をクリックします。 表示される結果の例を次に示します。

image:https://assets.digitalocean.com/articles/memsql/img2.png [速度テストの結果例]

このチュートリアルでは、複数のサーバーにMemSQLをインストールする方法については説明しませんが、比較のために、3つの8GB Ubuntu 14.04ノード(1つのアグリゲーターノードと2つのリーフノード)があるMemSQLクラスターのベンチマークを次に示します。

画像:https://assets.digitalocean.com/articles/memsql/img3.png [img]

リーフノードの数を2倍にすることで、挿入率をほぼ2倍にすることができました。 * Rows Read *セクションを見ると、3ノードクラスターが、同じ時間内に単一ノードクラスターよりも12M多くの行を同時に読み取ることができたことがわかります。

ステップ3-mysql-clientを介してMemSQLと対話する

クライアントにとって、MemSQLはMySQLのように見えます。どちらも同じプロトコルを話します。 MemSQLクラスターとの対話を開始するには、mysqlクライアントをインストールしましょう。

最初に、次のステップで最新のクライアントをインストールするようにaptを更新します。

sudo apt-get update

次に、MySQLクライアントをインストールします。 これにより、実行する `+ mysql`コマンドが提供されます。

sudo apt-get install mysql-client-core-5.6

これで、MySQLクライアントを使用してMemSQLに接続する準備が整いました。 * root *ユーザーとして、ポート3306でホスト + 127.0.0.1 +(ローカルホストIPアドレス)に接続します。 また、プロンプトメッセージを「+ memsql> +」にカスタマイズします。

mysql -u root -h 127.0.0.1 -P 3306 --prompt="memsql> "

数行の出力に続いて `+ memsql> +`プロンプトが表示されます。

データベースをリストしましょう。

show databases;

この出力が表示されます。

データベース出力

+--------------------+
| Database           |
+--------------------+
| information_schema |
| memsql             |
| sharding           |
+--------------------+
3 rows in set (0.01 sec)
  • tutorial *という新しいデータベースを作成します。

create database tutorial;

次に、「+ use +」コマンドで新しいデータベースの使用に切り替えます。

use tutorial;

次に、 + id of`と + email + フィールドを持つ + user in`テーブルを作成します。 これら2つのフィールドのタイプを指定する必要があります。 idをbigintにして、長さ255のvarcharをメールで送信しましょう。 また、データベースに、「+ id 」フィールドが主キーであり、「 email +」フィールドをnullにできないことを伝えます。

create table users (id bigint auto_increment primary key, email varchar(255) not null);

その最後のコマンドの実行時間が短い(15〜20秒)ことがあります。 MemSQLがこの新しいテーブルの作成に時間がかかる主な理由は、コード生成です。

内部では、MemSQLは_code generation_を使用してクエリを実行します。 これは、新しいタイプのクエリが検出されるたびに、MemSQLがクエリを表すコードを生成およびコンパイルする必要があることを意味します。 このコードは、実行のためにクラスターに送られます。 これにより、実際のデータの処理が高速化されますが、準備に費用がかかります。 MemSQLは、事前に生成されたクエリを再利用するためにできることを行いますが、構造がまだ確認されていない新しいクエリの速度は低下します。

usersテーブルに戻って、テーブル定義を見てください。

describe users;

テーブル定義の出力

+-------+--------------+------+------+---------+----------------+
| Field | Type         | Null | Key  | Default | Extra          |
+-------+--------------+------+------+---------+----------------+
| id    | bigint(20)   | NO   | PRI  | NULL    | auto_increment |
| email | varchar(255) | NO   |      | NULL    |                |
+-------+--------------+------+------+---------+----------------+
2 rows in set (0.00 sec)

それでは、いくつかのサンプルメールをユーザーテーブルに挿入しましょう。 この構文は、MySQLデータベースに使用するものと同じです。

insert into users (email) values ('[email protected]'), ('[email protected]'), ('[email protected]');

電子メール出力の挿入

Query OK, 3 rows affected (1.57 sec)
Records: 3  Duplicates: 0  Warnings: 0

ここで、ユーザーテーブルをクエリします。

select * from users;

入力したデータを確認できます。

ユーザー表出力

+----+-------------------+
| id | email             |
+----+-------------------+
|  2 | [email protected]   |
|  1 | [email protected]   |
|  3 | [email protected] |
+----+-------------------+
3 rows in set (0.07 sec)

ステップ4-JSONの挿入とクエリ

MemSQLはJSON型を提供するため、このステップでは、着信イベントを利用するためのイベントテーブルを作成します。 このテーブルには(ユーザーに対して行ったように) + id`フィールドと、JSONタイプの + event on`フィールドがあります。

create table events (id bigint auto_increment primary key, event json not null);

いくつかのイベントを挿入しましょう。 JSON内で、ステップ3で挿入したユーザーのIDを参照する「+ email +」フィールドを参照します。

insert into events (event) values ('{"name": "sent email", "email": "[email protected]"}'), ('{"name": "received email", "email": "[email protected]"}');

これで、挿入したイベントを確認できます。

select * from events;

イベントテーブル出力

+----+-----------------------------------------------------+
| id | event                                               |
+----+-----------------------------------------------------+
|  2 | {"email":"[email protected]","name":"received email"} |
|  1 | {"email":"[email protected]","name":"sent email"}     |
+----+-----------------------------------------------------+
2 rows in set (3.46 sec)

次に、JSONの `+ name +`プロパティがテキスト「received email」であるすべてのイベントをクエリできます。

select * from events where event::$name = 'received email';

「受信メール」クエリ出力

+----+-----------------------------------------------------+
| id | event                                               |
+----+-----------------------------------------------------+
|  2 | {"email":"[email protected]","name":"received email"} |
+----+-----------------------------------------------------+
1 row in set (5.84 sec)

そのクエリを変更して、「+ name +」プロパティが「sent email」というテキストであるものを見つけてください。

select * from events where event::$name = 'sent email';

「送信メール」クエリ出力

+----+-------------------------------------------------+
| id | event                                           |
+----+-------------------------------------------------+
|  1 | {"email":"[email protected]","name":"sent email"} |
+----+-------------------------------------------------+
1 row in set (0.00 sec)

この最新のクエリは、前のクエリよりもはるかに高速に実行されました。 これは、クエリ内のパラメーターのみを変更したため、MemSQLはコード生成をスキップできたためです。

分散SQLデータベースについて高度なことをしましょう。結合の1つの値がJSON値内にネストされているが、異なるJSON値でフィルター処理される非プライマリキーで2つのテーブルを結合しましょう。

まず、イベントテーブルが結合されたユーザーテーブルのすべてのフィールドに、イベント名が「received email」である一致する電子メールを要求します。

select * from users left join events on users.email = events.event::$email where events.event::$name = 'received email';

「受信メール」フィールドの出力

+----+-----------------+------+-----------------------------------------------------+
| id | email           | id   | event                                               |
+----+-----------------+------+-----------------------------------------------------+
|  2 | [email protected] |    2 | {"email":"[email protected]","name":"received email"} |
+----+-----------------+------+-----------------------------------------------------+
1 row in set (14.19 sec)

次に、同じクエリを試しますが、「送信メール」イベントのみにフィルターをかけます。

select * from users left join events on users.email = events.event::$email where events.event::$name = 'sent email';

「送信メール」フィールドの出力

+----+-----------------+------+-------------------------------------------------+
| id | email           | id   | event                                           |
+----+-----------------+------+-------------------------------------------------+
|  1 | [email protected] |    1 | {"email":"[email protected]","name":"sent email"} |
+----+-----------------+------+-------------------------------------------------+
1 row in set (0.01 sec)

前と同様に、2番目のクエリは最初のクエリよりもはるかに高速でした。 ベンチマークで見たように、数百万行以上を実行するとコード生成のメリットが得られます。 JSONを理解し、テーブル間で任意に参加する方法を理解するスケールアウトSQLデータベースを使用する柔軟性は、強力なユーザー機能です。

結論

MemSQLをインストールし、ノードのパフォーマンスのベンチマークを実行し、標準のMySQLクライアントを介してノードと対話し、MySQLにはないいくつかの高度な機能を試しました。 これは、インメモリSQLデータベースができることの良い味です。

MemSQLが実際にデータを分散する方法、パフォーマンスを最大化するためにテーブルを構造化する方法、複数のノードにMemSQLを拡張する方法、高可用性のためにデータをレプリケートする方法、MemSQLを保護する方法について学ぶことはまだたくさんあります。