複数の zabbix-agent から取得した値を集約する zabbix-aggregate-agent を書いた

Immutableなインフラがなんやかんやと喧しい今日この頃ですが、インスタンスが頻繁に増えたり減ったりすると、監視サービスで継続的な値を追うのが難しくなるよね、という問題を最近感じています。

サービス全体で複数のホストの合計値を取得しておくことで使用量の推移を見たいような値、具体的には以下のようなものです。

  • 外向けのネットワークトラフィック
  • クライアントと永続接続する daemon の持っているコネクション数
  • ジョブの処理数
  • 複数MySQL slaveが処理した参照クエリ数

ということで、zabbix-agent への proxy として動作する、複数 agent からの数値を合計して返すようなものがあったら捗るんじゃないかと書いてみました。

公式ページ fujiwara.github.io/zabbix-aggregate-agent

リポジトリ zabbix-aggregate-agent Github

アーキテクチャ

[zabbix-server(or zabbix-proxy)]
    |           ^
    | (1)key    | (6)aggregated value
    |           |
    v           |
 [zabbix-aggregate-agent] <--- (2) list of zabbix-agents from static list or file or command output
    |           ^
    | (3)key    | (4)values(*)
    v           |
  [zabbix-agents(*)]

1. zabbix server(またはproxy) が aggregate-agent に値を要求
2. aggregate-agente はファイルやコマンドから値を集約する対象 agent を解決

    • 解決には、設定ファイルに定義した静的リスト、行区切りのテキストファイル、標準出力に対象を出力するコマンド、が利用できます

3. aggragate-agentは解決した複数の agent に値を並列に要求
4. それぞれの agent は自分の持っている値を返す
5. aggregate-agent が値を集約する
6. server(proxy) に値を返す

Zabbixには「Aggregate checks」という仕組みがあるけど…?

Aggregate checks - Zabbix

それぞれ、利点欠点があります。

Aggregate checks

Pros.

  • 標準機能です

Cons.

  • 集約したいアイテムにそれぞれについて、アイテムとグラフとトリガの定義を行う必要があります
    • Web UIでぽちぽちぽちぽち……
  • 集約したい zabbix-agent はすべて zabbix-server に登録する必要があります

zabbix-agentの自動登録によって登録することは簡単ですが、不要になった情報を別途削除するために別途 Zabbix API を利用する処理を書く必要があります。

zabbix-aggregate-agent

Pros.

  • アイテム、グラフ、トリガの定義は既に agent 向けに定義されたものをそのまま利用できます
    • zabbix-serverから見ると agent そのものに見える
  • 集約される zabbix-agent は、必ずしも zabbix-server 上に定義されている必要はありません
    • たとえばオートスケールで起動して短時間で落ちるような一時的なインスタンスについて aggregate-agent が存在を認知(APIなどで)できれば、zabbix-serverへの登録は不要です

Cons.

  • zabbix-aggregate-agentのdeamonを1プロセス、起動する必要があります

使用方法

Goで書いてあるので、公式ページからバイナリをダウンロードするだけで動作可能です。

$ zabbix-aggregate-agent --config /path/to/config.toml

設定ファイル例は以下のような感じです。

複数の aggregate-agent インスタンスを1プロセスで起動可能です。

zabbix-serverには集約用のホスト定義を行い、Listenするアドレスを zabbix-agent のアドレスとして指定します。

[[agent]]
# Name: 識別子(ログに出力される)
Name = "web_servers"
# Listen: aggregate-agentが Listen する address (default "127.0.0.1:10052")
Listen = "0.0.0.0:10052"
# List : 静的リストによる解決
List = [ "web01:10050", "web02:10050" ]

[[agent]]
Name  = "app_servers"
Listen = "0.0.0.0:10053"
# ListFile: 改行区切りのテキストファイルによる解決
ListFile = "/path/to/agent.list"

