isuconアプリを書いてみましたシリーズ。
生でOpenresty+Luaで書いても良かったんですが
せっかくなのでLapisというWebフレームワークを使ってみました。
実は自分も初触り。
最初にLapisの概要など
LuaのWebアプリケーションフレームワークです。*1
バックエンドはOpenresty(Nginx)を利用しています。既に速そうな感じがしますね…!
WebFrameworkBenchmarksでも割と上位にいます。
Lapis、実は生のLuaスクリプトではなく moonscript で書くのを推奨しているようです。
JavaScriptにおけるCoffeeScriptのようなものですね。
構文も似ているのでJS書いている人には取っ付き易いかもしれません。
isucon4 Lapis版ソースコード
こちら。
https://github.com/toritori0318/isucon4
また、Gistにitamaeレシピを置いておきました。
こちらを実行すると Openresty+Luarocks+Lapis がインストールされますので
試したい方はお使いください。
# itamaeインストール gem install itamae # レシピダウンロード wget https://gist.githubusercontent.com/toritori0318/2f2e080f906dbbbd0dea/raw/b0de3d7e8ece81fc81514b074e49549d0975da16/isucon4_lapis_recipe.rb # レシピ実行 itamae ssh isucon4_lapis_recipe.rb -h xxx.xxx.xxx.xxx -u ec2-user -i /path/to/aws.pem
isucon4 Lapisバージョンを動かすための手順
1. isucon4アプリを上記ソースコードに置き換えます
2. /etc/supervisord.confのminfdsを増やしておき、 service supervisord restart を実行します。
[supervisord] logfile=/tmp/supervisord.log loglevel=info pidfile=/var/run/supervisord.pid nodaemon=false minfds=100000 minprocs=200
3. /etc/supervisord.confに以下を追記し、supervisorctl reload を実行します。
[program:isucon_lua] directory=/home/isucon/webapp/lua command=/opt/openresty/nginx/sbin/nginx -p /home/isucon/webapp/lua -c "nginx.conf.compiled" #command=/home/isucon/env.sh /usr/bin/lapis server production user=isucon environment=LAPIS_OPENRESTY="/opt/openresty",PATH="/opt/openresty/nginx/sbin:$PATH" stdout_logfile=/tmp/isucon.lua.log stderr_logfile=/tmp/isucon.lua.log autostart=true
ベンチマーク
kazeburoさんの "ISUCON4 予選でアプリケーションを変更せずに予選通過ラインを突破するの術" を参考にし、
サーバに対してほぼ同じ修正をした後のベンチマークです。
perlアプリケーション(kazeburoさんversion)で実行
$ ./benchmarker bench --workload 8 18:17:59 type:info message:launch benchmarker 18:17:59 type:warning message:Result not sent to server because API key is not set 18:17:59 type:info message:init environment 18:18:07 type:info message:run benchmark workload: 8 18:19:07 type:info message:finish benchmark workload: 8 18:19:12 type:info message:check banned ips and locked users report 18:19:15 type:report count:banned ips value:593 18:19:15 type:report count:locked users value:4357 18:19:15 type:info message:Result not sent to server because API key is not set 18:19:15 type:score success:186360 fail:0 score:40258
Lapisアプリケーションで実行
$ ./benchmarker bench --workload 8 18:54:06 type:info message:launch benchmarker 18:54:06 type:warning message:Result not sent to server because API key is not set 18:54:06 type:info message:init environment 18:54:14 type:info message:run benchmark workload: 8 18:55:14 type:info message:finish benchmark workload: 8 18:55:19 type:info message:check banned ips and locked users report 18:55:22 type:report count:banned ips value:859 18:55:22 type:report count:locked users value:4747 18:55:22 type:info message:Result not sent to server because API key is not set 18:55:22 type:score success:221580 fail:0 score:47865
やはり速かった。
Lapis雑感
全体的につらい方が多い :(
つらい点
実例が少ない
Lapis(Lua)自体のユーザ数が少ないこともあり、ノウハウ的な情報はほぼ皆無です。
自力で頑張る必要があるでしょう。
Webに情報が少ない公式ドキュメント以外は情報少ないというかほぼ皆無です。
自力で頑張る必要があるでしょう。
エコシステムが弱い
そもそも便利ライブラリが少ない、またはメンテされていないのが多いので
普通のWebアプリケーションを作ろうとした時につらいです。
自力で頑張る必要があるでしょう。
MySQL非対応
PostgreSQLはバッチリ対応していますが、現時点で何故かMySQLは非対応です。
Pull Requestはされているようなのでその内当たるかも。
しかも現時点ではそのまま利用しようとすると動かないバグがあるので
1行パッチを当てる必要があります。(こちらのレシピでもパッチを実行しています)
良い点
Openrestyの遺産が使える
普通にngxの情報にアクセスできますし、Openrestyのライブラリも使えます。
これは結構な利点だと思います。
速い
パフォーマンスはだいぶ良いので
単純なアプリでパフォーマンスが必要であれば
選択肢として考えてもよいかもしれません。
まとめ
Lapisでisucon4予選問題アプリを書いてみました。
実際のWebアプリケーションを作るにはだいぶ茨の道だと思いますが
LLのように書ける割には速いですし
isuconのような一発アプリに使うのはアリかなと思いました。
またLua/MoonScript、実際書いてみるとわかるのですが
構文はJavaScript/CoffeeScriptに似ている部分があるので
実は(書くだけであれば)そんなに違和感なく書けたりします。
Go速いけどまだちょっと手を出しにくい…という人には
割とマッチするかもしれません。
ぼくはオススメはしませんが!!!