2014年10月26日日曜日

EC2のInstance Store ボリュームをSWAP領域として利用

EC2には無料で利用できるInstans Store ボリュームを備えているインスタンスタイプがあります。
ただ、このInstans Store ボリュームはEC2をStop/Terminateすると消えてしまうので、データ保存領域としては利用できません。
せっかく無料で利用できるのでSWAP領域として活用することを考えその手順をまとめてみました。
※今回利用したインスタンスタイプ(m3.medium)には4GBのInstans Storeが付随します。

OS: amazon-linux-ami/2014.09 (64-bit)


■Instans Store ボリューム追加
Instans Store ボリュームはデフォルトでは追加されないのでマネージメントコンソールにてEC2作成時に指定します。

■SWAP領域追加前
[ec2-user@alnx-web01 ~]$ free -m
             total       used       free     shared    buffers     cached
Mem:          3768        134       3633          0          7         60
-/+ buffers/cache:         65       3702
Swap:            0          0          0
[ec2-user@alnx-web01 ~]$


■AmazonLinuxのデフォルト設定を修正
## デフォルト設定確認
[ec2-user@alnx-web01 ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  15G  0 disk
└─xvda1 202:1    0  15G  0 part /
xvdb    202:16   0   4G  0 disk /media/ephemeral0
[ec2-user@alnx-web01 ~]$ cat /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
/dev/sdb        /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2
[ec2-user@alnx-web01 ~]$
/dev/sdb が Instans Store ボリュームのデバイスです。/dev/xvdb のシンボリックリンクです。

## マウント解除
[ec2-user@alnx-web01 ~]$ sudo vi /etc/fstab
[ec2-user@alnx-web01 ~]$ tail -1 /etc/fstab
#/dev/sdb       /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2
[ec2-user@alnx-web01 ~]$ sudo umount /media/ephemeral0
[ec2-user@alnx-web01 ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  15G  0 disk
└─xvda1 202:1    0  15G  0 part /
xvdb    202:16   0   4G  0 disk
[ec2-user@alnx-web01 ~]$
lsblkコマンドで約4GBの Instans Store ボリュームの存在を確認できます。


■SWAP領域作成&有効化
mkswapコマンドでSWAP領域を作成し、swaponコマンドで有効化します。
[ec2-user@alnx-web01 ~]$ ll /dev/sdb
lrwxrwxrwx 1 root root 4 Oct  8 13:40 /dev/sdb -> xvdb
[ec2-user@alnx-web01 ~]$ sudo mkswap /dev/sdb
mkswap: /dev/sdb: warning: wiping old ext3 signature.
Setting up swapspace version 1, size = 4188668 KiB
no label, UUID=8bd2611b-a850-4186-bdf8-b1769ff92a17
[ec2-user@alnx-web01 ~]$ sudo swapon /dev/sdb
[ec2-user@alnx-web01 ~]$

## 確認
[ec2-user@alnx-web01 ~]$ free -m
             total       used       free     shared    buffers     cached
Mem:          3768        139       3628          0          7         62
-/+ buffers/cache:         69       3698
Swap:         4090          0       4090
[ec2-user@alnx-web01 ~]$
約4GBのSWAP領域が追加されました。


■OS起動時にSWAP自動有効化
[ec2-user@alnx-web01 ~]$ sudo vi /etc/fstab
[ec2-user@alnx-web01 ~]$ tail -1 /etc/fstab
/dev/sdb    swap        swap    defaults        0   0
[ec2-user@alnx-web01 ~]$ sudo reboot

## 再起動後に確認
[ec2-user@alnx-web01 ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  15G  0 disk
└─xvda1 202:1    0  15G  0 part /
xvdb    202:16   0   4G  0 disk [SWAP]
[ec2-user@alnx-web01 ~]$ free -m
             total       used       free     shared    buffers     cached
Mem:          3768        137       3630          0          7         60
-/+ buffers/cache:         69       3699
Swap:         4090          0       4090
[ec2-user@alnx-web01 ~]$
今回はfstabにSWAP領域を定義したが、場合によっては/etc/rc.localにswapon情報を記載することも検討の余地ありです。


こちらの情報が何かのお役に立てましたら幸いです。サイト継続ご協力のほどお願い致します。m(_ _)m

2014年9月21日日曜日

MongoDBのreplicationを利用してfailoverを検証する

mongodの4インスタンスでレプリケーションを構成し、各インスタンスで障害が発生した場合、どのようにフェイルオーバーするかの動作検証を行います。
votesやpriorityの値を変更して、可用性向上(Primaryインスタンスを選出できるか)を試みています。

OS: amazon-linux-ami/2014.03 (64-bit)
MongoDB: 2.6.4


■システム構成概要図


■方針
mongod0/mongo1はアプリケーションと対面するインスタンス。
mongod2はバックアップ用のインスタンス。Priorityの値を0に設定しPrimaryに昇格させない。バックアップ時の計画停止を想定。
mongod3はArbiter固定のインスタンス。
mongo-a/mongo-b/mongo-cの3台のサーバの内、1台に障害が発生してもアプリケーションに対してDBサービス提供が継続できることを目標とする。
さらに、mongod2を計画停止中に他のインスタンスに障害が発生してもPrimaryを選出してサービスが継続できることを目標とする。


■起動用設定ファイル準備
## mongo-aサーバ
[ec2-user@mongo-a ~]$ mkdir /data/mongo_rs/mongod0
[ec2-user@mongo-a ~]$ cat /data/mongo_rs/conf/mongod0.conf
bind_ip=mongo-a
port=30000
dbpath=/data/mongo_rs/mongod0
pidfilepath=/var/run/mongodb/mongod0.pid
logpath=/var/log/mongodb/mongod0.log
logappend=true
fork=true
replSet=rep1
httpinterface=true
[ec2-user@mongo-a ~]$

## mongo-bサーバ
[ec2-user@mongo-b ~]$ mkdir /data/mongo_rs/mongod1
[ec2-user@mongo-b ~]$ cat /data/mongo_rs/conf/mongod1.conf
bind_ip=mongo-b
port=30001
dbpath=/data/mongo_rs/mongod1
pidfilepath=/var/run/mongodb/mongod1.pid
logpath=/var/log/mongodb/mongod1.log
logappend=true
fork=true
replSet=rep1
[ec2-user@mongo-b ~]$
サーバが異なるインスタンスについてはポート番号を変える必要はないが、管理しやすさを考慮してインスタンス番号と合わせてみた。

## mongo-cサーバ
[ec2-user@mongo-c ~]$ mkdir /data/mongo_rs/mongod2
[ec2-user@mongo-c ~]$ mkdir /data/mongo_rs/mongod3
[ec2-user@mongo-c ~]$ cat /data/mongo_rs/conf/mongod2.conf
bind_ip=mongo-c
port=30002
dbpath=/data/mongo_rs/mongod2
pidfilepath=/var/run/mongodb/mongod2.pid
logpath=/var/log/mongodb/mongod2.log
logappend=true
fork=true
replSet=rep1
[ec2-user@mongo-c ~]$ cat /data/mongo_rs/conf/mongod3.conf
bind_ip=mongo-c
port=30003
dbpath=/data/mongo_rs/mongod3
pidfilepath=/var/run/mongodb/mongod3.pid
logpath=/var/log/mongodb/mongod3.log
logappend=true
fork=true
replSet=rep1
[ec2-user@mongo-c ~]$


■起動/停止/ステータス確認スクリプト準備
## 起動用
[ec2-user@mongo-a ~]$ vi start-mongod0.sh
[ec2-user@mongo-a ~]$ cat start-mongod0.sh
sudo mongod --config /data/mongo_rs/conf/mongod0.conf
[ec2-user@mongo-a ~]$ chmod 755 start-mongod0.sh
[ec2-user@mongo-a ~]$
※オフィシャルサイトでは起動前に"ulimit -n 64000"を推奨しているようだが、EC2がしょぼいので今回はパス。

## 停止用
[ec2-user@mongo-a ~]$ vi stop-mongod0.sh
[ec2-user@mongo-a ~]$ cat stop-mongod0.sh
sudo kill -9 `ps -ef | grep mongod0.conf | grep -v grep | awk '{print $2}'`
[ec2-user@mongo-a ~]$ chmod 755 stop-mongod0.sh
[ec2-user@mongo-a ~]$

## 確認用
[ec2-user@mongo-a ~]$ vi mongod-status.sh
[ec2-user@mongo-a ~]$ cat mongod-status.sh
mongo mongo-a:30000 --eval "printjson(rs.status())" | egrep "name|stateStr"
echo ""
mongo mongo-a:30000 --eval "printjson(rs.conf())" | egrep "host|votes|priority|arbiter"
[ec2-user@mongo-a ~]$ chmod 755 mongod-status.sh
[ec2-user@mongo-a ~]$
各サーバに同様のスクリプトを準備。


■mongod起動
[ec2-user@mongo-a ~]$ ./start-mongod0.sh
about to fork child process, waiting until server is ready for connections.
forked process: 1871
child process started successfully, parent exiting
[ec2-user@mongo-a ~]$
同様に各サーバのmongodも起動。


■replication設定
## ReplicaSetの初期化
[ec2-user@mongo-a ~]$ mongo mongo-a:30000
MongoDB shell version: 2.6.4
connecting to: mongo-a:30000/test
> rs.initiate();
{
        "info2" : "no configuration explicitly specified -- making one",
        "me" : "mongo-a:30000",
        "info" : "Config now saved locally.  Should come online in about a minute.",
        "ok" : 1
}
> rs.conf();
{
        "_id" : "rep1",
        "version" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "mongo-a:30000"
                }
        ]
}
rep1:PRIMARY>

## SecondaryとArbiter追加
rep1:PRIMARY> rs.add( { _id: 1, host: "mongo-b:30001" } )
{ "ok" : 1 }
rep1:PRIMARY> rs.add( { _id: 2, host: "mongo-c:30002", priority: 0, votes: 0 } )
{ "ok" : 1 }
rep1:PRIMARY> rs.add( { _id: 3, host: "mongo-c:30003", arbiterOnly: true } )
{ "ok" : 1 }
rep1:PRIMARY>

## 設定確認
rep1:PRIMARY> rs.conf();
{
        "_id" : "rep1",
        "version" : 4,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "mongo-a:30000"
                },
                {
                        "_id" : 1,
                        "host" : "mongo-b:30001"
                },
                {
                        "_id" : 2,
                        "host" : "mongo-c:30002",
                        "votes" : 0,
                        "priority" : 0
                },
                {
                        "_id" : 3,
                        "host" : "mongo-c:30003",
                        "arbiterOnly" : true
                }
        ]
}
rep1:PRIMARY> rs.status();
{
        "set" : "rep1",
        "date" : ISODate("2014-09-17T07:13:20Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "mongo-a:30000",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 592,
                        "optime" : Timestamp(1410937918, 1),
                        "optimeDate" : ISODate("2014-09-17T07:11:58Z"),
                        "electionTime" : Timestamp(1410937614, 1),
                        "electionDate" : ISODate("2014-09-17T07:06:54Z"),
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "mongo-b:30001",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 103,
                        "optime" : Timestamp(1410937918, 1),
                        "optimeDate" : ISODate("2014-09-17T07:11:58Z"),
                        "lastHeartbeat" : ISODate("2014-09-17T07:13:19Z"),
                        "lastHeartbeatRecv" : ISODate("2014-09-17T07:13:20Z"),
                        "pingMs" : 0,
                        "syncingTo" : "mongo-a:30000"
                },
                {
                        "_id" : 2,
                        "name" : "mongo-c:30002",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 91,
                        "optime" : Timestamp(1410937918, 1),
                        "optimeDate" : ISODate("2014-09-17T07:11:58Z"),
                        "lastHeartbeat" : ISODate("2014-09-17T07:13:19Z"),
                        "lastHeartbeatRecv" : ISODate("2014-09-17T07:13:19Z"),
                        "pingMs" : 2,
                        "syncingTo" : "mongo-a:30000"
                },
                {
                        "_id" : 3,
                        "name" : "mongo-c:30003",
                        "health" : 1,
                        "state" : 7,
                        "stateStr" : "ARBITER",
                        "uptime" : 82,
                        "lastHeartbeat" : ISODate("2014-09-17T07:13:18Z"),
                        "lastHeartbeatRecv" : ISODate("2014-09-17T07:13:18Z"),
                        "pingMs" : 2
                }
        ],
        "ok" : 1
}
rep1:PRIMARY>
votesとpriorityのdefault値は"1"となる。
default値の場合はrs.conf();のOutputとして表示されない。

