Docker+Amazon ECS+ElasticSearchでkibana用のElasticSearchクラスタ

[AWS][ECS][ElasticSearch][Docker] Docker+Amazon ECS+ElasticSearchでkibana用のElasticSearchクラスタを組んだ話


ElasticSearchクラスタをDockerでやろうと思った理由

  • chatopsでコンテナのデプロイをできる環境がある
    • 外出時に再起動だけならスマホでchatopsが可能
  • がっつりECSを利用している環境になっている
    • 本番環境もECSを利用
  • ElasticSearchはクラスタにジョインしたらデータをうまく分散してくれる
    • 手動リストアする必要がない
  • dockerhub にElasticSearchのDockerfileがある
    • そのまま使えるかも
      • 後述するが、少しいじった



上記理由からElasticSearchをDocker+ECSでやってみることにした

設計

1ECSクラスタ、1オートスケールのパターン(webサーバはこの構成)
  • ECSの1クラスタで全コンテナを立ち上げ直してしまう
    • 全台コンテナが再立ち上げされてしまうとElasticSearchへの接続がすべて止まってしまう
  • オートスケールで縮小する時レプリカ数と同じ台数が一気に落ちるとデータロストが起きてしまう


*** 上記理由から1ECSクラスタ、1オートスケールのパターンは無しにした


1ECSクラスタ、1インスタンス、複数Dockerコンテナのパターン
  • ECSの1クラスタで全コンテナを立ち上げ直してしまう
    • 先ほど同様ElasticSearchへの接続がすべて止まってしまう
    • コンテナからホストDiskをマウントすればデータロストは起きない
  • ホスト障害があった時にElasticSearchへの接続が止まる
    • EBSを利用していればOSを起動すればデータロストはない
      • AutoRecoveryも合わせて使うとよい


*** 分散型データストアなのに1台ホストが死んだら接続できなくなる時点でダメなので無しにした


1ECSクラスタ、1インスタンス、1Dockerコンテナのパターン
  • ECSでデプロイしても1コンテナが立ち上げ直されるだけ
    • なのでクラスタ内でリシャードは発生するが接続は瞬断がおきるレベルでほぼ影響なし
    • デプロイも1台ずつ順番に可能になる
  • ホスト障害があっても1コンテナが落ちるだけなのでクラスタ自体は壊れない
    • 複数ホストの同時障害は考えないものとする(Dockerとか関係ない部分)
    • EBSを利用してコンテナからホストDiskをマウントすればOSが再起動してもデータは残っているのでリシャード時間が短くなる
    • AutoRecoveryも使うと尚良
  • 手動でconfigはいじれないがconfigを変えたDocker imageを1台ずつ変更して設定できる
  • クラスタ分EC2を立てるのでお金はかかる
  • linkでのコンテナ間通信はできないのでホストに対して接続するようにしなければいけない


*** メリットも多いのでこの構成で行くことにした


ElasticSearch on Dockerでハマったポイント

  • dockerhubのDockerfileだとCLUSTER_NAMEやヒープサイズの指定ができない?
    • 調査不足感はあります
  • AWS自体でDocker関係なくあるのがMULTICASTは使えないのでUNICASTでクラスタを組む必要がある
    • UNICASTでホストを都度増やすなどconfig変更が大変
    • elasticsearch-cloud-aws MULTICASTができるができるだけVPC内通信でやりたかった
  • コンテナ内にelasticsearchユーザを作らないと起動できず
  • DockerからPublishするIPがコンテナのIPになってしまってクラスタが組めなかった


ハマったポイントの解決策
  • dockerhubのDockerfileをベースに起動スクリプトを自前で作成した
    • ECSで指定した環境変数もこの起動スクリプトで拾いconfigをsedで書き換えた
    • 環境変数を利用することで開発環境と本番環境のDockerfileは同じものを利用できる
  • config内のUNICAST先を増やす度にconfig再起動等したくないのでUNICAST先をELBにした
    • terraformを使っているのでホストを追加する度にELBにも追加して自動でクラスタのホスト追加ができるようにした

  • elasticsearchユーザを作ってもよかったがDocker imageを少しでも小さくするためrootで起動できるようにした
    • elasticsearchコマンドで起動オプションに-Des.insecure.allow.root=trueを付けた
  • publishIPがコンテナになってしまうのはホスト側のIPで出るようにした
    • elasticsearchコマンドで起動オプションに-Des.network.publish_host=${local_dns}を付けた
      • ${local_dns}はterraformでEC2を作る際にNAME_TAG.hoge.localと内部DNSをRoute53で設定しているものを指定するようにした


