funasaki memo

このブログ上の投稿は個人のものであり、所属する企業を代表する投稿ではありません。所属:AWSのSolutions Architect

Amazon RDS(MySQL)のログファイル出力について

Amazon RDSでログファイルにアクセス可能になりました。

【AWS発表】Amazon RDS - より簡単にログファイルにアクセス可能に

今まではRDS MySQLのgeneral logなどはRDSのテーブル内に出力していました。
上記機能により、テーブルではなくファイルのみに出力させることが可能となっています。

f:id:kenjifunasaki:20130313143806p:plain

TABLEかFILEか、どちらかを選択する形です。

ファイルの出力先の場所はgeneral_log_fileの場合は、/rdsdbdata/log/general/mysql-general.logですが、こちらの出力先の場所を変更することは出来ないようです。

また、ログファイルのサイズが大きくなりすぎてしまい、DBのパフォーマンスに影響が出てしまうのを避けるため、以下の条件になったときにログファイルが自動的にrotateされます。

  • When disk space usage is greater than 90% of the allocated space and a log uses either more than 10% of the allocated storage or the log uses greater than 5 GB.
  • If a log uses more than 20% of the allocated storage or a log uses greater than 10 GB, regardless of total disk usage.

参照
http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_LogAccess.Concepts.MySQL.html

GitマスターサーバをAmazon Linuxにインストールしてみる

Gitマスターサーバにgitをインストールする。

$ sudo yum install git git-all git-daemon
$ git --version
git version 1.7.4.5

xinetdを使ってgitサーバを起動する

sudo /etc/init.d/xinetd start

gitの設定ファイルでdisable = no に変更

sudo vi /etc/xinedt.d/git
# default: off
# description: The git damon allows git repositories to be exported using \
#       the git:// protocol.

service git
{
        disable         = no
        socket_type     = stream
        wait            = no
        user            = nobody
        server          = /usr/libexec/git-core/git-daemon
        server_args     = --base-path=/var/lib/git --export-all --user-path=publ
ic_git --syslog --inetd --verbose
        log_on_failure  += USERID
}

xinetdをrestartする。

sudo /etc/init.d/xinetd restart

リポジトリを作成する。

cd /var/lib/git
sudo mkdir test
cd test
sudo git --bare init --shared
sudo chmod 777 -R test

次にリモートのGitクライアントの設定
Gitをインストールする。

sudo yum install git

サンプルテキストの作成

mkdir ~/test
cd ~/test
vi test.txt
aiueo

作成したテキストをcommitする

git init
git add .
git commit -m "First Commit"

リモートのGitマスターサーバに接続するためのSSHの設定をする

vi ~/.ssh/config
Host ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com
User ec2-user
IdentityFile ~/.ssh/xxxxxx.pem
sudo chmod 600 /home/ec2-user/.ssh/config
sudo chmod 600 /home/ec2-user/.ssh/xxxxxx.pem

リモートのマスターを追加する

$ git remote add origin ssh://ec2-user@ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com/var/lib/git/test

リモートのマスターのリポジトリにpushする。

$ git push origin master

これで、マスター側の該当ディレクトリを見ると

$ ls -F
branches/  config*  description*  HEAD*  hooks/  info/  objects/  refs/

branchesディレクトリ等いろいろできている。

まだ確認できることはありそうだけど、今回はここまで。

ElastiCacheを使ってみる

Amazon ElastiCacheはインストール、構築不要のmemcachedクラスタ
現状はMemcached 1.4.5, 1.4.14 に対応しているようです。

使ってみて気づいたことは以下です。

  • ElastiCacheへはEC2(VPC)インスタンスからのみアクセスが可能。
    • ElastiCacheのセキュリティグループの設定により、指定したセキュリティグループを持ったインスタンスしかアクセスを許さない。
  • Management ConsoleでJavaPHPのクライアントアクセスライブラリを取得可能

それではElasticCacheを起動して、Java Clientからアクセスしてみます。

まずは、作成・起動。
Management Consoleから、
f:id:kenjifunasaki:20130214180429p:plain
ElastiCacheを起動します。
f:id:kenjifunasaki:20130214180450p:plain
起動画面で名前、Node Type(インスタンスのタイプ)、Nodeの数、等を指定します。
f:id:kenjifunasaki:20130214180725p:plain
Cache Security Groupを指定します。ここで指定するものは事前に作成しておいたものを利用します。Cache Security Groupの中では、EC2のどのセキュリティグループ(を持つインスタンス)をアクセス許可するかを指定します。
f:id:kenjifunasaki:20130214180814p:plain
確認してLaunch Cache Clusterします。
f:id:kenjifunasaki:20130214181134p:plain
これで起動完了すれば、エンドポイントおよびデフォルトポート11211番を使ってアクセスできるようになります。

