[AWS] EC2マイクロインスタンスのベンチマークしてみた

いつの間にやらEC2にsmallインスタンスの更に下のmicroインスタンスってのが使えるようになったらしいので、ちょっとやってみた。

他のサービスと比較

まずは似たようなサービスと比較してみます。
AWSの東京リージョンも最近できましたが、前からシンガポール使ってたので、それ基準で。
VPSとEC2は違うものですが、値段的に同じくらいのさくらVPSとServersMan@VPSも表に入れてみた。

  スペック 初期費用(年) 料金/時間 料金/月間
EC2 スモール
(オンデマンド)
CPU:仮想1コア
メモリ:1.7GB
ストレージ:160GB*
0 $0.095 $68.4 (約5,700円)
EC2 マイクロ
(オンデマンド)
CPU:仮想1コア
メモリ:613MB
ストレージ:従量(EBS)
0 $0.025 $18 (約1,500円)
EC2 マイクロ
(リザーブ)
CPU:仮想1コア
メモリ:613MB
ストレージ:従量(EBS)
$54 $0.01 $7.2 (約600円)
さくらのVPS
512
CPU:仮想2コア
メモリ:512MB
ストレージ:20GB
0 980円
ServersMan@VPS
Standard
CPU:仮想2コア
メモリ:512MB
ストレージ:30GB
0 980円

*ただしシャットダウンすると跡形も無く消え去ります><

スモールはちょっと頭抜けてますが、マイクロのリザーブは初期費用入れるとだいたい980円くらいなのでさくらVPS 512やServersMan@VPS Standardとほぼぴったりな感じです。
ただ、EC2はデータの転送量に応じた料金がかかりますし、EC2のマイクロインスタンスはEBSブートのみなのでストレージ費用も別途かかります(月$0.1/GB+I/0に応じて)
そのためやっぱちょっと金額は他と比べるとかかっちゃいます。ただ、普通のVPSと違ってアクセスが集中した時でもある程度ブーストしてくれるのでその辺はクラウドの強みかなと思います。

ベンチマーク!

では皆さんも大好きなベンチマーク結果をw
ベンチマークはAWS, さくらVPS, hetemlでベンチマークしてみたと同じくPHPspeedでやってみました。
アレから時間も経ってるので、スモールとさくらVPSも再計測してみました+ServersMan@VPSも最近使い始めたのでそれもまとめてみました。

  EC2 micro
EBS
EC2 small
instance-store
さくらVPS
512
ServersMan@VPS
Standard
Synthetic PHP BenchMark 3,267 1,262 2,507 1,693
Synthetic MySQL BenchMark 13,748 5,234 11,072 5,168
Synthetic Read/Write BenchMark 865 792 1,406 901
Real World PHP BenchMark 2,639 1,320 4,659 3,090
Real World PHP & MySQL BenchMark 838 994 2,179 1,287
Server BenchMark 1,415 969 2,548 1,300

まとめ

いや、何かの間違いと思いたいのですが、EC2のsmallが一番しょぼいってどうよ?w
何かもう全部マイクロインスタンスに変えてやろうかと思ってしまったわ><
ちなみにsmallとmicroは同じAMIで、instance-storeで使ってたAMIをEBSに変換してmicroで使ってみました。
(この辺はまた別エントリーで書いてみます)
EBSブートの方がinstance-storeよりもIO性能が低いってAWSのページには書いてあったのですが、全然変わらないというかむしろ逆転している感が漂っています。。。

相変わらずさくらVPSがスゴすぎるのはいうまでもない感じですが、ServersMan@VPSが意外と健闘している感じがします。実際使ってみるとServersMan@VPSはたまに引っかかる感じというか、遅いと感じる時があるのですが、ベンチマークとってみるとあまり目立ってばらついては無かったです。

一番ばらつきが大きかったのがEC2のmicroでした。短期ブーストってAWSの説明に書いてあったけど、いざという時は瞬発力を発揮してくれるのかもしれないですね。