以上のハマったポイントを直したことでDocker+ECSのElasticSearchクラスタが構築できました。コンテナの再起動もchatopsでできるようになり簡単な再起動だけならパソコンを開く必要もなくなりました(*´ω`*)



kibanaからの接続

UNICASTでELBを作成したので、kibanaからも同じELBを指定しておくことでノードが増えてもkibana側の設定変更がいらなくなった

本番のアクセスログをkibanaにぶっこんだら問題が

  • 容量が多すぎてElasticSearchでOOMが発生
  • Disk容量も数日で7割近く利用している



ヒィィィ((((;゚Д゚))))ガクガクブルブル
やべーよ、ちょっと甘くみてたよ((((;゚Д゚))))ガクガクブルブル


対応
  • EC2のスペックアップをする
    • ついでにEBSの容量も大容量に・・・
  • terraformで1台ずつスペックとEBS容量を増やしてapplyした
    • 1台ずつEC2を再作成させ、chatopsでデプロイを行って、Diskのデータはなくなるがリシャードでクラスタがgreenになるのを待つ
  • これを繰り返してスペックアップを行えた


高速スケーラブル検索エンジン ElasticSearch Server (アスキー書籍)

高速スケーラブル検索エンジン ElasticSearch Server (アスキー書籍)

Amazon Web Services企業導入ガイドブック -企業担当者が知っておくべきAWSサービスの全貌から、セキュリティ概要、システム設計、導入プロセス、運用まで-

Amazon Web Services企業導入ガイドブック -企業担当者が知っておくべきAWSサービスの全貌から、セキュリティ概要、システム設計、導入プロセス、運用まで-

EC2(EBS)はオンラインではDisk容量は増やせない

※最下部に追記あり

っぽい。管理コンソールからいろいろ見てみたけどなさそう。
これ調べた理由はEBSボリュームのsnapshotを自動で取るようにしたけど、実際それを使ってどうやって戻すんだろうかという手順知らないからちゃんと確認しただけ。

EBSについてはこちらの資料がわかりやすいと思います

AWS歴1ヶ月ちょいの人が書いてるので間違えがあったらツッコミお願いします

1. 対象のインスタンスを確認する

ここで確認するのは「ルートデバイスタイプ」が「ebs」になっていること。
ebsタイプじゃないインスタンスインスタンスタイプで容量が決まってるので変更できません。
あともう一つ、アベイラビリティゾーン(今後AZと略します)の確認。
今回は「ap-northeast-1a」である。
なんでAZを確認するかは後述します。

2. ボリュームから対象のEBSを選択してSnapshotを取得する

EC2の管理コンソールからボリュームをクリックするとEBSボリュームが表示されます。
Nameタグは空なのでわかりづらいですが、どのインスタンスにアタッチされているかは「アタッチ済み情報」を見るとEC2インスタンスのNameタグの名前が表示されているので、対象のEBSボリュームをクリックして選択します。
そしたら上の方にある「アクション」をクリックして「スナップショットの作成」をクリックします。

そしたら「Name」と「説明」の入力欄が出るのでわかりやすく入力してください。

「作成」をクリックするとSnapshotが作成が始まります


3. Snapshotから作成したSnapshotの確認

2で作成したSnapshotができていることをここで確認します。容量が大きいと時間かかるかも。8GBだと結構一瞬で終わります。

今度はSnapshotからボリュームを作成します。
EC2管理コンソールのスナップショットから対象のものを選びます。
2でSnapshotを作成するときにNameを指定したものを見ればわかりますが、Snapshotのボリュームの項目を見るとEBSボリュームIDが書かれているのでそこでも確認できます。同じEBSボリュームIDのものが複数ある場合は「開始」の項目を見ていつ作られたものかで確認してください。
SnapshotはS3上にあるためそのままEBSとしては利用ができません。ちなみにS3の管理コンソールを見てもEBSのSnapshotは見えないのでご注意ください。S3を使ってるのでSnapshotを取り過ぎるとそれだけお金もかかるので注意です( ・`ω・´)
対象のスナップショットをクリックして選択したら上の「アクション」から「ボリュームの作成」をクリックします。