ただ、上記にもあるようにEC2のセキュリティグループを持ったインスタンスしかアクセスできないため、ローカルのPCからElastiCacheクラスタノードに直接アクセスできません。(試したかったのですが。)

なので、今回はEC2インスタンス上で以下のJavaソースコードを作成して、コンパイルしたものでアクセスしてみました。

import java.io.IOException;
import java.net.InetSocketAddress;

import net.spy.memcached.AddrUtil;
import net.spy.memcached.BinaryConnectionFactory;
import net.spy.memcached.ClientMode;
import net.spy.memcached.MemcachedClient;


public class ElastiCacheSample {

        public static void main(String[] args) {
                String hostname = "cachecluster2.wfisum.cfg.apne1.cache.amazonaws.com";
                int portNum = 11211;
                String hostnamePort = hostname + ":11211";
                String key = "12345";

                try {
                        MemcachedClient c = new MemcachedClient(new InetSocketAddress(hostname, portNum));
                        // Store a value (async) for one hour
                        c.set("key1", 3600, key);
                        // Retrieve a value.
                        Object myObject=c.get("key1");
                        c.shutdown();
                } catch (IOException e) {
                        e.printStackTrace();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
}

今回はMemcachedClientのshutdown()メソッドを呼び出して、終了するようにしています。

こちらを実行すると

$ java -cp ".:./AmazonElastiCacheClusterClient-1.0.jar" ElastiCacheSample

2013-02-14 18:20:25.826 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/10.160.135.101:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2013-02-14 18:20:25.837 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@5ca46701
2013-02-14 18:20:25.858 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/10.160.135.101:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2013-02-14 18:20:25.859 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/10.160.83.93:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2013-02-14 18:20:25.865 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@42704baa
2013-02-14 18:20:25.866 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@5a77a7f9
2013-02-14 18:20:25.915 INFO net.spy.memcached.MemcachedConnection:  Shut down memcached client

以上のようにmemcachedに指定したkeyが追加され、取得も無事できました。

好きなドメイン名でS3のオブジェクトにアクセスさせる

S3で静的なWebホストが出来ることは周知の事実ですが、そのURLが
xxxxxx.s3-website-ap-northeast-1.amazonaws.com
といった形で、S3にホストしていることがユーザーさんにもわかってしまっていました。

S3を使っているのがわからないようにしたい!という場合には、WebサーバーのbackendでS3からファイルを適宜ダウンロード・アップロードするなどの対応が必要でした。

そこで、2012年12月に発表されたS3ルートドメイン機能を使えば、S3にホストしていることがわからないようにすることができます!

早速試してみました。

今回はxxxxx.infoサイトをS3ルートドメインとして使用します。

まずは、S3で二つのバケットを作ります。

  • xxxxx.info
  • www.xxxxx.info

作成後、これらの二つのバケットのアクセスを全員アクセス許可に設定します。
f:id:kenjifunasaki:20130213134245p:plain

xxxxx.infoのバケット側の設定で、www.xxxxx.infoにリダイレクトする設定を入れます。
f:id:kenjifunasaki:20130213134301p:plain

www.xxxxx.infoのバケット側でStatic Web Hostingの設定で、Indexドキュメントを指定します。
f:id:kenjifunasaki:20130213141320p:plain

次にRoute 53で以下のようにxxxxx.infoとwww.xxxxx.infoの二つのレコードを作成します。

そして、www.xxxxx.info側はCNAMEでxxxxx.infoを指定、
xxxxx.info側はAレコードのエイリアスでS3のxxxxx.infoのバケット(=Static Web Host)を指定します。

これで準備完了です。
http://www.xxxxx.infoへアクセスすると、www.xxxxx.infoバケットにあるindex.htmlが表示されます。
f:id:kenjifunasaki:20130213140627p:plain

設定イメージとしては以下のような感じですかね。
f:id:kenjifunasaki:20130213142140p:plain
ご参考
http://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html

Route 53でELBと通常のサーバをアクセス分散させてみる

下記のような構成をRoute 53の重みづけラウンドロビンでアクセス分散できるか試しました。
f:id:kenjifunasaki:20130212190700p:plain
結果としては、アクセス分散できます。

ただ1点注意が必要なのは、Route 53でELBにエイリアス機能を使ってアクセスを割り振る場合に、TTLの値をRoute 53側で現状セットできないことです。

フォーラムに以下のような説明がありました。

Currently, Amazon Route 53 supports aliases only for routing traffic to
Elastic Load Balancing domains. You cannot set the time to live (TTL) 
for alias records; Amazon Route 53 honors the Elastic Load Balancing TTL.
For the current TTL value for Elastic Load Balancing, see the introduction 
to "Using Domain Names With Elastic Load Balancing."

https://forums.aws.amazon.com/thread.jspa?messageID=259743

ELB はデフォルトで60秒のTTLがセットされているので、今回は通常のインスタンス側に割り振る場合もTTLを60秒にしました。
f:id:kenjifunasaki:20130212192052p:plain

重みづけラウンドロビンによって、ELBと通常インスタンスへのアクセスを分散させる設定をしています。

これをdigコマンドを使って、同じホスト名に対してELBと通常インスタンスのIPが表示されるか確認してみました。

dig server3.funasaki.info
(途中省略)
server3.funasaki.info.  60       IN      A       54.248.139.176
(省略)

通常インスタンス:54.248.139.176
ELBの(この時点での)IP:54.248.223.170

※ELBのIPアドレスは変更することがあるので、IPアドレスDNSに登録しないこと!

60とあるのは、TTLの時間が60秒という意味。これが、digコマンドを実行するたびに秒数が減っていくのがわかります。

dig server3.xxxxxxx.info
(途中省略)
server3.xxxxxxx.info.  50       IN      A       54.248.139.176
(省略)
dig server3.xxxxxxx.info
(途中省略)
server3.xxxxxxx.info.  30       IN      A       54.248.139.176
(省略)
dig server3.xxxxxxx.info
(途中省略)
server3.xxxxxxx.info.  5       IN      A       54.248.139.176
(省略)

60秒経過後、再度digコマンドを実行すると、以下のように今度はELB側のIPアドレスを返すようになりました。

server3.xxxxxxx.info.  60      IN      A       54.248.223.170

このように、ちゃんとIPが変わっているので、負荷分散できますね!
DNSのキャッシュが効いてて、IPが変わらない場合もあるので要注意ですが!

Route 53で重みづけラウンドロビンしてみる

前回シンプルなDNSラウンドロビンを試したので、今回はWeighted (重みづけ)ラウンドロビンをRoute 53で実行してみる。

AWS Management Console上では以下のように設定した。
f:id:kenjifunasaki:20130212165604p:plain

注意事項としては、Set IDのところに異なるIDを入れること。
あとは、TTLの値を小さめにしておかないと、アクセス先がコロコロは変わらないこと。

TTLを3秒にして、curlで同じホストにGETリクエストを投げ続けてみると、

$ curl http://server3.xxxxxx.info
aiueo
$ curl http://server3.xxxxxx.info
aiueo
$ curl http://server3.xxxxxx.info
aiueo
$ curl http://server3.xxxxxx.info
kakikukeko
$ curl http://server3.xxxxxx.info
kakikukeko
$ curl http://server3.xxxxxx.info
kakikukeko
$ curl http://server3.xxxxxx.info
aiueo
$ curl http://server3.xxxxxx.info
aiueo

返ってくるコンテンツが異なるのがわかる。これは、バックエンドのサーバのindex.htmlが異なるコンテンツを持っているため。これでアクセス分散が正しくできていることが確認できた。

Route 53でアクセスを分散させてみる

Amazon Route 53でアクセスを分散させてみます。
通常のDNSサーバで出来るように、Route 53でもホスト名を使って、ラウンドロビンでアクセスを分散できます。

その方法は、AWS Management Consoleを使って、
f:id:kenjifunasaki:20130212162110p:plain

一つの名前に複数のIPアドレスを割り当ててみます。

該当するIPアドレスのサーバでは、Apacheが動いていて、異なるコンテンツを返すようにしてあります。
最初にserver3.xxxx.infoに対してcurlでHTTP GETリクエストを送ってみると、

$ curl http://server3.xxxxxxx.info
kakikukeko

kakikukekoと書かれただけのコンテンツが返ってきました。
再度同じコマンドを実行してみると、

$ curl http://server3.xxxxxxx.info
aiueo

今度はaiueoというコンテンツが返ってきました。

これで異なるWebサーバにちゃんとアクセスが分散されていることが分かりました。
簡単ですね!