まぁ取りあえずさくらのVPS
使っとけば間違いは無いってことですかね?W



Filed under: AWS,Internet,MySQL,PHP — maesan 12:36 AM

[cakePHP] floatのフィールドが指数表記になっちゃう

cakePHPでfloatのフィールドを使った場合、7桁を超える数値を入れたらフォームで指数表記されちゃうのが困る。

これが

こうなる

仕方ないのでviewで

$this->data["Article"]["point"] = sprintf('%.2f', $this->data["Article"]["point"]);

って書いたらいけるかと思ったらいけなかった。
よくよく考えたらviewをレンダリングする前にformが出来上がってんじゃなかったっけ?w
ってことに気付いて素直にcontrollerに書いたら期待通りに動いた。

function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid article', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
if ($this->Article->save($this->data)) {
$this->Session->setFlash(__('The article has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The article could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->Article->read(null, $id);
$this->data["Article"]["point"] = sprintf('%.2f', $this->data["Article"]["point"]);
}
}


何かイマイチすっきりしないのですが、他の解決策ないのかねぇ?

Filed under: cakePHP,PHP,Programming — maesan 5:17 PM

[cakePHP] 1.3でForm->selectのパラメータ変わったのか

今までだと、formヘルパーを使って空白を出さないselectは以下の様に書いてました

echo $this->Form->select('hoge_id', $hoges, null, null, false);

で1.3でこれやるとダメで、ソース見たらこうやるのが正しいっぽい

echo $this->Form->select('hoge_id', $hoges, null, array('empty' => false));

だれかCookbookのフォームヘルパーのselectのページを修正してください><
http://book.cakephp.org/ja#!/ja/view/1430/select
↑英語版を見るとそっちは正しいみたいだった!

Filed under: cakePHP,PHP,Programming — maesan 11:31 PM

jQueryで.postしようと思ったらfileはpostできない件

今更ながらjQueryにハマってまして、今日も画面遷移なしで画像がアップロードできるスクリプトを書こうとしたのですが、Javascriptではfileをpostできないことに気付いた><

で、画面遷移なしでファイルをアップロードしようと思ったらiframeを使ったりするらしい。Ajaxではないけど、Ajaxっぽい動きですな。

ということでサクっと書いてみた

アップロード用ページ upload.html

<html>
<head>
<style>
#dummy{
/* display:none; するとSafariだとおかしくなるらしい? */
border:0px;
width:0px;
height:0px;
}
#image{
display:none;
max-width:480px;
}
</style>
</head>
<body>
<iframe name="dummy" id="dummy"></iframe>
<div id="message"></div>
<img id="image"></div>
<form action="upload.php" method="post" target="dummy" enctype="multipart/form-data">
<input type="file" name="img" />
<input type="submit" value="Upload">
</form>
</body>
</html>

注意点はiframeにdisplay:none;するとSafariだとおかしくなるらしいんだけど、ウチの環境では別にどっちでも行けた(Mac OSX 10.6.6, Safari 5.0.3)
http://groundwalker.com/blog/2007/02/file_uploader_and_safari.html

ファイルアップロード処理とか upload.php

<?php
$error = 0;
$msg = "";
$filename = "";
if ($_FILES["img"]["error"] == 0) {
$info = getimagesize($_FILES['img']['tmp_name']);
if ($info[2] != 2 && $info[2] != 3 && $info[2] != 6) {
$msg = "画像ファイルでお願いします。";
$error++;
} else {
$exts = array(2 => '.jpg', 3 => '.png', 6 => '.bmp');
$ext = $exts[$info[2]];
$filename = "tmp/hoge".$ext;
move_uploaded_file($_FILES["img"]["tmp_name"], $filename);
chmod($filename, 0666);
$msg = "ファイルをアップロードしました。";
}
} else {
$msg = "ファイルのアップロードに失敗しました。";
$error++;
}
// jsonで出してeval
$results = sprintf('{"error":"%s","msg":"%s","filename":"%s"}', $error, $msg, $filename);
?>
<html>
<head>
<script src="jquery.js"></script>
<script type="text/javascript">
//<![CDATA[
$('document').ready(function(){
var results = eval('(<?php echo $results;?>)');
// 親ウィンドウのオブジェクトはwindow.parent.documentってやったらとれる
$('#message', window.parent.document).html(results["msg"]);
if (results["error"] == 0) {
$('#image', window.parent.document).css('display', 'block').attr('src', results["filename"]);
}
});
//]]>
</script>
</head>
<body>
</body>
</html>

