0

EC2のReserved Instances

EC2では通常の従量課金制(On-Demand Instances)の他にイニシャル+従量課金制(Reserved Instances)が用意されています。
長期契約で先に多めに払ってくれたらランニング費用を安くしますよー的なもので、一般的な専用サーバーの初期費用+月額に近い。金額はEC2の方が安いと思う。

契約期間は1年と3年があるけど、3年だとアジアにデータセンターができた時に残念な思いをしそうなのでとりあえず現状の東海岸で申込んでみた。
たぶんこの認識であってると思うけど、Reserved Instancesといってもそれ専用のインスタンスが用意されているわけでもなく、ゾーンとインスタンスタイプのセットの枠買いのようなものです。
us-east-1aのm1.large枠を購入。そこに好きなAMIを突っ込むといった形。途中でAMIを変えてもOKだし使わなければその期間の費用はかかりません。

現在運用中のOn-Demand Instancesにも適用できるので、サービスを止めることなくReserved Instancesの料金を適用させることができます。

実際の例をだすとOn-Demand Instances(us-east-1aのm1.large)の場合
$0.34 * 24時間 * 365日 = $2,978.4
これをReserved Instancesに切り替えると
$910 + ($0.12 * 24時間 * 365日) = $1,961.2
となり年間$1,017.2のコスト削減となります。
おお、素晴らしい!

これだけ差がでると予定してる利用期間が11ヶ月とかでもReserved Instancesの方が得じゃないのかと思い計算したところ、
利用日数240日(約8ヶ月)を超えて使う予定があるのならReserved Instancesの方が安い。
そうでなければOn-Demand Instancesで払ってる方が安いといった結果でした。

上記の金額に転送量に応じての費用も多少かかります。

0

戦う自分をつくる13の成功戦略

戦う自分をつくる13の成功戦略
ジョン・C. マクスウェル
三笠書房 ( 2009-10 )
ISBN: 9784837957065
おすすめ度:アマゾンおすすめ度

なんだかちょっと恥ずかしいタイトルの本。
最近の俺を見て何か思うところでもあったのか、誕生日に父親から貰いました。渡すのが恥ずかしかったのかなぜか嫁経由で。
あんまりこの手の自己啓発本は説教がましくて好きではなかったけど、これは素晴らしい名著だった。
書いている内容はベタベタの努力をしろとか目標を持てとかそういう内容だけど、なぜか素直に吸収できた。実行まで移せるかはわからんが。
その後2冊同系の本を購入したけどやはりこの本が一番良かった。
たぶん、これは著者の言葉が全部父親フィルターを通したからだと思う。父親に言われてるような感覚に陥る。
しかもこの本の監修者は「和民」の渡邉 美樹。あんまり好きな人ではないけど、それでもこの本は良かったと思える。

本というのは色んなバックグラウンドや読むタイミングによって全然印象が変わるもんだな〜。とふと思ったので書いてみた。

0

関西アンカンファレンス

kansaiun
関西アンカンファレンス出席してきました。
ほんとうにおもしろかった。
スタッフのみなさん、参加者のみなさんありがとうございました。

組み込みからデザインまで幅広いセッションがあってまったく飽きがくることがありませんでした。
全セッション後に交流会(アルコールがない懇親会)があったのも良かった。
席もコロコロ変えれるし、酒の飲めない自分としてはあれが20時くらいまであってもいいくらい。

僕はトップバッターでmixiアプリモバイルについての話をさせて頂きました。
想像以上に堅苦しいものになってしまったというところで後悔してなくもないけど、来年の原動力として前向きに捉えときます。
時間があればEC2ネタももっと絡めていきたかったけど15分ではちょっと厳しかった。
資料はまたアップします。
アップしました。
フォントや改行がおかしくなってるけど参考までに。
相当でっかくまとめると

  • mixiアプリPCよりmixiアプリモバイルの方が作るの簡単だよ。
  • トラフィックが読めないのでサーバーの増減が簡単なEC2がいいよ。

って話でした。

