2014年11月2日日曜日

Golang Cafe #52を開催しました。

Golang Cafe #52を開催しました。

今回は、isuconという「与えられたサーバとそこで動作するWebアプリケーションを高速化してアクセス数を競うイベント」の予選問題でGolangが使われたという情報を聞いたので、実際に挑戦してみようという主旨で開催しました。

本来はAMIというAWSで動作するイメージを使ってAWSにデプロイして競うようなのですが、「課金前提」ということで、GCEに…というのもやめまして、ローカルにデプロイしようと頑張ってみました。

最初、「Dockerを使おう」ということで、

$ docker pull mysql

としたのですが、これが大失敗。関連する全てのコンテナをダウンロードし始めて、1時間待ってもダウンロードが終了しなかったので(Wimax回線の調子が悪かった…?)ローカルのhomebrewを使ったインストールに切り替えました。

$ brew update
$ brew install mysql

これで、mysqlがインストールできたので、早速ログインしてバージョンを確認します。

$ mysql.server start

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.6.20    |
+-----------+
1 row in set (0.03 sec)

インストールが完了したので、次にinit.shを動かしました。
すると、"MySQL server has gone away"というメモリ不足で発生するエラーに悩まされました。
drupalのblogに設定の記載例があったのでそれを元に、my.cnfを修正しました。
ただし、table_cacheという設定はないようで、そのままコピペしても改善しませんでした。実際に編集する時はtable_cacheの行は書かないようにしましょう。

[mysqld]

# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M

# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin

# These are commonly set, remove the # and set as required.
# basedir = .....
# datadir = .....
# port = .....
# server_id = .....
# socket = .....
skip-external-locking
key_buffer = 384M
max_allowed_packet = 64M
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 64M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
max_allowed_packet = 32M
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M 

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 

これでinit.shを実行した所、今度は、

ということになったので、いろいろ試行錯誤した結果、+0900という記載がダメなようなので
$ sed -e s/\+0900//g dummy_log2.sql

として、+0900の記述を消してから登録しました。homebrewでインストールした時のtimezoneがJSTになっていたので、これをUTCに変えてやればそんなことをしなくても良さそうな気がしてきました。が、本来の主旨と違う気がしたのでそこまで検証していません。

次に、Webサーバの起動ですが、Goの場合は、アプリケーションにhttpサーバの機能があるので、go buildして、起動するだけです。
$ cd webapp/go
$ ./build.sh
$ ./golang-webapp

これで、http://localhost:8080に接続すると「いすこん銀行」が表示されるはずです。

次に、ベンチマーク用コマンドもGoで書かれていますので、go buildすればいいのですが、makefileが用意されているので、それに従ってコンパイルします。
中身を見ると、標準でAWSにリクエストを飛ばすようになっているので、
$ cd benchmarker
$ make debug

として、コンパイルします。すると、localhostに対するリクエストになります。
ですが、そのままだと、http://localhostへのリクエストになり、goのwebappにリクエストが送信されないので、main.goの81行目付近を書き換えます。

    cli.StringFlag{
     Name:   "host",
     Value:  "localhost:8080",
     Usage:  "Bench Endpoint host",
     EnvVar: "ISUCON4_BENCH_HOST",
    },

これでビルドしなおせばローカルホストに対するリクエストが送信されるようになり、スコアも表示されるようになります。

ということで、今回はGoに関する内容ができなかったので、次回(今日、これから)に持ち越しとなります。