[[agent]]
Name = "db_servers"
Listen = "0.0.0.0:10054"
# ListCommand: 標準出力に集約対象を改行区切りで出力するコマンドを指定
ListCommand = [ "/path/to/generate_list.sh", "arg1", "args2" ]
# CacheExpires : コマンド実行結果のキャッシュ保持期間
CacheExpires = 300

で実際どうなの

Aggregate checksでは、

  • すべての監視対象を zabbix-server に登録する
  • 集約対象ごとにホストグループを定義する

必要があるので、一時的に増えたり減ったりするすべてのホストをかっちりzabbix-serverで登録、削除する仕組みがあればこちらを使うほうがよいと思います。

aggregate-agentはファイルやコマンドの実行結果で集約対象を定義できるため、

  • zabbix以外のAPIでホストグループ的なものが解決できる

(つまりzabbix-serverにホストメタデータの管理を全部寄せきれていない場合) には便利に使えるかと思います。

あとは既存の監視対象アイテム、グラフ、トリガの定義をそのまま流用できるのが個人的には嬉しいところで、Web UIでぽちぽち定義をしていく必要がありません。

書いてみて

複数の agent にリクエストを飛ばして受けるところ、複数の aggregate-agent インスタンスを立てるところは Goroutine で簡単に並列化できたので、大変楽ですね。PerlでAnyEventで非同期処理とか、複数の子プロセスをforkしてプロセス間通信するのとは比較する気も起きないぐらいです。

Redisを使って排他制御するwrapperコマンド Redis-Setlock をPerlとGoで書いた

しばらく前に作って書きそびれていましたが、Yokohama.pm #10 でLTしたのでエントリもあげます。

LTのスライドはこちら ⇒ Redis-Setlockを書いたはなし

なにをするもの?

setlockコマンドのロック処理をRedisサーバで行うもの」です。

setlockはflockを使ってロックを獲得したら引数に渡されたコマンドをexecする、daemontools付属のwrapperコマンドで、cronでコマンド実行するときなど多重実行を制御する場合に重宝します。

flockだとホストをまたいだロック処理が行えないため、その部分をRedisを使った排他制御に置き換えたものを書いてみました。

使い方

$ redis-setlock [-nNxX] KEY program [ arg ... ]
$ go-redis-setlock [-nNxX] KEY program [ arg ... ]

--redis (Default: 127.0.0.1:6379): redis-host:redis-port
--expires (Default: 86400): The lock will be auto-released after the expire time is reached.
--keep: Keep the lock after invoked command exited.
-n: No delay. If KEY is locked by another process, redis-setlock gives up.
-N: (Default.) Delay. If KEY is locked by another process, redis-setlock waits until it can obtain a new lock.
-x: If KEY is locked, redis-setlock exits zero.
-X: (Default.) If KEY is locked, redis-setlock prints an error message and exits nonzero.

オプションと使い方は基本的に setlock と同じで、使用する Redis サーバ、ロックを自動開放するための expire、終了してもロックを(expireまで)開放しないというオプションが追加されています。

実装

Redisでの排他制御公式ドキュメントに書いてあるものをそのまま使用しています

SET に NX フラグを付けると、「すでにKeyが存在しない場合のみSETが成功する」という動作をするためにロックに使えるんですね。

setlockはロックを獲得したらそのまま単にexecveすることで、プロセス終了時にロックが解放されるという素敵な実装なのですが、Redisを使う場合は自分でRedisサーバにコマンドを発行して開放処理を行う必要があるため、execではなく子プロセスをforkしています。

その関係で、(Go版での) 標準入出力の扱いやシグナルハンドリングなど、いろいろ泥臭いコードが増えてしまっているのが美しくないところです……

Go版はクロスコンパイル可能なので、本来はWindows版も作れるはずなのですが、子プロセスの終了コードを取得する処理でWindowsだと動かないコードがあるらしく、コンパイルできませんでした。自分では使わないからまあいいか、とそのままになっています。

