2015年6月23日火曜日

ELB + nginxでアクセス元IPアドレスを取得できるようにする

followtheseinstructions balancing https://www.flickr.com/photos/followtheseinstructions/6871361948/in/photolist-btcwvJ-kLNmB-pEqkEV-9LdVCR-e6ptdo-4KHT6F-ipytp-qtnMTQ-7Jv54j-rDRPnV-aJrjqD-TpXTt-4YGqj2-8VqoLR-66jA7n-713w4e-9RnAYq-mBmNr-fXPtKt-9DTPjg-jAgTSf-5Z3R3b-4J6sJx-7HXvnz-9herYu-a1rJqP-MuHLf-9M2hY-kZWKN-dhk9hV-8ooruK-oBvk1y-8PTEaE-6kcWZN-9mBnuR-fpd7mC-5G9EW-9qK22M-a1vKe3-FAfU4-jCn6m5-dgCPD8-9sqRoJ-8VsFMt-nw2A7-78mWWw-8FGGDL-7J2sqS-6s863B-8Vtr59
Module ngx_http_realip_module
http://nginx.org/en/docs/http/ngx_http_realip_module.html

ELBを使ったときに、EC2ではアクセス元のIPアドレスがELBのIPアドレスとなります。
このとき、ELBはヘッダー情報 X-Forwarded-For にクライアントのIPアドレス格納して情報をEC2に渡すので、これをnginxモジュールを利用して、リアルIPとして扱うように設定をすることができます。

以下、設定方法です。

現在のアクセス元のIPアドレスを確認。
確認のために phpinfo() のファイルを開いてみます。
これは、ELBのIPアドレスになっています。
# curl -s http://test-247271050.ap-northeast-1.elb.amazonaws.com/ | grep REMOTE_ADDR
_SERVER["REMOTE_ADDR"] 172.31.6.30
nginx設定ファイルの http ディレクティブもしくは、server ディレクティブに追記します。 ser_real_ip_from にELBのIPアドレスを設定します。VPCのサブネット・ネットワークアドレスを指定します。
Availability Zone:ap-northeast-1a CIDR:172.31.16.0/20
Availability Zone:ap-northeast-1c CIDR:172.31.0.0/20
VPCで上記のように設定している場合は、172.31.0.0/16(172.31.0.1~172.31.255.254)とすればよいでしょう。
set_real_ip_from 172.31.0.0/16;
real_ip_header  X-Forwarded-For;
nginxをリスタート
# /etc/init.d/nginx restart
REMOTE_ADDRを確認。
# curl -s http://test-247271050.ap-northeast-1.elb.amazonaws.com/ | grep REMOTE_ADDR
_SERVER["REMOTE_ADDR"] 52.69.60.48
クライアントのIPアドレスになりました。

Passengerのインストール時にNginxのモジュールを追加する方法

Gilles Klein morback.jpg https://www.flickr.com/photos/gilles_itzkovitchklein/113465270/in/photolist-dEnXug-dvAaeK-bNaXdV-aBT9uo-aA8brF-94bhss-89ebqc-7HtXwj-tQGxu-67QN3h-67QMjo-67LwnX-66XpqH-5Wkyfs-52zqHk-52c9gv-4UtYhS-4UpJfZ-4UtSoh-4UpBGT-4rLhSg-4kVHg4-4kVHen-4kZKwh-4kZKvf-4kZKu5-4kZKtu-4kZKsL-4kVH8M-4kZKqY-4kVH78-4kVH5V-BpNi9-BpJfY-8Bfix3-fHvZzN-5wa6hd-jp97fU-7UFAt9-3ggX9r-dvA9Ga-8S42MH-8S76vj-dvAW7R-55XBWP-8S76tQ-jp7hvp-b2xgL-nBowA6-7SQswu
http://wiki.nginx.org/HttpHeadersMoreModule#more_set_headers
Nginxのモジュール more_set_headers を使いたかったのですが。Passenger を使っている場合にはどのようにモジュールを追加したら良いのか解らなかったので調べました。
more_set_headersが必要なシーンはどんなときでしょう?以下の記事を参照してみましょう。
nginxで任意のHTTPヘッダーを追加したい場合にはadd_headerディレクティブを用いますが、add_headerディレクティブは追加しようとしたフィールド名が重複するHTTPヘッダーが既に用意されていた場合には既にある物に「,」区切りで連結してしまいます。たとえば強制的に出力するContent-Typeを変更するためにadd_header Content-Type text/css;のようにしてもContent-Type: text/html, text/cssといった形の不正なHTTPヘッダーが出力されてしまいます。
解決方法は簡単でHTTP Headers More Moduleのmore_set_headersディレクティブをつかえばすぐです。使い方も簡単でadd_headerディレクティブをつかっている箇所をそのままmore_set_headers "Content-Type: text/css";と置きかえれば良いだけです。
http://memo.overknee.info/post/20308520977

