ブログトップ 記事一覧 ログイン 無料ブログ開設

床のトルストイ、ゲイとするとのこと

2012-01-09

プログラマと爪の手入れ

f:id:mirakui:20120109195745j:image

一日中キーボードを叩く仕事なので、爪の手入れには気を使っています。ちょっとでも爪が伸びてると指先が気持ち悪くて良いコード書けない気がしてきますね。

最近ガラスの爪やすりを買ったんですが、すごくいいっすこれ。それまで爪切りについてるヤスリを使ってたんですが、ガラスのやつは気持ちよくヤスレるので捗ります。

ガラス製爪ヤスリ 大小セット

ガラス製爪ヤスリ 大小セット

爪切りはこれ。いいやつを買うとスパスパ切れるのがいいですね。

木屋 爪切り 黒

木屋 爪切り 黒

2011-12-23

WEB+DB PRESS Vol.66 に寄稿しました

Web業界のエンジニアは全員読んでるWEB+DB PRESSですが、本日12月23日発売のVol.66に寄稿しました。

特集3「クックパッド開発ノウハウ大公開」ということで、クックパッドのエンジニア5名で開発スタイルやノウハウを書いてます。

僕が書いたのはインフラについてです。僕の担当であるレスポンスタイム、画像配信についてを主に書いてます。

クックパッドの開発はユーザ体験を主軸に据えた、業界でも最先端のスタイルを採用してます(個人の感想です)。手前味噌ですが面白い特集に仕上がっていると思いますのでぜひ読んでみてください!!

編集長の @inao さんどうもありがとうございます!

読もう! WEB+DB PRESS!

2011-12-10

S3のダウンロード速度を1.5〜4.5倍高速化する怪しげな方法

バケットのIPアドレスを適切なものに固定することで、期待値でいうと1.5倍、最大で4.5倍程度高速にダウンロードできます。

この方法は非常に効果が高いですが、非公式なものであり、ある日突然破綻する可能性もありますので自己責任でお願いします。

S3のバケットとエンドポイント

まずは前提知識として、S3の名前解決について説明します。

S3のバケット "mybucket" というバケットを東京リージョンに持っているとします。するとそのバケットのドメイン名は

mybucket.s3.amazonaws.com

になります。これをエンドポイントと呼びます。このバケットの中にあるファイル "hello.txt" にアクセスする場合には、

http(s)://mybucket.s3.amazonaws.com/hello.txt

というようなURLを用います。*1

エンドポイントのIPアドレス

この mybucket.s3.amazonaws.com は東京リージョンの場合、 s3-ap-northeast-1-w.amazonaws.com のCNAMEです。*2

s3-ap-northeast-1-w.amazonaws.com について調べてみると、

$ dig s3-ap-northeast-1-w.amazonaws.com
  :
s3-ap-northeast-1-w.amazonaws.com. 60 IN A     27.0.1.77
  :

となり、 27.0.1.77 を指しているAレコードであることが分かります。

ある日、実はこのIPアドレスは 27.0.1.77 を含めて3パターンあることに気づきました。調べてみましょう。

for i in {1..100}; do dig @ns-911.amazonaws.com s3-ap-northeast-1-w.amazonaws.com A ; done | grep ^s3 | cut -f3 | sort | uniq -c | sort -n
     33 27.0.1.207
     33 27.0.2.77
     34 27.0.1.77
  • 27.0.1.207
  • 27.0.2.77
  • 27.0.1.77

という3パターンがランダムに返されるようです。

実はこの3つのIPアドレスは、どれを使うかによってダウンロード速度が4.5倍ほど異なります。

ベンチマーク

東京リージョンのS3バケットに 100KB のファイルを置いて、EC2インスタンス(c1.xlarge)でのダウンロード速度を計測しました。

EC2インスタンスは、2つのAvailabilityZone(ap-northeast-1a、ap-northeast-1b)にそれぞれ1台ずつ立てて比較しました。

c1.xlargeという大きなインスタンスを選んだのは、Xenのホストである物理マシンの専有率を高くするためです。*3

ベンチマークにはabを使って以下のように行いました。

$ ab -n10000 -c 10 -H "Host: mybucket.s3.amazonaws.com" http://27.0.1.77/100k.dat
$ ab -n10000 -c 10 -H "Host: mybucket.s3.amazonaws.com" http://27.0.2.77/100k.dat
$ ab -n10000 -c 10 -H "Host: mybucket.s3.amazonaws.com" http://27.0.1.207/100k.dat