ここでボリュームのタイプ、サイズ、AZが選択できます。
タイプは変更する必要なければ今までのものと同じものを選択し、サイズは容量を増やす場合は希望の容量を記載します。ちなみにSnapshot取得時の容量よりも少なくすることはできないので要注意です。
AZの選択は要注意です。1で容量を変更するEC2インスタンスのAZを確認したのはここで必要だからです。
今回は「ap-northeast-1a」が対象のAZだったためこのAZを選択します。
異なるAZのEBSをEC2インスタンスはアタッチすることができないため、同じAZを選択する必要があります。

「作成」を押すとEBSボリュームが作成されます。

ここでは作成されたボリュームIDは確認しておきましょう。EBSボリューム数が少なければわかりやすいですが、アタッチされてないものが多いと行方不明になります。
(ボリュームのNameタグの入力項目くらい作って欲しいものです)

4. 作成したEBSボリュームをEC2にアタッチして容量を増やす

3で作成したEBSボリュームを確認します。

ここで見るべきは「状態」です。「In-use」の場合はEC2インスタンスにアタッチ済みになります。「available」の場合はどのEC2インスタンスからもアタッチされていないので利用可能です。
今8GBのボリュームがアタッチされていて、30GBのボリュームはアタッチされていないものになります。
このままではEC2に割り当てるボリュームを付け替えられないので、まずは対象のEC2インスタンスを停止します。

インスタンスから対象のEC2インスタンスを選択して「アクション」から「インスタンスの状態」→「停止」を選択します。
OS自体がシャットダウンされるので、サービス影響があるEC2インスタンスの場合はメンテナンス等に振るか、ELBから外して影響ないようにします。
EC2インスタンスを停止したら今度は、今までアタッチしていたEBSボリュームをデタッチ(外す)します。

外れない場合は「強制デタッチ」してもいいかも。でも「デタッチ」でエラーになる場合はEC2インスタンスがちゃんと停止されてない可能性があるのでちゃんと確認します。
デタッチをするとEC2インスタンスの「ルートデバイス」の項目と「ブロックデバイス」が「-」になります。
インスタンスの管理画面で確認するとこんな感じです。

デタッチができたら、今度は容量を増やしたEBSボリュームをアタッチします。
対象のボリュームを選択して上の「アクション」から「ボリュームのアタッチ」を選択します。

どのインスタンスにアタッチするかの項目とデバイスのPATHを入力するように求められます。
インスタンスはNameタグのものを入力するとサジェストされるのでインスタンスIDを覚える必要はありません。インスタンスにNameタグがついてない場合はインスタンスIDを確認して入力してください。
バイスPATHは1で確認したものを入力します。今回は「/dev/sda1」でした。
「アタッチ」をクリックするとインスタンスにこのボリュームがアタッチされます。

アタッチするとボリュームの「状態」の項目が「In-use」に変わってるはずです。

5. アタッチしなおしたものになっているか確認する

EC2インスタンスのルートデバイスをクリックするとボリュームIDが表示されるので、新しいボリュームIDになっているのを確認します。

あとはインスタンスを起動してあげたら容量が変わっています。
ワーイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワーイ

まとめ

Snapshotを作成した後のファイル等は移行できないので、完全にインスタンスをサービスアウト(ファイル等更新されないようにする)してから本作業をすることをおすすめします。
更新されても捨てれるようなものだったらいいですが。
インスタンスを停止している状態からでも本作業は可能ですので、EBSを付け替える前にインスタンスを停止しておいた方がいいかも。差異がなくなるので。
容量を増やすのは割と簡単なので本番環境だからといって最初からガツンと容量を当てるのではなく、スモールスタートで容量を決めて後から必要になったら容量を増やす運用にするとコスト削減ができるのではないかと思います。

定期的にEBSのバックアップを取っている場合は3の作業から実施すればバックアップから復旧させることが可能ですので、手順としては同じになります。

追記

AMIがLVMを使っている場合上記手順だけではボリュームが増えませんでした。

下記スクリプトを作ってrootユーザで実行したらボリュームが増えました。
再起動(reboot)がかかるので気をつけてください。

 #!/bin/sh

DEVICE=/dev/xvda
RCLOCAL=/etc/rc.d/rc.local