このように、クロスドメインな環境を設定したい時に使ったりするNginxモジュールです。
more_set_headers 'Access-Control-Allow-Origin: *';
以下。セットアップ方法です。

passengerがインストールされているか確認します。
$ gem list | grep passenger 
もし、なかったらインストールします。
$ gem install passenger
作業ディレクトリに移動。
$ cd /usr/local/src
Nginxを用意。
$ wget http://nginx.org/download/nginx-1.8.0.tar.gz
$ tar -zxf nginx-1.8.0.tar.gz
Passengerをインストール。
$ wget https://github.com/openresty/headers-more-nginx-module/archive/v0.26.tar.gz
$ tar xvfz v0.26.tar.gz
$ passenger-install-nginx-module 

 2. No: I want to customize my Nginx installation. (for advanced users)
2 # 2を選択

Where is your Nginx source code located?
Please specify the directory: /usr/local/src/nginx-1.8.0 # Nginxのディレクトリを指定

Extra arguments to pass to configure script: --add-module=/usr/local/src/headers-more-nginx-module-0.26 # モジュールのディレクトリを指定
インストールされたNginxを確認します。
# /opt/nginx/sbin/nginx -V
nginx version: nginx/1.8.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx --with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module --with-cc-opt=-Wno-error --with-pcre=/tmp/passenger.l7zbkj/pcre-8.34 --add-module=/usr/lib/ruby/gems/2.0.0/gems/passenger-5.0.7/ext/nginx --add-module=/usr/local/src/headers-more-nginx-module-0.26
headers-more-nginx-module-0.26 の文字が見えます。
あとは、このバイナリをいつも使っているNginxと置き換えればOKです。

2015年6月22日月曜日

Amazon Redshiftのバキュームに必要な時間


縦軸が分(minutes)、横軸がテーブルのレコード数です。

Table count minutes
25000 1
130000 1
41000000 7
400000000 65
670000000 210
2600000000 730
3000000000 1200
4800000000 4680

Amazon Redshiftのインスタンスタイプはds1.xlargeです。
数億分のデータをためた場合、どのくらいの時間でバキュームできるかを測ってみました。
バキューム実行コマンドは VACUUM FULL table_name; です。
(実際に使っているテーブルにバキュームをかけようとしているので、継続的にデータのインサートを行いながらの計測になります。そのためどんな環境で行っても同じ結果になるわけではないとおもいます。その点注意をお願いします。)
結果、1億程度ならば数分でバキューム完了しますが、10億を超えたあたりから実行時間が伸び、30億を超えるとほぼ1日がかりという時間が必要になりました。

まとめ
レコード数が大量になるにつれてバキューム実行時間が増えることがわかりました。
今回のバキューム中にはAmazon Redshiftのレスポンスが悪くなる現象は、とくにみられませんでした(すごい)、ですが、更に大量のデータを扱うときにはどうなるかわかりません。あらかじめテストしておくと良いでしょう。
すぐに数億のデータが溜まるようなテーブルを扱うときには。月ごと、日ごとのテーブルを用意して一つ一つのテーブルのサイズを小さく保つという運用をしたほうが、より少ない時間でバキュームができるので、パフォーマンスを維持できるとおもいます。

参考文献
テーブルのバキューム処理 - Amazon Redshift
http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/t_Reclaiming_storage_space202.html
VACUUM - Amazon Redshift
http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_VACUUM_command.html
Analyzeの必要性とvacuumの落とし穴
http://www.slideshare.net/motonobufukao/analyzevacuum
Amazon Redshift Useful SQL: VACUUM処理が必要なテーブルを洗い出す | Developers.IO
http://dev.classmethod.jp/cloud/aws/amazon-redshift-useful-sql-require-tables-to-vacuum/

2015年6月10日水曜日

Amazon DynamoDBに関する資料まとめ

"Dynamo Electric Machine" (end view, partly section, U.S. Patent 284,110) http://en.wikipedia.org/wiki/Dynamo#/media/File:DynamoElectricMachinesEndViewPartlySection_USP284110.png
Real-Time Ad Impression Bids Using DynamoDB
http://aws.amazon.com/jp/blogs/aws/real-time-ad-impression-bids-using-dynamodb/

以前から、RTBでAmazon DynamoDBを使っている漢構成なところがあって気になっていたのですが。
「AWS Summit Tokyo 2015」でSmartNewsが発表していたように、Amazon DynamoDBの採用事例がどんどん増えているように感じます。
最近は、AWSでKVSを使うとしたらどれを使うか?といった時に無視できないくらい盛り上がっているみたいです。

Amazon DynamoDBを試験するにあたって以下の資料を参考にしました。
参考資料としてリンクをまとめておきます。


* AWS製品ページ

Amazon DynamoDB
http://aws.amazon.com/jp/dynamodb/


* 「AWS Summit Tokyo 2015」

アンサーにおけるDynamoDBの運用
http://www.slideshare.net/akiyan/amazon-dynamodb-48929424
=>Amazon DynamoDBの基本的な概要とハマリどころを解説している。


