まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

2014/05

2台の CentOS サーバーで MySQL クラスタ環境を構築する機会があったので、その作業メモです。


前提条件として、2台の CentOS 6.5(x64_86) をそれぞれ A, B とします。それぞれの IP アドレスを AAA.AAA.AAA.AAA / BBB.BBB.BBB.BBB とします。これらにそれぞれ MySQL のデータノードと SQL ノードを構築します。A, B には MySQL 関連モジュールの導入は一切行っていないものとします。
なおサーバー A は管理ノードを兼ねることにします。以下の手順は2台構成ですが、3台目以降を追加する場合は B と同じ手順を行うことになります。

【手順1 MySQL Cluster をインストール(A, B)】
A/B 両方のサーバーに MySQL Cluster をインストールします。CentOS 6.x では MySQL Cluster は標準の yum リポジトリには含まれていないようなので、公式サイトからソースをダウンロードしてインストールします:
Download MySQL Cluster

上記サイトから最新版のインストールセットをダウンロードします。今回の前提環境(CentOS 6.5 64bit)であれば Platform に "Linux Generic" を選択して 64bit 版のモジュールファイルをダウンロードします(ダウンロード時に Oracle のアカウントが必要になります):
2014052801

ちなみに 2014/05/28 現在、この方法で取得すると MySQL Cluster 7.3.5(ファイル名 mysql-cluster-gpl-7.3.5-linux-glibc2.5-x86_64.tar.gz)がダウンロードできます。以下、このモジュールを使っている前提で記載を続けます。バージョン差異などでファイル名が異なる場合は適宜読み替えてください。

ダウンロードしたモジュールファイルを A, B 両方にコピーします(/tmp にコピーしたと仮定します)。そして以下の導入作業を A, B 双方で行います。

サーバーに root でログインし、まず mysql 用のユーザーとグループを作成します:
# groupadd mysql
# useradd -g mysql mysql

コピーした MySQL Cluster インストールモジュールを /usr/local/ 以下に展開し、mysql という名称でアクセスできるようにシンボリックリンクを張ります:
# cd /usr/local
# tar xzvf /tmp/mysql-cluster-gpl-7.3.5-linux-glibc2.5-x86_64.tar.gz
# ln -s mysql-cluster-gpl-7.3.5-linux-glibc2.5-x86_64 mysql

ファイルオーナーとファイルグループを変更します:
# chown -R root.mysql mysql-cluster-gpl-7.3.5-linux-glibc2.5-x86_64
# chown -R mysql.mysql mysql/data/

/usr/local/mysql/bin に PATH を通します:
(例)こういう結果になるよう ~/.bash_profile を編集する
# cat ~/.bash_profile
  :
  :
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
  :
  :

MySQL の管理用データベースを初期化して、デーモン起動用スクリプトをコピーして用意します:
# cd /usr/local/mysql
# ./scripts/mysql_install_db --user=mysql
# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
# chown root.root /etc/init.d/mysql
# chmod u+x /etc/init.d/mysql

これでモジュールの導入は完了です、意外と簡単。この処理は全てのサーバー(今回の例であれば A と B)に対して行います。


管理ノードではないサーバー(B) のみ、/var/lib/mysql-cluster/ というフォルダを作成しておきます。中身は不要ですが MySQL が利用するのでファイルオーナーとグループオーナーを変更しておきます:
# mkdir /var/lib/mysql-cluster
# chown -R mysql.mysql /var/lib/mysql-cluster

管理ノードサーバー(A) に関しては、この作業は次の手順の中に含まれているので不要です。


【手順2 MySQL Cluster 管理ノードの設定(Aのみ)】
次に管理ノードの設定を行います。この作業はサーバー A に対してのみ行います。

今回は設定ファイルを /var/lib/mysql-cluster/ 以下に作成します。場所は任意で構いませんが、変更する場合は適宜読み替えてください。
# mkdir /var/lib/mysql-cluster
# chown -R mysql.mysql /var/lib/mysql-cluster
# vi /var/lib/mysql-cluster/config.ini
  :
  :
[NDB_MGMD]
hostname=AAA.AAA.AAA.AAA  # 管理サーバー(サーバーA)のIPアドレス

[NDBD default]
NoOfReplicas=2  # クラスタ環境の冗長化数(台数)
datadir=/var/lib/mysql-cluster