色んな方と名刺交換させてもらいましたが、ほとんどの方がブログURLとtwitter名が入った個人名刺を持ってることに驚かされました。しかもみんな個性的でかっこいい。
次のこういう機会では自分も個人名刺を用意しとこう。

0

mixiアプリモバイルのOAuth

mixiアプリモバイルのAPIへのアクセスはOAuth認証が必要です。
twitterやlastFM等が採用してるOAuthと少し違う2-legged OAuthというやつです。
簡単にいうとエンドユーザーによる承認のプロセスが省略されたバージョン。(たぶん)

ユーザー情報やマイミクの情報を取得したい場合はこの認証を突破して取得する必要があります。
以下phpのサンプルです。
require_once 'OAuth.php';
 
/**
* oAuthで認証後mixiAPIをたたく
*
* @param string $user ユーザー
* @param string $feed エンドポイント以降のURL
* @return object APIで取得したデータ 失敗時:false;
*/
function getMixiAPI($user, $option_feed)
{
define('CONFIG_API_ENDPOINT', 'http://api.mixi-platform.com/os/0.8');
 
$CONSUMER_KEY = 'xxxxxxxxxxxxxx';
$CONSUMER_SECRET = 'xxxxxxxxxxxxxxx';
$consumer = new OAuthConsumer($CONSUMER_KEY, $CONSUMER_SECRET, NULL);
 
$feed = CONFIG_API_ENDPOINT . $option_feed;
  // マイミク一覧取得の場合はここを変える
$params = array('xoauth_requestor_id' => $user, 'fields' => 'addresses,birthday,gender');
$request = OAuthRequest::from_consumer_and_token($consumer, NULL, 'GET', $feed, $params);
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
$url = $feed . '?' . implode_assoc('=', '&', $params);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_ENCODING , "gzip");
 
$auth_header = $request->to_header();
if ($auth_header) {
curl_setopt($curl, CURLOPT_HTTPHEADER, array($auth_header));
}
 
$response = curl_exec($curl);
if (!$response) {
$response = curl_error($curl);
}
curl_close($curl);
 
$response = json_decode($response);
 
if (is_object($response)) {
return $response;
}
else {
return false;
}
}
 
function implode_assoc($inner_glue, $outer_glue, $array)
{
$output = array();
foreach($array as $key => $item) {
$output[] = $key . $inner_glue . urlencode($item);
}
return implode($outer_glue, $output);
}

$response = getMixiAPI($_REQUEST['opensocial_owner_id'], '/people/@me/@self');
利用には、OAuth.phpが必要です。
上記の例は単純にアクセスしたユーザーの情報を取得します。

mixiアプリは過度にAPIへのアクセスがあったり5秒以内にレスポンスを返せないことが多々あると
アプリ一覧から消されて新規ユーザーが取り込めない状態になります。
色々対策をとって負荷を軽減しレスポンスを速くすることに努めなければなりません。
APIのアクセスももちろんその対象です。
対策というほどでもないけど下記の3点くらいは守るべき。

1、必要な情報だけとる。
addresses,birthday,gender等は必要があれば取得する
$params = array('xoauth_requestor_id' => $user, 'fields' => 'addresses,birthday,gender');

2、圧縮して通信する。
curl_setopt($curl, CURLOPT_ENCODING , "gzip");

3、一度取得したら数時間はSAP側でキャッシュしておく。

0

ソーシャルアプリ

ソーシャルアプリという言葉が出てきて久しいけど、opensocialの提唱からたった数年でここまでくるとは思いもよらなかった。
ドリコムがブログを捨ててソーシャルアプリの市場に参入したりサイバーエージェントが参入したりと日本でも大人気。
来年1月にはmixiに続いてモバゲーもソーシャルアプリを開始するとのことで、2010年は本格的にソーシャルアプリが流行しそうです。
webに積極的な企業の要望も「twitterと連携して〜」から「mixiアプリも作りたい!」へ変わるのかな。
それにしても「ソーシャルアプリ」という名前は堅苦しい。
「mixiアプリ」「モバゲーアプリ」として浸透させないと、一昔前もフィード(RSS)と同じ道を歩みそう。
フィードが人気があるのかと聞かれると否だけど、人気のあるサイトでフィードを活用してないところはない。
フィードという名前が流行らなかっただけ。

