EC2のmicroインスタンスでMySQLが落ちる場合

2012 年 5 月 2 日

EC2でMySQLを走らせていて、何度かMySQLが落ちるという事態が発生しました。
だいたいの場合はテスト用・開発用なのでMySQL再起動で問題は無いわけですが、
場合によっては(主にお金の問題で…)microインスタンスを商用に使う場合もあります。

ということで原因を探りにログをあさってみたところ、どうやら、MySQL自体は生きているものの、InnoDBストレージエンジンがメモリ不足で落ちている模様です。
確かに、インストールしたままで動かしていたこともあり、また、microインスタンスの総メモリは613MBなので足りなくなってもおかしくはありません。

そんな時、「確かMySQLの想定メモリ使用量を計算する方法があったなあ」と思い出したので、そもそも計算上どうなのよ、というのを再確認しようと思い立った次第です。

公式リファレンスには

innodb_buffer_pool_size + key_buffer_size + max_connections * (sort_buffer_size + read_buffer_size + binlog_cache_size) + max_connections * 2MB

となっています。
http://dev.mysql.com/doc/refman/5.1/ja/innodb-configuration.html
この計算式でざっくりデフォルト値を計算すると、だいたい400MBくらいになります。

また、O’Reilly本の計算式に基づくと
http://rental.off-soft.net/323.html
ということで1GBくらい、という計算になっているようです。
#そういえばこの本、手元にもあった(笑)。

そもそもmicroインスタンスにApacheなどWebサーバとして最小限のパッケージを入れて動かしている状態で、MySQLが動いていなくても既に300MBくらいは使用しています。たとえv5系リファレンスの計算通りだとしても足りないわけです。

じゃあmicroインスタンスでMySQLは使えないのか、というともちろんそんなことはなく、単純に max_connections の値を減らせば、メモリの使用量は減ります。どの計算式を使ったとしても、結局のところ全体の数値が押し上がっているのは、「* max_connections」の部分で100倍されているからです。
ということで、 /etc/my.cnf などに

max_connections=10

と追加することになります。

もちろん、レスポンスには影響が出ます。
これ以上のレスポンスを求めるのであればもっと大きいインスタンス使ってね、ということなわけですね。
#そこんとこどうにかなりませんか、と問われてもさすがにどうにも…。

s3fsの使い道

2012 年 4 月 3 日

s3fsを使うとAmazon S3をディスクとしてマウントすることができるということで、そこかしこでぼちぼち取り上げられています。
確かにインストールは可能で、動かすところまでは進めることができるのですが、実際にはできることとできないことがあって、それが原因でs3fsを採用できないパターンが出てきます。

結論から先に言ってしまうと、「隠しフォルダ・ファイル」への読み書きが発生するサービスへの使用は、うまく動作しない場合があるようです。
そこで、試したこと、断念したパターン、最終的にとった方法などのメモを書いておこうと思います。
問題のあるパターン、問題なく使用できているパターンともに、環境に左右されます。
s3fsやfuseのバージョン・forkはもちろん、OSの種類やkernelのバージョンなどによっては問題ない場合や、逆に問題の出る場合があると思われます。
基本的に、以下の結果は、
・CentOS 5.6/6
・Fedora 15/16
で検証したものです。

1. Sambaで使うには問題がある?

s3fsでマウントした領域をSamba共有に指定して使えれば、多少読み書きは遅くてもかなり重宝するだろう、ということで作成してみましたが、最終的にはあきらめました。
正確に言うと、Samba自体はなんとかなるのですが、OSXからの読み書きが正常にできません。
ログを見ると、.DS_Storeなど隠しファイルへの読み書きにエラーが発生しているようです。
OSX側で.DS_Storeを生成しないようにするという方法もありますが、
http://support.apple.com/kb/HT1629?viewlocale=ja_JP
OSXユーザー全員に「コマンド叩いて」というのは事実上不可能という環境だったため、断念しました。
WindowsだけならOKか、というと、これが謎の不安定具合。2007年ごろの開発MLには確かに「NFS使うな」という話が出ていましたが、今でもそうなんでしょうか?
http://lists.samba.org/archive/samba/2007-August/134280.html
http://lists.samba.org/archive/samba/2007-September/135357.html
余談ですが、Sambaは歴史が長いので情報が多い分、その分古いバージョンについての情報が圧倒的に多いため、最新版ではどうなのかがいまいち分かりづらい状況があります。
枯れている技術というのもあり、業務では最新版にはあまり手を出さないでしょうし。

