2011年8月31日水曜日

EC2でMySQL(Spider編3 Spiderの先にSpider)

EC2はあまり関係なくなってきていますが、Spiderの話題はまだ続きます。
Spiderの特性や構成を考えていくと、Spiderで分割するためのパーティショニングにより、さまざまな分割方法を考えることができます。
また、データが増加していくと、分散した先でもさらに負荷軽減が必要になる可能性も考えられます。

Spider編1で少し触れましたが、Spiderはストレージエンジンであり、リンク先のテーブルのストレージエンジンに制限はありません。
ここで、Spiderのリンク先にSpiderテーブルを指定したらどうなるか実験してみました。

構成は以下のとおりです。
ここでは全てTokyoリージョン内とします。
またIPは仮のものです。



  • SpiderノードA(111.111.0.1)
  • データノードA-1(111.111.0.2)
  • SpiderノードB(111.111.0.3)
  • データノードB-1(111.111.0.4)
  • データノードB-2(111.111.0.5)

SpiderノードBはSpiderノードAのデータノードとしての振る舞い、また一方でデータノードB-1,B-2のSpiderノードとしても振る舞います。
インストールやデータベースの作成、セキュリティグループの設定など基本的な部分は、前回、前々回と同じため省きます。


データノードの設定

SpiderノードA、SpiderノードB以外の全てのデータノードでmemberテーブルを作成します。
# mysql -u root
mysql> use cloudpack
Database changed
mysql> create table member(
id int(11) auto_increment,
name varchar(256),
primary key(id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8; 

データノードA-1、SpiderノードBではSpiderノードAを許可します。
mysql> GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@"spider-a" IDENTIFIED BY 'remote_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@"111.111.0.1" IDENTIFIED BY 'remote_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@"ec2-111-111-0-1.ap-northeast-1.compute.amazonaws.com" IDENTIFIED BY 'remote_pass'; 

データノードB-1、B-2ではSpiderノードBを許可します。
mysql> GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@"spider-b" IDENTIFIED BY 'remote_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@"111.111.0.3" IDENTIFIED BY 'remote_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@"ec2-111-111-0-3.ap-northeast-1.compute.amazonaws.com" IDENTIFIED BY 'remote_pass';

SpiderノードAの設定

まず最終的に全てを束ねるSpiderノードAを設定します。
データノードA-1とSpiderノードBにリンクを張りますが、
ここでのパーティショニングはRANGEパーティションを採用します。
idの1~5がデータノードA-1、6~10がSpiderノードBに流れるように設定しました。
mysql> create table member(
id int(11) auto_increment,
name varchar(256),
primary key(id)
) engine = Spider DEFAULT CHARSET=utf8
CONNECTION ' table "member", user "remote_user", password "remote_pass" '
PARTITION BY RANGE (id) (
    PARTITION data-a1 VALUES LESS THAN (6) comment 'host "111.111.0.2", port "3306"',
    PARTITION spider-b VALUES LESS THAN (11) comment 'host "111.111.0.3", port "3306"'
);

SpiderノードBの設定

次にSpiderノードBを設定します。
データノードB-1,B-2を束ねますが、
ここではKEYパーティションで分散させます。
mysql> create table member(
id int(11) auto_increment,
name varchar(256),
primary key(id)
) engine = Spider DEFAULT CHARSET=utf8
CONNECTION ' table "member", user "remote_user", password "remote_pass" '
PARTITION BY KEY() (
    PARTITION data-b1 comment 'host "111.111.0.4", port "3306"',
    PARTITION data-b2 comment 'host "111.111.0.5", port "3306"'
);
これで設定は終了です。


確認

それではSpiderノードAで以下のように、10行追加してみます。
# mysql -u root
mysql> use cloudpack
Database changed
mysql> INSERT INTO member (name) VALUES ('ichiro'),('jiro'),('sub-Low'),('shiro'),('goro'),('rokuro'),('shichro'),('hachiro'),('kuro'),('juro');
Query OK, 10 rows affected (0.03 sec)
Records: 10  Duplicates: 0  Warnings: 0

SELECTすると正常に10件投入されていることが確認できます。
mysql> select * from member order by id;
+----+---------+
| id | name    |
+----+---------+
|  1 | ichiro  |
|  2 | jiro    |
|  3 | sub-Low |
|  4 | shiro   |
|  5 | goro    |
|  6 | rokuro  |
|  7 | shichro |
|  8 | hachiro |
|  9 | kuro    |
| 10 | juro    |
+----+---------+
10 rows in set (0.00 sec)

それでは、各ノードにどのように分配されているか見てみましょう。

●データノードA-1
ここにはRANGEパーティションのルールどおり、idの1~5が投入されています。
mysql> select * from member order by id;
+----+---------+
| id | name    |
+----+---------+
|  1 | ichiro  |
|  2 | jiro    |
|  3 | sub-Low |
|  4 | shiro   |
|  5 | goro    |
+----+---------+
5 rows in set (0.00 sec)

●SpiderノードB
こちらもRANGEパーティションのルールどおり、idの6~10が投入されています。
mysql> select * from member order by id;
+----+---------+
| id | name    |
+----+---------+
|  6 | rokuro  |
|  7 | shichro |
|  8 | hachiro |
|  9 | kuro    |
| 10 | juro    |
+----+---------+
5 rows in set (0.01 sec)

しかし、これは別のSpiderノードでもあり、データノードB-1,B-2にさらに分散されています。
さらに、その分散先を見てみます。

●データノードB-1
mysql> select * from member order by id;
+----+---------+
| id | name    |
+----+---------+
|  7 | shichro |
|  9 | kuro    |
+----+---------+
2 rows in set (0.00 sec)

●データノードB-2
mysql> select * from member order by id;
+----+---------+
| id | name    |
+----+---------+
|  6 | rokuro  |
|  8 | hachiro |
| 10 | juro    |
+----+---------+
3 rows in set (0.00 sec)

SpiderノードBの先で、さらにKEYパーティショニングによって、idのハッシュ値で均等に分散されていることがわかります。

このように、途中で負荷が増えても、さらに分散させて1ノードあたりの負荷を減らすことも可能です。

以上です。