## 上記設定の目論見:
mongod2のvotesの値を0にすることで、votesの初期合計値は3となる。
mongod2を含む2インスタンスが停止しても、残りインスタンスのvotesの合計値が2となり、過半数を超える(= 2/3)ため、Primaryが選出される。


◆参考: votesの値を変更
rep1:PRIMARY> cfg = rs.conf();
{
        "_id" : "rep1",
        "version" : 4,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "mongo-a:30000"
                },
                {
                        "_id" : 1,
                        "host" : "mongo-b:30001"
                },
(以下略)
rep1:PRIMARY> cfg.members[1].votes = 0;
0
rep1:PRIMARY>
rep1:PRIMARY> rs.reconfig(cfg);
2014-09-17T16:23:13.386+0900 DBClientCursor::init call() failed
2014-09-17T16:23:13.388+0900 trying reconnect to mongo-a:30000 (10.54.10.90) failed
2014-09-17T16:23:13.388+0900 reconnect mongo-a:30000 (10.54.10.90) ok
reconnected to server after rs command (which is normal)

rep1:SECONDARY> rs.conf();
{
        "_id" : "rep1",
        "version" : 5,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "mongo-a:30000"
                },
                {
                        "_id" : 1,
                        "host" : "mongo-b:30001",
                        "votes" : 0
                },
(以下略)
※エラーメッセージの調査はですね、、、後回し。


◆参考: Replicasetから除外
あらかじめ除外対象のmongod(今回はmongod2とする)を停止しておく
[ec2-user@mongo-c ~]$ ./stop-mongod2.sh
[ec2-user@mongo-c ~]$
rep1:PRIMARY> rs.remove("mongo-c:30002");
2014-09-17T16:29:42.296+0900 DBClientCursor::init call() failed
2014-09-17T16:29:42.297+0900 Error: error doing query: failed at src/mongo/shell/query.js:81
2014-09-17T16:29:42.298+0900 trying reconnect to mongo-a:30000 (10.54.10.90) failed
2014-09-17T16:29:42.298+0900 reconnect mongo-a:30000 (10.54.10.90) ok
rep1:PRIMARY>
[ec2-user@mongo-a ~]$ ./mongod-status.sh
                        "name" : "mongo-a:30000",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo-b:30001",
                        "stateStr" : "SECONDARY",
                        "name" : "mongo-c:30003",
                        "stateStr" : "ARBITER",

                        "host" : "mongo-a:30000"
                        "host" : "mongo-b:30001"
                        "host" : "mongo-c:30003",
                        "arbiterOnly" : true
