2013年12月30日月曜日

ncコマンドでmemcachedにコマンドを送りつける

開発用のサーバでmemcachedのキャッシュを全消しするために flush_all をよく使うんだけど、telnetで対話的にコマンド送り込むのだるいのでそういう場合はnc(netcat)を使えばいいよー、という話。

下記はlocalhostの11211でLISTENしてるmemcachedにflush_allを送りつける例。

$ echo flush_al | nc localhost 11211

2013年12月28日土曜日

IntelliJ IDEAを使いやすくするための設定とか

3ヶ月前ぐらいからPython、RubyやJavaScriptなどのスクリプト言語でコードを書く時はIntelliJ IDEA(有償版)を使うようになった。以前はEmacsユーザだった。乗り換えた理由としては

  • IntelliJを試しに使ってみたらけっこう使い勝手が良かった
    • 例えばPythonだと、SDKの設定さえすればimportしているモジュールのメソッドに簡単にジャンプできたり、変数や関数などのシンボルも可能な限り補完してくれる
  • Emacsの設定をするのが辛くなった(プログラマとして恥ずべきことであるのは知っている)
  • IntelliJが様々な言語に対応しているため、これ一つあれば大丈夫感が強い

などだろうか。有償版はパーソナルライセンスで2万円ぐらいだけど、そのぐらい払う価値はあるかなぁと今のところ感じている。ただ、そんなIntelliJさんもやっぱり使いづらいところはあるので、個人的に必ず設定している項目を書いてみる。なお環境はMacで、IntelliJのバージョンは13。

概念とか

Eclipseユーザの人はEclipseユーザの為のIntelliJ IDEA QA を読むといいと思う。Eclipseとの違いが書かれている。ちなみに自分はJavaを書く時はいまだにEclipse使ってるw 長年蓄積された手癖というものがどうにも捨てられない。

プラグインのインストール

IntelliJでPythonやRubyを書くにはプラグインをインストールする必要がある。PreferencesのPluginsからポチポチ選択する。自分が入れているのは下記。

  • Python
  • Ruby
  • NodeJS
  • Scala
  • ReStructuredText

IDEAが使うJVMを変更する

IntelliJはJVM上で動く。そのJVMを変えたい場合は

/Applications/IntelliJ\ IDEA\ 13.app/Contents/Info.plist を下記のように修正

<key>JVMVersion</key>
<string>1.6*</string>
       ↓
<key>JVMVersion</key>
<string>1.7*</string>

IntelliJ IDEAのヒープサイズ

Version 12以降は /Applications/IntelliJ IDEA XX.app/bin/idea.vmoptions を ~/Library/Preferences/IntelliJIdeaXX/ にコピーして編集する。自分は下記のようにしてる。

-Xms768m
-Xmx768m
-Xmn384m
-XX:MaxPermSize=384m
-XX:ReservedCodeCacheSize=96m
-XX:+UseCodeCacheFlushing
-XX:+UseCompressedOops

設定のimport/export

Preferences -> File -> import settings / export settings

でできる。SDKの設定はexport/importしない方が無難かもしれない。

エディタのタブの設定

Preferences -> Editor -> Editor Tabs

以下の2つの設定をデフォルトから変えている。

  • Show directory in editor tabs for non-unique filenames: ファイル名が同じものを開いている場合ディレクトリ名を表示
  • Mark modified tabs with asterisk: 編集されたファイルのタブにはアスタリスクをつける

エディタ上でコピペした時に自動でフォーマットしない

コピペする時に勝手にフォーマットしてくれて元のテキストの体裁を維持してくれない場合があるので、自分はCmd + V でペーストした場合の挙動を変えている。

Preferences -> Keymap -> Paste Simple にCmd + V を割り当て

英語のスペルチェックをオフ

造語などにいちいち波線がついてうざいのでオフにしてる。

Preferences -> Inspections -> Spellingのチェックを外す

クォートやカッコを自動挿入しない

自分はこういうのオフにする派。

Preferences -> Editor -> SmarkKeys -> Insert pair bracket

エディタで表示しているファイルとプロジェクトのツリーの選択ファイルを同期する

Eclipseではデフォルトで有効になっている機能。ファイルが多いプロジェクトだとこの機能ないとつらい。

  • プロジェクトを開いた状態で、projectの設定(歯車みたいなやつ)をクリック
  • Auto Scroll from Sourceにチェックをつける