# modify partition table
fdisk ${DEVICE} <> ${RCLOCAL}
echo -n 'lvresize -l +100%FREE /dev/VolGroup/lv_root && ' >> ${RCLOCAL}
echo -n 'resize2fs /dev/VolGroup/lv_root && ' >> ${RCLOCAL}
echo -n 'sed -i -e '\''$d'\'' /etc/rc.d/rc.local ' >> ${RCLOCAL}

reboot

ハマったのは

echo -n 'pvresize /dev/xvda1 && ' >> ${RCLOCAL}
の部分が配られてるスクリプトだとxvda2だったので適用されず、手動でxvda1に変更したら反映されました。

デフォルトのエディタがnanoで発狂しそうになった

とあるldapサーバでldapviでユーザ削除しようとした時にnanoで開かれてm9(^Д^)プギャーってなった。
作業はnanoで頑張ったんだけど、これは今後作業効率が悪いということでvimにしようと。
(多分初期の頃に選択できるタイミングがあったんだけど間違えたんだと思う)

で、どうやるのかわからなくてググったらでてきた。


# update-alternatives --config editor
There are 4 choices for the alternative editor (providing /usr/bin/editor).

Selection Path Priority Status
------------------------------------------------------------
* 0 /bin/nano 40 auto mode
1 /bin/ed -100 manual mode
2 /bin/nano 40 manual mode
3 /usr/bin/vim.basic 30 manual mode
4 /usr/bin/vim.tiny 10 manual mode

Press enter to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in manual mode.

これでとりあえず、3を選んだ

確認、


# update-alternatives --config editor
There are 4 choices for the alternative editor (providing /usr/bin/editor).

Selection Path Priority Status

                                                                                                                      • -

0 /bin/nano 40 auto mode
1 /bin/ed -100 manual mode
2 /bin/nano 40 manual mode
* 3 /usr/bin/vim.basic 30 manual mode
4 /usr/bin/vim.tiny 10 manual mode

ldapviで開いたらちゃんとvimになってましたよっと。
⊂(^ω^)⊃ セフセフ!!

elasticsearchの構築をしてみた

[Elasticsearch][構築]

環境

・サーバ
某社プライベートクラウド
CentOS release 6.5
4コア メモリ15GB Disk160GB
IPv4,IPv6両方付いてる
このインスタンスを4台(なんとなく4台にした)


・elasticsearch
バージョン: 1.0.1

構築手順

今回は公式サイトのダウンロードページにあるRPMを利用しようと思います

rpmのダウンロード

とりあえず、rootになってrpmファイルをダウンロードしてきます
※最新版は公式サイトに行ってURL確認してください


$ sudo su -
# cd /usr/local/src/
# wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.1.noarch.rpm

elasticsearchのインストール

そしたらローカルインストールをする


# yum install elasticsearch-1.0.1.noarch.rpm

ここで注意点があって、jdkが必要なんですがrpmで紐付けられてないので別途自分でインストールする必要があります。
今回はOracleJDKをrpm化したオレオレrpmで入れました。
/usr/bin/javaにパスが通ってる必要があるので、それ以外にjavaコマンドがある場合はシンボリックリンクとかチョメチョメしてパスを通してください。

設定をする

elasticsearchはymlファイルがconfになっているのでこいつを書き換えます。
中身は全てコメントアウトされていて書き換えなくても起動しますが、もろもろ変更するのでやります。
変更というか、追記です。


# vim /etc/elasticsearch/elasticsearch.yml

cluster.name: onuki-elasticsearch
node.name: "stg-onuki-elasticsearch01"
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["192.168.0.100", "192.168.0.101" , "192.168.0.102" , "192.168.0.103"]

