#概略
H2O にちょっと手を加えて、爆速 (希望的観測) な OpenStreetMap のタイルサーバを作りました。
#背景
私は今、おしごとで OpenStreetmap (以下 OSM) の地図を使ったサービスを作っている。
ところで、OSM は規約上、
- 商用アプリとかでは http://openstreetmap.org でホストされている地図に直接アクセスしないでね。
というタテマエになっているので、真面目にやるなら、自前でタイルサーバを立てなければいけない。
ちなみに、「タイルサーバ」というのは
- 地図のデータ (今の話では OSM のサイトからダウンロードする) をデータベースに落として
- 細かく分けた領域ごとに .png 画像にお絵かきして
- HTTP(S) でサーブする
というお仕事を担う、用途特化した HTTP サーバのことだ。
モチベーション
私は真面目なので (本当だよ) 今作っているサービスでも自前のタイルサーバを立てている。しかし遅い。
遅い理由はだいたい2つぐらいあって:
- ハードウェアがしょっぼい
- Apache + タイル用モジュールといういかにももっさりな (印象論です) ソフトを使っている
(1.) はどうしょうもないとして、(2.) はもうちょっとなんとかしたい、というのが動機だ。
おっちゃんが開発を始めた時は、ほぼこれしか選択肢がなかったのである。
今は、node.js やら nginx やらをベースにしたものがいっぱいあるので、今から同じようなものを再発明するのは明らかにダメな方針なのだが、でも、せっかく H2O という面白そうな HTTP 実装が出てきたし、なんかやってみたいやん?
もしかしたら node や nginx のイケてる実装をさらに outperform する可能性がゼロではないし。
というのが本当の動機だ。
#目標
すでにお絵かきされた地図画像を、爆速でサーブすることを目指す。
「爆速」とは、具体的には node や nginx やらのイケてる実装を超えること。
まだお絵かきされていない画像の on-demand でのレンダリング速度は、それほど気にしない。レンダリングはどうやたって遅いのだ。
#方針
H2O のソースをいじくる。いじくり方としては
- 改変部分はできるだけ別のソースに分ける
- どうしても本家のソースに手を入れねばならん所は、
#ifdef
で囲む
とした。
いじくるポイントは主に3つで:
- 地図画像のURL「のように見える」リクエストをパーズして、ファイルシステム上の物理的な画像のパスに書き換える
- (1.) の画像が存在しなければ、お絵かきライブラリ (Mapnik) にレンダリングの仕事を投げる
-
.conf
の directive に、Mapnik の設定に必要な物を追加実装する (フォントやスタイルファイルのパスなど)
#実装
GitHub に現状のものを置いた。注意点として:
-
tile
ブランチ が、ここで紹介した実装だ -
master
は、今のところ 本家の H2O そのまま でそっとしておいている
よって、中身を見たい人は git checkout tile
すること。
#現状 (げんじつ)
今のところ、おそらく作った本人しかビルドできない & 使えない 程度のクオリチーだと思う。
タイルサーバを毎日スクラッチから立まくっているようなマニアなら別かもしれないが...
これは、今後ゆっくりとドキュメント等を整備していく。明日から絶対がんばる。本当だよ。
また、おっちゃんは意識が低いので、今のところテストを書いていない。
「動かしたらなんかそれっぽい地図が出るしええやん」で済ませてしまっている。
これもそのうちがんばる。本当だよ。
#デモ
とりあえず、動作するデモをたててみた: http://a.tile.michisuji.com:8080/
地図がでてくるだけで、「だから何?」って感じだが、「レスポンスヘッダにちゃんと h2o
の名前が入っている」とかそういうとこで作者の気持ちを読み取りましょう。
サーバは AWS の t2.micro (いちばんしょぼいの) なので、そこまで爆速さを感じないかもしれないが、仮想 1コア でもまあまあ動く、というところで作者の気持ちを読み取りましょう。
ハイエンド環境のスポンサーを誰かやってくれてもいいんだよ?バーチャル・スシぐらいならおごりますよ?
#謝辞
@kazuho さんをはじめ、本家 H2O 開発者の皆様、および OpenStreetMap のコントリビュータの皆様に感謝いたします。