[ec2-user@mongo-a ~]$

## 再び追加
[ec2-user@mongo-c ~]$ ./start-mongod2.sh
about to fork child process, waiting until server is ready for connections.
forked process: 2723
child process started successfully, parent exiting
[ec2-user@mongo-c ~]$
[ec2-user@mongo-a ~]$ mongo mongo-a:30000
MongoDB shell version: 2.6.4
connecting to: mongo-a:30000/test
rep1:PRIMARY> rs.add( { _id: 2, host: "mongo-c:30002", priority: 0, votes: 0 } )
{ "ok" : 1 }
rep1:PRIMARY>


◆rs関連コマンド
rep1:PRIMARY> rs.help();
        rs.status()                     { replSetGetStatus : 1 } checks repl set status
        rs.initiate()                   { replSetInitiate : null } initiates set with default settings
        rs.initiate(cfg)                { replSetInitiate : cfg } initiates set with configuration cfg
        rs.conf()                       get the current configuration object from local.system.replset
        rs.reconfig(cfg)                updates the configuration of a running replica set with cfg (disconnects)
        rs.add(hostportstr)             add a new member to the set with default attributes (disconnects)
        rs.add(membercfgobj)            add a new member to the set with extra attributes (disconnects)
        rs.addArb(hostportstr)          add a new member which is arbiterOnly:true (disconnects)
        rs.stepDown([secs])             step down as primary (momentarily) (disconnects)
        rs.syncFrom(hostportstr)        make a secondary to sync from the given member
        rs.freeze(secs)                 make a node ineligible to become primary for the time specified
        rs.remove(hostportstr)          remove a host from the replica set (disconnects)
        rs.slaveOk()                    shorthand for db.getMongo().setSlaveOk()

        rs.printReplicationInfo()       check oplog size and time range
        rs.printSlaveReplicationInfo()  check replica set members and replication lag
        db.isMaster()                   check who is primary

        reconfiguration helpers disconnect from the database so the shell will display
        an error, even if the command succeeds.
        see also http://:28017/_replSet for additional diagnostic info
rep1:PRIMARY>


■障害シミュレーション
## 正常時
[ec2-user@mongo-a ~]$ ./mongod-status.sh
                        "name" : "mongo-a:30000",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo-b:30001",
                        "stateStr" : "SECONDARY",
                        "name" : "mongo-c:30002",
                        "stateStr" : "SECONDARY",
                        "name" : "mongo-c:30003",
                        "stateStr" : "ARBITER",


## mongo-aサーバ停止
[ec2-user@mongo-c ~]$ ./mongod-status.sh
                        "name" : "mongo-a:30000",
                        "stateStr" : "(not reachable/healthy)",
                        "name" : "mongo-b:30001",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo-c:30002",
                        "stateStr" : "SECONDARY",
                        "name" : "mongo-c:30003",
                        "stateStr" : "ARBITER",

mongo-bサーバのmongod1インスタンスがPRIMARYに選出される。mongod2インスタンスが選出されないのはpriorityの値を"0"に設定しているから。

## mongo-bサーバ停止
[ec2-user@mongo-a ~]$ ./mongod-status.sh
                        "name" : "mongo-a:30000",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo-b:30001",
                        "stateStr" : "(not reachable/healthy)",
                        "name" : "mongo-c:30002",
                        "stateStr" : "SECONDARY",
                        "name" : "mongo-c:30003",
                        "stateStr" : "ARBITER",


## mongo-cサーバ停止
[ec2-user@mongo-a ~]$ ./mongod-status.sh
                        "name" : "mongo-a:30000",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo-b:30001",
                        "stateStr" : "SECONDARY",
                        "name" : "mongo-c:30002",
                        "stateStr" : "(not reachable/healthy)",
                        "name" : "mongo-c:30003",
                        "stateStr" : "(not reachable/healthy)",

Default設定のままだと生きているインスタンスが両方とも"SECONDARY"となってしまうが、votesの設定が功を奏し"PRIMARY"を保持できている。

## mongo-cのSecondaryを停止中にmongo-aサーバ停止
[ec2-user@mongo-c ~]$ ./mongod-status.sh
                        "name" : "mongo-a:30000",
                        "stateStr" : "(not reachable/healthy)",
                        "name" : "mongo-b:30001",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo-c:30002",
                        "stateStr" : "(not reachable/healthy)",
                        "name" : "mongo-c:30003",
                        "stateStr" : "ARBITER",

バックアップ用インスタンスであるmongod2を停止中に、運悪く他のインスタンスが落ちても1つなら大丈夫。
以上、全パターン想定どおりとなりました。


■まとめ
## 3インスタンス構成
votes/priority
設定なし(default)
mongod0
votes:1 priority:1
mongod1
votes:1 priority:1
mongod2
votes:1 priority:1
Initial State PRIMARY SECONDARY ARBITER
Failure mongod0 × PRIMARY ARBITER
mongod1 PRIMARY × ARBITER
mongod2 PRIMARY SECONDARY ×

## 4インスタンス構成(1)
votes/priority
設定なし(default)
mongod0
votes:1 priority:1
mongod1
votes:1 priority:1
mongod2
votes:1 priority:1
mongod3
votes:1 ArbiterOnly
Initial State PRIMARY SECONDARY SECONDARY ARBITER
Failure mongod0 × PRIMARY
(SECONDARY)
SECONDARY
(PRIMARY)
ARBITER
mongod1 PRIMARY × SECONDARY ARBITER
mongod2 PRIMARY SECONDARY × ARBITER
mongod3 PRIMARY SECONDARY SECONDARY ×
mongod0,1 × × SECONDARY ARBITER
mongod0,2 × SECONDARY × ARBITER
mongod0,3 × SECONDARY SECONDARY ×
mongod1,2 SECONDARY × × ARBITER
mongod1,3 × × SECONDARY ARBITER
mongod2,3 SECONDARY SECONDARY × ×
votes/priorityがdefault値の場合、同時に2つのインスタンスに障害が発生した場合アウト!!
つまり、mongod2,mongod3が同居しているmongo-cサーバに障害が発生した時点でPrimaryを保持できなくなりサービスを継続できない。

## 4インスタンス構成(2)
votes/priority
カスタマイズ設定
mongod0
votes:1 priority:1
mongod1
votes:1 priority:1
mongod2
votes:0 priority:0
mongod3
votes:1 ArbiterOnly
Initial State PRIMARY SECONDARY SECONDARY ARBITER
Failure mongod0 × PRIMARY SECONDARY ARBITER
mongod1 PRIMARY × SECONDARY ARBITER
mongod2 PRIMARY SECONDARY × ARBITER
mongod3 PRIMARY SECONDARY SECONDARY ×
mongod0,1 × × SECONDARY ARBITER
mongod0,2 × PRIMARY × ARBITER
mongod0,3 × SECONDARY SECONDARY ×
mongod1,2 PRIMARY × × ARBITER
mongod1,3 × × SECONDARY ARBITER
mongod2,3 PRIMARY SECONDARY × ×
mongod2を計画停止中に他のmongodに障害が発生しても、Primaryを選出できるのでサービス継続可能。