これだけ追記しました。(IPは適当なのに書き換えてます)
elasticsearchはマルチキャストで勝手にノードを探してクラスタリングしてくれるんですが、
某社プライベートクラウドではクラスタリングできたり、できなかったりしました('A`)マンドクセ
たぶん、DHCPでv4を振ってるのでなんかダメなのかもしれないっす。そこの検証はしてないです。
そのため
discovery.zen.ping.multicast.enabled: false →マルチキャストしないように設定
discovery.zen.ping.unicast.hosts: [hogehoge] →クラスタリングするノードのIPを直書き('A`)ダセー

そして起動

rpmで入れたら起動スクリプトもあったのでそれで起動しました


# /etc/init.d/elasticsearch start
# ps uaxf |grep elasticsearch
497 17199 0.7 2.8 4519940 440188 ? Sl 17:39 2:02 /usr/bin/java -Xms256m -Xmx1g -Xss256k -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseCon
〜略〜

起動できました。

ログを見る

ログもあるのでログを眺めて見ます


# tail -f /var/log/elasticsearch/onuki-elasticsearch.log
[2014-03-05 22:29:04,467][INFO ][node ] [stg-onuki-elasticsearch01] version[1.0.1], pid[18703], build[5c03844/2014-02-25T15:52:53Z]
[2014-03-05 22:29:04,468][INFO ][node ] [stg-onuki-elasticsearch01] initializing ...
[2014-03-05 22:29:04,483][INFO ][plugins ] [stg-onuki-elasticsearch01] loaded [analysis-kuromoji], sites [head, bigdesk]
[2014-03-05 22:29:07,674][INFO ][node ] [stg-onuki-elasticsearch01] initialized
[2014-03-05 22:29:07,675][INFO ][node ] [stg-onuki-elasticsearch01] starting ...
[2014-03-05 22:29:07,900][INFO ][transport ] [stg-onuki-elasticsearch01] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.0.100:9300]}
[2014-03-05 22:29:10,955][INFO ][cluster.service ] [stg-onuki-elasticsearch01] new_master [stg-onuki-elasticsearch01][sjLm_35aRZWYN59AASGfBA][stg-onuki-elasticsearch01][inet[/192.168.0.100:9300]], reason: zen-disco-join (elected_as_master)
[2014-03-05 22:29:10,975][INFO ][discovery ] [stg-onuki-elasticsearch01] onuki-elasticsearch/sjLm_35aRZWYN59AASGfBA
[2014-03-05 22:29:11,018][INFO ][http ] [stg-onuki-elasticsearch01] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/192.168.0.100:9200]}
[2014-03-05 22:29:11,991][INFO ][gateway ] [stg-onuki-elasticsearch01] recovered [11] indices into cluster_state
[2014-03-05 22:29:12,684][INFO ][node ] [stg-onuki-elasticsearch01] started

なんか起動してる感のあるログになりました。

他のノードのelasticsearchも起動します。

02ノードのログはこんな感じになりました。


[2014-03-05 22:30:51,117][INFO ][transport ] [stg-onuki-elasticsearch02] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.0.101:9300]}
[2014-03-05 22:30:54,271][INFO ][cluster.service ] [stg-onuki-elasticsearch02] detected_master [stg-onuki-elasticsearch01][sjLm_35aRZWYN59AASGfBA][stg-onuki-elasticsearch01][inet[/192.168.0.100:9300]], added {[stg-onuki-elasticsearch01][sjLm_35aRZWYN59AASGfBA][stg-onuki-elasticsearch01][inet[/192.168.0.100:9300]],}, reason: zen-disco-receive(from master [[stg-onuki-elasticsearch01][sjLm_35aRZWYN59AASGfBA][stg-onuki-elasticsearch01][inet[/192.168.0.100:9300]]])
[2014-03-05 22:30:54,323][INFO ][discovery ] [stg-onuki-elasticsearch02] onuki-elasticsearch/8FYOPb0OT4iKc54jcJ493Q

クラスタリングされたっぽいログが出てます。

01ノードのログも見てみます


[2014-03-05 22:30:54,238][INFO ][cluster.service ] [stg-onuki-elasticsearch01] added {[stg-onuki-elasticsearch02][8FYOPb0OT4iKc54jcJ493Q][stg-onuki-elasticsearch02][inet[/192.168.0.101:9300]],}, reason: zen-disco-receive(join from node[[stg-onuki-elasticsearch02][8FYOPb0OT4iKc54jcJ493Q][stg-onuki-elasticsear
ch02][inet[/192.168.0.101:9300]]])

新しいノードを追加したログが出ていました。
今回4台用意したので全部起動して、それぞれ追加されたログが出ました。

ノードを追加する時

最初3台でクラスタリングを組んでノード05のIP(192.168.0.103)をymlにあえて書かずに起動させました。
ノード05の設定にはノード01〜03のIPをdiscovery.zen.ping.unicast.hosts:に追記して起動させたら
自動でクラスタリング組んでくれました。既存のノードの設定をいちいち書き換えて再起動とかいらないようです。