平均のrequest/secをグラフにしたものが以下です。数値が大きいほど高速です。

f:id:mirakui:20111210180643p:image

ap-northeast-1aのインスタンスでは27.0.1.77から、ap-northeast-1bの場合は27.0.1.207からダウンロードするのが高速であることが分かります。逆に、 27.0.2.77 を引いてしまった場合は大変に残念なことになります。

randomとなっているのは、IPアドレスを固定せず、AWSのネームサーバがランダムに返してくるIPアドレスをそのまま使った場合の速度です。つまりこれが普段の速度だとみなしていいでしょう。

結論

同じ東京リージョン内でS3->EC2という転送をする場合、/etc/hostsに

# ap-northeast-1aの場合
27.0.1.77 mybucket.s3.amazonaws.com
# ap-northeast-1bの場合
27.0.1.207 mybucket.s3.amazonaws.com

みたいに書けば普段の1.5倍ほどのダウンロード速度を得ることができます。

EC2ではない場合でも、27.0.2.77以外を使うようにすればそれなりの高速化が見込めるでしょう。今だけかもしれないけどね!!

なんでこんなことに気づいたのか

S3を使ったとあるサーバを運用しているのですが、ある日名前解決がボトルネックになっている思って/etc/hostsに上記のような記述をしてみたところ、指定するIPアドレスによってえらく速度が変わっていることに気づきました。

3ヶ月前くらいからこの現象を観察していたのですが、これらの転送速度は日によって変わったりはせず、速いIPアドレスは3ヶ月間安定して速く、遅いものは安定して遅いという状態が続いています。

ただし今後はどうなるか分かりません!!

まとめ

バケットのIPアドレスなんてAmazonの内部的なアレなので、ある日突然増えたり減ったり変わったりする可能性が高いですが、このリスクは監視を入れるなどしてある程度技術的に補えると思うので、S3の転送速度に困っている方は試してみるといいかもしれません。

あと今回は東京リージョンでのみ試したので、他のリージョンの事情はまったく知りません。なにか情報があれば教えて下さい。

DO IT AT YOUR OWN RISK!!!!

*1:この場合はhello.txtをpublicにする必要があります

*2ap-northeast-1は東京リージョンを指す

*3:EC2では物理マシンの占有率が高いほどネットワークが安定する

2011-07-18

#RubyKaigi 2011で気になったgem 13選

Rubyist達の夏フェスであるところのRubyKaigiが今年も開催され、猛暑の練馬が大いに盛り上がりました。今回が最後の開催とのことで、関係者各位は素晴らしい会議を本当にどうもありがとうございました。

さて、今年のRubyKaigi2011での各セッションで紹介されたgemのうち、気になったものをピックアップしてみました。

1. fakeweb

fakewebは、指定したURLHTTPレスポンスを偽装する、テスト用のライブラリ。外部サービスと連携するプログラムのテストを書くにはとても便利ですね。

Engine YardのAndy Delcambre氏による「Toggleable Mocks and Testing Strategies in a Service Oriented Architecture」という発表で紹介されました。

以下、サンプルコードです。(READMEより)

FakeWeb.register_uri(:get, "http://example.com/test1", :body => "Hello World!")

Net::HTTP.get(URI.parse("http://example.com/test1"))
=> "Hello World!"

Net::HTTP.get(URI.parse("http://example.com/test2"))
=> FakeWeb is bypassed and the response from a real request is returned
参考
追記(2011/07/19)

id:secondlife 氏によれば、今はfakewebよりwebmockの方がイケてるとのことです。

2. artifice

artificeも、HTTPレスポンスを偽装する、テスト用のライブラリです。上記と同じ発表の中で紹介されました。fakewebは偽物のNet::HTTPのレスポンスオブジェクトを生成するだけなので通信は発生しないのに対し、artificeは、rackでWebサーバを立てて通信を行います。fakewebでは偽装度が物足りない方にオススメですね。

参考

3. showoff

showoffは、RubyKaigiで海外勢のスピーカーの方々が使っていたruby製のプレゼンライブラリです。特徴としては以下のとおりです。

日本ではruby製のプレゼンライブラリといえばrabbitが有名ですね。RubyKaigi2011では海外のスピーカーの方がこぞってshowoffを使っていたので、これからは日本のRuby界隈でもこのshowoffが流行るかもしれません。

参考

4. drip

dripは、dRubyでの分散処理で、プロセス同士でオブジェクトをやりとりするための機構です。途中から聴講したため詳細まで理解できませんでしたが、複雑な依存関係を持つデータをキューイングするときに活躍しそうです。