ただ日本のソーシャルアプリはモバイルが切っても切れないものとなっているので、欧米のPC中心のソーシャルアプリブームとは少し違う。
(ここでも日本の携帯はガラパゴス状態。それが悪いとは思わないけど市場が小さくなるのはもったいない。)
モバイルのソーシャルアプリに関してはopensocialの仕様とはかけ離れたものとなっており、ベンダーの独自路線のようなものが多い。
人気があるアプリもfacebookやhi5とは違って、農園アプリや占いアプリや育てゲー等の若者向けのがほとんど。
結局はそこ。
エンジニアの端くれとしてはopensocialに準拠したPCよりモバイルの方が人気があるのは複雑な気もするけど、それが現実。
webが動くのは若者に爆発的な人気が出たときであって新しい技術が出たときでない。
現実に目を向ければ、iPhoneのシェアなんて2%程だしtwitterとかtumblr使って喜んでるのはこの業界の人間ばかり。
ソーシャルアプリを実際動かしてるのは若年齢層。
好き嫌い作る作らないは別として、求められてるのはそのあたりと言う事は常に意識しとかなければと思いました。

よくわからんけど明日もがんばろう。

0

mixiアプリのライフサイクルイベント

ライフサイクルイベント
ライフサイクルイベントは、OpenSocial 0.8.1 にて規定されている「コンテナ上で起こったアプリケーションに関する事象を、アプリケーションプロバイダに送信するための仕様」です。

mixiアプリでライフサイクルイベントが扱えるようになりました。
なんだか分かりにくい名前だけど、アプリのインストール、アンインストールがSAP(アプリ)側に通知されるようになりました。
今まではmixiアプリをインストール&アプリを使い出した時点で初めてSAP側はアプリユーザーとして認識してたのが、インストールした時点でアプリユーザーとして認識できるようになりました。
以前は、インストールしたものの一度もアプリを使ってないユーザーをmixi側ではアプリユーザーと認識してたけど、SAP側では認識してませんでした。
この差異がなくなることによってより正確なユーザー数を把握できます。

またアンインストール情報も通知されるのでSAP側で「退会」処理ができます。
今まで、アンインストールしてもSAP側に通知されなかったので一度インストールして使いだすと永遠にそのアプリのユーザーとしてSAP側は認識してました。アンインストールしたユーザーのデータもずっと持ち続ける状態。

一旦アンインストールして再度インストールしても以前のデータが残ってるという状況だったのもアンインストール情報の通知が開始されたことによって回避できるようになります。

mixiアプリネタがしばらく続きます。

0

google public DNSの速度テスト

google public DNSがリリースされました。
DNSは海外にあって、結局海を渡るためレイテンシーは発生する。
とか
国内(アジア)にキャッシュサーバーがあるから速くなる。
とかいわれたりするので試してみた。

まずは海外にあるサーバー。
google public DNS導入前
ping yahoo.com
PING yahoo.com (209.191.93.53): 56 data bytes
64 bytes from 209.191.93.53: icmp_seq=0 ttl=49 time=159.474 ms
64 bytes from 209.191.93.53: icmp_seq=1 ttl=49 time=157.518 ms
64 bytes from 209.191.93.53: icmp_seq=2 ttl=49 time=156.937 ms
64 bytes from 209.191.93.53: icmp_seq=3 ttl=49 time=158.342 ms
64 bytes from 209.191.93.53: icmp_seq=4 ttl=49 time=156.778 ms