こちらの情報が何かのお役に立てましたら幸いです。
今回はかなり頑張って記載したので、ご利用、転記する場合はコメントいただけるとありがたいです。m(_ _)m

2014年9月7日日曜日

AWS上に実践的なMongoDBのレプリケーション構成を構築

AWS上に実践的なMongoDBのレプリケーション構成を構築する手順をまとめます。
前回MongoDBインストール後に作成したAMIから、異なるAvailability ZoneにEC2を作成します。
ホスト名(mongo1、mongo2)を定義して、なるべくec2-userで操作します。
今回はReplicationの設定が中心です。Shardingの設定は別の機会に…。

OS: amazon-linux-ami/2014.03 (64-bit)
MongoDB: 2.6.4


■システム構成概要図と方針

mongo1サーバ(10.54.10.90) → port=30001:Primary(初期)
mongo2サーバ(10.54.30.152) → port=30002:Secondary(初期)、port=30003:Arbiter
ReplicaSet Name: psa ←名前は適当です。 Primary/Secondary/Arbiterの頭文字。
MongoDBを利用するアプリの都合ではりますが、フェイルオーバー時の差分更新を考慮して、Priorityは設定せず、PrimaryとSecondaryは随時入れ替わることを想定してディレクトリ構成はできるだけ同一とします。
まず、MongoDBをインストールしたAMIを作成し、先にSecondary/Arbiter側から設定します。次にPrimary側でreplication設定すると作業の流れがスムーズです。


******* Secondary/Arbiter *******

前回作成したAMIからmongo2サーバを作成。mongo1サーバとは別のAZを利用する。
replication設定は後ほどPrimaryを想定しているmongo1サーバで実施するため、Secondary/Arbiterの設定を先に進める。


■EC2概要
Instance: i-bb41xxx2 (mongo2)
Private IP: 10.54.30.152
Availability zone: ap-northeast-1c
OS: amazon-linux-ami/2014.03 (64-bit)


■ホスト名変更
[ec2-user@ip-10-54-30-152 ~]$ sudo cp -p /etc/sysconfig/network /etc/sysconfig/network.org
[ec2-user@ip-10-54-30-152 ~]$ sudo vi /etc/sysconfig/network
[ec2-user@ip-10-54-30-152 ~]$ diff /etc/sysconfig/network /etc/sysconfig/network.org
2c2
< HOSTNAME=mongo2
---
> HOSTNAME=localhost.localdomain
[ec2-user@ip-10-54-30-152 ~]$ sudo reboot


■hostsファイルの設定
[ec2-user@mongo2 ~]$ sudo vi /etc/hosts
[ec2-user@mongo2 ~]$ cat /etc/hosts
127.0.0.1   localhost localhost.localdomain

10.54.10.90   mongo1
10.54.30.152  mongo2
[ec2-user@mongo2 ~]$


■設定ファイル作成(初期SecondaryおよびArbiter)
※Arbiterは固定だが、Primary/Secondaryは入れ替わることを想定しているので、secondary.confのようなファイル名にはしない。
[ec2-user@mongo2 ~]$ vi /data/mongo_rs/conf/mongod.conf
[ec2-user@mongo2 ~]$ cat /data/mongo_rs/conf/mongod.conf
bind_ip=mongo2
port=30002
dbpath=/data/mongo_rs/db
pidfilepath=/var/run/mongodb/mongod.pid
logpath=/var/log/mongodb/mongod.log
logappend=true
fork=true
replSet=psa
[ec2-user@mongo2 ~]$ mkdir /data/mongo_rs/arb
[ec2-user@mongo2 ~]$ vi /data/mongo_rs/conf/arbiter.conf
[ec2-user@mongo2 ~]$ cat /data/mongo_rs/conf/arbiter.conf
bind_ip=mongo2
port=30003
dbpath=/data/mongo_rs/arb
pidfilepath=/var/run/mongodb/arbiter.pid
logpath=/var/log/mongodb/arbiter.log
logappend=true
fork=true
replSet=psa
[ec2-user@mongo2 ~]$


◆参考:ファイルディスクリプタ数上限値拡張
デフォルトの1024→2048に変更。
[ec2-user@mongo2 ~]$ ulimit -a | grep open; ulimit -n 2048; ulimit -a | grep open
open files                      (-n) 1024
open files                      (-n) 2048
[ec2-user@mongo2 ~]$
システムの規模に応じて上限値を拡張する。
MongoDBのオフィシャルサイトでは"64000"を推奨しているようですが、EC2インスタンスがしょぼいので今回は2048に設定してみます。
この値はログインしているシェルで保持されているため、恒久的な設定でないことに注意!


■mongod起動
## Secondary
[ec2-user@mongo2 ~]$ ulimit -n 2048; sudo mongod --config /data/mongo_rs/conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1732
child process started successfully, parent exiting
[ec2-user@mongo2 ~]$
※ec2-userをmongodグループに所属させたり、pidファイルやlogファイルの権限を変えてみたが、ec2-userで起動すると失敗する。
mongodはrootで起動することを想定している??

## Arbiter
[ec2-user@mongo2 ~]$ ulimit -n 2048; sudo mongod --config /data/mongo_rs/conf/arbiter.conf
about to fork child process, waiting until server is ready for connections.
forked process: 17768
child process started successfully, parent exiting
[ec2-user@mongo2 ~]$

## 起動確認
[ec2-user@mongo2 ~]$ /etc/init.d/mongod status
mongod (pid 17768 1732) is running...
[ec2-user@mongo2 ~]$ ps aux | head -1; ps aux | grep mongod
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1732  0.1  3.1 725500 32024 ?        Sl   15:27   0:00 mongod --config /data/mongo_rs/conf/mongod.conf
root     17768  0.1  3.1 717308 32076 ?        Sl   15:32   0:00 mongod --config /data/mongo_rs/conf/arbiter.conf
ec2-user 17862  0.0  0.0 110280   840 pts/0    S+   15:36   0:00 grep mongod
[ec2-user@mongo2 ~]$

## 停止させる場合
mongod stopコマンドだとSecondary/Arbiterのどちらかしか停止できない。
完全に停止させるにはkillコマンドを使用する。


■データベース接続確認
[ec2-user@mongo2 ~]$ mongo mongo2:30002
MongoDB shell version: 2.6.4
connecting to: mongo2:30002/test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        http://docs.mongodb.org/
Questions? Try the support group
        http://groups.google.com/group/mongodb-user
> show dbs
admin  (empty)
local  0.078GB
> exit
bye
[ec2-user@mongo2 ~]$ mongo mongo2:30003
MongoDB shell version: 2.6.4
connecting to: mongo2:30003/test
> show dbs
admin  (empty)
local  0.078GB
> exit
bye
[ec2-user@mongo2 ~]$
Secondary/Arbiterの準備はこれで完了です。次はPrimaryの設定になります。


◆参考:MongoDBインスタンスの設定値の確認
[ec2-user@mongo2 ~]$ cat /proc/1732/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             7772                 7772                 processes
Max open files            2048                 2048                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       7772                 7772                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us
[ec2-user@mongo2 ~]$
※1732はSecondaryのPIDです。