別にこの程度ならjQuery使う必要は全然ないんですけどねw
フツウに書いてもコード量は変わらんですw

ポイントはjQueryでiframeから親windowのDOM要素を操作する場合は
$(‘対象のidとか’, window.parent.document)
ってやるとできる。

素のjavascriptで書いた
parent.document.getElementById(“対象のid”)
とほぼ一緒かな。

Filed under: Javascript,PHP,Programming — maesan 9:15 PM

[PHP] move_uploaded_file→ご一緒にchmodはいかがっすか?

いや、たまにやるんだけど自分メモ

PHPでファイルアップロードする場合に

$filename = "hoge.jpg";
move_uploaded_file($_FILES["hoge"]["tmp_name"], $filename);

とかするっしょ?
んで普通に使う分には問題ないんだけど、デフォルトのパーミッションが600で保存されちゃうので、ちょっとftpとかSCPでアクセスした時に何にもできないってなるんだよね><
root権限とかあったらイイけど、フツウにレンタルサーバーとかでやっちゃったらもう大変w
わざわざファイルの削除するスクリプト書いてapacheに実行してもらわないといけないw
なので、move_uploaded_fileしたあとはchmodで666とかにしといたほうがよいです。

$filename = "hoge.jpg";
move_uploaded_file($_FILES["hoge"]["tmp_name"], $filename);
chmod($filename, 0666);

※ 666じゃなくて0666って書かないとダメかもよ

Filed under: PHP,Programming — maesan 5:03 PM

[Mac] phpでcurlが入って無かった

ちょっとお遊びでtwitter botでも作ろうかと思ってphpのOAuthライブラリのtwitteroauthを使おうと思ったら

PHP Fatal error: Call to undefined function curl_init() in /hogehogehogehoge/twitteroauth.php on line 199

って怒られた。

curlってwgetみたいなやつだっけ?
phpでそれ関係使ったこと無いので気付かなかったんだけど、phpでcurlを使えるようにしないとダメっぽい。
portでphp入れてたので以下でおkだった

$sudo port install php5-curl

Filed under: Internet,PHP,Programming — maesan 10:59 PM

[cakePHP] PHP5.3にしたらDeprecatedが表示されまくったでござる

ちょっとMacBookのHDDの調子が悪くなってきたので一旦OSから再インストールして環境を再構築したのですが、PHP5.3にするとcakePHP1.2だとDeprecatedがでまくりでかなり鬱陶しい事になってしまいました。

php.iniを書き換えたり、cakePHPのソースを書き換えたりする方法は何となくイヤだったので、.htaccessで対応することにしました。

適当にcakePHPのルートの.htaccessに以下を追記すればおkでした

php_value error_reporting 22527

Filed under: cakePHP,PHP,Programming — maesan 12:26 PM

AWS, さくらVPS, hetemlでベンチマークしてみた

hetemlはスゴく機能がいっぱいで使いやすくて大好きなのですが、どうも遅い。他にもAWSや、さくらVPSを使ってるのでベンチマークしてみた。

ベンチマーク方法

とりあえずPHP+MySQLの性能が図れれば一般的なwebアプリの性能が分かりやすいと思ったのでPHPspeedをやってみました。