[NDBD]
hostname=AAA.AAA.AAA.AAA  # 1台目のデータノードの IP アドレス
datadir=/var/lib/mysql-cluster

[NDBD]
hostname=BBB.BBB.BBB.BBB  # 2台目のデータノードの IP アドレス
datadir=/var/lib/mysql-cluster

[MYSQLD]
hostname=AAA.AAA.AAA.AAA  # 1台目のSQLノードの IP アドレス

[MYSQLD]
hostname=BBB.BBB.BBB.BBB  # 2台目のSQLノードの IP アドレス


【手順3 MySQL Cluster SQL ノードの設定(A, B)】
次にSQLノードの設定を行います。この作業はサーバー A, B 両方に対して行います。

具体的には /etc/my.cnf をクラスタ環境向けに編集します:
# vi /etc/my.cnf
  :
  :
[mysqld]
ndbcluster
character-set-server=utf8

[mysql]
default-character-set=utf8

[mysql-cluster]
ndb_connectstring=AAA.AAA.AAA.AAA

[ndb_mgmd]
config_file=/var/lib/mysql-cluster/config.ini


【手順4 MySQL Cluster の起動(A, B)】
ここまでの作業で MySQL Cluster が起動できるようになっています。ただ MySQL Cluster を起動する際の注意点として、起動する時の順序は必ず以下の順番で行う必要があります。また停止は逆の順序で行う必要があります:
(1) 管理ノード起動(A)
(2) データノード起動(A, B)
(3) SQL ノード起動(A, B)

具体的には以下の様なオペレーションで MySQL Cluster を起動します:
管理ノード起動(A)
# cd /var/lib/mysql-cluster # ndb_mgmd
(起動メッセージが表示される。管理ノードがSQLノードを兼ねている場合は警告が表示されるが無視)

データノード起動(A, B)
# ndbd

SQLノード起動(A, B) # /etc/init.d/mysql start

この段階でサーバー A, B 双方で MySQL サーバーが起動して、それらはクラスタリング構成になっています。そのことを管理ノード A から ndb_mgm を実行後のプロンプトから show コマンドで確認してみます:
# ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: AAA.AAA.AAA.AAA:1186 管理ノード
Cluster Configuration
 ---------------------
[ndbd(NDB)]     2 node(s)
id=2    @AAA.AAA.AAA.AAA  (mysql-5.6.17 ndb-7.3.5, Nodegroup: 0, *) データノード(マスター)
id=3    @BBB.BBB.BBB.BBB  (mysql-5.6.17 ndb-7.3.5, Nodegroup: 0) データノード

[ndb_mgmd(MGM)] 1 node(s)
id=1    @AAA.AAA.AAA.AAA  (mysql-5.6.17 ndb-7.3.5) 管理ノード

[mysqld(API)]   2 node(s)
id=4    @AAA.AAA.AAA.AAA  (mysql-5.6.17 ndb-7.3.5) SQLノード
id=5    @BBB.BBB.BBB.BBB  (mysql-5.6.17 ndb-7.3.5) SQLノード

ndb_mgm>

こんな感じになっていれば正しくクラスタリングできています。


【手順5 MySQL ユーザーやデータベースの設定(A, B)】
MySQL Cluster では対象のデータベースの同期が取られますが、同期が取られないデータもあります。それらは個別に生成/設定する必要があります:
root ユーザーパスワード設定(A, B)
# mysql -u root
mysql> set password for root@localhost=PASSWORD('XXXXXXXX');

データベース作成(A) これは B に同期される
mysql> create database testdb default character set utf8;

データベースユーザー作成(A, B)
mysql> grant all privileges on testdb.* to test_user@localhost identified by 'test_pass'; 

そして改めて A で作成したデータベース testdb が B に同期されていることを確認します:
test_user ユーザーで testdb にログイン(B)
# mysql -u test_user -ptest_pass testdb
mysql> Bでは作成していないデータベースにログインできた!

※B での mysql コマンドでソケットファイルのエラーが表示される場合は
# mysql -u test_user -ptest_pass testdb --socket=/tmp/mysql.sock
といった感じで、ソケットファイルのパスを指定して実行する必要があります。


【手順6 データの同期を確認(A, B)】
最後に A で作成したテーブルやデータが B に同期されることを確認します。まずはクラスタ対応のテーブルを作成します:
(サーバー A で作業)
# mysql -u test_user -ptest_pass testdb
mysql> create table testtbl(n int) engine=ndbcluster; mysql> show table status *************************** 1. row *************************** Name: testtbl Engine: ndbcluster Version: 10 : :
mysql>