◆参考:MongoDBモニタリングツール
[ec2-user@mongo2 ~]$ mongostat -h mongo2 --port 30002
connected to: mongo2:30002
insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time
    *0      1     *0     *0       0     1|0       0    80m   709m    31m      0 local:0.0%          0       0|0     0|0    62b     3k     1  REC   15:41:44
    *0      1     *0     *0       0     1|0       0    80m   709m    31m      0 local:0.0%          0       0|0     0|0    62b     3k     1  REC   15:41:45
    *0      1     *0     *0       0     1|0       0    80m   709m    31m      0 local:0.0%          0       0|0     0|0    62b     3k     1  REC   15:41:46
    *0      1     *0     *0       0     1|0       0    80m   709m    31m      0 local:0.0%          0       0|0     0|0    62b     3k     1  REC   15:41:47
    *0      1     *0     *0       0     1|0       0    80m   709m    31m      0 local:0.0%          0       0|0     0|0    62b     3k     1  REC   15:41:48
^C
[ec2-user@mongo2 ~]$



******* Primary *******

■EC2概要
Instance: i-eca4xxx5 (mongo1)
Private IP: 10.54.10.90
Availability zone: ap-northeast-1a
OS: amazon-linux-ami/2014.03 (64-bit)


■ホスト名変更
[ec2-user@ip-10-54-10-90 ~]$ sudo cp -p /etc/sysconfig/network /etc/sysconfig/network.org
[ec2-user@ip-10-54-10-90 ~]$ sudo vi /etc/sysconfig/network
[ec2-user@ip-10-54-10-90 ~]$ diff /etc/sysconfig/network /etc/sysconfig/network.org
2c2
< HOSTNAME=mongo1
---
> HOSTNAME=localhost.localdomain
[ec2-user@ip-10-54-10-90 ~]$ sudo reboot


■hostsファイルの設定
[ec2-user@mongo1 ~]$ sudo vi /etc/hosts
[ec2-user@mongo1 ~]$ cat /etc/hosts
127.0.0.1   localhost localhost.localdomain

10.54.10.90   mongo1
10.54.30.152  mongo2
[ec2-user@mongo1 ~]$
※AWSの場合、SecurityGroupでmongo2サーバとの通信を許可しておいてください。


■設定ファイル作成(初期Primary)
[ec2-user@mongo1 ~]$ vi /data/mongo_rs/conf/mongod.conf
[ec2-user@mongo1 ~]$ cat /data/mongo_rs/conf/mongod.conf
bind_ip=mongo1
port=30001
dbpath=/data/mongo_rs/db
pidfilepath=/var/run/mongodb/mongod.pid
logpath=/var/log/mongodb/mongod.log
logappend=true
fork=true
replSet=psa
[ec2-user@mongo1 ~]$


■mongod起動
[ec2-user@mongo1 ~]$ ulimit -n 2048; sudo mongod --config /data/mongo_rs/conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1615
child process started successfully, parent exiting
[ec2-user@mongo1 ~]$
この時点ではまだreplicationされていませんのでご注意を。


■replication設定
いよいよrepricationの設定です。rs.initiate()実行後にコマンドプロンプトが
"ReplicaSet名:PRIMARY>"に変更されます。

## ReplicaSetの初期化
[ec2-user@mongo1 ~]$ mongo mongo1:30001
MongoDB shell version: 2.6.4
connecting to: mongo1:30001/test
> rs.initiate()
{
        "info2" : "no configuration explicitly specified -- making one",
        "me" : "mongo1:30001",
        "info" : "Config now saved locally.  Should come online in about a minute.",
        "ok" : 1
}
>
psa:PRIMARY> rs.conf()
{
        "_id" : "psa",
        "version" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "mongo1:30001"
                }
        ]
}
psa:PRIMARY>

## SecandaryとArbiter追加
psa:PRIMARY> rs.add("mongo2:30002")
{ "ok" : 1 }
psa:PRIMARY> rs.addArb("mongo2:30003")
{ "ok" : 1 }
psa:PRIMARY>

## 設定の確認
psa:PRIMARY> rs.conf()
{
        "_id" : "psa",
        "version" : 3,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "mongo1:30001"
                },
                {
                        "_id" : 1,
                        "host" : "mongo2:30002"
                },
                {
                        "_id" : 2,
                        "host" : "mongo2:30003",
                        "arbiterOnly" : true
                }
        ]
}
psa:PRIMARY> rs.status()
{
        "set" : "psa",
        "date" : ISODate("2014-09-04T07:13:39Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "mongo1:30001",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 461,
                        "optime" : Timestamp(1409814782, 1),
                        "optimeDate" : ISODate("2014-09-04T07:13:02Z"),
                        "electionTime" : Timestamp(1409814552, 2),
                        "electionDate" : ISODate("2014-09-04T07:09:12Z"),
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "mongo2:30002",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 53,
                        "optime" : Timestamp(1409814782, 1),
                        "optimeDate" : ISODate("2014-09-04T07:13:02Z"),
                        "lastHeartbeat" : ISODate("2014-09-04T07:13:38Z"),
                        "lastHeartbeatRecv" : ISODate("2014-09-04T07:13:38Z"),
                        "pingMs" : 2,
                        "syncingTo" : "mongo1:30001"
                },
                {
                        "_id" : 2,
                        "name" : "mongo2:30003",
                        "health" : 1,
                        "state" : 7,
                        "stateStr" : "ARBITER",
                        "uptime" : 37,
                        "lastHeartbeat" : ISODate("2014-09-04T07:13:38Z"),
                        "lastHeartbeatRecv" : ISODate("2014-09-04T07:13:39Z"),
                        "pingMs" : 2
                }
        ],
        "ok" : 1
}
psa:PRIMARY>

## 念のためSecondary側でも確認
[ec2-user@mongo1 ~]$ mongo mongo2:30002
MongoDB shell version: 2.6.4
connecting to: mongo2:30002/test
psa:SECONDARY> rs.conf()
{
        "_id" : "psa",
        "version" : 3,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "mongo1:30001"
                },
                {
                        "_id" : 1,
                        "host" : "mongo2:30002"
                },
                {
                        "_id" : 2,
                        "host" : "mongo2:30003",
                        "arbiterOnly" : true
                }
        ]
}
psa:SECONDARY>


◆参考:replicationの動作検証
Primaryで作成した1000件のレコードが、Secondaryにレプリケートされいているか確認。

## レコード作成(Primary)
[ec2-user@mongo1 ~]$ mongo mongo1:30001/reptest
MongoDB shell version: 2.6.4
connecting to: mongo1:30001/reptest
psa:PRIMARY> for(var i=0; i<1000; i++) db.repcoll.insert( { "uid":i, "value":Math.floor(Math.random()*1000+1) } )
WriteResult({ "nInserted" : 1 })
psa:PRIMARY> db.repcoll.count()
1000
psa:PRIMARY> db.repcoll.find()
{ "_id" : ObjectId("5408144a85529d4cbf6eb107"), "uid" : 0, "value" : 929 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb108"), "uid" : 1, "value" : 547 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb109"), "uid" : 2, "value" : 26 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10a"), "uid" : 3, "value" : 813 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10b"), "uid" : 4, "value" : 609 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10c"), "uid" : 5, "value" : 992 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10d"), "uid" : 6, "value" : 75 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10e"), "uid" : 7, "value" : 449 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10f"), "uid" : 8, "value" : 817 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb110"), "uid" : 9, "value" : 422 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb111"), "uid" : 10, "value" : 133 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb112"), "uid" : 11, "value" : 280 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb113"), "uid" : 12, "value" : 613 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb114"), "uid" : 13, "value" : 830 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb115"), "uid" : 14, "value" : 790 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb116"), "uid" : 15, "value" : 155 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb117"), "uid" : 16, "value" : 915 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb118"), "uid" : 17, "value" : 317 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb119"), "uid" : 18, "value" : 903 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb11a"), "uid" : 19, "value" : 89 }
Type "it" for more
psa:PRIMARY>