* 「AWS Summit Tokyo 2014」

Amazon DynamoDB テーブル設計と実践 Tips
http://media.amazonwebservices.com/jp/summit2014/TA-10.pdf
=> あわせて読みたい。
AWS Summit 2014 Tokyo「Amazon DynamoDB テーブル設計と実践 Tips」レポート
http://dev.classmethod.jp/cloud/aws/aws-summit2014tokyo-dynamo/

ビッグデータだけじゃないAmazon DynamoDBの活用事例 ~CassandraからAmazon DynamoDBへの移行で見えたその特徴~
http://media.amazonwebservices.com/jp/summit2014/TC-01.pdf
=>PHPでのベンチマークが参考になる。
”速度追求部分には非公式PHPライブラリで対応”
”アクセスされるキーに偏りが発生すると思うように性能がでないという自体を招くため、Hash keyの設計には注意が必要”


* その他

ddbcli - 対話型のDynamoDBクライアント - lambda {|diary| lambda { diary.succ! } }.call(hatena)
http://d.hatena.ne.jp/winebarrel/20130506/p1
https://github.com/winebarrel/ddbcli
=>DynamoDBのMySQLコマンドライクなCLIクライアントです。

Amazon DynamoDB(初心者向け 超速マスター編)JAWSUG大阪
http://www.slideshare.net/shimy_net/amazon-dynamodb-23315068
=>Key, Indexに関しても基本的な解説が参考になる。

DynamoDB 入門編
http://blog.serverworks.co.jp/tech/2013/09/25/dynamodb-01/
=>PHPで接続するサンプルコードあり。

DynamoDBによるソーシャルゲーム実装
http://www.slideshare.net/itoyusaku/jawsug-201303
=>実装方法について参考になる

AWS Summit 2014 Tokyo ユーザーの趣味趣向に適した広告配信システムDynalystが出来るまで
http://niwatako.tips/20140717/article71.html
”DynamoDBのユースケースとしては典型的になっている。ハッシュキーでユーザーが居て、RangeKeyでいつ、そのあと、どの広告主の何をどうしたという情報を入れていく形になっている。”

【AWS発表】 Amazon DynamoDB でローカルセカンダリインデックスを作成可能に
http://aws.typepad.com/aws_japan/2013/04/local-secondary-indexes-for-amazon-dynamodb.html

slideshare (search DynamoDB)
http://www.slideshare.net/search/slideshow?searchfrom=header&q=DynamoDB

speakerdeck (search DynamoDB)
https://speakerdeck.com/search?utf8=%E2%9C%93&q=DynamoDB


* Dynamic DynamoDB

Dynamic DynamoDBは、DynamoDBをオートスケーリングするためのツールです。

sebdah_dynamic-dynamodb
https://github.com/sebdah/dynamic-dynamodb

Dynamic DynamoDB — Dynamic DynamoDB 1.20.5 documentation
https://dynamic-dynamodb.readthedocs.org/en/latest/

DynamoDBをオートスケールできるDynamic DynamoDBのご紹介
http://aws.typepad.com/aws_japan/2014/03/auto-scale-dynamodb-with-dynamic-dynamodb.html

Dynamic DynamoDB を使ってみた
http://dev.classmethod.jp/cloud/aws/try-dynamic-dynamodb/

EC2にDynamic-DynamoDBをインストールする
http://qiita.com/hawaku/items/138da162cf8bb9fecf08

2015年6月2日火曜日

CentOSでyumが壊れたときの対処方法

Yum - Jelly by Oh-mai-gawd http://oh-mai-gawd.deviantart.com/art/Yum-Jelly-114439461
新しくPythonをインストールした時などに、yumが壊れることがあります。
(しっかり、configureを設定しろ。という話ではありますが。ついうっかり。ということはあるでしょう・・・。)
以下は、そんなときの対処方法です。

yumが壊れたときのメッセージです。
"No module named yum" と怒られています。
# yum
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

   No module named yum

Please install a package which provides this module, or
verify that the module is installed correctly.

It's possible that the above module doesn't match the
current version of Python, which is:
2.7.9 (default, Mar  6 2015, 15:07:57)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)]

If you cannot solve this problem yourself, please go to
the yum faq at:
  http://yum.baseurl.org/wiki/Faq
Python2.6とyumをrpmから強制再インストール。
# rpm -Uhv --force http://mirror.centos.org/centos/6.6/os/x86_64/Packages/python-2.6.6-52.el6.x86_64.rpm
# rpm -Uhv --force http://mirror.centos.org/centos/6.6/os/x86_64/Packages/yum-3.2.29-60.el6.centos.noarch.rpm
yumの動作確認。
# yum --help
別バージョンのPythonとyumを共存させたい場合は、 /usr/bin/yum ファイルの1行目のシェバンを調整すると良いでしょう。
# emacs /usr/bin/yum

#!/usr/bin/python
->
#!/usr/bin/python2.6