このテーブルに適当にデータを入れておきます:
(サーバー A で作業)
mysql> insert into testtbl values (123); mysql> select * from testtbl; +------+ | n | +------+ | 123 | +------+

このテーブルとデータがサーバー B にも同期されていることを確認します:
(サーバー B で作業)
# mysql -u test_user -ptest_pass testdb (--socket=/tmp/mysql.sock) mysql> select * from testtbl; +------+ | n | +------+ | 123 | +------+

無事、データの同期もできていることが確認できました。





先日の IBM XCITE イベントの中で、IBM BlueMix のアプリケーション開発コンテストの開催が発表されています:
IBM BlueMix Challenge
2014052501



このブログでも何度か触れてきましたが、IBM BlueMix は、いわば「IBM 版 CloudFoundry」です。IBM の提供するクラウド上に CloudFoundry 環境が構築されており、現在は無料ベータ版という扱いで誰でも利用することができるようになっています。素の CloudFoundry と異なるのは IBM ソフトウェア製品も利用可能なサービスとして統合されているので、BlueMix 上で Java アプリケーションサーバーや DB2 を始めとするデータベースサーバーなども利用できるようになっている点です。BlueMix 上で稼働する IBM 製品については原則的に IBM からの製品サポートが提供され、それ以外のものについても一部はサードパーティからの製品サポートが提供される、という形態になっています。

この BlueMix 環境上でアプリケーションを開発/構築するというコンテストです。なお、コードそのものの良し悪しだけで判断されるわけではなく、用意されたサービスをどのように組み合わせて、どのようなイノベーションを実現するか、という総合的な判断に基づくコンテストのようです。

気になる商品は Mac Book Pro やルンバといった、デベロッパー(やその家族)が喜びそうなものが用意されています。実際にはこれらの中でも上位機種が準備されているとの噂も・・・


参加する場合、6月30日までにそのための登録申請を行う必要があります。アプリケーションそのものは申請の段階で開発されている必要はなく、アプリケーションの提出期限は8月12日となっているようです。


注目の PaaS 環境である Cloud Foundry のアプリケーションを開発するいい勉強の機会にもなるし、あわよくば Mac Book Pro も手に入れるチャンスです。普通にアプリを開発できれば BlueMix(Cloud Foundry)対応はさほどハードルが高いとは思わないので、多くの開発者にチャンスがあると思います。


「興味はあるけど、まだあまりよく BluxMix(Cloud Foundry) 分からないんだよなあ・・・」という方は、拙作ですが、以下の僕のブログエントリがお役に立てれば幸いです:

- BlueMix を使う
- BlueMix のダッシュボードとデータベースサービスを使う
- BlueMix 上で PHP アプリを動かす
- BlueMix を使ってみて
- BlueMix で Twilio を使う
- BlueMix 向けに(Java)アプリを開発するといいことはあるか?
- BlueMix 向け Twilio アプリのサンプル
- BlueMix 開発コンテストが開催されるらしい
- BlueMix のデータストア比較
- BlueMix の cf コマンド
- BlueMix 上の DB2 をハック
- MySQL が 3306 番以外のポートで動いている時の WordPress 設定
- モバイル向けdeveloperWorks ページを作ってみた





 

UNIX/Linux 系 OS 用の仮想端末マネージャーである screen コマンド。以前に紹介した tmux に似てるけど、screen は多くのケースで標準導入されているので、ビルドとかなしにそのまま使えることが多いです。

というわけで、概要と使い方のメモ:

【screen コマンドとは?】
- 1つのターミナル上で、仮想的に複数の端末を同時にオープンして作業するツール。
- 仮想端末が開かれた状態を保ったままターミナルをログアウトできる。後から再度ターミナルでログインして、screen を呼び出すことで仮想端末の状態に復帰できる。
- 1つのターミナルの画面を上下に分割して、複数の端末を同時にアクティブにして(切り替えながら)操作できる。