google public DNS導入後
ping yahoo.com
PING yahoo.com (209.131.36.159): 56 data bytes
64 bytes from 209.131.36.159: icmp_seq=0 ttl=52 time=111.162 ms
64 bytes from 209.131.36.159: icmp_seq=1 ttl=52 time=110.919 ms
64 bytes from 209.131.36.159: icmp_seq=2 ttl=52 time=110.410 ms
64 bytes from 209.131.36.159: icmp_seq=3 ttl=52 time=110.704 ms
64 bytes from 209.131.36.159: icmp_seq=4 ttl=52 time=111.652 ms

確かに速くなってる。
通常のブラウジングでは体感速度は変わらないけどサーバーサイドでクローラー作ったりするときは効果的かもしれない。

次に国内サーバー
google public DNS導入前
ping yahoo.co.jp
PING yahoo.co.jp (203.216.227.176): 56 data bytes
64 bytes from 203.216.227.176: icmp_seq=0 ttl=55 time=25.431 ms
64 bytes from 203.216.227.176: icmp_seq=1 ttl=55 time=25.047 ms
64 bytes from 203.216.227.176: icmp_seq=2 ttl=55 time=24.925 ms
64 bytes from 203.216.227.176: icmp_seq=3 ttl=55 time=24.681 ms
64 bytes from 203.216.227.176: icmp_seq=4 ttl=55 time=24.697 ms

google public DNS導入後
ping yahoo.co.jp
PING yahoo.co.jp (124.83.139.192): 56 data bytes
64 bytes from 124.83.139.192: icmp_seq=0 ttl=50 time=27.587 ms
64 bytes from 124.83.139.192: icmp_seq=1 ttl=50 time=25.896 ms
64 bytes from 124.83.139.192: icmp_seq=2 ttl=50 time=30.405 ms
64 bytes from 124.83.139.192: icmp_seq=3 ttl=50 time=26.908 ms
64 bytes from 124.83.139.192: icmp_seq=4 ttl=50 time=26.220 ms

若干だけど遅くなってる。
他にも2つほど試したけど同様の結果。
海外は高速になり、国内は微遅。

こんなテストで結論はだせんけど、
DNSは海外にあって、結局海を渡るためレイテンシーは発生する。
ってのが正解か?

0

rsyncのincludeが面倒臭い

下階層のファイル数点だけrsyncさせたいときincludeオプションを使います。
/vol/html/webapp/modules/ktai/page/change.phpだけをrsyncだと下記のようにやってしまいそうになる。
rsync -avz -e ssh --include=*change.php /vol/html root@hogehoge.com:/vol
これだと全部同期される。

じゃあこれ。
一旦全ファイルを除外した上でrsync。
rsync -avz -e ssh --include=*change.php --exclude=* /vol/html root@hogehoge.com:/vol
これだと何も同期されない。

じゃあこれ。
change.phpに辿るディレクトリを一つ一つincludeした上でrsync。
rsync -avzn -e "ssh -i /vol/mnt/hoge.pem" --include=html --include=webapp --include=modules --include=ktai --include=page --include=change.php --exclude=* /vol/html root@hogehoge.com:/vol
これで上手くいく。

これは極端な例だけどよく忘れて焦る。

0

mySQLでレプリケーション

レプリケーションの設定のメモ。
まずマスターとなるサーバーで設定。
/etc/my.confを編集

[mysqld]
datadir=/mnt/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
log-bin
server-id=10
log-bin=mysql-bin
log-bin-index=mybin.index
expire_logs_days=14

log-binでバイナリログを保存しますよの宣言
server-idはスレーブと重複しないサーバーIDのようなもの。
log-bin=mysql-binとlog-bin-index=mybin.indexはバイナリログのファイル名。
mysql-bin.000001のようになります。
ここで指定したら/mnt/mysqlにバイナリログは蓄積されていきます。
指定しなかった場合、俺の環境では/var/run/mysqlに溜まりEC2のHDを圧迫してたので必須でした。
expire_logs_daysはログのローテーションの期間です。2週間サイクルにしています。

mySQLを再起動したらSQLを発行する度にバイナリログに書き込まれていきます。

スレーブの設定で使う読み取りバイナリログの読み取り開始位置を確認しておく。
mySQLにログイン

> SHOW MASTER STATUS;