動作確認

curlでelasticsearchのHTTPポートを叩けるか試しました


# curl -XGET http://localhost:9200/
{
"status" : 200,
"name" : "stg-onuki-elasticsearch01",
"version" : {
"number" : "1.0.1",
"build_hash" : "5c03844e1978e5cc924dab2a423dc63ce881c42b",
"build_timestamp" : "2014-02-25T15:52:53Z",
"build_snapshot" : false,
"lucene_version" : "4.6"
},
"tagline" : "You Know, for Search"
}

ステータス200がちゃんと返ってきました。

次にデータのインサート、サーチをします。


# curl -X POST http://localhost:9200/hogege/dayo/5 -d '{"famiry_name":"onuki","first_name":"aaa","email" :"sample@sample.email.com","age":27}'
{"_index":"hogege","_type":"dayo","_id":"5","_version":1,"created":true}

# curl -X GET http://localhost:9200/hogege/dayo/_search -d '{"query":{"match":{"famiry_name":"onuki"}},"size":10,"from":0}'
{"took":109,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.30685282,"hits":[{"_index":"hogege","_type":"dayo","_id":"5","_score":0.30685282, "_source" : {"famiry_name":"onuki","first_name":"aaa","email" :"sample@sample.email.com","age":27}}]}}

インサートとサーチ両方できました。

プラグイン

ここまでで、アプリから使うことはできるんですが、もうちょい便利にしたいなーってことでいろいろ入れてみました

headプラグイン

インストールは1行だけです


# /usr/share/elasticsearch/bin/plugin --install mobz/elasticsearch-head

GUIでインデックス作成したり、検索したりいろいろできます

bigdeskプラグイン?(正式名称わからん)


# /usr/share/elasticsearch/bin/plugin --install lukas-vlcek/bigdesk

これで動的にリソース監視が可能になります。いろんな項目が取れるのでいいかなーっと思います。

感想

一旦入れて動かすところまでの確認だけですが、やってみました的な感じです。

MHA構築時に困った('A`)


[server default]
# mysql user and password
user=test
password=test
ssh_user=mysql

# working directory on the manager
manager_workdir=/var/log/masterha/hoge

# working directory on MySQL servers
remote_workdir=/var/log/masterha/hoge

# binary_log path
master_binlog_dir=/var/lib/mysql

# Master vip Failover
master_ip_failover_script=/etc/mha/master_ip_failover_hoge

[server1]
hostname=192.168.0.100
candidate_master=1

[server2]
hostname=192.168.0.101
candidate_master=1

[server3]
hostname=192.168.0.102
candidate_master=1

[server4]
hostname=192.168.0.103
candidate_master=1
## backup server
[server5]
hostname=192.168.0.104
no_master=1



[mysql@hoge-mha-manager01 ~]$ masterha_check_ssh --conf=/etc/hoge.cnf
Wed Jan 22 22:57:05 2014 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Wed Jan 22 22:57:05 2014 - [info] Reading application default configurations from /etc/hoge.cnf..
Wed Jan 22 22:57:05 2014 - [info] Reading server configurations from /etc/hoge.cnf..
Wed Jan 22 22:57:05 2014 - [info] Starting SSH connection tests..
Wed Jan 22 22:57:06 2014 - [debug]
Wed Jan 22 22:57:05 2014 - [debug] Connecting via SSH from mysql@192.168.0.100(192.168.0.100:22) to mysql@192.168.0.101(192.168.0.101:22)..
Wed Jan 22 22:57:05 2014 - [debug] ok.
〜略〜
Wed Jan 22 22:57:08 2014 - [info] All SSH connection tests passed successfully.


[mysql@hoge-mha-manager01 ~]$ masterha_check_repl --conf=etc/hoge.cnf
Wed Jan 22 22:59:19 2014 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Wed Jan 22 22:59:19 2014 - [info] Reading application default configurations from /etc/hoge.cnf..
Wed Jan 22 22:59:19 2014 - [info] Reading server configurations from /etc/hoge.cnf..
Wed Jan 22 22:59:19 2014 - [info] MHA::MasterMonitor version 0.55.
Wed Jan 22 22:59:19 2014 - [info] Dead Servers:
Wed Jan 22 22:59:19 2014 - [info] Alive Servers:
〜略〜
Wed Jan 22 22:59:19 2014 - [info] Current Alive Master: 192.168.0.100(192.168.0.100:3306)
Wed Jan 22 22:59:19 2014 - [info] Checking slave configurations..
Wed Jan 22 22:59:19 2014 - [warning] relay_log_purge=0 is not set on slave 192.168.0.101(192.168.0.101:3306).
Wed Jan 22 22:59:19 2014 - [warning] relay_log_purge=0 is not set on slave 192.168.0.102(192.168.0.102:3306).
Wed Jan 22 22:59:19 2014 - [warning] relay_log_purge=0 is not set on slave 192.168.0.103(192.168.0.103:3306).
Wed Jan 22 22:59:19 2014 - [warning] relay_log_purge=0 is not set on slave 192.168.0.104(192.168.0.104:3306).
Wed Jan 22 22:59:19 2014 - [info] Checking replication filtering settings..
Wed Jan 22 22:59:19 2014 - [info] binlog_do_db= , binlog_ignore_db=
Wed Jan 22 22:59:19 2014 - [info] Replication filtering check ok.
Wed Jan 22 22:59:19 2014 - [info] Starting SSH connection tests..
Wed Jan 22 22:59:22 2014 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln386] Error happend on checking configurations. SSH Configuration Check Failed!
at /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm line 341
Wed Jan 22 22:59:22 2014 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln482] Error happened on monitoring servers.
Wed Jan 22 22:59:22 2014 - [info] Got exit code 1 (Not master dead).