【screen コマンドの使い方】
screen 起動
# screen
screen 内で新しい仮想端末を開く
[ctrl]+a c
screen 内で動いている仮想端末の一覧表示
[ctrl]+a w
screen 内で動いている別の仮想端末に移動する
[ctrl]+a n または [ctrl]+a [space] 昇順移動 [ctrl]+a p または [ctrl]+a [del] 降順移動 [ctrl]+a 数字 (数字)で示される仮想端末に移動 [ctrl]+a [ctrl]+a 直前に使っていた仮想端末へ戻る
現在開いている仮想端末を閉じる(キル)
[ctrl]+a k
現在開いている仮想端末をサスペンド状態にして閉じる(デタッチ)
[ctrl]+a d
screen 内でデタッチ状態で動いている仮想端末の一覧表示
# screen -ls (ここで PID が確認できる)
screen 内でデタッチ状態で動いている仮想端末に戻る(アタッチ)
# screen -r PID
デタッチせずに screen を終了する
[ctrl]+a \
起動中の screen をバックスクロールモードにする
[ctrl]+a [
バックスクロールモードでテキストコピー
カーソルを始点に移動させて [space] または [enter] カーソルを終点に移動させて [space] または [enter]
コピーしたテキストのペースト
[ctrl]+a ]
画面を上下2分割
[ctrl]+a S
画面分割後にフォーカス画面を変更
[ctrl]+a [tab]
画面分割をやめる
[ctrl]+a Q

【実際の使い方】
一度実行すると、処理完了まで1日程度かかるコマンド(# php test.php)があるとします。
これをサーバー上で実行して、一度デタッチして(バックグラウンドで処理を続けて)からサーバーとの接続を切断し、翌日サーバーに再度ログインして結果を確認する。
(ssh や telnet でサーバーにログイン)

# screen screen 実行(この時点で仮想端末0が実行される)

[ctrl]+a c 新しい仮想端末1を作成して移動

# php test.php 処理実行開始・・・・

[ctrl]+a d 処理実行中の仮想端末をデタッチ(この時に screen からも抜ける)

# screen -ls デタッチした処理の PID を確認( XXXX だったとする)

# exit (サーバーからログアウト)

  :
  :
  :

(翌日、再度 ssh や telnet でサーバーにログイン)

# screen -r XXXX 前日デタッチした仮想端末をアタッチ

(処理が完了していたらそのまま続きの作業を行う。まだ完了してなかったら再びデタッチして完了を待つ)







高速な HTTP サーバーである Nginx を使って cakePHP を利用する場合の設定をまとめました。注意点としてはリライトの扱いとファイルパーミッションです:


前提として cakePHP は(Apache HTTPd で使う前提の内容でいいので)設定ができているものとします。cakePHP の導入先は /var/www/html/cakephp/ であると仮定します。Apache HTTPd は導入しないか、サービスを止めておきます。cakePHP の導入手順についてはこちらを参照ください:
cakePHP を CentOS にインストールする


また PHP-FPM や Nginx の導入自体はできているものとします。これらの手順はこちらを参照ください:
CentOS に Nginx をインストールして PHP を使う


では Nginx を cakePHP の環境に合わせて設定していきます。まずは /etc/nginx/conf.d/default.conf を以下の内容に変更します(特に赤字部分は各自の環境に合わせて編集するよう、注意してください):
server {
    listen       80;
    server_name  localhost;
 
    root   /var/www/html/cakephp/app/webroot;
    index  index.php index.html;
 
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
 
    location / {
        try_files $uri $uri?$args $uri/ /index.php?$uri&$args /index.php?$args;
    }
 
    #error_page  404              /404.html;
 
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}
 
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        try_files       $uri =404;
        fastcgi_pass    127.0.0.1:9000;
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }
 
    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

※追記1
index 節に index.html を追加。webroot/sub/index.html に /sub/ でアクセスできるようにするため

※追記2
try_files 節に /index.php?$args を追加。/controller/view?key=value を正しくハンドルできるようにするため



次に cakePHP 内の app/tmp フォルダに(Apache HTTPd ではなく) nginx が書き込めるような権限を与えます:
# chown -R nginx.nginx /var/www/html/cakephp/app/tmp
# chmod -R 700 /var/www/html/cakephp/app/tmp

また、/etc/php.ini に以下の内容を加えて、セッションデータを保存するディレクトリを設定しておきます:
session.save_path = "/var/lib/php/session"

これで Nginx を起動して、ブラウザで http://(サーバー名)/ にアクセスすると Nginx 環境下で動いている cakePHP のホーム画面が表示されるはずです:
# /etc/init.d/nginx start (Nginx サービス起動)
# chkconfig nginx on (自動起動設定)