dRubyの作者である関将俊さんの発表「Drip: Persistent tuple space and stream.」で紹介されました。

関さんのdRuby本の英語版が出るらしく、そちらではこのDripが紹介される予定だそうです。

参考

5. rails_best_practices

rails_best_practicesは、あなたのRuby on Railsプロジェクトにおける code smell (コードの不審な臭い)のする箇所や、「ここはこう書いたほうがRails的にクールだよ!」というような箇所を指摘し、修正方法を提案してくれるライブラリです。指摘されるプラクティスは、同名のウェブサイト Rails Best Practices | rails best practices list で投票の多いものが採用されています。

rails_best_practicesはOpen FeintのエンジニアでありRails Best Practicesの作者でもあるRichard Huangさんの発表、Use rails_best_practices to refactor your rails codes で紹介されました。

参考

6. ruby_parser

ruby_parserは上記のrails_best_practicesがrubyコードの解析に使用しているpure ruby実装によるrubyパーサです。ruby_parserは、rubyコードをS式に展開します。

例として、次のようなRubyコードは、

def conditional1(arg1)
  if arg1 == 0 then
    return 1
  end
  return 0
end

以下のようなS式に展開されます。(READMEより)

s(:defn, :conditional1, s(:args, :arg1), s(:scope, s(:block, s(:if, s(:call, s(:lvar, :arg1), :==, s(:arglist, s(:lit, 0))), s(:return, s(:lit, 1)), nil), s(:return, s(:lit, 0)))))

7. fabrication

fabricationは、ActiveRecordのテストデータ生成用ライブラリです。Mongoid、Sequelにも対応しています。

railsには組み込みでfixturesという機能がありますが、これがいけてないので皆 machinistfactory_girl を使うわけですが、この fabrication はそれらよりも後発であり、より記述がすっきりしているのが特徴です。

例えば、以下のようなDSLでテストデータを記述できます。(公式サイトより)

Fabricator(:person) do
  name { Faker::Name.name }
  email { |person| "#{person.name.parameterize}@example.com" }
end

fabricationは、諸橋 恭介さん(@moro)の発表「5 years know-how of RSpec driven Rails app. development.」の中で触れられました。

参考

8. mustang

mustangは、Googleの高速JSエンジン「V8」をrubyから使うためのラッパーです。

以下のように、rubyからJSコードをevalすることができます。rubyを経由しているので一見遅そうですが、JSエンジンがV8なのである程度高速に実行できるとのことです。

require 'mustang'

cxt = Mustang::Context.new
cxt.eval("'Hello' + ' World!';") # => 'Hello World!'
cxt.eval("var a=1;")
cxt.eval("a+5;") # => 6

cxt[:puts] = method(:puts)
cxt.eval("puts(a)") # displays "1" on the screen
cxt[:a] # => 1

Chris Kowalik氏の発表Efficient JavaScript integration testing with Ruby and V8 engine.で紹介されました。mustang自体もご自身の作です。

参考

9. mike

mikeは上記のmustang+V8を利用した高速なheadless browser(画面は表示されないがブラウザと同様の挙動を再現できるブラウザ)です。mustangの作者Chris Kowalik氏が高速なJSテストのために開発されたそうです。

mikeという名前はMike the headless chicken (首なし鶏マイク)から来ているそうです(ややグロ注意)。

参考

10. james

jamesはMax OSX音声認識音声合成機能を利用し、人工無能的な対話を記述できるライブラリです。

# READMEより
James.dialog do

  hear 'What time is it?' => :time

  state :time do
    hear ['What time is it?', 'And now?'] => :time
    into { time = Time.now; "It is currently #{time.hour} #{time.min}." }
    exit {} # Optional, listed for completeness.
  end

end

このような簡単な記述で、macとの音声対話が楽しめます。

jamesは、Florian Hanke氏のLT「James: An electronic butler that you can talk to.」で紹介されました。Jamesさんとの絶妙な掛け合いは爆笑でしたね。

参考

11. rios

riosは標準入出力の間のプロキシです。riosを使うと、標準入出力をフックして処理を書けます。cursesなどを使ったインタラクティブで複雑なコマンドラインツールのテストを書くために作成されたそうです。

小山田昌史さんのLT「Rios Proxy - コマンドラインインタフェースのためのプロキシフレームワーク」で紹介されました。

以下、READMEのサンプルコードです。「vim」という文字列が出力される前に、「***」に書き換えてしまうというサンプルです。