MySQL Replication Health is NOT OK!

masterha_check_sshはOKになるし、実際にsshしてもノンパスで通るのにmasterha_check_replでSSH Configuration Check Failed!って怒られる('A`)
絶賛答えが見つからないところ・・・


【2014/01/22 23:14 追記】

http://mizzy.org/blog/2013/02/06/1/:MHA for MySQL の概要というページを見つけ、masterha_managerというコマンドがあると言うことに気がついた。
(起動スクリプトの中にがっつり書いてあるんですが・・・)


[mysql@hoge-mha-manager01 ~]$ masterha_manager --conf=/etc/hoge.cnf
Wed Jan 22 23:13:34 2014 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Wed Jan 22 23:13:34 2014 - [info] Reading application default configurations from /etc/hoge.cnf..
Wed Jan 22 23:13:34 2014 - [info] Reading server configurations from /etc/hoge.cnf..
Wed Jan 22 23:13:34 2014 - [info] MHA::MasterMonitor version 0.55.
Wed Jan 22 23:13:34 2014 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln386] Error happend on checking configurations. Permission denied:/var/log/masterha/hoge/hoge.master_status.health at /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm line 294
Wed Jan 22 23:13:34 2014 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln482] Error happened on monitoring servers.
Wed Jan 22 23:13:34 2014 - [info] Got exit code 1 (Not master dead).
Wed Jan 22 23:13:34 2014 - [error][/usr/share/perl5/vendor_perl/MHA/ManagerUtil.pm, ln178] Got Error on finalize_on_error at monitor: Permission denied:/var/log/masterha/hoge/hoge.master_status.health at /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm line 591

なんかログディレクトリでパーミッションがないって言ってる


# ll /var/log/masterha
d--------- 2 mysql mysql 4096 Jan 22 23:11 hoge

(・∀・)
( ꒪⌓꒪)
(´つω・`)シュン

はい、chefでディレクトリ掘ったので気がついてなかったのですが、recipeでパーミッション間違ってました(´;ω;`)ブワッ
すいません、ただのクズです・・・


$ masterha_check_repl --conf=/etc/hoge.cnf
〜略〜
Wed Jan 22 23:18:59 2014 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

