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
<?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 <?xml version="1.0" encoding="UTF-8" ?> <data> <info> <datetime>%s</datetime> <address>%s</address> <content>%s</content> </info> </data> 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といいます。 炭水化物大好き 日々の「なんじゃ?」を記事にしてます。