2. WebDAVは問題ない

実は上記1の前に「速度はFTP=Samba>WebDAV」というとあるベンチマークを読んでいたため、WebDAVを選択肢に入れつつも先にSambaに着手していたのでした。
上記1の結果をふまえて、WebDAVも一応試してみることにしました。これも結論から先に言いますと、問題ありません。Sambaほど複雑な規格ではないので、さもありなんです。
読み書きのスピードは確かに速くありませんが、そもそもS3への読み書きのスピードが上限になるので、実用に耐えないというほどのものではありません。

3. Subversionのレポジトリとして使うには問題がある?

上記1で隠しフォルダ・ファイルへの読み書きに問題があることがわかっていたので、おそらく問題があるだろうとは思っていましたが、まんまと予想通りでした。
レポジトリを作ること自体はできますが、.svnなどのアップデートがうまくいかない模様です。

4. s3fsかs3fs-cか?

s3fsの最大の特徴は、他のS3クライアントと一部互換性が無いことです。s3fsはS3上にディレクトリを作る際、Content-type: application/x-directory の空ファイルを生成するわけですが、これが大多数の他のS3クライアントにはディレクトリとして認識されません(ディレクトリ+同名の空ファイルとして認識される)。逆に、他のS3クライアントが生成したディレクトリはs3fsから認識できません。
s3fsへの読み書きがサーバ内で完結していれば問題はないわけですが、別途API経由でS3にアクセスする必要がある場合や、AWSコンソールでもファイルを操作する場合などは困ったことになります。また、サーバ運用開始時S3上に初期状態のファイル群を用意するような場合には、S3クライアントから直接UPしてしまった方が速いのに〜ということもありえます。
この点を変更したものとして、s3fsからforkしたs3fs-cというものもあります。また、s3fs-cがs3fsからforkした後のs3fsのバージョンアップ分をs3fs-cにパッチした、s3fs-cloudpackというものもあります。
どちらがいいか、ということは観点によって異なるとは思うのですが、今回はあくまで実務的な観点から互換性を重視して、s3fs-c系(s3fs-cloudpack)を採用することとしました。

…まあそういうことで、「S3が直接マウントできたらあんなことやこんなことが!」と思っていたんですが、現実はそう甘くはなかった、ということだったわけなんです。

CakePHP2+XMLView+Cache

2012 年 3 月 23 日

直接自分で扱っていたわけではないですが、社員がCakePHPでハマっていたのでメモとして。

1.「XMLViewで $this->set(‘_serialize’, ‘hogehoge’); したのに意図した通りのXMLが出力されない」

外部APIを叩く→受け取ったXMLをいったんパース→(中略)→別の外部APIへXMLを投げる

ということをしようとしたら、なぜか最後のXML出力内容が壊れている?という現象です。
$this->set(‘_serialize’,'hogehoge’); はViewファイル無しで出力できるメソッドなわけですが、これで組み立てられるXMLは(当然ながら)シンプルな構造のXMLが想定されているはずです(ソースまでは見てないけど)。
ということで元のXMLを見てみたところ、RootにAtributeが付いてたんですね。
このような形式だと、たとえばsimplexml_load_stringでパースした場合、Atributeはデータ配列本体とは別のラベルが付いた配列に入ります。
XMLViewで壊れてたというよりは、ひとつ前の段階のXMLObjectが既に意図した構造ではなかった、というオチです。
_serialize で自動的に生成するのではなく、Viewファイルを用意して差し込み置換すれば、当然、複雑な構造でも意図したように生成できるわけなので、「Viewファイル作れ」という結論になりました。

2.「ディレクトリ移動したら500エラーが出る」

これはほぼこのまんまですが、いったんCakePHPで作っていたアプリケーションを、とある理由で別のディレクトリに移動したら、500エラーで動作しなくなってしまったというものです。

Apacheのエラーログに何も出てないのでこりゃCake側だろうなーとは思ったのですが、原因は、app/tmp/cache/persistent/cake_core_file_mapにカレントパス文字列を含むキャッシュが作られていたということでした。
つまり以前の置き場所を読みに行ってしまっていたということですね。
他のConfigをアップデートしたり、キャッシュファイルを消せば再生成されるということなので、キャッシュを消してOKということになります。

どちらもCakePHP2系の機能ということで、情報が少なめではあるんでしょうね。