Fileがlog-bin.000001
Positionが128
となってたのでそれをメモる。

ログインついでにスレーブからの接続専用のユーザーを作成する

> GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY 'replrepl';

スレーブと同期を取るために一旦mySQLを止める。
下記のようにしてスレーブにデータディレクトリをごっそり持っていきます。

rsync -avz -e ssh /mnt/mysql root@ec2-174-129-***-**.compute-1.amazonaws.com:/mnt

続けてスレーブのmy.confを設定
[mysqld]

datadir=/mnt/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
relay-log=relay-bin
server-id=14
master-host=ec2-174-129-**-**.compute-1.amazonaws.com
master-user=repl
master-password=replrepl
replicate-do-db=access
expire_logs_days=14

relay-log=relay-binでリレーされたらログがrelay-bin.000001という形で蓄積されていきます。
master-hostでマスターのサーバーのホスト名を
master-userとmaster-passwordで接続情報を登録しておきます。
replicate-do-dbで指定したDBだけリレーションするようにします。この場合accessのいうデータベースだけリレーションします。

次にmySQLにログイン。
バイナリログがまったくなければ

> start slave;

だけでもいけるかも。

>change master to master_host = 'ec2-174-129-**-**.compute-1.amazonaws.com', master_port = 3306, master_user = 'repl', master_password = 'replrepl', master_log_file = 'mysql-bin.00001', master_log_pos = 128;
start slave;

ここで先ほどメモった読み取り開始位置を入力する。

これでレプリケーションが始まる。
マスターで何かinsertしてスレーブに反映されていればOK。
レプリケーションされてなければmysqld.logを確認する。

0

/mntを有効活用しよう

今回もしつこくEC2ネタ。

Filesystem サイズ 使用 残り 使用% マウント位置
/dev/sda1 9.9G 8.9G 467M 96% /
/dev/sda2 147G 34G 107G 24% /mnt
none 854M 0 854M 0% /dev/shm

上記はスモールインスタンスのサーバーの状況です。
EC2はインスタンスを立ち上げたらすぐでも使えるけれども、実際は設定をちょこちょこ変えないと本番環境としては使えません。
その代表たるものが/dev/sda1の容量。
/dev/sda1にOSが入っていてwindowsでいうところのCドライブで、/dev/sda1がDドライブになります。
この/dev/sda1というのが最大10Gとなっており、OSをインストール後は実際使えるのは5〜6Gくらいしかない状態になります。
バックアップデータ等人為的に作成するデータはもちろん/mnt(/dev/sda1)以下におけばいいのだけど、システム的に肥大化していくファイルたちも/mntで展開するようにしないといけません。
これを忘れるとあっという間にHDがいっぱいになってしまいます。

/mntに移すファイルとしては下記のようなものがあります。
1、/var/log/httpd→/mnt/log/httpd
アクセスログやエラーログの保存場所を変更ローテーションしていても少し大きなサイトなら5Gくらいのログはあっという間です。
httpd.confで設定変更

2、/var/lib/mysql/→/mnt/mysql
mySQLのデータが肥大化していくので保存先を変更。
バイナリログを吐き出す設定にしている場合はなおさら。
my.confで設定変更

3、/var/www/→/mnt/www
apacheの公開ディレクトリもサービスによってはユーザーのデータが増えたりログが増えたりするので変更。
httpd.confで設定変更

4、/home/(ユーザーディレクトリ)/→/mnt/home/(ユーザーディレクトリ)
ユーザーによってどんなファイルをおくかわかないのでユーザー作成時に/mnt以下にホームディレクトリを作るように癖付けとく。
useradd -d /mnt/home hogeで明示

もちろんシンボリックでもOK。

但しこの/mnt以下はイメージを作成しようとしても対象外となる。
イメージ化できるのは/dev/sda1のみです。
またこうしてできたAMIで新たにインスタンスを立ち上げても/mnt以下に適切なディレクトリができてないためapacheやmySQLの起動にこけるので注意。
ここは起動スクリプトでも書いとけばok。