Go版は http://fujiwara.github.io/go-redis-setlock/ からバイナリをダウンロードするだけで動くので deploy がお手軽だと思います。

Perl版にはライブラリとして使用できるインターフェースも用意してあります。

my $redis = Redis->new( server => 'redis.example.com:6379' );
if ( my $guard = Redis::Setlock->lock_guard($redis, "key", 60) ) {
   # got a lock!
   ...
   # unlock at guard destroyed.
}
else {
   # could not get lock
}

複数ホスト間で気軽に排他制御できるので、是非お試しください。

nginx で gzip_static と gunzip を使ってストレージを節約する

一月ほど前に 社内Gyazoの画像をAmazon S3に逃がしてスケーラブルに運用する - 酒日記 はてな支店 というエントリを書いて一段落と思いきや、そのサーバには社内向けの nopaste アプリも同居しており、気がつけばテキストファイルが10GB以上積もっていたのでした…

社内 nopaste アプリの実装はDBなどを使用せず単にテキストファイルを保存しているだけだったので、ファイルを gzip して nginx の http_gzip_static_module を使って配信したらディスクを節約できていいんじゃないか、と思いついたのですが、Accept-Encoding: gzip でないクライアントからアクセスすると 404 になってしまうので圧縮前のファイルが消せない。

今時ブラウザで対応していないものは少ないとはいえ、curlとか各種言語のHTTPクライアントでアクセスする場合もあるので、gzip 非対応クライアントには展開した内容を返したいところです。

それ ngx_http_gunzip_module でできるよ、ということでこうなりました。

gzip_static always を指定するため、nginx version 1.3.6 以降が必要です。
また、gzip_static と gunzip モジュールはデフォルトでは組み込まれないため、build時に --with-http_gunzip_module --with-http_gzip_static_module を指定して有効にする必要があります。

    location ~ ^/nopaste/([0-9a-f]+)\.txt {
         gunzip       on;
         gzip_static  always;
    }

これで動作としては

  • gzip_static always によりクライアントの gzip 対応非対応お構いなしに .gz ファイルの内容を配信
  • gunzip on により、クライアントが gzip 非対応であればその場で展開

となり、どちらのクライアントに対しても .gz で保存された内容を送信することが可能になりました。

社内Gyazoの画像をAmazon S3に逃がしてスケーラブルに運用する

Gyazo、便利ですよね。大変便利なので、社内でプライベートなGyazoサーバを用意して使っている会社も多いと思います。

うちでもサーバのパフォーマンスは特に必要ないので社内に適当なVMを立てて運用していたのですが、数年単位で運用していると画像ファイルが増えていくためdiskをなんとかする必要に迫られました。

ここでどんどん増えるファイルはAmazon S3に逃がそう、という自然な発想に至るわけですが、Gyazoサーバアプリが投稿を受けたときにS3にアップロードするような改修をするのは年末の忙しい時期に面倒。楽したい。

ということで S3 と nginx を組み合わせていいかんじに運用できるようにしてみました。

Gyazoに限らず、

  • ローカルに書き込んだファイルをhttpで閲覧する
  • 一度書き込まれたファイルには変更がない
  • ファイルは消えないでどんどん増える

ようなものには応用できると思います。

S3 に bucket を用意

普通に S3 に bucket を作ります。ここでは internal-gyazo.example.com とします。

社内のみにアクセス制限している画像なので、S3から直接一般に公開してしまうわけにはいきません。しかし、S3 API をちゃんと実装して nginx から画像を取得するのは面倒なので、IPアドレス制限をして特定のIPアドレス(ここでは社内gyazoサーバ) からのみ閲覧を許可します。

bucket policy の設定を開いて、AWS Policy Generator で生成した以下のようなJSONを記述します。

