東京Node学園祭2015に登壇してきました!

東京Node学園祭2015に登壇してきました!

はじめに

リクルートテクノロジーズの伊藤です。
私は今年4月(2015年4月)にリクルートホールディングスに入社し、3ヶ月の研修を経て、7月にリクルートテクノロジーズへと配属されました。
今はAPソリューションGでPush通知基盤Pusna-RSの運用開発に取り組んでいます。
Pusna-RSはNode.jsで開発されたスマホアプリ向けの大規模Push通知基盤で、詳しくはこの記事をご覧ください。
今回はこのPusna-RSについて、2015年11月7日の東京Node学園祭2015にて

「Node.js v0.8からv4.xへのバージョンアップ ~大規模Push通知基盤の運用事例~」

というタイトルで発表してきたので、その報告と裏話を少しだけしたいと思います。

東京Node学園祭って?

東京Node学園祭はNode.js日本ユーザグループが主催する日本最大規模のNode.jsのカンファレンスです。
Node界の紅白みたいなものです。
今年はNode.jsのコミュニティの中心にいるDomenic Denicola(@domenic), Rod Vagg(@rvagg), Kat Marchan(@maybekatz)などの超豪華なゲストを迎え開催されました。
私たちリクルートグループもスポンサーとして毎年参加しており、過去には同じくAPソリューションGの髙林さん(私の教育担当になっていただいてます!)が登壇しています。

登壇の経緯

東京Node学園祭はNode界の紅白みたいなものと書きました。
じゃあここで登壇する伊藤というのは紅白レベルのNode使いなのかというと、
全くそんなことはなく
むしろ素人に近い部類です。
自分がNode.jsを本格的に触り始めたのは今の部署に配属されてからで、それまではJavaやCなどの一般的なプログラミング言語しか触ったことがありませんでした。
配属されてから、つまり7月下旬くらいからNode.jsを勉強し始め、ようやくちょっとだけ書けるようになってきたかな、と思っていた時にこの登壇の話が舞い込んできました。
そんな自分がなぜ登壇することになったのかというと、下のメールを見てみてください。
髙林(@tatakaba)さんとAPソリューショングループのマネージャーの宮川(@m_nori)さんのやり取りです。

脳DE.jsが何かは気になるところですが、ともかくある日会社に来てPCを開けたらこの2通のメールが来ていて、自分は東京Node学園祭に登壇することになっていました。
しかも最初はLT(Lightning Talk)の予定だったのに、気がつくと本セッションへの登壇になっていました。
こうして登壇が決まり、宮川さんや髙林さん、また、某ASGの技術顧問といった錚々たるメンバーにレビューや監修、技術的なアドバイスをうけつつ、準備を行いました。

  • 発表の様子
    発表の様子

  • 懇親会ではNode.jsのロゴが入ったケーキが登場!
    懇親会ではNode.jsのロゴが入ったケーキが登場!

発表したこと

スライドは以下にアップしてありますので、補完しながら話します。

Node.jsv0.8からv4.xへのバージョンアップ ~大規模Push通知基盤の運用事例~ from Recruit Technologies

アップデートのタイミングについて

Pusna-RSは2年前に作られたシステムでNode.js v0.8.24で作られています。
当時すでにv0.10系が出ていましたが、あえてv0.8系を採用したのには様々な理由があり、そのひとつがStreamです。
スライドの中でも触れていますが、v0.10系のStreamはStream2と呼ばれ、v0.8系の実装とは互換性の面で様々な問題があり、
すでに実装済みのコードをStream2に改修するコストや安定性の観点から、Pusna-RSではv0.8系で開発を続けることになりました。
その後、Stream1と完全な互換性のあるStream3が実装されましたが、当時Node.jsとIo.jsが分裂するなど、コミュニティの動きが不安定であったため、アップデートの機会を逸していました。
また、Pusna-RSはすでにリクルートグループの大部分のモバイルアプリで用いられており、一瞬たりとも停止させることができないシステムです。
そのような中で、安定稼動しているシステムを大胆にアップデートするきっかけをつかめずにいましたが、
Node.jsとIo.jsの統合とLTSプランの発表、また、iOSのhttp/2.0対応などの要因が重なり、具体的に計画を立てることが出来るようになりました。

実際にアップデートでおこなったこと

この話はスライドにはあまり盛り込んでいませんが、もちろんNode.js v0.8.24をv4.2に上げたことによるコードの修正はある程度発生しています。
特に、Elasticsearchのクライアントライブラリとして、Pusna-RSではelasticalというnpmパッケージを採用していましたが、
このelasticalがNode.js v4.xでは動かなくなってしまいました。
elasticalが依存しているnpmパッケージのバージョンが古く、Node.js v4.xに対応していなかったことが原因でしたが、
幸いElasticsearchの公式のnpmパッケージがリリースされていましたので、それに置き換えました。
それ以外にも主にネットワーク周りのパッケージが特に修正を要したように感じました。
Node.jsのコミットの履歴をたどってみると、v0.8系からv4.x系にかけてネットワーク周りで内部的にかなり多くの修正が入っていることがわかります。
その影響で、メンテナンスされていないネットワーク系のnpmパッケージは軒並み動作しなくなっていました。

また、Stream以外にもPusna-RSではパフォーマンスを上げるために各種の独自実装を行っています。
例えば、httpのソケットを管理するhttp.Agentモジュールを独自実装し、細かいオプションをとれるように拡張し、Node.jsのCoreで提供されているものよりも高いスループットと安定性を達成しています。
しかし、Streamと同じくこういった機能の多くがv4.x系になり標準実装に取り込まれています。
こういった独自実装も保守性の観点から積極的に標準実装に置き換えています。
上記のhttp.Agentも独自実装から標準実装に置き換え、(若干のパフォーマンスの劣化があるものの)同様の動作をしていることを確認しています。

今後に向けて

スライドの終盤でも触れていますが、Node.js v4.xに移行したことにより、スループットの劣化が起きています。
npmパッケージの問題であったり、上記のようにPusna-RSに最適化された独自実装を標準実装に修正したことであったりと、様々な要因があり、
現在は、その検証やパフォーマンスのチューニング、また、どうしてもスループットの低下が起きてしまう場合はそれが本当に許容できない程度のものなのかを判断しています。
また、それ以外にも積極的に新技術を取り入れていくという文脈で、例えばasyncのnpmモジュールをPromiseに置き換えたり、
underscoreをlodashに置き換えたり、あるいはNodeSourceのプロダクトを検証してみたりといった様々な取り組みをしています。

まとめ

新卒のエンジニアが大して詳しくもないNode.jsのアップデートと発表を無茶振りされ、
様々な方の協力を得ながらなんとかやり切りました。

今回はNode.jsに話を絞りましたが、Pusna-RSではそれ以外にも様々な新技術やリクルートテクノロジーズならではの工夫が用いられています。
それらは来る12月のElastic{ON}で同じPusna-RSチームの中原さんが話してくれると思います。

アップデート計画、あるいはPusna-RSそのものについて何か大きな進展がありましたらまた報告したいと思います!

それでは失礼します。