## 確認(Secondary)
[ec2-user@mongo1 ~]$ mongo mongo2:30002/reptest
MongoDB shell version: 2.6.4
connecting to: mongo2:30002/reptest
psa:SECONDARY> db.repcoll.count()
2014-09-04T16:30:49.898+0900 count failed: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" } at src/mongo/shell/query.js:191
psa:SECONDARY>
→読み取り許可設定が必要。
psa:SECONDARY> db.getMongo().setSlaveOk()
psa:SECONDARY> db.repcoll.count()
1000
psa:SECONDARY> db.repcoll.find()
{ "_id" : ObjectId("5408144a85529d4cbf6eb107"), "uid" : 0, "value" : 929 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb108"), "uid" : 1, "value" : 547 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb109"), "uid" : 2, "value" : 26 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10a"), "uid" : 3, "value" : 813 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10b"), "uid" : 4, "value" : 609 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10c"), "uid" : 5, "value" : 992 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10d"), "uid" : 6, "value" : 75 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10e"), "uid" : 7, "value" : 449 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb10f"), "uid" : 8, "value" : 817 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb110"), "uid" : 9, "value" : 422 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb111"), "uid" : 10, "value" : 133 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb112"), "uid" : 11, "value" : 280 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb113"), "uid" : 12, "value" : 613 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb114"), "uid" : 13, "value" : 830 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb115"), "uid" : 14, "value" : 790 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb116"), "uid" : 15, "value" : 155 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb117"), "uid" : 16, "value" : 915 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb118"), "uid" : 17, "value" : 317 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb119"), "uid" : 18, "value" : 903 }
{ "_id" : ObjectId("5408144a85529d4cbf6eb11a"), "uid" : 19, "value" : 89 }
Type "it" for more
psa:SECONDARY>
Primaryに登録されたデータがSecondaryにレプリケートされていることを確認できました。


◆参考:MongoDBフェイルオーバー検証
Primaryに障害が発生した場合、SecandaryがPrimaryに昇格するか確認してみます。

## mongo1サーバのPrimary停止前(Arbiterに接続して確認)
[ec2-user@mongo1 ~]$ mongo mongo2:30003 --eval "printjson(rs.status())" | egrep "name|stateStr"
                        "name" : "mongo1:30001",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo2:30002",
                        "stateStr" : "SECONDARY",
                        "name" : "mongo2:30003",
                        "stateStr" : "ARBITER",
[ec2-user@mongo1 ~]$
mongo ホスト名:ポート番号 --eval "printjson(mongoシェル)" とすると、Bashから直接mongoシェルを実行できます。

## mongo1サーバのPrimary停止
[ec2-user@mongo1 ~]$ ps -ef | grep mongo
root      1615     1  1 16:05 ?        00:02:43 mongod --config /data/mongo_rs/conf/mongod.conf
ec2-user  3681  2574  0 19:04 pts/0    00:00:00 grep mongo
[ec2-user@mongo1 ~]$ sudo kill -9 1615
[ec2-user@mongo1 ~]$
[ec2-user@mongo1 ~]$ mongo mongo2:30003 --eval "printjson(rs.status())" | egrep "name|stateStr"
                        "name" : "mongo1:30001",
                        "stateStr" : "(not reachable/healthy)",
                        "name" : "mongo2:30002",
                        "stateStr" : "PRIMARY",
                        "name" : "mongo2:30003",
                        "stateStr" : "ARBITER",
[ec2-user@mongo1 ~]$
SecandaryがPrimaryに昇格しました!!
※この後、元Primaryを復旧させると優先順位を定義していないのでSecondaryとなります。


長文にお付き合いいただきありがとうございました。こちらの情報が何かのお役に立てましたら幸いです。

2014年9月6日土曜日

AmazonLinuxにMongoDBをインストール

AWS上に実践的なMongoDBのReplication構成を構築するための事前作業としてAmazonLinuxにMongoDBをインストールする手順をまとめます。
データベース格納先のディレクトリは/(ルート)とは別ボリュームのEBSを利用するようにしています。
インストール完了後にAMIを作成します。
次回以降は、このAMIから複数のEC2を作成し、MonogoDBのReplication設定を進めていきます。併せてお読みください。

OS: amazon-linux-ami/2014.03 (64-bit)
MongoDB: 2.6.4



■EC2概要
Instance: i-eca4xxx5
Private IP: 10.54.10.90
Availability zone: ap-northeast-1a
OS: amazon-linux-ami/2014.03 (64-bit)


■AmazonLinux初期設定作業
TimeZone変更: Asia/Tokyo
iptables off
[ec2-user@ip-10-54-10-90 ~]$ sudo date; sudo cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime; sudo date
[ec2-user@ip-10-54-10-90 ~]$ sudo chkconfig iptables off; sudo chkconfig --list iptables
[ec2-user@ip-10-54-10-90 ~]$ sudo chkconfig ip6tables off; sudo chkconfig --list ip6tables
(出力結果省略)


■yum repository の追加
[ec2-user@ip-10-54-10-90 ~]$ sudo vi /etc/yum.repos.d/mongodb.repo
[ec2-user@ip-10-54-10-90 ~]$ cat /etc/yum.repos.d/mongodb.repo
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=0
[ec2-user@ip-10-54-10-90 ~]$
オフィシャルサイトでは"enabled=1"となっているが、他用途でyumコマンドを実行したときにmongodb.repoをデフォルトで参照する必要はないので"enabled=0"とする。


■Install MongoDB
[ec2-user@ip-10-54-10-90 ~]$ sudo yum --enablerepo=mongodb install mongodb-org
(中略)
============================================================================
 Package                      Arch        Version       Repository     Size
============================================================================
Installing:
 mongodb-org                  x86_64      2.6.4-1       mongodb       4.6 k
Installing for dependencies:
 mongodb-org-mongos           x86_64      2.6.4-1       mongodb       6.8 M
 mongodb-org-server           x86_64      2.6.4-1       mongodb       9.0 M
 mongodb-org-shell            x86_64      2.6.4-1       mongodb       4.3 M
 mongodb-org-tools            x86_64      2.6.4-1       mongodb        89 M

Transaction Summary
============================================================================
Install  1 Package (+4 Dependent packages)

Total download size: 109 M
Installed size: 276 M
(以下略)


■version確認
[ec2-user@ip-10-54-10-90 ~]$ mongod -version
db version v2.6.4
2014-09-04T11:28:44.181+0900 git version: 3a830be0eb92d772aa855ebb711ac91d658ee910
[ec2-user@ip-10-54-10-90 ~]$


■MongoDBのデフォルト設定確認
[ec2-user@ip-10-54-10-90 ~]$ grep -v "^#\|^$" /etc/mongod.conf
logpath=/var/log/mongodb/mongod.log
logappend=true
fork=true
dbpath=/var/lib/mongo
pidfilepath=/var/run/mongodb/mongod.pid
bind_ip=127.0.0.1
[ec2-user@ip-10-54-10-90 ~]$
※コメント行と空白行を非表示。