2013年12月14日土曜日

環境をリセットする

最近日々思っていることを文章にしてみる。特に深い意味はないし結論もない。

何年も同じ会社や部署にいると、自分の立ち位置・イメージみたいなものが凝り固まってくる。「この人はすごいデキる人だ」「この人と一緒に仕事をすればいいものが作れる」とか、もしくはその逆。こうなってくると自分は定期的に「ああ、リセットしてゼロからやり直したい」と思ってしまう。いわゆるダーマの神殿行く的な?おそらく頻繁に転職する人だったり部署異動する人はこういうリセット志向が強い人だと思う。

例えば転職して新しい会社でまわりは誰も知らない人だと、早く一人前に仕事できるようになってまわりからの期待に応えたいと思うし、そうやって信頼を勝ち取って行くのは自分にとってもすごく嬉しい。何より転職前に比べてモチベーションは圧倒的に高い。

なので、頻繁に転職するいわゆるジョブホッパーな人は、ネガティブに見れば「どこの組織でもうまくやれてない」可能性もあるんだけど、上のようなリセット力の高い人もけっこういるんじゃないかなぁと思うし、そういう人はいろんな環境・仕事をやってて経験豊富で優秀だったりする。でも世間ではあまりこういう考え方が浸透していない気がしていて残念。

2013年12月7日土曜日

MacでターミナルからSublimeTextでファイルを開く

こんな感じでPATHが通っているところにsublコマンドのシンボリックリンクをはってやる。

$ ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl

で、あとはsublコマンドでファイルなりディレクトリを開けばOK。

2013年10月20日日曜日

標準出力・標準エラー出力をキャプチャするPythonのライブラリを作った

https://pypi.python.org/pypi/iocapture

PerlでいうCapture::Tiny みたいなやつのPython版が欲しかったので作ってみた。Python3にも対応させた(つもり)。

ここ3ヶ月で取り組んだ技術とか

去年から新規のソーシャルゲームの立ち上げのヘルプをしていて、つい最近も1つリリースした。リリースも何とか無事に終わりデスマも落ちついたので、ここ3ヶ月ぐらい主に仕事で使ってきた技術をここらでまとめておこうと思う。

Java

うちの会社はサーバサイドの言語はJavaかNode.js(JavaScript)が多い。自分がたずさわっているプロジェクトはJava。正直Javaなんて面倒なんでやめたいんだけど、これ使えばけっこう開発が楽になる、っていう技術が2つ。

JRebel

いわゆるホットリローディングを実現してくれるソフトウェア。IDEに組み込んで使う。該当クラスのソースを編集すると自動的にクラスを再ロードしてくれる。有償製品だけどJRebel Socialなんていう謎なライセンスで無料で使うことができる。

Lombok

会社のブログ に概要を書いたので見てくらはい。

NewRelic

パフォーマンス解析ツール。負荷テストをしながらNewRelicを使ってどこがボトルネックかを調査した。任意のURL(に対する処理)を一定時間プロファイリングするX-Rayっていう機能が便利だった。ただNewRelicの全機能の10%も使ってないと思われる。

Vagrant

うちの会社はChefでサーバ構築するようになってきていて、自分もやっと真面目にChefに取り組んでみた。VagrantはChefのレシピをテストするのに使っていた。

$ vagrant up
$ vagrant provision

で cookbooks がゲストOSに転送されてchef-soloが実行される。すごいシームレスに統合されていてすごいなぁと思う。ドキュメントもしっかりしていて特に躓くこともなかった。

Fabric

Python版のCapistranoみたいなやつ。最初はShellScriptでディプロイスクリプトを書いていたんだけど、複雑な処理をやらせるにはちょっと役不足だったので、代わりにこれを使った。@parallel っていうデコレータつけるだけでタスクが並列で実行されるのがよい。

Grunt

最近流行っているnode.js製のJavaScript関連のタスクランナー。JavaScriptのminifyとかconcatするのに使った。

ChatWork

Skypeの代わりにこれを使っていた。ただ正直Skypeの方が好きだ。HipChatはいつか試したい。

IntelliJ IDEA

JavaのコードはEclipseで書いてたんだけど、PythonやRubyのコードはIntelliJで書いてる。ちょっと設定するだけで補完が利くようになるのがいい。

