Ubuntu14.04にMemSQLをインストールする方法
MemSQLと共同で作成
序章
MemSQLは、従来のデータベースよりも高速な読み取りと書き込みを提供できるインメモリデータベースの一種です。 これは新しいテクノロジーですが、MySQLプロトコルを話すため、操作に非常に慣れているように感じます。
MemSQLは、JSONサポートやデータのアップサート機能などの最新機能を備えたMySQLの最新機能を採用しています。 MySQLに対するMemSQLの最大の利点の1つは、超並列処理と呼ばれる、単一のクエリを複数のノードに分割できることです。これにより、読み取りクエリがはるかに高速になります。
このチュートリアルでは、単一のUbuntu 14.04サーバーにMemSQLをインストールし、パフォーマンスベンチマークを実行し、コマンドラインMySQLクライアントを介してJSONデータを挿入してみます。
前提条件
このチュートリアルに従うには、次のものが必要です。
-
少なくとも8GBのRAMを搭載した1つのUbuntu14.04×64ドロップレット
-
sudo権限を持つroot以外のユーザー。これは、 Ubuntu14.04チュートリアルを使用したサーバーの初期設定に従って設定できます。
ステップ1—MemSQLのインストール
このセクションでは、MemSQLをインストールするための作業環境を準備します。
MemSQLの最新バージョンは、ダウンロードページにリストされています。 MemSQL Opsをダウンロードしてインストールします。これは、MemSQLを正しく実行するためのサーバーのダウンロードと準備を管理するプログラムです。 執筆時点でのMemSQLOpsの最新バージョンは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] y
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...
これで、MemSQLクラスターがUbuntuサーバーにデプロイされました。 ただし、上記のログから、MemSQLが2回インストールされていることがわかります。
MemSQLは、アグリゲーターノードとリーフノードの2つの異なる役割として実行できます。 MemSQLが2回インストールされた理由は、クラスターが動作するために少なくとも1つのアグリゲーターノードと少なくとも1つのリーフノードが必要なためです。
アグリゲーターノードは、MemSQLへのインターフェイスです。 外の世界から見ると、MySQLによく似ています。同じポートでリッスンし、MySQLと通信することを期待するツールと標準のMySQLライブラリを接続できます。 アグリゲーターの仕事は、すべてのMemSQLリーフノードについて知り、MySQLクライアントを処理し、それらのクエリをMemSQLに変換することです。
リーフノードは実際にデータを格納します。 リーフノードは、アグリゲーターノードからデータの読み取りまたは書き込みの要求を受信すると、そのクエリを実行し、結果をアグリゲーターノードに返します。 MemSQLを使用すると、複数のホスト間でデータを共有でき、各リーフノードにはそのデータの一部があります。 (単一のリーフノードがある場合でも、データはそのリーフノード内で分割されます。)
複数のリーフノードがある場合、アグリゲーターは、MySQLクエリをそのクエリに関与する必要のあるすべてのリーフノードに変換する役割を果たします。 次に、すべてのリーフノードから応答を受け取り、結果を1つのクエリに集約してMySQLクライアントに返します。 これは、並列クエリの管理方法です。
シングルホストセットアップでは、アグリゲーターとリーフノードが同じマシンで実行されていますが、他の多くのマシンにさらに多くのリーフノードを追加できます。
ステップ2—ベンチマークを実行する
MemSQLのインストールスクリプトの一部としてインストールされたMemSQLOpsツールを使用して、MemSQLがどれだけ高速に動作するかを見てみましょう。
Webブラウザーで、http://your_server_ip:9000
に移動します
MemSQL Opsツールは、クラスターの概要を提供します。 マスターアグリゲーターとリーフノードの2つのMemSQLノードがあります。
単一マシンのMemSQLノードで速度テストを行いましょう。 左側のメニューからSpeedTest をクリックし、 STARTTESTをクリックします。 表示される可能性のある結果の例を次に示します。
このチュートリアルでは、複数のサーバーにMemSQLをインストールする方法については説明しませんが、比較のために、3つの8GB Ubuntu 14.04ノード(1つのアグリゲーターノードと2つのリーフノード)を備えたMemSQLクラスターのベンチマークを示します。
リーフノードの数を2倍にすることで、挿入率をほぼ2倍にすることができました。 行の読み取りセクションを見ると、3ノードのクラスターが同じ時間内に単一ノードのクラスターよりも12M多くの行を同時に読み取ることができたことがわかります。
ステップ3—mysql-clientを介したMemSQLとの対話
クライアントにとって、MemSQLはMySQLのように見えます。 どちらも同じプロトコルを話します。 MemSQLクラスターとの通信を開始するには、mysql-clientをインストールしましょう。
まず、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
フィールドとemail
フィールドを持つusers
テーブルを作成します。 これら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がこの新しいテーブルの作成に時間がかかる主な理由が1つあります。それは、コード生成です。
内部的には、MemSQLはコード生成を使用してクエリを実行します。 つまり、新しいタイプのクエリが検出されるたびに、MemSQLはクエリを表すコードを生成してコンパイルする必要があります。 次に、このコードは実行のためにクラスターに送信されます。 これにより、実際のデータの処理が高速化されますが、準備にはコストがかかります。 MemSQLは、事前に生成されたクエリを再利用するためにできることを実行しますが、構造がまだ確認されていない新しいクエリでは速度が低下します。
ユーザーテーブルに戻り、テーブル定義を確認します。
- 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)
それでは、usersテーブルにいくつかのサンプルメールを挿入しましょう。 この構文は、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
次に、usersテーブルをクエリします。
- 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
フィールド(ユーザーの場合と同様)とevent
フィールドがあります。これはJSONタイプになります。
- create table events (id bigint auto_increment primary key, event json not null);
いくつかのイベントを挿入しましょう。 JSON内で、email
フィールドを参照します。このフィールドは、手順3で挿入したユーザーのIDを参照します。
- 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)
次に、JSONname
プロパティが「受信した電子メール」というテキストであるすべてのイベントをクエリできます。
- 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
プロパティが「sentemail」というテキストであるクエリを見つけてみてください。
- 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つのテーブルを結合しましょう。
まず、イベント名が「受信メール」であるメールを照合することにより、イベントテーブルが結合されたユーザーテーブルのすべてのフィールドを要求します。
- 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を保護する方法について学ぶことはまだたくさんあります。