#!/usr/bin/env ruby

require "rios/easy"

on_output { |s|
  s.gsub(/vim/i) { |match| "***" }
}

listen

参考

12. interactive-macruby

interactive-macrubyは、MacRuby版のirbです。MacRubyなので、コマンドラインからウィンドウを作るなどのGUI操作ができます。

Eloy Durán さんと Vincent Isambart さんによるLT「A Hayabusa-speed talk about living under the MacRuby rainbow」で紹介されました。

参考

13. aviglitch

aviglitchは、グリッチアーティストの大家、ucnvさんによる動画グリッチライブラリです。AVIフォーマットに則ってグリッチをするので、安全にバイナリを破壊することができて便利です。ucnvさんの発表「Visual Glitch, using Ruby」で紹介されました。

以下は、aviglitchのサイト(http://ucnv.github.com/aviglitch/)から引用したサンプルコードです。これはキーフレームをすべて削除することで動画を壊すグリッチ手法(datamoshと呼ばれる)を実現しています。

require 'aviglitch'
 
a = AviGlitch.open 'file.avi' # Rewrite this line for your file.
a.glitch :keyframe do |f|     # To touch key frames, pass the symbol :keyframe.
  nil                         # Returning nil in glitch method's yield block
end                           # offers to remove the frame.
a.output 'out.avi' 

このコードを使ってグリッチした動画例は以下のとおりです。

参考

最後に

ここで紹介しているのは僕が聴講したセッションからのみなので、RubyKaigi2011で発表された魅力的なgemのうちのごく一部だと思います。他の皆さんも別のセッションで知ったものなどあればぜひブログ書いてください!

2011-06-19

私がクックパッドの画像配信野郎です

一年ほど前にヤフーを退職した私ですが、その後なにをやっているかというと、クックパッドに入社して画像配信をしています。私が入社する前から動いていた画像配信の仕組みは設計が古くてなにかと困っていたので、より良いシステムを開発してリプレースというのをやっています。前職ではなかなかこういう基盤システムを一人でイチから作って運用までするという体験はできなかったので、でかい仕事をできるチャンスに恵まれて大変充実した毎日です。

入社当初はサービス開発の担当だったんですが、開発に必要な基盤システムを作り始めたらどんどんエンジニアリングのレイヤーが下がってきて、気づけばインフラチームに所属していました。

まあそんな話はさておき、この画像配信関連の成果をいくつかの勉強会で発表したので、その資料を紹介します。

サイバーエージェントxクックパッド合同勉強会(amepad)

弊社オフィスで開催された、サイバーエージェント様との合同勉強会での発表です。

サイバーエージェント×クックパッド合同勉強会のお知らせ?それぞれのクラウド活用事例? « クックパッド開発者ブログ

「料理を楽しくする画像配信システム」というタイトルで、私が作ってる画像配信システム「tofu」を紹介しました。

tofuは動的にサムネイル生成をするシステムです。動的と聞くと遅そうに感じる人もいるかも知れませんが、意外といけます。しかもImageMagickで。

Varnish勉強会 Tokyo.vcl

Varnish 3.0 のリリースにあわせて id:hxmasaki 主催で開催された勉強会です。

Varnish勉強会 Tokyo.vcl : ATND

tofuでvarnishを使おうと試みて失敗した話を発表しました。タイトルは「EC2とVarnishで画像配信」です。

EC2でVarnishを使うという例は世の中にまだほとんど公開されていないので、みんなどんどん試してチューニングなどについて情報交換しましょう。

DSC_0720

左が私です。右がtokyo.vcl主催者の id:hxmasaki(@hmsk)。

画像配信野郎の皆様に感謝

この2回の勉強会を通じて、様々な企業の画像配信野郎の方々に出会うことができました。たとえばpixivの @kamipo さん、 @phji さん、楽天の @spchildren さん、livedoorの @yamashitatakuya さん、GREEの @yoya さんなどなど、非常に技術力の高い方々が担当されているんだなーと身の引き締まる思いです。

画像配信というのは、基本的にはHTTP(S)で画像を返すだけなんですが、実に奥深い分野です。大量の画像をどんなストレージにどうやって保存するのか、キャッシュはどうするのか、モバイルではどうするのか、入稿はどうするのか、サムネイルをいつどのように作るのか、などなど、様々な課題があり、各社それぞれ工夫して解決しているようです。

各社の画像配信野郎様を集めてコミュニティを作りたいですね。