計測対象は以下の5つです
・Local : MacOSX, Core2Duo 2.0GHz, メモリ4GB, HDD
・AWS small : EC2 smallインスタンス, Debian, シンガポール
・AWS medium : EC2 mediumインスタンス, Debian, シンガポール
・さくらVPS : Debian (カスタムOSインストール)
・heteml : OS不明

計測結果

すべて3回やって平均値です。

  Local AWS
small
AWS
medium
さくらVPS heteml
Synthetic PHP BenchMark 3,666 1,281 2,976 2,816 2,185
Synthetic MySQL BenchMark 1,615 5,613 10,028 9,281 175
Synthetic Read/Write BenchMark 1,886 798 1,950 1,784 2,053
Real World PHP & MySQL BenchMark 2,644 1,035 2,398 2,623 2,180
Server BenchMark 1,996 1,002 2,245 2,658 689

結論

イメージ的にはAWSのmediumが一番で速いのではないかと思っていて、だいたいあってる感じだったのですが、実はそれ以上にさくらVPSがかなり優秀だということがわかりました。
hetemlの遅さの原因がMySQLってのがわかりました。このへんちょっと改善してもらえれば快適になるような気がします。

まだまだサービス開始からあまり時間も経っていないので、さくらVPSが快適に使えているのかもしれませんが、コストパフォーマンスを考えてもダントツにおすすめな感じがしました。
サーバーの構築やら管理やらが苦にならないのであれば、heteml等のレンタルサーバーを借りるよりもさくらVPSSを借りて好き勝手やっちゃったほうがかなりお得な気がします。

サービス内容で比較するとAWSとさくらVPSは似て非なるサービスで、AWSのほうが色々そろってます。個人的に一番の差と感じるのがOSのイメージをS3に保存しておける点でしょうか。
さくらVPSのOSインストールもかなり簡単で、すぐ環境は用意できるのですが、やっぱりOSイメージそのものから復帰するのとはだいぶ違いますね。
このあたりは使い道とかで変わってくるとは思いますが、まぁコスト的にさくらVPSとAWSのsmallで6倍(円高ありがとう価格で)、mediumになると10倍以上の差があるのでコストパフォーマンスは抜群でしょうね。



Filed under: AWS,PHP — maesan 5:47 PM  Comments (3)

為替レートを取得するプログラム書いてみた

ちょっと自動で別通貨から日本円に変換する処理が必要になったのでなんとか自動で為替レートを取得できないかと試行錯誤してみた。

データソース

調べてみるとYahoo!ファイナンスやら証券会社のページをスクレイピングしてる人とか多いみたいですが、仕様が変わったりすると面倒だったり、何となく邪道な感じがしたので、為替レートをRSSで提供しているサイトを発見したのでそれをパースすることにしました。
使ったのはココ→http://xurrency.com/

方法

APIも用意されているみたいなのですが、アクセスキーを取得しないと1日10回までの制限があったり、商用利用じゃ無かったらお金はかからないっぽいのですが何となくAPIは使わずにRSSをパースすることにしました。
今回は日本円基準なのでhttp://xurrency.com/jpy/feedを使います。
最終的にはデータベースに格納することにしました。DBはこんな感じcakePHPとかで使えそうな構造にしました。

CREATE TABLE `currencies` (
`id` int(11) NOT NULL auto_increment,
`base` varchar(3) collate utf8_unicode_ci NOT NULL COMMENT '基準通貨',
`target` varchar(3) collate utf8_unicode_ci NOT NULL COMMENT '対象通貨',
`value` float NOT NULL COMMENT 'レート',
`inverse` float NOT NULL COMMENT 'レート逆数',
`created` datetime default NULL COMMENT '作成日時',
`modified` datetime default NULL COMMENT '更新日時',
PRIMARY KEY (`id`),
KEY `target` (`target`),
KEY `created` (`created`)
) ENGINE=InnoDB;

ソースコード

とりあえずサクっとPHPで作ってみた