2013年10月7日月曜日

#isucon の予選に出場して惨敗してきた( ー`дー´)キリッ

@la_luna_azul さんと@oranie さんとでISUCON1日目に参戦してきた。結果から言うとトップと約8倍差がついて惨敗10位ぐらいには入れるかなーと思ったけど考えが甘かったし、準備も実力も足りなかった。

準備

  • bitbucketにプライベートリポジトリ作って、そこのWikiに事前にやったほうがいいことなどをまとめたりした。
  • 必要そうなRPMを事前に作ってもらった

やったこと

  • 言語はPythonを選択
    • Python 3.3.2が使われていたのが予想外だった
  • ソースはすべてbitbucketのプライベートリポジトリに突っ込み、簡単にディプロイするようにした
  • 最初の方はset global general_log =ONにしたり、mysqldumpslowやapachetopで傾向を把握
  • memcachedが11212で立ち上がっていたので、アプリからmemcachedへの向き先のポートを変えた
  • my.cnfのチューニング
    • クエリキャッシュ多め
    • あとは一般的なチューニング
  • SELECT username FROM users WHERE id = ? みたいなクエリが多かったのと、userのレコード数が400だったので、usernameをアプリ起動時に全件取得してmemcachedに全て突っ込むようにした
    • Flaskには @before_first_request なんていう便利なデコレータがあることをこの時初めて知る
  • memosのuser, created_atにインデックスが貼ってなかったのではった
    • 複合インデックスより個別にインデックスを貼ったほうがなぜか速かった
    • ただしbenchコマンドを実行するとテーブルが初期化されることに14時ぐらいまで気付かなかったorz
  • 静的ファイルをApacheで返すようにした
    • 最後にはnginxに変更。ただしスコア的には変わらず
  • SELECT count(id) AS c FROM memos WHERE is_private=0 みたいなカウントをmemcachedに突っ込んだ
  • 自家製のスクリプトを使って下記のようにどのURLが全体として遅いのかを把握
  • MarkdownをHTMLに変換する処理がbin/markdownコマンドをサブプロセス起動で行っていたので、これをPythonのMarkdownモジュールを使って変換するようにした。結局、これが一番スコアに効いた
  • SELECT COUNT(*) しているところを SELECT COUNT(id)に変えた
  • SELECT * FROM users WHERE id=? をキャッシュするようにした
  • NewRelicのインストールを試みるもうまくいかず頓挫
  • SELECT * FROM memos WHERE is_private=0 ORDER BY created_at DESC, id DESC LIMIT 100 みたいなクエリがあったので、created_atとidをASCでソートできるように逆順カラムを作った。ただしこれは最後のほうにbenchmarkコマンドでFAILしたので諦めた
  • geventをインストールしようとするも頓挫
  • gunicornのworker数の調整

反省点

  • 事前の打ち合わせで @la_luna_azul = フロント回り、@oranie = データベース回り、@oinume = アプリ回りと役割を分担してしまっていたため、「その時の最大のボトルネック」を直すことより各々で担当領域のことをやってしまっていた。ボトルネックを全員で全力で解決するアプローチのほうがこういうケースだと良かったのでは?と反省会で話していた。
  • EC2のインスタンスを3人分作ってやっていたので、おのおのが行ったサーバの設定変更などを反映させるのに無駄に時間がかかってしまった。本番環境とテスト環境、の2つぐらいで良かったのでは?と思う。
  • 「このURLが遅いしアクセス数も多い」みたいなことまでしか把握せずに、アプリケーションのどこがボトルネックかを正確に追ってなかったので、効果が高いチューニングをあまり行えなかったような気がする
  • Markdownのサブプロセス問題に気付いたのが14:00ぐらいだった。最初からソースを全部読んでいればもっと早くここは直せたように思う。
  • NewRelicインストールできなかった

感想

  • 自分の力のなさがわかっただけでも参加した甲斐があった
  • コードの修正は意外と早くできたので、もっと怪しい箇所のあたりをつけるのを的確にできるようになりたい(ので修行します)
  • 正攻法では突き抜けたスコアは出ないだろうなぁと思ったけど意外とそうでもなさそうだった(1, 2位の人たち以外)
  • あの問題やベンチマークツールを作るの大変だっただろうなぁ。運営の皆さまお疲れさまでした!