share facebook facebook2 twitter menu hatena pocket slack

2013.06.07 FRI

spiderってなんじゃ?(spider自身の冗長化)

三浦 悟

WRITTEN BY三浦 悟

いままではSpiderがひとつに対して、データノードが複数ある構成をとってきましたが、実戦ではSpiderが単一障害点になるため好ましくありません。ここではSpider自身の冗長化を行なってみます。
いままでのSpider x 1 + mroonga x 2 の構成に対してデータを入れ込むためのappノードを用意します。

○SpoderのSPOF

■mroonga


CREATE TABLE doc (
id INT PRIMARY KEY AUTO_INCREMENT,
created_at datetime,
content text,
FULLTEXT INDEX (content)
) ENGINE = mroonga;

■spider


CREATE TABLE doc (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
created_at datetime,
content text,
FULLTEXT INDEX (content)
) ENGINE = spider CHARSET utf8
CONNECTION ' table "doc", user "memorycraft_user", password "memorycraft_pass" '
PARTITION BY KEY() (
PARTITION db1 comment 'host "10.0.1.136", port "3306"',
PARTITION db2 comment 'host "10.0.1.137", port "3306"'
);

■app


# yum install -y php php-mbstring php-pdo php-mysql
$ vim links.php


//ランダム文字列
function getRandomString($size = 8){
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
mt_srand();
$char = "";
for($i = 0; $i < $size; $i++) {
$char .= $chars{mt_rand(0, strlen($chars) - 1)};
}
return $char;
}

//XMLテンプレート
$tmpl =<<< END



%s
%s

%s


END;

//XMLテンプレートに流しこむcontent要素の内容を読み込む
$contents = array();
for($i=0;$i<10;$i++){
$contents[] = file_get_contents(dirname(__FILE__)."/dummy".$i.".txt");
}

//spiderホストは引数から取得する
$host = $argv[1];
//タイムゾーン
date_default_timezone_set('Asia/Tokyo');

//無限ループ
while(true){
//XMLテンプレートに各要素を割り当てる
$xml = sprintf($tmpl, date('Y/m/d H:i:s'), getRandomString(), $contents[rand(0,9)]);
echo ".";
//DB接続
$pdo = new PDO(
"mysql:dbname=memorycraft;host=$host;",
"memorycraft_user",
"memorycraft_pass",
array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`"
));
$pdo->query("SET NAMES utf8;");
//投入
$st = $pdo->prepare("INSERT INTO doc VALUES(NULL,NOW(),?);");
$rslt = $st->execute(array($xml));
}
?>

実行します


$ php links.php 10.0.1.20
.......................................

Spiderノードで投入されていることを確認します。


mysql> select id, created_at from doc limit 10;
+------+---------------------+
| id | created_at |
+------+---------------------+

| 1 | 2013-05-25 11:27:47 |
| 2 | 2013-05-25 11:27:47 |
| 3 | 2013-05-25 11:27:47 |
| 4 | 2013-05-25 11:27:47 |
| 5 | 2013-05-25 11:27:47 |
| 6 | 2013-05-25 11:27:48 |
| 7 | 2013-05-25 11:27:48 |
| 8 | 2013-05-25 11:27:48 |
| 9 | 2013-05-25 11:27:48 |
| 10 | 2013-05-25 11:27:48 |
+------+---------------------+
10 rows in set (0.06 sec)

これで、spider x 1 + mroonga x 2 + app x 1になりました。

○Spiderの冗長化

次は、Spider x 2 + mroonga x 2 + internal ELB + app x 4 にしてみます。

Spiderノードをもう1台(spider2)追加します。

テーブルはspider1と同じ内容にします。
/etc/my.cnfでauto_increment_increment = 100でoffsetを1,2でずらします。
これについては、こちらの記事「mysqlってなんじゃ?(マルチマスタでauto_increment)」で触れています。

また、spiderを複数にした場合、appからの接続は1つにまとめます。
Proxy系のソフトウェアを入れるのも1つの方法ですが、ここでは内部ELBを利用してみます。

ヘルスチェックは3306ではなく別のポート経由でMySQL監視プロセスに接続すべきですが、ここではとりいそぎhttpdを立ちあげ80番に対してヘルスチェックします。

それではappで投入プログラムを実行します。
対象のホストは内部ELBのDNSNameになります。


$ php links.php internal-spider-2040122974.ap-northeast-1.elb.amazonaws.com
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

spider1でデータを見てみます。


mysql> select id, created_at from doc limit 20;
+------+---------------------+
| id | created_at |
+------+---------------------+
| 1 | 2013-05-25 11:27:47 |
| 101 | 2013-05-25 11:27:47 |
| 201 | 2013-05-25 11:27:47 |
| 202 | 2013-05-25 11:27:47 |
| 601 | 2013-05-25 11:27:47 |
| 701 | 2013-05-25 11:27:48 |
| 1101 | 2013-05-25 11:27:48 |
| 1201 | 2013-05-25 11:27:48 |
| 1601 | 2013-05-25 11:27:48 |
| 1701 | 2013-05-25 11:27:48 |
| 2101 | 2013-05-25 11:27:49 |
| 2201 | 2013-05-25 11:27:49 |
| 2301 | 2013-05-25 11:27:49 |
| 2601 | 2013-05-25 11:27:49 |
| 2701 | 2013-05-25 11:27:49 |
| 2802 | 2013-05-25 11:27:49 |
| 3101 | 2013-05-25 11:27:49 |
| 3201 | 2013-05-25 11:27:49 |
| 3301 | 2013-05-25 11:27:49 |
| 3601 | 2013-05-25 11:27:50 |
+------+---------------------+

mysql> select count(*) from doc;
+----------+
| count(*) |
+----------+
| 111433 |
+----------+

順調に入っていってるみたいです。
あとはSpiderノードを必要に応じて追加していき、my.cnfでoffsetをずらして起動するだけです。
offsetずらしの処理はcloud-initなどで行うと、AutoScalingすることもできそうです。

こちらの記事はなかの人(memorycraft)監修のもと掲載しています。
元記事は、こちら

三浦 悟

三浦 悟

高円寺在住のなんじゃ系男子 またの名をmemorycraftといいます。 炭水化物大好き 日々の「なんじゃ?」を記事にしてます。