■mongod自動起動off
replication設定でmongodを起動したいので、 デフォルト設定のmongodは起動しないようにしておく。
[ec2-user@ip-10-54-10-90 ~]$ sudo chkconfig mongod off; sudo chkconfig --list mongod
mongod          0:off   1:off   2:off   3:off   4:off   5:off   6:off
[ec2-user@ip-10-54-10-90 ~]$


■データベース格納用ボリューム準備
あらかじめ、EC2作成時に別EBS(今回は10GBとした)を作成しておく。

## EBSのデバイス名を確認
[ec2-user@ip-10-54-10-90 ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
??xvda1 202:1    0   8G  0 part /
xvdb    202:16   0  10G  0 disk
[ec2-user@ip-10-54-10-90 ~]$

## ext4でフォーマット
[ec2-user@ip-10-54-10-90 ~]$ sudo mkfs.ext4 /dev/xvdb
mke2fs 1.42.8 (20-Jun-2013)
(中略)
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

[ec2-user@ip-10-54-10-90 ~]$

## 自動マウント設定
[ec2-user@ip-10-54-10-90 ~]$ sudo vi /etc/rc.local
[ec2-user@ip-10-54-10-90 ~]$ tail -2 /etc/rc.local
# for MongoDB data
mount /dev/xvdb /data
[ec2-user@ip-10-54-10-90 ~]$


■データベース格納先ディレクトリ準備
[ec2-user@ip-10-54-10-90 ~]$ sudo mkdir /data
[ec2-user@ip-10-54-10-90 ~]$ sudo mount /dev/xvdb /data
[ec2-user@ip-10-54-10-90 ~]$ df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/xvda1     ext4      7.8G  1.2G  6.5G  16% /
devtmpfs       devtmpfs  486M   60K  486M   1% /dev
tmpfs          tmpfs     499M     0  499M   0% /dev/shm
/dev/xvdb      ext4      9.8G   23M  9.2G   1% /data
[ec2-user@ip-10-54-10-90 ~]$

## データベース格納先作成(replication考慮)
[ec2-user@ip-10-54-10-90 ~]$ sudo mkdir -p /data/mongo_rs/db

## configファイル格納先作成と所有者変更
[ec2-user@ip-10-54-10-90 ~]$ sudo mkdir /data/mongo_rs/conf
[ec2-user@ip-10-54-10-90 ~]$ sudo chown ec2-user: -R /data/mongo_rs


★AMI(201409xx_mongo_install_only)作成
データ格納先を独自に指定したいので、デフォルト設定のままではMongoDBを起動しない。
mongo1サーバおよび、mongo2サーバでホスト名を定義したそれぞれのレプリケーション用のmongod.confを作成するためこの時点でAMIを作成しておく。


今回の手順はここまでとします。Replication設定についてはこちらの記事にまとめます。
こちらの情報が何かのお役に立てましたら幸いです。サイト継続ご協力のほどお願い致します。m(_ _)m

2014年8月10日日曜日

AWS上のLinuxにリモートデスクトップ接続

xrdpを利用してAWS上のLinuxサーバにリモートデスクトップ接続する手順をまとめます。
接続元PCはWindows7を利用しました。標準のリモートデスクトップ接続クライアントで接続できるため
とても便利ですが、ベースがVNCのため微妙に描画が遅く感じられることは否めません。
今回利用したAMIのLinuxのデフォルト言語は英語ですが、日本語化する手順も記載します。

OS: RHEL 6.5 (64-bit)
xrdp: 0.5.0
リモートデスクトップ接続クライアント: 6.3.9600


■EC2準備
Quick Startにある下記のAMIからEC2を作成しました。
Red Hat Enterprise Linux 6.5 (PV) - ami-e9aee0e8 (64-bit) / ami-cfbff1ce (32-bit)


■初期ログイン&rootパスワード変更
Using username "ec2-user".
Authenticating with public key "imported-openssh-key"
[ec2-user@ip-10-86-30-138 ~]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.5 (Santiago)
[ec2-user@ip-10-86-30-138 ~]$ sudo passwd
Changing password for user root.
New password:
BAD PASSWORD: it is based on a dictionary word
Retype new password:
passwd: all authentication tokens updated successfully.
[ec2-user@ip-10-86-30-138 ~]$
## ec2-userのパスワードも設定
[root@ip-10-86-30-138 ~]# passwd ec2-user


■SELinux/iptables無効化
[ec2-user@ip-10-86-30-138 ~]$ su -
Password:
[root@ip-10-86-30-138 ~]# vi /etc/selinux/config
[root@ip-10-86-30-138 ~]# grep disabled /etc/selinux/config
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
[root@ip-10-86-30-138 ~]# chkconfig iptables off; chkconfig --list iptables
iptables        0:off   1:off   2:off   3:off   4:off   5:off   6:off
[root@ip-10-86-30-138 ~]# chkconfig ip6tables off; chkconfig --list ip6tables
ip6tables       0:off   1:off   2:off   3:off   4:off   5:off   6:off
[root@ip-10-86-30-138 ~]#
AWS上のEC2へのアクセス制御はとりあえずSecurityGroupで。


■TimeZoneとHostName変更
ここの手順は省略可です。後々の運用を考慮して設定しておきます。
[root@ip-10-86-30-138 ~]# date; cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime; date
Sun Aug 10 00:15:37 EDT 2014
cp: overwrite `/etc/localtime'? y
Sun Aug 10 13:15:39 JST 2014
[root@ip-10-86-30-138 ~]#
[root@ip-10-86-30-138 ~]# vi /etc/sysconfig/network
[root@ip-10-86-30-138 ~]# grep HOSTNAME /etc/sysconfig/network
# HOSTNAME=ip-10-86-30-138.localdomain
HOSTNAME=rhel65-rdp
[root@ip-10-86-30-138 ~]# reboot


■GnomeGUIインストール
[root@rhel65-rdp ~]# yum groupinstall "X Window System" "GNOME Desktop Environment" "Desktop"
(中略)
Install     273 Package(s)
Upgrade       6 Package(s)
(以下省略)


■vncserverのインストールと起動準備
xrdpはVNCを利用しているようなので。

## VNCインストール
[root@rhel65-rdp ~]# yum install tigervnc-server
(中略)
===============================================================================
 Package           Arch   Version       Repository                        Size
===============================================================================
Installing:
 tigervnc-server   x86_64 1.1.0-8.el6_5 rhui-REGION-rhel-server-releases 1.1 M
Installing for dependencies:
 xorg-x11-fonts-misc
                   noarch 7.2-9.1.el6   rhui-REGION-rhel-server-releases 5.8 M

Transaction Summary
===============================================================================
Install       2 Package(s)
(以下省略)
## VNCサーバ設定
[root@rhel65-rdp ~]# vi /etc/sysconfig/vncservers
[root@rhel65-rdp ~]# tail -3 /etc/sysconfig/vncservers
VNCSERVERS="1:ec2-user 2:root"
VNCSERVERARGS[1]="-geometry 1024x768"
VNCSERVERARGS[2]="-geometry 1024x768"
[root@rhel65-rdp ~]# chkconfig vncserver on; chkconfig --list vncserver
vncserver       0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@rhel65-rdp ~]#
## VNC接続ユーザパスワード設定
[root@rhel65-rdp ~]# vncpasswd
Password:
Verify:
[root@rhel65-rdp ~]# su - ec2-user
[ec2-user@rhel65-rdp ~]$ vncpasswd
Password:
Verify:
[ec2-user@rhel65-rdp ~]$
## VNCサーバ起動
[root@rhel65-rdp ~]# /etc/init.d/vncserver start
Starting VNC server: 1:ec2-user xauth:  creating new authority file /home/ec2-user/.Xauthority
xauth: (stdin):1:  bad display name "rhel65-rdp:1" in "add" command

New 'rhel65-rdp:1 (ec2-user)' desktop is rhel65-rdp:1

Creating default startup script /home/ec2-user/.vnc/xstartup
Starting applications specified in /home/ec2-user/.vnc/xstartup
Log file is /home/ec2-user/.vnc/rhel65-rdp:1.log

2:root xauth:  creating new authority file /root/.Xauthority
xauth: (stdin):1:  bad display name "rhel65-rdp:2" in "add" command

New 'rhel65-rdp:2 (root)' desktop is rhel65-rdp:2

Creating default startup script /root/.vnc/xstartup
Starting applications specified in /root/.vnc/xstartup
Log file is /root/.vnc/rhel65-rdp:2.log

                                                           [  OK  ]
[root@rhel65-rdp ~]#


■EPELリポジトリのインストール
[root@rhel65-rdp ~]# rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
Retrieving http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
warning: /var/tmp/rpm-tmp.D24qpa: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Preparing...                ########################################### [100%]
   1:epel-release           ########################################### [100%]
[root@rhel65-rdp ~]#
## yum実行時にEPELリポジトリをデフォルト参照しない設定
[root@rhel65-rdp ~]# sed -i 's/enabled=1/enabled=0/g' /etc/yum.repos.d/epel.repo


■xrdpのインストール
[root@rhel65-rdp ~]# yum --enablerepo=epel install xrdp
(中略)
================================================================================
 Package        Arch             Version                   Repository      Size
================================================================================
Installing:
 xrdp           x86_64           0.5.0-0.13.el6            epel           240 k

Transaction Summary
================================================================================
Install       1 Package(s)
(以下省略)
[root@rhel65-rdp ~]# chkconfig xrdp on; chkconfig --list xrdp
xrdp            0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@rhel65-rdp ~]#


■日本語キーボード対応
km-e0010411.iniをダウンロードしてシンボリックリンクを作成。
[root@rhel65-rdp ~]# cd /etc/xrdp/
[root@rhel65-rdp xrdp]# wget http://www.mail-archive.com/xrdp-devel@lists.sourceforge.net/msg00263/km-e0010411.ini
[root@rhel65-rdp xrdp]# mv km-e0010411.ini km-0411.ini
[root@rhel65-rdp xrdp]# ln -s km-0411.ini  km-e0010411.ini
[root@rhel65-rdp xrdp]# ln -s km-0411.ini  km-e0200411.ini
[root@rhel65-rdp xrdp]# ln -s km-0411.ini  km-e0210411.ini
[root@rhel65-rdp xrdp]#


■xrdp起動
[root@rhel65-rdp xrdp]# /etc/init.d/xrdp start
Starting xrdp:                                             [  OK  ]
Starting xrdp-sesman:                                      [  OK  ]
[root@rhel65-rdp xrdp]#


■リモートデスクトップ接続
事前にSecurity GroupでPort 3389を開放しておきます。
Windows7のRDPクライアントから接続します。バージョンは、6.3.9600です。


AWS上のLinuxにリモートデスクトップで接続できました。



■GUIを日本語化
せっかくなのでGUIを日本語化してみます。

## 日本語化に必要なパッケージインストール
[root@rhel65-rdp ~]# yum groupinstall "Japanese Support"
(中略)
==================================================================================
 Package            Arch   Version         Repository                        Size
==================================================================================
Installing:
 Red_Hat_Enterprise_Linux-Release_Notes-6-ja-JP
                    noarch 5-1.el6         rhui-REGION-rhel-server-releases  98 k
 ibus-anthy         x86_64 1.2.1-3.el6     rhui-REGION-rhel-server-releases 133 k
 ipa-gothic-fonts   noarch 003.02-4.2.el6  rhui-REGION-rhel-server-releases 3.6 M
 ipa-mincho-fonts   noarch 003.02-3.1.el6  rhui-REGION-rhel-server-releases 5.0 M
 ipa-pgothic-fonts  noarch 003.02-4.1.el6  rhui-REGION-rhel-server-releases 3.6 M
 ipa-pmincho-fonts  noarch 003.02-3.1.el6  rhui-REGION-rhel-server-releases 5.0 M
 man-pages-ja       noarch 20100115-6.el6  rhui-REGION-rhel-server-releases 5.5 M
 vlgothic-fonts     noarch 20091202-2.el6  rhui-REGION-rhel-server-releases 2.2 M
 vlgothic-p-fonts   noarch 20091202-2.el6  rhui-REGION-rhel-server-releases 2.2 M
Installing for dependencies:
 anthy              x86_64 9100h-10.1.el6  rhui-REGION-rhel-server-releases 6.0 M
 ibus               x86_64 1.3.4-6.el6     rhui-REGION-rhel-server-releases 337 k
 ibus-gtk           x86_64 1.3.4-6.el6     rhui-REGION-rhel-server-releases  26 k
 ibus-libs          x86_64 1.3.4-6.el6     rhui-REGION-rhel-server-releases  99 k
 im-chooser         x86_64 1.3.1-3.el6     rhui-REGION-rhel-server-releases 144 k
 imsettings         x86_64 0.108.0-3.6.el6 rhui-REGION-rhel-server-releases 190 k
 imsettings-libs    x86_64 0.108.0-3.6.el6 rhui-REGION-rhel-server-releases 103 k
 kasumi             x86_64 2.5-1.1.el6     rhui-REGION-rhel-server-releases  71 k
 libgxim            x86_64 0.3.3-3.1.el6   rhui-REGION-rhel-server-releases 126 k
 notify-python      x86_64 0.1.1-10.el6    rhui-REGION-rhel-server-releases  26 k
 pyxdg              noarch 0.18-1.el6      rhui-REGION-rhel-server-releases  79 k
 vlgothic-fonts-common
                    noarch 20091202-2.el6  rhui-REGION-rhel-server-releases  16 k

Transaction Summary
==================================================================================
Install      21 Package(s)
(以下省略)
## OSの言語を日本語を設定し再起動
[root@rhel65-rdp ~]# vi /etc/sysconfig/i18n
[root@rhel65-rdp ~]# cp -p /etc/sysconfig/i18n /etc/sysconfig/i18n.org
[root@rhel65-rdp ~]# vi /etc/sysconfig/i18n
[root@rhel65-rdp ~]# cat /etc/sysconfig/i18n
LANG="ja_JP.UTF-8"
SYSFONT="latarcyrheb-sun16"
[root@rhel65-rdp ~]# vi .bash_profile
[root@rhel65-rdp ~]# tail -1 .bash_profile
export LANG=ja_JP.UTF-8
[root@rhel65-rdp ~]#
[root@rhel65-rdp ~]# reboot
## 再びリモートデスクトップ接続

日本語GUI画面が表示されました。


こちらの情報が何かのお役に立てましたら幸いです。サイト継続ご協力のほどお願い致します。m(_ _)m