LINE Developer Days 2015に行ってきたメモ
あわせて読みたい
- 【全部入り】LINE DEVELOPER DAY_2015 Tokyo まとめまとめ #linedevday - Togetterまとめ
- LINE DEVELOPER DAY_2015 Tokyo「LINE Platform Development Chronicle」レポート #linedevday | Developers.IO
- LINE DEVELOPER DAY_2015 Tokyo「ビッグデータを活用するための分析プラットフォーム」レポート #linedevday | Developers.IO
- LINE Platform Development Chronicle by TOMU TSURUHARAさん 参加メモ
Opening CEO 出澤さん
LINEは世界でもっとも早く成長しているアプリの1つである
最初のブレークスルーは無料通話とスタンプ
1億8千万ユーザ、170億コミュニケーション以上
日本では5800万ユーザ
GameだけでなくEntertainment領域でもPlatformを作っている
LINE関連アプリで76アプリ9億ダウンロード
これからGlobalとLifeの2点においてビッグプレイヤーに対して追いつき追い抜かなければいけない
LINE Global Culture朴 CTOの話
8カ国にブランチがあり、協力して開発している。東京、福岡、大連、ソウルなどなど
Autonomous Teams
LINEが大事にしていることとして、主体的に動けるチームである、ということを目指している
Cold-caseプロジェクト
開発をしているとバックログが溜まっていくが。バックログを消化するため年に一度、未消化のバックログを集めてプロジェクトとして立ち上げる。
それをCold-Caseプロジェクトと言う。エンジニアで協力してバックログを片付ける
普通自分が経験できなかった領域のプロジェクトに参加することもできる
Remote Collaboration
遠隔地のチームと一緒に作業をするため、課題の可視化、議論の可視化が基本となる
- 色々喋っていたけどメモできず
Challenge and Contribution
機能開発をしていくにあたり、スケーラビリティやパフォーマンスを基本として考える必要がある
安定していなくてもLINEの水に合えばオープンソースを入れて、Contributeしていく
Trust & Respect
信頼と尊重がベースとなり、各自が自主的に動いていくことに価値を置いている
Trust & Respect ↓ Responsibility-basedPlanning & Self-directing Work & Peer Code Review ↓ Positive Peer Pressure & Co-worker Review
Global Player
Global Enginnerを目指す人はみなシリコンバレーに向かっている
が、シリコンバレーとの競争が激しいからこそ日本発のグローバルサービスを作っていきたい
感想
信頼をベースにしたマネジメントフリーな組織を作っている、というのはとても興味深い話だと思う。
人材の質がある程度のレベルを超えたのを揃えないと難しい話ではあるが、達成できている、ということなのかな
LINEメッセンジャー基盤の話
LINE遠征隊
現地に行って、どういう使われ方をしているのかを把握する。そのチームをLINE遠征隊と呼んでいる
開発者は様々な地域に遠征している
現地と同じネットワーク環境を整備して、スタンプの送受信とか写真の利用とかをしている
飛行機内のWifiが不安定だったので飛行機の中でテストした。
日本と海外の違いとしてモバイルネットワークの通信環境の品質差がある
IDLE → CELL_DCH → CELL_FACH
実際のメッセージの前に先にサーバにウォームアップ用のパケットを送っておくことによって3G環境下のユーザ体験を改善する
日本の場合は問題ないが、海外の低速な回線では非常に意味がある
上記の技術を3G WARMUP と呼んでいる
グローバルなメッセンジャーの特徴としてPakistanからの発信がPakistanよりもSaudiArabiaへの発信の方が多い
そういう国の事情を考慮して実装をする必要がある
スペインでAndroidのバッテリー消耗が激しいという注文が来ていた。素早く通知して欲しい、長い間待ち受けて欲しいという命題を満たす必要がある
メッセンジャーがサーバと通信する頻度を減らしたり、というような細かいチューニングを1年かけてやった
ネットワーク的な位置の近さを実現するためにPOP(Point to Peer)を設置する
LINEアプリ→Frontend→Backendという3層構造となっている
開発言語は基本的にJavaを使用しているが、POPについてはErlangを使用してPOPしている
ユーザ体験の向上について
ユーザがどう思っているのかを知らなければいけない
AppStoreやGoogle Playのレビューを集計して、ある程度定量化して調べられるようにしている
それにより改善のプロセスを早めている
イベントの送信によってイベントがあってシステムからわかるようになる
AppReviewとEvent Analyticsの2つからーザの志向を分析している
まとめ
現地に行って同じ環境を作るというエモーショナルなアプローチとアナリティクスのアプローチの両方のアプローチをとっている
感想
グローバルなサービスを作るために各国のネットワーク回線や端末品質、文化などを知っておく必要がある、という話
Erlangでfront serverを作るというのは自分には無い発想だけど、生Cで書くよりは良さそうだ。
なぜErlangなのかをもっと深掘りして話を聞いてみたい
アプリレビュー分析などは自社サービスで作らなくてもありそうな気はするけど以外と無いのが不思議
Line Platform Developer Chronicle
LINEサーバサイドの開発をしているつるはらさん
- LINEメッセージング基盤の進化
- LINE流マイクロサービス
LINEメッセージング基盤の進化の歴史について
2011年6月 リリース。開発開始から2ヶ月でリリース
Polling+Push通知の問題点として以下のような問題があった * Pushは自社でコントロールできないのでメッセージの通知が遅れる * pollingをずっとやっているので、無駄なリクエストが大量に来る
ClientとServerの間にgatewayという層を容易した
ClientがGatewayにfetchをリクエストするとGatewayはServerにたいしてコネクションを確立し、Serverからレスポンスが返ってくるのを待つ
Gateway層はnginxと拡張モジュールで層を作っている
拡張モジュールでsegmentation fault地獄におちいった
同期処理が上手くいっていなかった。共有メモリらへん?
やはり安定性に問題があったのでErlangを採用してnginxの層を置きかえた
Erlangはホットスワップ機能があり、並行性や分散性に優れるのでとても良い
LEGYという名前のLINE Event Delivery Gatewayというものを作った
2012年7月 にconnection数が多すぎるという問題になった。
Connectionにまつわる問題としてProtocolがHTTPでLong Pollingのコネクションを貼り続けている
API用コネクションもLong Polling用コネクションも必要だったのでたくさんコネクションを貼る必要があった
SPDYを採用した
ClientとLEGY間の通信が
1 Connection Multiplex ヘッダ圧縮
で行われるようになり、メリットが大きかった
2012年10月頃 に海外でのパフォーマンスを追求した。
Clientは最寄りのLEGYに接続する。LEGYは専用線でApplication Serverと接続をする
LEGY-メインサーバは距離が離れていて遅いので、LEGYは返事を待たずにClientにレスポンスを返す。それによってClient側のUXが向上する
LINEのサービスをどのように実装してきたか
スピード & 機能 & 品質を満たさなければならない
マイクロサービス的に開発をしている。モノシリックな場合、優秀な人が入ってきても全体を把握しないと開発できない。マイクロサービスとして作成し、その間をAPIなりJob Queueなりで繋いでいる
Talk-Serverはメッセージング・ソーシャルグラフの機能のみ実装している
それ以外は別のサービスとして動いていて、開発プロセスやデプロイフローもそれぞれ独自である
Talk-ServerはJava、公式アカウント系の機能はScalaなど、ものによって色々なツールを使っている
バックエンドサービス:認証管理、Abusing、Push通知、イベント処理、外部連携gateway、などなど
マイクロサービスは単にサービスを分けて開発すればいい、というものではない。組織に関する問題も一緒に考える必要がある
LINE流マイクロサービスを支える組織
組織図や会社をまたぐアドホックなチームを形成し、独立して裁量を持たせないと単にサービスを分割しただけではコミュニケーションコストが増加してしまう
チームは短期間でiterationをまわし、目的を達成したら縮小あるいは解散する
LINE流マイクロサービスを支えるプロトコル管理
Apache Thrift、Protobuf、REST
ドキュメントでAPIの仕様の定義をして、これを使ってください、というやり方もあるがそうではなくApacheThriftで仕様を定義している
Apache ThriftはIDLでのプロトコル定義から各種言語のStubを吐いてくれる
LINE流マイクロサービスを支えるファシリティ
github→Jenkins→maven repository→PMC(内製のデプロイツール)→Server→IMON(モニタリングツール)
といった開発フローが共有されている
今やっていること、今後やっていくこと
マルチデータセンター
各拠点にはフロントエンドサーバしかない。
マイクロサービスの発展
Talk-Serverの機能がふくれ上がっているのでマイクロサービス化していかなければならない
具体的なところは午後のセッションで説明する
HBaseとRedisを使った100億超/日メッセージを処理するLINEのストレージ
聞いたけどHBaseの知識が乏しく説明できる自信が無いのでパス
4年に渡るLINE Androidアプリの進化とチャレンジ
2011.4 開発開始。Androidアプリの開発経験もないが一ヶ月半でリリース
秘訣はない。試行錯誤が多い
印象にある苦労したことは デザインの適用 。デザイナが少ないため、iPhoneのデザインをAndroidに適用した。Androidは画面解像度など端末の種類が多いので、画像サイズを9-patchで適切に変更する必要があった。画面下にコントロールが集まるなど、Androidのアプリとしては違和感のある配置だった。
現在 iPhoneとAndroidでデザインが異なっている。9-patchもデザイナーがやってくれる
当初はGoole PlayのDeveloper Consoleを使っていたが以下のような問題があった
- コードを難読化しているので、クラッシュレポートが読みづらい
- クラス名などで検索したい
- BTSと連動したい
- 任意の場所でレポートしたい
特に最後の問題が重要で、そもそもクラッシュをすべきではない。不明の異常が起こった場合でもクラッシュはしないようにしたい、その場合も任意の場所でレポートさせる必要がある
そのため独自のCrash Reporting System を用意している(Treasure DataSDKなどで同様のことができそう)。専用のSDKも用意している。難読化を元に戻してからスタックトレースを投げている
ソースコードのsubmoduleによる分割
ソースコードを一箇所で管理すると、開発・運用規則などのコミュニケーションがめんどいので、gitのsubmoduleを利用してソースコードを分離した。
main repositoryから機能ごとにsubmoduleを作ることにより、コミュニケーションコストを削減した。
リリースのときと共通サブモジュールの変更のときだけ意識合わせが必要
開発進行方法 について以下のような問題があった * 同じようなクラスが作成される * チーム間で知識が共有されない
新しい機能を開発するときに、一時的なチームを作り、終わればそのメンバーは解散するようにしていた
2013年
通信方法の改善
大きな修正項目として通信方法の改善を行った(実は2012年から継続してやっていた)
接続するサーバの数が増えていった。公式アカウント、メッセージ管理、スタンプ情報などなどのサーバにアクセスする必要があったが、それぞれのサーバにコネクションを貼るのはコストが高い。
Gatewayサーバが手前に入ることになった。1つのコネクションを使い回すので簡単にリクエストを送信できる
HTTP pipeliningを使うが、1,2,3と投げたときに2番目が遅くなると3番目も合わせて遅くなる
↑説明用の写真が欲しい
SPDYは1,3,2と受けとることができる
自社製Pushサービス
Google Play Serviceを利用できない端末がある。(子供向けのらくらくフォンなど)
Google Play Serviceが使えないと → 位置情報が使えない、Google Mapが使えない、GCMが使えない
対策として自社で開発したPushサービスを利用している。状況によって、GCMと自社Push Serviceを切り替えて使用している
GCMを利用できないと判断した場合のみ自社のpush serviceを利用している
低スペック端末に対する最適化
最初はデフォルトのイメージを表示し、ダウンロードしたイメージと切りかえているが、fade inのアニメーションを使っている
低スペック端末の場合、fade inが重くスムーズに切りかわらない
CPUの速度に問題がある場合、画面効果を切り替えている
バッテリー容量に対する最適化
サーバとの通信の話をしていたがメモできず
現在 開発メンバー:22名 ソースコード量:437000行 コミット:200 commits/week
ビッグデータを活用するための分析プラットフォーム
データ分析について
- Collecting(集約)
- リーズナブルなデータの収集
- 大量データの保持
- Reporting(報告)
- 柔軟なデータの集計
- わかりやすいチャートでの可視化
- Analyzing(分析)
- 簡便で高速なデータの抽出
異なるニーズ
- エンジニアの声
- UIなんてどうでもいい
- 生のデータに触りたい
- プランナーの声
- KPI
- きれいなグラフで見たい
- Excelでダウンロードできる
Forエンジニア
サーバ→LogCollector→[Realtimeanalyzing(Norikia)→Notification Dashboard] →[Data lake(Hadoop)→ Query UI]
LogCollector = Fluentd
Norikra(リアルタイム集計処理システム)
Shib/ShibUI(Webベースのクエリツール)
Forプランナー
- データを可視化
- データのダウンロード
- NoSQL
Hadoop
大規模分散データ処理環境
Hive/Presto: PrestoはHiveより高速なのでBIツールのバックエンドに使用している
PrestogresというPrestoをPostgresのように見えるコネクタを使っている
DWHはInfiniDBを使っている いまいち何でだっけというのがわからん
InfiniDBはカラム型分散データベースで、フロントエンドからはMySQLとして認識される
BIツール
IBM Cognosを使っている。レポートオーサリングツール
ヒートマップのような複雑なものも作れる
Pentaho:OLAP型の多次元分析システム
重要視すること
- データはなるべく隠蔽する
- ユーザトラッキングはしない ユーザ数が多すぎて苦労の割にメリットがないのでやっていない
グローバル化で見えてきた課題
- サービスの変化
- グローバル化
- 多様化
- 長寿化
- 人の変化
- プランナーの増加
結果的にKPIが増加する
サービス x メジャー x ディメンションで種類が爆増してしまう。
KPIが増加し、忙しくなる → 誰もKPIをつぶさに見なくなる
KPIなんて人手で見なくても良い。KPIの変化を伝えることをツールでサポートしてあげれば良い
KPIモニタリングシステムを開発している
- すべてのKPIのトレンド分析の自動化
- 時系列から予測値を算出する
- 異常値を検出してアラート
Spark Clusterを使っている
- KPIの時系列データを分析して予測モデルを構築し、Kafkaに保存する
- 予測値と実際値を比較し、大幅に異なる場合通知する
まとめ
Akka ActorとAMQPで作るLINEメッセージングパイプライン
LINEのメッセージングとは * 人と人(一般アカウントと一般アカウント) * 人とシステム(一般アカウントと公式アカウント)
公式アカウントはたくさん友達がいて、一気にブロードキャストする必要がある
なのでトラフィックがバーストしやすい
LINEメッセージングパイプライン
デバイス -> Talk -> Fethcher -> 受信キュー → Pusher → 外部システム ← FanOut← 送信キュー ← APIサーバ ← 外部システム
- 1: 受信キュー(RabbitMQ) AMQPを使っている
- 2: Pusher
- 3: FanOut
メッセージングならではの要件として * 送信した順序で受信側に到達しなければならない
通常のProducer/Workerパターンだと処理順序が保証されない。そこで1Q1C(1 Queue 1 Consumer)という構成にしなければならない
Consumerが死ぬとキューが溜まりつづけるのでFailOverする必要がある。
AMQP ACK
これからの話としてAMQPの仕組みとして↓のような状態遷移をするという前提知識が必要
実装例
* メッセージキュー(3) * コンシュマー(4) * コーディネーションキュー(キューの名前を入れる)
コンシュマーはコーディネーションキューからメッセージキューの名前を取りにいく。このとき、コンシュマーはackを返さないであえてキューデータの状態をunackedのままにする。
特定のコンシュマーがダウンした時にキューデータがunlockされるので空いたメッセージキューが待機中のconsumerに割り振られる
課題 スループットの改善
micro batch処理をしていたがstreaming処理に変更した
並行プログラミングがあるが、職人芸的なやり方になるのでScalaのAkkaを使った
Akkaのアクターモデルについて
actorがmailboxをもっていて、順に処理していく
古くからあるthread and lockingだと定期的にlockingしないといけないから大変
有限ステートマシンとしてのアクター
- Receive Functionの切り替えが可能
- 内部ステートを引き継ぎつつ、状況に応じて異なる動作を定義できる
- 複雑なメッセージフローを
Supervisorによるエラー処理フローの分離
Akka ActorによるPusherの実装
後で説明を埋める
メッセージ送信をFIFOからラウンドロビンに変更する
ネットワークのQOSのラウンドロビンと同じものを実装している
なぜ非同期技術が重要なのか
- マイクロサービスの採用によりサービス間通信の重要性が高まった
- 同期サービスは連鎖的な障害が起きやすい