Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

如何に “データが壊れない” 管理画面を作るか - 管理画面開発の裏側

3.308 visualizaciones

Publicado el

JJUG CCC 2018 Spring
http://www.java-users.jp/ccc2018spring/#/session/d0f5a2c8-0186-4bf2-a0fd-f6e4ec1fa9a2

#jjug_ccc #ccc_a5

Publicado en: Ingeniería
  • Sé el primero en comentar

如何に “データが壊れない” 管理画面を作るか - 管理画面開発の裏側

  1. 1. 如何に“データが壊れ ない” 管理画面を作る か kjim @ JJUG CCC 2018 Spring 2018/05/26
  2. 2. Who I am: ● 村石 恵示 (Keiji Muraishi / @kjim) ● Software Engineer, Ads ● 2014/09 SmartNews 入社 ● 変遷 ○ SIer 1.5 years ○ TowersQuest 2.0 years ○ Freelance 3.5 years ○ IIJ 2.0 years ○ SmartNews 3.8 years (now!)
  3. 3. http://about.smartnews.com/ja/2018/05/10/20180510/
  4. 4. Agenda: ● SmartNews Ads の紹介 ● SmartNews Ads システム外観 ● Ad Frontend ● データにまつわる話 ● Productivity を保つ実装への落とし方
  5. 5. Agenda: ● SmartNews Ads の紹介 ● SmartNews Ads システム外観 ● Ad Frontend ● データにまつわる話 ● Productivity を保つ実装への落とし方
  6. 6. Sma w A s from 2014/12
  7. 7. Sma w A s http://static.smartnews.com/smartnews-ads/key_mediaguide_smartnews.pdf
  8. 8. SmartNews Ads テクノロジーの力で「Ads as Content」の実現を 目指す広告プラットフォーム
  9. 9. Sma w A s こんなことができます: ● SmartNews アプリへの広告配信 ○ 運用型 / 純広型 ● ターゲティング ○ ユーザー属性によって広告配信先をコントロールする ● 入札価格の自動調整 - oCPC ○ ユーザに合わせてアルゴリズムが入札価格を自動的に最適化し、効果的 に広告を配信 (https://markezine.jp/article/detail/26204)
  10. 10. Sy em O v e Agenda: ● SmartNews Ads の紹介 ● SmartNews Ads システム外観 ● Ad Frontend ● データにまつわる話 ● Productivity を保つ実装への落とし方
  11. 11. Sy em O v e 端折って単純化したりしてますが、大体こんな感じです Ad Server Ad DMP Ad Frontend
  12. 12. 今日、お話すること
  13. 13. Ad Frontend SmartNews Ads の機能にアクセスするための広 告管理コンソール
  14. 14. Add full width photo/video here! Cover up this placeholder with an image that touches the right/left sides and colored top bar Ad F o t いい感じのスクショを貼る Ad Frontend - 広告管理コンソール
  15. 15. といっても、 今日は画面の話というより もデータに着目した話をし ます。
  16. 16. Ad F o t Ad Frontend: ● 広告の出稿にまつわるあらゆる機能にアクセ スするための広告管理コンソール ● 画面だけでなく、広告代理店向けの API も 持っている ● SmartNews Ads システムの Hub 役 ○ ユーザーとシステムの Hub として ○ コンポーネント間の Hub として
  17. 17. Ad F o t 汚すのは一点: ● 広告配信プラットフォームは多様なコンポーネ ントで構成されている ○ AdServer, DMP, Tracking, AdFrontend, etc… ● 必然的にコンポーネント間の接続点が発生す る ○ どのコンポーネントがどこに接続するべきかという問題が生じる ● SmartNews Ads では、汚れ役を立ててそれ以 外を clean に保つという設計をしている 汚れ役としての Ad Frontend
  18. 18. Ad F o t 汚れ役としての二つの役割: ● サブコンポーンエント間の接続点の仲介 ○ 管理画面は多様なコンポーネントの機能を利用して「統合されたコ ントローラ」として機能する ○ 管理画面はそもそも多くのコンポーネントに接続する必要がある ● データを利用しやすい形で正確に保つ ○ データの入力側で正確なデータが担保されていれば、そのデータ の利用側は不必要な例外条件を考えなくて良くなる ○ データの利用側は、ある機能が “機能する” ための最低限の validation だけを意識すれば良い
  19. 19. Ad F o t 1. コンポーネント間の仲介: ● 接続点が増えるとメンテコストはどうしても上が る ○ システム全体としての変更耐性が下がる ○ 変更耐性が下がるとプロダクトの productivity に影響する ○ 接続点には必ず制約(仕様)が存在し、その一つの制約を複数のコンポー ネントが把握するというのはコストが高い作業である ● SmartNews Ads では、基本、直接の依存コン ポーネントを極力減らすという判断で作ってる
  20. 20. Ad F o t Mesh or Line? Mesh Line Ad Server Ad Frontend DMP Ad Server Ad Frontend DMP ● Ad Server と DMP は直 接の依存関係を作らない ● 両者の制約を吸収すること によって互いの進化のス ピードを落とさない ● Hub があることで、例え ば、機能実装の世代交代に 柔軟に対応できる
  21. 21. Agenda: ● SmartNews Ads の紹介 ● SmartNews Ads システム外観 ● Ad Frontend ● データにまつわる話 ● Productivity を保つ実装への落とし方
  22. 22. The Data SmartNews Ads における データにまつわる話
  23. 23. The データは誰が決める? ● SmartNews Ads の場合、”広告配信” に最適 なデータ構造は何か? が出発点 ○ AdServer が出発点 ● 管理画面の開発は、その設計を Follow する 形で始まった ここで問題が生じる
  24. 24. The 解く問題が異なる: ● Ad Server 大量の広告リクエストを、どのようにして効果を 最大化しつつ高速に捌くか ● Ad Frontend 広告データを、どのように直感的かつ平易な UI で正しく作れるようにするか 広告出稿までの業務フローの中でシステムを どのように介在させるか
  25. 25. 解くべき問題が異なれば必要 になるデータも異なる
  26. 26. example 1 “審査ステータス” と “有効フラグ”
  27. 27. 審査ステータス: The ● 広告の審査状態を管理する ● 審査OKの広告のみ配信できる ● 審査ステータスは広告審査の業務ルールに よって状態管理される ○ 審査業務に依存するデータである ○ この業務ルールは広告主や審査オペレータのためのものであり、 配信にも影響すべきデータである ○ 業務ルールは変更されうるデータである
  28. 28. The 審査ステータス: ステータス 配信可否 未審査 × 審査待ち × 審査OK ◯ 審査NG ×
  29. 29. 審査ステータス: Ad Server The ● 広告の審査状態を管理する ● 審査OKの広告のみ配信できる ● 審査ステータスは広告審査の業務ルールに よって状態管理される ○ 審査業務に依存するデータである ○ この業務ルールは広告主や審査オペレータのためのものであり、本質的 には配信に影響するデータである ○ 業務ルールは変更されうるデータである
  30. 30. Ad Server を変更されうる データに依存させることに なる
  31. 31. The “有効フラグ” の登場: ● Ad Server からは審査のビジネスルールに依 存したデータ参照を失くしたい ○ それによって、審査業務の変更耐性を上げることができる ● 審査ステータスに従属し管理される “有効フラ グ” を作って、Ad Server はこれに依存させる ○ Ad Server は単に ON か OFF を見れば良くなり、その背後にあるビジネ スから切り離すことができる ● “審査ステータス” と “有効フラグ” のデータは Ad Frontend が責任を持つ
  32. 32. 依存性を閉じ込めて 全体としての複雑性を 下げる
  33. 33. example 2 ユーザー定義オーディエンス (aka. Custom Audience)
  34. 34. The Custom Audience とは? “広告主が有するさまざまなユーザー情報を活用 し、SmartNews Adsにおいてターゲットとする ユーザーの条件を自在に組み合わせることがで きる機能” http://about.smartnews.com/ja/2016/03/07/20160307customaudience/
  35. 35. The 例えば: ● A という商品ページを閲覧したことのあ るユーザーにだけ広告を配信したい ● B というアプリを既にダウンロードした ユーザーは除外して広告を配信したい
  36. 36. The アーキテクチャ: ● Tracker ○ 外部 Signal(Event) を集める ● Ad Frontend ○ ユーザー定義オーディエンスを定義する ● Ad DMP ○ ユーザー定義オーディエンスと Tracker の Signal か らオーディエンスの実体を計算する ● Ad Server ○ オーディエンスの実体を利用して広告を配信する
  37. 37. The データの性格に着目: ● イベントソースが多様である ○ 過去に広告配信したことのある... A の Page にアクセスしたことのある... B というアプリをインストールしたことのある... etc… ● “自在に組み合わせる” ○ オーディエンス定義に Composability が要求される ● データ仕様が拡張される RDB のテーブル定義に マッピングするのは適さない類のデータ
  38. 38. Document Format: The ● Database には Document 形式 (JSON) で持 つようにすることによって動的性と拡張性を柔 軟に担保できるようにする ● もちろん、この判断はタダではなく、データ定義 の複雑性と正確性をきちんとコントロールする 必要が生じる ● そもそも、誰がデータを定義するかという問題 もある (Database は単なる箱と化すので)
  39. 39. The Productivity を優先する: ● 僕らのようなスタートアップにとってスピードは 非常に大事 ● 完璧を求める時間は無駄であり、割り切りとい う判断が必要 ● Document 形式を定義するのは DMP ○ そのデータの本質的なユーザーである ○ Ad Frontend はそのデータを Follow する関係
  40. 40. “Done is better than Perfect”
  41. 41. The 対処すべき問題: ● 拡張性を犠牲にしない ○ 足が遅くなってしまっては、なぜこのデータ形式を選択したのか分からなく なってしまう ● データの互換性には十分気を付けなければい けない ○ 拡張性の高さによって、新たに実装される Custom Audience 定義が発 生した時に、操作できなくとも壊れない状態にする必要性がある ● データを守るのは Ad Frontend の至上命題
  42. 42. Ad Frontend The 実装戦略: 中間モデルを作る Business Logic Ad DMPAurora SerDeLib (partofAdDMP) Converter 1. データベースの Raw データを Ad DMP の SerDe Lib を使って変換 2. [1] の結果を Ad Frontend の SerDe 実装を使っ て都合の良い中間モデルに変換 3. 画面との API はこの中間モデルを利用する
  43. 43. The 実装戦略: ● 中間モデルとRawモデルの相互変換実装は特 にしっかりとテストを書く ● エラーハンドリング処理をこの一点に集約する ○ 仮に、Ad Frontend が未知のデータを受け取ったとしても想定内エラーと して扱うようにする ● 仮に未知のデータを受け取ったとしても、その データへの操作をできなくして、データが不正 状態で更新されることを防ぐ
  44. 44. Agenda: ● SmartNews Ads の紹介 ● SmartNews Ads システム外観 ● Ad Frontend ● データにまつわる話 ● Productivity を保つ実装への落とし方
  45. 45. 機動性と安全性を 両立する 実装への落とし方
  46. 46. 原則 低レイヤーに行く程にルールをより強く強制する ことができる “蛇口よりも元栓”
  47. 47. Lay Ar it re Frontend (client) Layers: Controller Service Repository Datastore 右に行く程にデータに対するルールの 強制力は強くなる
  48. 48. Lay Ar it re Trade off: (LEFT) Front-side Store-side (RIGHT) Pros: ● (開発初期において) Productivity を高く保つこ とができる Pros: ● あらゆるデータ処理で制約 違反しないように考慮して実 装しなければいけない ● データを保全することが本質 的に難しくなる Pros: ● 強制力の強い制約条件を課 すことができる Pros: ● 拡張性と柔軟性 (Productivity) が 犠牲になる
  49. 49. Lay Ar it re Frontend (client) Layers: Controller Service Repository Datastore この図でもう一つ 言えることがあります
  50. 50. Lay Ar it re Frontend (client) Layers: Controller Service Repository Datastore 右に行く程にパフォーマンスチューニン グの余地が拡がる
  51. 51. Lay Ar it re Frontend (client) Layers: Ad Frontend の場合 Controller Service Repository Datastore Datastore の手前にデータ制約の 最終防衛ラインを敷く Repository ↓ Resource
  52. 52. Lay Ar it re 最終防衛ライン: ● Productivity を保ちつつ ● おかしなデータが渡された場合 ○ 更新せずに無視する ○ 例外状態にする といった挙動を実装することによって、デー タが保全されるようにコントロールすること ができる
  53. 53. Lay Ar it re 最終防衛ライン: ● Datastore に近い場所に防衛ラインを引くこと で、より Primitive なデータ管理が可能になる ● 一度に多くのことを考える必要がなくなる 制約ロジックの実装がシンプルになる
  54. 54. Lay Ar it re データ操作の3要素: ● Model ○ データモデル ● Resource ○ データモデルを Datastore に対して操作 するための API を提供 ● Query ○ データ操作の実装を提供
  55. 55. Resource Layer QueryQuery Lay Ar it re Resource Layer: ResourceService Query SQL ORM API Call Datastore (Database) External Component
  56. 56. Resource Layer データ操作の抽象度を保ちつつ、 そうしたくなったら 低レベルな実装にもすることができる
  57. 57. Lay Ar it re Resource ONLY: trait FooResource { def get(id: ID): Seq[Foo] def update(id: ID, foo: Foo): Int } ● Resource の api call のタイミングが操作の 実行タイミングと同期されてしまう ● 仮に update に特別なモードで処理させたい 場合、引数を追加するか、新たにメソッドを生 やすしかない
  58. 58. Resource だけでは 柔軟な API を表現 できない
  59. 59. Query データの集合を表すインタフェース表現で クエリの実行結果を抽象化して遅延実行や その他の表現力と拡張性を追加する
  60. 60. Lay Ar it re 二つの Query 定義: // for refer trait Query[T] extends Iterable[T] { def iterator(): Iterator[T] } // for update trait UpdateQuery[T] { def apply(): Query[T] }
  61. 61. Resource + Query
  62. 62. Lay Ar it re Resource meets Query: trait FooResource { def get(id: ID): Query[Foo] } ● Resource の api call のタイミングとクエリ実 行は切り離される
  63. 63. Lay Ar it re Resource meets Query: trait ExUpdateFooQuery extends UpdateQuery[ID] { def withSpecialSomething(): ExUpdateQuery } trait FooResource { def update(id: ID, foo: Foo): ExUpdateFooQuery } ● UpdateQuery で不十分なら互換性を保ちつ つ追加の API を生やす表現力が加わる
  64. 64. Lay Ar it re Resource + Query: ● 実体が欲しい時にはいつでも要求できる ● Query 取得後、実体が必要なければ余計なク エリ実行のコストを省くこともできる ● Query の結果を memory 上に cache した Query を返すこともできる ○ そして Interface は何も変わらないので同じように扱うことができる ● Query 自体を拡張した独自の Query を定義 すれば独自の API を生やすこともできる
  65. 65. Lay Ar it re Resource meets Query: trait FooQuery extends Query[Foo] { def partialize(): FooQuery } trait FooResource { def get(id: ID): FooQuery } // usage resource.get(“3838”).partialize()
  66. 66. Query データの集合を表すインタフェース表現で クエリの実行結果を抽象化して遅延実行や その他の表現力と拡張性を追加する API 表現に柔軟性と拡張性を持たせつつ、 統一的なインタフェースを提供する
  67. 67. Conclusion Con s o ● SmartNews Ads のシステム全体と Hub としての Ad Frontend ● データを利用するコンポーネントの依存関係を 適切にコントロールし、不用意に依存関係を増 やさない ● 機動性と安全性を両立する実装としての Resource + Query
  68. 68. Thank you! https://bit.ly/sn-eng-jobs

×