{
	"Version": "2008-10-17",
	"Id": "Policy1",
	"Statement": [
		{
			"Sid": "Stmt138795173604",
			"Effect": "Allow",
			"Principal": {
				"AWS": "*"
			},
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::internal-gyazo.example.com/*",
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": "192.0.2.1/32"
				}
			}
		}
	]
}
  • s3:::internal-gyazo.example.com/* に対して
  • 192.0.2.1/32 から
  • s3:GetObject を許可する

というルールです。

nginxの設定

try_files を利用して、

  • ローカルファイル (/usr/local/gyazo/data/*) がある場合はそれを返す
  • ない場合は S3 に proxy_pass

という設定をします。

実際は別途Basic認証を掛けているため、AuthorizationヘッダをS3に送ってしまうと認証エラーになるので proxy_pass する前に削除しています。

S3 のホスト名を proxy_pass に直書きしないで一旦変数に set している記述については、Nginxでproxy_passにホスト名を書いた時の名前解決のタイミング - (ひ)メモ を参照してください。

また、無駄に S3 にリクエストを飛ばさないために proxy_cache も設定しています。

proxy_cache_path /var/lib/nginx/tmp/proxy levels=1:2 keys_zone=gyazo:500m max_size=1000m inactive=24h;
server {
    listen 80 default_server;
    resolver  127.0.0.1;
    location /gyazo/data {
        root /usr/local;
        try_files $uri @s3;
    }
    location @s3 {
        set  $s3_host  "internal-gyazo.example.com.s3-ap-northeast-1.amazonaws.com";
        proxy_set_header   Host $s3_host;
        proxy_set_header   Authorization "";
        proxy_set_header   Cookie "";
        proxy_cache        gyazo;
        proxy_cache_valid  404 1m;
        proxy_cache_valid  any 24h;
        proxy_pass  https://$s3_host;
    }
    location /gyazo {
        proxy_pass  http://127.0.0.1:5000;
    }
}

運用

  • Gyazoサーバに投稿があるとローカルファイルが生成されます。その後の閲覧はローカルファイルから配信されます
  • 適当なタイミングで、ローカルファイルを S3 にアップロードして削除します
  • ローカルファイルが削除された後は、S3 から GET したファイルが配信されます

これで、ローカルファイルは適宜削除できるので disk 容量を気にする必要がなくなりました。年末にdisk 掃除ができてすっきりです。

ISUCON3 チームごとのベンチマーク試行回数

すっかりISUCONのことも忘れかけたある日曜日のこと…


そういえば公開していませんでしたので公開します。

success, fail, 順位とベンチマーク試行回数の相関はあまりなさそうに見えますね。

rank name count(*)
Miami 11
50ms or die. 15
Noder 25
1 LINE選抜「チーム生ハム原木」 25
白金動物園 27
( (0) / (0)) ☆祝☆ 28
:ok_woman: 28
5 山形組 31
4 くらげとみかんと江戸幕府 34
6 銀杏絶滅しろ 34
ぜかまし 40
チームぽわわ2 40
かまたまうどん 40
勝浦タンタンメン 41
カヤック選抜「流れ弾」 42
2 オシャレ怪盗スワロウテイル 43
7 Third Party Cookies 43
坂パスタ 46
チームたこやき 50
└('-'└)└)└)<HEARTBEATS 50
335 57
The Revenge of Mr. Frank & Co. 57
3 Fulab 62
潰すつもりで来てください 62
進撃の超大型パティスリー兄弟 71

ISUCON3 を開催しました

参加者の皆様、共催で運営となった LINE, DataHotel, カヤック各社の皆様、本当にありがとうございました。いくつかトラブルがあったものの、本選もなんとか無事に終えることができました。

まずは優勝した LINE 選抜チームの皆様、おめでとうございます!なかなか初期スコアから上がってこないので内心ものすごく心配していましたが、ポイントを見極めて作業が終わったところで一気にスコアを上げてきたのは感服しました。

本選終了から48時間経過したいまでも頭の疲労が回復しきっていない感じで、整理できていないので思うままにつらつら書きます。

以下長文になってしまうので最初に告知です。

ISUCON3反省会 というイベントを 11/15(金) に行います。ISUCON参加者でなくてもどなたでも無料でプレミアムモルツ飲み放題ですので、日時が迫っていますが是非お越しください。

出題内容について

お題は以下のような感じです。

  • 画像版のTwitterみたいなリアルタイム投稿アプリ
  • 投稿の公開レベルを、パブリック、フォロワーのみ、プライベートで指定可能。閲覧権限がないユーザの画像ファイルへのアクセスには 404 を返す
  • HTTP long polling でのタイムライン取得機能あり

『予選とがらっと変えてきた』的な反応が多かったのですが、これは実は順序が逆でして。ISUCON3出題の裏側 | tech.kayac.com - KAYAC engineers' blog で書かれているとおり、最初に出題内容を考えたときには本選のお題を決めたんですね。

画像投稿で、リアルタイム通知があって、複数台ちゃんと分散しないと勝てないようにしよう、という方向でした。

予選をやるとなると、本選のネタバレに繋がる内容を盛り込むわけにはいかず、必然的に全然違うタイプの出題になった、ということなのです。

リアルタイム通知によって同時に画像変換にリクエストが殺到する、というネタは、弊社の提供しているチャットサービス Lobi で実際にあった現象を元にしています。

実運用を考えるとリサイズ済みの画像をあらかじめ持つのは容量とファイル数の問題で避けたい、けれども参照時に変換すると殺到問題がある、というあるあるネタですね。

『罠』について

初回の ISUCON 1 での通称「kazeburoの罠」の印象があまりに鮮烈なため、ISUCONといえば『罠』的な印象があるのですが、実は ISUCON 2 には特に罠らしい罠はないのですよね。

今回の予選では意図的な罠ネタを入れすぎてしまったのですが、これはおそらく出題したことのある人にしか分からない心理がありまして…

出題しているとお題についてあまりに熟知してしまうために、この程度の問題ではあっさり解かれてしまうのではないか、という恐怖心が時間を追うごとにどんどん増してしまうのです。その恐怖心に負けるとああなってしまう。

…というのを予選後かなり反省しまして、予選を通ってきた強者たちにはまっすぐな出題で応えるべきと思い直したため、今回の本選には特に意図して仕掛けた『罠』はありません。

意図せず罠的な挙動をしていた事象としては、

  • PerlでImagerを使うと画像差分が大きくなりがち (特に小さいサイズやアイコン)
    • これは出題中に image diff の閾値を決めるときに気がついていました
    • 実際に変換した画像をリファレンス実装のものと並べてみると、デフォルトだと1ピクセルずつ右下にずれたように見えます

というのがあります。画像変換のライブラリによって結果に差分がでるのは当然のことなので、差分を検出するツールを提供すれば問題なかろう、という判断でした。

あとは1MBを超えるサイズのデータで nginx で 413 がでるとか、memcachedに入らないとか、そういう現象もありました。これも出題時に当然気がついていたのですが、昨今のスマフォは1MB以上のJPEG画像を平気で撮影できますし、仕方ないですよね。
(ただし、全画像を大きくすると100Mbpsの帯域に対するインパクトが大きすぎるため、1MBを超えるのは全体の数%程度です)

配点について

POST /entry とタイムラインへの反映については、レスポンス速度によって加点があります。

score = log(10 / $response_time) / log(2)

なぜ log(2) で割っているかというと、ベンチマーククライアントのタイムアウトが5秒なので、5秒ちょうどで1点になるようにしたかったためです。

10ms で返せれば約10点になるのですが、1秒で処理した場合との差分が7点弱。通常のGETが1リクエスト1点なので、あまりそこで速度を上げるのを頑張らずにGETを捌くので高得点が狙えるのは優勝チームが示したとおりです。

これは出題の罠といえば罠でしょうか。事前検証ではPOST時には保存のみ、初回GETで変換という方策でもスコアを出すことはできているので、どちらを取るかで直接の有利不利はないと思います。

初回GET時に変換という戦略をとった場合、タイムラインが流れた瞬間に複数のクライアントが同一画像を GET に来るため、そこですべてに変換処理を走らせるとCPUの無駄遣いになりますし、workload を上げれば上げるほど効率が落ちるのでスコアを出すのが難しくなります。

これを回避するためには同一画像に対する変換が同時に複数走らないように、なんらかの方法で排他制御 (事前検証ではRedisを使用) をする必要があり、本選のように時間が限られた状況では実装しきるのが難しい、ということはありそうです。

ベンチマークツールについて

予選では同一ホストで動作させる関係上、ソースコードが読めてしまうと対応が容易になってしまうので Go を使用しましたが、本選では参加者の触れないサーバからベンチマークをするためその心配はない、ということで、自分が一番実装速度が出せる Perl で書かれています。
(ソースコード提供は数日中にはしますのでお待ちください)

リクエストを順次実行するタイプのプロセスには Furl、タイムラインを監視して同時アクセスを飛ばすタイプのプロセスには AnyEvent::HTTP を使用し、複数のタイプのプロセスを拙作の Parallel::Benchmark で束ねて実行するような作りになっています。

帯域制限は tc を wrap してくれる大変便利な qos-control で1ベンチマークホストに対する設定を吐き出してから、設定ファイルを加工して125ホスト分定義しました。

複数ホストに対するベンチマーク実行は、LVS で NAT 構成を取っています。参加チームごとに 8000 + チームID のポートを割り当てて ipvsadm で設定、そのポートに対してクライアントが接続する形を取りました。(そのため一部のエラーメッセージで謎のURLが見えてしまうことになり、混乱をしたかたもいたようで、申し訳ないです)

このあたりの詳細は、ISUCON3反省会 で紹介する予定ですので、ISUCON参加者に限らずぜひ無限プレモルしに来てください。お待ちしております。

さいごに

まだこれから結果まとめエントリを書いたり、ソースコードやAMI(?)公開をしたり、いろいろ作業は残っていますが、とりあえず今日の所はこれぐらいで。

来年のISUCONがどうなるのかはまだ誰も分かりません。が、是非誰か出題に名乗り出ていただきたいなあ、というのが正直な気持ちです。

いきなり言語実装を大量に揃えて、となると準備も大変ですから、まずは社内や身内で1言語でやってみるといろいろ面白いのではないかと思います。身内だけなら実装に不備があってもごめんなさいで済みますし。実際出題すると相当勉強になりますし。

今回は100万円の賞金が掛かっているがために、出題で下手を打ったら切腹もの、というのが最大のプレッシャーでした。でも当日競技を見ていて、最後のほうは100万円のことを忘れるぐらい面白かったですね!

ISUCON3 予選を開催しました

出題担当なのですが正式名称が ISUCON3 なのか ISUCON 2013 なのか未だによく分かってない今日この頃です。

それはともかくとして、200名以上の皆様に参加していただいて ISUCON の予選を盛況のうちになんとか終えることができました。

  • スコアの算出方法が公表されていなかったり
    • 基本的に静的ファイル以外の1リクエストが1点 (ただしPOST→リダイレクト→GETは1点)、静的ファイルは0.02点、css扱いで で読まれるのは 0点、でした
    • Failについては合計3まで減点なし、それ以上は (Fails - 3)^2 * % を減点するので合計 Fails 13 で (10*10)% = 100% 減点でスコア0になります
  • 想定していない /recent/* 荒稼ぎポイントがあったり
    • 初日の競技中に気がついて、何チームぐらいここで稼いでくるかと思いましたがやはり60チーム以上いるとありますね

と、不備がいくつかありまして参加者の皆様には申し訳ないです。本選ではそのあたりしっかり準備します。

感想

予選を開催してみての感想をいくつか。

今回はフロントキャッシュ組と再実装オンメモリ組がどうしても強かったですね。

キャッシュ組が強かったのはチェッカーが甘かったからなのですが、オンメモリ実装組が強いのはある1インスタンスで予選をする以上ある程度仕方ないかな、という気がしています。

前回の ISUCON2 では4台のリソースをほぼすべて使い切った fujiwara 組とリバースプロクシのホスト1台にアプリ乗せて捌いた山形組が (1分計測では) 僅差でしたし、1台かつデータセットがメモリに保持できるという出題ではこれを覆すのはなかなか大変かなと。

本選では用意した複数台を使い切ることで性能が上がるような出題にしようと構想しています。

準備とか

準備はまあ、分かっていたことですが大変でした。

9/18〜20 の YAPC::Asia 前に出題のプロトタイプと Go でのベンチクライアントの仮実装ぐらいは何となくできていた状態で、YAPC 後の1週間でひとまず最初の版を仕上げて @acidlemon に解いてもらいはじめたのが 9/25(水)。

最初は /recent/* がなかったのですが、ちょっと簡単すぎるかも、ということで追加したのが 9/30(月)の昼。後付けだったから意図しない穴があったんですね。

そこから二人で Ruby, Python, Go, Node, PHP の移植をせっせとやって目処がついたのが10/2(水)〜3(木)。

開催前日10/4(金)にAMIの元になるインスタンスを用意して、結果登録管理サーバのAPI作成、ベンチツールもインターフェースを整備して管理サーバへの送信部分を作ったり……

ベンチツールにちょっと変更を入れると6実装分でチェックする必要があったのでなかなか時間は食われるし、想定外のFailを起こすことがあるとその原因を追及しないとリリースできないし、というのが面倒でしたね。

結局予選1日目用のAMIが仕上がったのが土曜日の午前3時過ぎでした。

直前の週は、(1日だけ子供を寝かしつけて寝落ちしましたが) ほぼ毎日3時ぐらいまでコードを書いていて、もうそろそろ不惑の身体にはなかなか辛かったです。

運営当日

当日は IRC で櫛井さんと @acidlemon と連絡を取りつつ、自宅でほぼ張り付き対応。土日を潰してしまって家族には申し訳ないことをしました。

AMI-id を提出してもらうことは決まっていたのですが、そのインターフェースがなかったので14時頃からせっせと管理画面を実装して18時にdeployしたり。

--workload の存在は気がつかない人多かったですね。途中でもうちょっとREADMEに親切に「負荷を変えることでスコアが伸びることがあります」とか書こうと思ったのですが、1日目と2日目で有利不利ができるとまずいのでそのままにしました。

1日目終了後、細かい不備が見つかったのでそれを直した AMI を作り直して、2日目用には別に用意することに。

2日目は終了後、とりあえず速報で暫定スコアと順位を出して終了。

予選後

週末を潰してしまったので、月曜日はさすがに有休を取って家族と買い物にいってました。

10/8(火) には公開用AMIの整備とか。

火曜日夜に提出 AMI が出そろったので、awscli を使って

  • チームごとにAMI-idを指定してインスタンス起動
  • user-data で指定されたベンチコマンドを実行する shell script を食わせて、結果を IRC チャンネルに通知

というスクリプトをぶん回してスコア確認をしました。中も見てみたかったので、2,3チームずつ run-instance して確認して terminate して、というかんじで合計3時間ぐらい。

user-dataから起動したからか、環境変数かカレントディレクトリの影響か何かでうまく動かないチームもいくつかあったので、その場合は SSH ログインして手動でベンチコマンド実行して確認しています。

10/9(水) に結果発表を行いまして、この記事を書いてなんとか予選の一連の作業をすべて終えられます。


……といってるまもなく一ヶ月後に本選がやってくるので、来週からはその準備ですね。

また本選で、よろしくお願いいたします。