概要
kagome を GAE で動かしたいってのをチラホラ耳にしてたのですが,先日ついに issue が投げられたので対応してみました. 正確には UniDic をあきらめて IPADic だけ対応してる kagome.ipadic で動かせることを確認しました.
何が問題なのか?
golang のプログラムを GAE で動かすには以下の2点の制限があります.
- GAE では unsafe, syscall, cgo を使ってると動かせない
- GAE では1ファイル32MBのサイズ制限がある
kagome を最初に作ったときは辞書を有限状態トランスデューサー(fst)で構築してて,どうしてもこいつが unsafe 使う実装になってたので対応あきらめてたんですが,なんかの時に辞書を double array trie になおして,辞書からは殆ど unsafe をなくしていたので,今回は1カ所直しただけでいけました. unsafe 使わなくてもパフォーマンスもそれほど変わるわけではないみたい・・・なのは意外でした(もちろん使った方が速いけど
これで対応できたかなと思ったんですけど,GAE には1ファイル32MBのサイズ制限があってそもそもGAEにデプロイ出来ないと教えてもらい (kaneshinさんありがとうございます),kagome から UniDic を削除した kagome.ipadic の方で対応する方針に切り替えました.
kagome.ipadic は blevesearch で「辞書重すぎで go get できんぞな」という声があって用意してたやつなんですけど,こちらに kagome の差分をバックポートして unsafe を取り除く対応しました.
ではGAE で動かしてみよう
アカウント作成
そもそも GAE の環境がなかったので,アカウント作るところからはじめました. 登録にクレカが必要ですが,試用期間があるのと試用期間後に勝手に課金しないというのを信じて登録.
SDK のダウンロード/設定
GAE/Go 用の SDK をダウンロードして設定します.
Download the App Engine SDK for Go | App Engine standard environment for Go | Google Cloud Platform
★ 注: macOS serria だと SDK がうまく動きません.VM 用意するか,Docker でやるかする必要があります.
プログラム作成
色々やり方あると思いますが,手っ取り早く $GOPATH/src 以下に myapp というフォルダ作って,そこに app.yaml と hello/hello.go を設定します. これはサンプルで用意されてるプログラムで kagome を呼ぶようにしただけの動作確認用のものです.
application: kagome-test version: 1 runtime: go api_version: go1 handlers: - url: /.* script: _go_app
package hello import ( "fmt" "net/http" "strings" "github.com/ikawaha/kagome.ipadic/tokenizer" ) var dic tokenizer.Dic func init() { http.HandleFunc("/", handler) dic = tokenizer.SysDic() } func handler(w http.ResponseWriter, r *http.Request) { t := tokenizer.NewWithDic(dic) tokens := t.Tokenize("寿司が食べたい。") for _, token := range tokens { if token.Class == tokenizer.DUMMY { fmt.Fprintf(w, "%s\n", token.Surface) continue } features := strings.Join(token.Features(), ",") fmt.Fprintf(w, "%s\t%v\n", token.Surface, features) } fmt.Fprint(w, "Hello, world!") }
まずはローカルで動かす
$ goapp serve myapp
で localhost:8080
にアクセスすると動作を確認できるはずです.
デプロイ
GAE でデプロイするために先にプロジェクトを作成して,プロジェクトIDをひかえおいて,デプロイコマンドに渡してやります.
$ goapp deploy -application <プロジェクトID> myapp
ところがどっこい動かない
デプロイしたサービスにアクセスすると....
原因はインスタンスが非力すぎること.
application: kagome-test version: 1 runtime: go api_version: go1 instance_class: B8 basic_scaling: max_instances: 1 idle_timeout: 1m handlers: - url: /.* script: _go_app
とりあえず B8 なら動く,動くぞ.(B4 あれば動きました
GAE で動かすモチベーションって何なの?
今回 GCPUG slack で kagome を GAE で動かすためのアドバイスいただいたんですが,何人かの人が過去に kagome を GAE で動かしてみようとしてくれたことを教えてくれました.そのモチベーションは何か?GAE で形態素解析するといい感じなのか?と色々想像したんですが,一番のモチベーションは「動かせるか試してみたかった」のようでした.そうですよねー.わかりますw
ということで,長いこと引っかかってた kagome を GAE で動かすアチーブメントを解放できました :p