<?php
// XML取得
$xml = file_get_contents('http://xurrency.com/jpy/feed');
// XML パーサー作ってパースする
$parser = xml_parser_create();
xml_parse_into_struct($parser, $xml, $values, $idx);
xml_parser_free($parser);

// とりあえずDB接続
$con = mysql_connect('localhost', 'root', 'root');
mysql_select_db('currency');
mysql_query('set names utf8');
// 挿入用のSQL
$sql_base = 'insert into currencies(base, target, value, inverse, created, modified)values("%s", "%s", %f, %f, "%s", now());';

$date = null;
foreach ($idx['DC:VALUE'] as $key => $val) {
if ($date == null) {
// RSSの構造によりdateが1個はじめにかぶるから1個ずらす
$date = date('Y-n-j H:i:s', strtotime($values[$idx['DC:DATE'][$key + 1]]['value']));
}
$data = array(
'value' => $values[$val]['value'],
'base' => $values[$idx['DC:BASECURRENCY'][$key]]['value'],
'target' => $values[$idx['DC:TARGETCURRENCY'][$key]]['value'],
'date' => $date,
);
$data['inverse'] = 1.0 / $data['value'];
$sql = sprintf($sql_base, $data['base'], $data['target'],
$data['value'], $data['inverse'],
$data['date']);
mysql_query($sql);
}
// おしまい
mysql_close($con);
?>

で見てもらうとわかると思うのですが、ちょっとXMLのパースの仕方が美しくない気がしません?何ていうか親子関係無視というかとりあえず上からパースしてタグ名でばらしてみましたみたいな?
なので最近お気に入りのPythonでも同じの書いてみた

#!/usr/bin/python
#coding -*- coding: utf-8 -*-

from xml.etree.ElementTree import ElementTree
from urllib import urlopen
import MySQLdb
import datetime

# ElementTreeを生成
xml = ElementTree(file=urlopen('http://xurrency.com/jpy/feed'))
# タグ名が"{ネームスペース}:タグ名"に展開されるのでネームスペースを書いとく
rss = 'http://purl.org/rss/1.0/'
dc = 'http://purl.org/dc/elements/1.1/'

# MySQL接続
con = MySQLdb.connect(db="currency", host="127.0.0.1", port=3306, user='root', passwd='root')
# 挿入用のSQL
base_sql = 'insert into currencies(base, target, value, inverse, created, modified)values("%(base)s", "%(target)s", %(value)f, %(inverse)f, "%(date)s", now());';

# itemタグ内に為替レートを持ってるので取得してループ回す
for items in xml.findall('.//{' + rss + '}item'):
currency = {}
for item in items.getiterator():
if item.tag == '{' + dc + '}value':
currency['value'] = float(item.text)
if item.tag == '{' + dc + '}baseCurrency':
currency['base'] = item.text
if item.tag == '{' + dc + '}targetCurrency':
currency['target'] = item.text
if item.tag == '{' + dc + '}date':
currency['date'] = datetime.datetime.strptime(item.text, "%a %b %d %H:%M:%S UTC %Y")
currency['inverse'] = 1.0 / currency['value']

sql = base_sql%{'base':currency['base'], 'target':currency['target'], 'value':currency['value'], 'inverse':currency['inverse'], 'date':currency['date']}
cur = con.cursor()
cur.execute(sql)

con.commit()

そこまでこだわるような物ではないのかもしれませんが、コッチの方が構造を解析している感じがして個人的には綺麗な気がします。

まとめ

頻繁にアクセスするのも申し訳ないので、1日に1回cronで取得してデータ溜めこむ予定。なんかに使えそうだしね。
何ていうか、とりあえず円高スゲー、早く外貨口座作ってそっちにお金移さないとダメだ。ま、そんなに日本円も持ってないけどなw

Filed under: cakePHP,PHP,Programming,Python — maesan 2:37 AM  Comments (1)
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)