通った(´;ω;`)ブワッ

スタートしたら


Checking MySQL-MHA
- Check SSH : OK
- Check MySQL-Replication : OK
プロセスも確認できたので大丈夫でした。

マジでクズです。これに2時間も時間かけたと思うとアホすぎる・・・

Cassandraの構築を初めてやってみた

今回やった手順とかです

おもむろにスペックのいいサーバを用意しましょう。
今回は5台用意しました。

jdkとCassandraのインストールはCassandraクラスタと、DataStax OpsCenterの構築を見てインストールできます。
大変お世話になりましたm(_ _)m

ん?じゃなんでこのエントリー書いてるの?

という話になると思うのですが、ちょっと詰まった箇所があったのでメモとして書いておこうと思いました。

詰まったポイント1

OpsCenterから各ノードを設定してクライアントをインストールしようとしたら
JAVA_HOMEが見つからないと言われた('A`)マンドクセ
理由はjdkをソースでインストールして/usr/local/java/bin/javaにコマンドがあり
このせいで見つからないと(´・ω・`)
m9(^Д^)プギャー

JAVA_HOMEで取った対応

ln -s /usr/local/java/bin/java /usr/bin/

シンボリックリンクで強制的にJAVA_HOMEに合わせた。

見つからないと言われた理由はCassandraの方はjdkをソースで入れて、OpsCenterの方は公式のrpmパッケージで入れたので
お互いのJAVA_HOMEが違うからじゃないかなと・・・あくまで予想ですが。

詰まったポイント2

OpsCenterで見た時にリングがすごい偏ってしまって工エエェェ(´д`)ェェエエ工
って感じになりました・・・
正直Cassandraの構築自体初だったので、よくわからずググってググって
initial_tokenというものでこのリングの位置を決めているようでfmfm
更にググって
initial_tokenの設定
を発見キタ━━━━(゚∀゚)━━━━!!

token-generatorなるコマンドがあるとfmfm

ノードが5台だったので引数を5にして計算したものを
各ノードのcassandra.yamlのinitial_token: のところに追記して
Cassandraを起動
psコマンドでプロセス確認!
node01しかCassandraが起動していない・・・・
キョロ(ω・`))(´・ω・`)(( ´・ω)キョロ
Cassandraちゃんどこに行ったの?

Cassandraのログを見るとExceptionを吐いている・・・
NumberExceptionがガガガ・・・
initial_tokenの数字が宜しくなかったようで(´・ω・`)

initial_tokenの追記したところを全部消して
再起動したら起動はするけど、やっぱりリングがバラバラに(´;ω;`)ブワッ
node-tool moveでさっきの計算したinitail_tokenの数字を書いたら
範囲外みたいなエラーが出てmoveできず

調べてたら英語のサイトにinitial_tokenを計算するpythonがあってやってみたらいけた!!!
pythonは下記の通り。


$ python -c 'print [((2**64 / 5) * i) - 2**63 for i in range(5)]'
[-9223372036854775808L, -5534023222112865485L, -1844674407370955162L, 1844674407370955161L, 5534023222112865484L]

この5のところがノード数ですね。
なので


$ python -c 'print [((2**64 / ノード数) * i) - 2**63 for i in range(ノード数)]'

token-generatorで出た数字でうまくいかなかった理由はよくわかりませんが、pythonでうまくいきました。

こんな感じで綺麗なリングが表示できました。

countはMyISAMの方が速い

実際にやってみた

MyISAMの方が速いのは知っていたのですが、どのくらい速いのか試したことないなーっと思ってやってみました。

mysql> select count(*) from hogehoge;

                      • +
count(*)
                      • +
3524448
                      • +

1 row in set (18.88 sec)

mysql> alter table hogehoge engine='MyISAM';
Query OK, 3524448 rows affected (1 min 0.29 sec)
Records: 3524448 Duplicates: 0 Warnings: 0

mysql> select count(*) from hogehoge;

                      • +
count(*)
                      • +
3524448
                      • +

1 row in set (0.03 sec)

mysql> alter table hogehoge engine='InnoDB';
Query OK, 3524448 rows affected (2 min 8.28 sec)
Records: 3524448 Duplicates: 0 Warnings: 0

mysql> select count(*) from hogehoge;

                      • +
count(*)
                      • +
3524448
                      • +

1 row in set (1.07 sec)

mysql> alter table hogehoge engine='MyISAM';
Query OK, 3524448 rows affected (57.29 sec)
Records: 3524448 Duplicates: 0 Warnings: 0

mysql> select count(*) from hogehoge;

                      • +
count(*)
                      • +
3524448
                      • +

1 row in set (0.03 sec)

最初はInnoDBです。1回目はキャッシュに乗ってないから18秒とかかかってると思います。

なのでストレージエンジンを変えたりして何度か試してみました。
33倍くらい違いました。
count(*)でやってるからこのくらいの差があるんでしょうね。


すいません、それだけです。

彡サッ