2014051701




心なしか速くなった・・・のかな?



Stackato を使ってプライベート環境に構築した Cloud Foundry 環境に、App Store というアプリケーション一覧からアプリケーションをデプロイしてみます。Stackato 環境構築の手順はこちらを参照してください:
Stackato を導入してプライベートな Cloud Foundry 環境を(KVM に)構築する
 ↑これの続きです


Stackato 管理コンソールにログインして、最初のページを下にスクロールすると "Deploy from the App Store" と書かれたリンクがあります。ここをクリックします:
2014051501


"App Store" という、Stackato 対応アプリケーション(正確にはサーバー&アプリケーション)の一覧が表示されます。CMS の Joomla やアプリケーション開発フレームワークの cakePHP など、メジャーどころが結構対応しています。これらは全て以下に紹介する簡単な手順で Stackato にデプロイできるようになっています:
2014051502


試しに、ブログや CMS では定番の1つになっている WordPress をデプロイしてみます。一覧の最後の方までスクロールして、"WordPress" を見つけたら、"Deploy App" ボタンをクリックします:
2014051503


WordPress アプリケーションサーバーのデプロイ情報を入力します。といってもここで気をつけるべきは一番上の "App Name" 欄だけです。デフォルトで設定されている名称をそのまま使ってもいいし、変更してもいいのですが、これがアプリケーションサーバー名の一部(****.stackato-mm7d.local の **** 部)になります。とりあえずこの例では "wordpress-y7unx" という名称にしています。最後に "Deploy Application" ボタンをクリックすると Stackato 環境にデプロイが開始されます:
2014051504


デプロイ中の画面はこんな感じでログが表示されます。しばらく待ちます・・・:
2014051505


ログに "Created app 'wordpress-y7unx(App Nameの値)'" と表示されて、ログの動きが止まったらデプロイが完了しています:
2014051506


この状況で画面左の "Instance" をクリックすると、Stackato 環境内で動いているサーバーインスタンスの一覧が表示されます。先程作成した WordPress サーバーがちゃんと Stackato 内で動いていることが確認できます。またこの画面から再起動などの管理オペレーションが可能になっています:
2014051507
 ↑仮想環境の KVM の中で動いている Stackato の中で動いている WordPress サーバー、です


では実際のアプリケーションにアクセスしてみます。

・・・が、その前に、このアプリケーションは Stackato 内で動いていて、IP アドレス自体は Stackato と同じものです。(恐らく VirtualHost 設定などで)アクセスサーバー名で切り替えられるようなので、この WordPress にアクセスするには改めて /etc/hosts を編集するなどして、サーバー名(wordpress-y7unx.stackato-mm7d.local)でアクセスできるようにしておく必要があります。

前回も紹介したように、ブラウザを利用するマシンの hosts ファイルを更に変更して、サーバー名と IP アドレスの対応を追加しておきます:
192.168.0.101 stackato-mm7d.local api.stackato-mm7d.local wordpress-y7unx.stackato-mm7d.local
(↑内容は各自の環境に合わせるようにして赤字部分を追加します


そしてブラウザで http://wordpress-y7unx.stackato-mm7d.local/ を開くと、、、WordPress の初期設定画面が表示されています。あっけなく動いてますね:
2014051508


初期設定を済ませれば、そのまま WordPress を使いはじめることができます:
2014051509


この WordPress の例に限らず、Stackato の App Store には初めから使えるアプリケーションが数多く用意されているので、これらを使ってアプリケーションをすぐに構築したり、ミドルウェア環境を手早く用意する、といったことができそうです。この WordPress アプリケーションの場合は 128MB メモリ環境で動作するようなので、これ1つ作った時点であればまだまだ余裕があるので他のアプリケーションを同時に作って動かす、ということもできると思っています(他のリソースはともかくメモリ的には)。

今回使った Stackato の mini Cloud Foundry 環境の場合はメモリ上限が 4GB と比較的小規模運用が前提になっていますが、この範囲で収まる使い方であれば、社内やチーム内利用には充分すぎる環境だと思います。仮に収まりきらなくなった場合でも、(有料の)上位エディションに移行したり、各社から提供されている Cloud Foundry ベースの環境に移行ことで運用先に困ることはないと思っています。 

こういう移行選択肢がある、ということがオープン環境の素晴らしいところです。


このページのトップヘ