$30 off During Our Annual Pro Sale. View Details »

Presto Connector を自作した話

nel215
July 19, 2016

Presto Connector を自作した話

nel215

July 19, 2016
Tweet

More Decks by nel215

Other Decks in Programming

Transcript

  1. Topics • なぜ Connector を作るに至ったか • Connector について • Plugin

    Architecture • どのように実装/テストしたか • まとめ
  2. なぜ Connector を作るに至ったか • デバイスからデータを集約して可視化・分析したい • 扱うデータの規模が大きくなってきた • e.g.) 200,000~

    devices • Hadoop サービスは提供していない • オブジェクトストレージは提供している • Presto / Spark 等からバックエンドとしての 活用を検討 • 自社オブジェクトストレージ向けの Presto Connector を作成・検証
  3. 自作した Connector の概要 • Metadata の操作と SELECT のみ実装 • バージョンは

    0.147 • 負荷検証のみで運用はしていない Coordinator Client Connector Worker オブジェクト ストレージ implemented 設定ファイル resource
  4. Plugin Overview Plugin Connector Factory Connector Connector SplitManager Connector RecordSetProvider

    Connector Metadata getService() create() getRecordSetProvider() Connector Transaction Handle beginTransaction() … getSplitManager() getMetadata() https://github.com/prestodb/presto/blob/0.147/presto-spi/src/main/java/com/facebook/presto/spi/Plugin.java
  5. Plugin Overview Tips ① • ドキュメント • 9. Developer Guide

    (https://prestodb.io/docs/current/develop.html) • しかし “This interface is too big to list in this documentation” なのでソースを読む必要がある • Deprecated Interface • Deprecated: com.facebook.presto.spi.Connector • New: com.facebook.presto.spi.connector.Connector • Warning は出るので心配ないかと思いきや…
  6. Plugin Overview Tips ② • プリセットされている Connector を参考にする場合 • Deprecated

    Interface を 利用しているConnectorがある • Redis Connector, Mongo Connector, etc. • ドキュメントでは下記をおすすめしている • Example HTTP Connector • Cassandra Connector
  7. SELECT を実装するには • SELECT には下記の実装が必要 • ConnectorMetadata • Schema や

    Table の情報を扱う • ConnectorSplitManager • DataSource にリクエストする情報を扱う ConnectorSplit を生成する • ConnectorRecordSetProvider • 実際に DataSource にリクエストする RecordSet を生成する • ConnectorTransactionHandle • トランザクションに関する情報を扱う
  8. Table Scan Flow Connector SplitManager Connector RecordSetProvider Connector Metadata Data

    Source RecordSet getRecordSet() request data Connector SplitSource Connector Split getSplits() 0..* Config request table layout Connector TableLayout getTableLayout() request data locations Data Source API
  9. Table Scan Flow Connector SplitManager Connector RecordSetProvider Connector Metadata Data

    Source RecordSet getRecordSet() request data Connector SplitSource Connector Split getSplits() 0..* Config request table layout Connector TableLayout getTableLayout() request data locations Data Source API
  10. ConnectorMetadata ① • 設定ファイル や Data Source の API, Presto

    本体から渡って来た情報を 元に Metadata を生成する Connector Metadata Connector TableLayout getTableLayout() Data Source Config Data Source API List<String> Connector TableHandle … listSchemaNames() getTableHandle() request metadata
  11. ConnectorMetadata ② • Presto からは MetadataManager 経由で呼ばれる • 例: https://github.com/prestodb/presto/blob/0.147/presto-

    main/src/main/java/com/facebook/presto/sql/planner/optimizations/MetadataQueryOptimizer.java#L142 • どの Metadata をどこから取得するかが重要 • 設定ファイル, API, etc. • Schema 一覧は設定ファイルで Table 一覧は API 経由という形にもできる Connector Metadata Metadata Manager getLayout() presto-main planner.* getTableLayout() Connector TableLayout presto-spi
  12. Table Scan Flow Connector SplitManager Connector RecordSetProvider Connector Metadata Data

    Source RecordSet getRecordSet() request data Connector SplitSource Connector Split getSplits() 0..* Config request table layout Connector TableLayout getTableLayout() request data locations Data Source API
  13. ConnectorSplitManager ~ ConnectorSplit ① • ConnectorSplitManager • ConnectorSplit を ConnectorTableLayout

    から生成 • ConnectorTableLayout には うまく split するための情報を入れておく • ConnectorSplit • データソースにリクエストするための情報 Connector SplitManager Connector SplitSource Connector Split 0..* Connector TableLayout Data Source block1 block2 block3 know request locations getSplits()
  14. ConnectorSplitManager ~ ConnectorSplit ② • Presto からは Planner で利用される •

    https://github.com/prestodb/presto/blob/0.147/presto- main/src/main/java/com/facebook/presto/sql/planner/DistributedExecutionPlanner.java#L112 • 設計ポイントはデータの配置 • Split して並列アクセスできるように配置する • オブジェクトストレージであれば キーのフォーマット Connector SplitManager Distributed Execution Planner SplitManager getSplits() getSplits() presto-spi presto-main
  15. Table Scan Flow Connector SplitManager Connector RecordSetProvider Connector Metadata Data

    Source RecordSet getRecordSet() request data Connector SplitSource Connector Split getSplits() 0..* Config request table layout Connector TableLayout getTableLayout() request data locations Data Source API
  16. Data Source RecordSetProvider ~ RecordSetCursor ① • RecordSet は ConnectorSplit

    から生成 • RecordCursor を生成する際に 実際にデータを取得する Connector RecordSetProvider RecordSet Record Cursor getRecordSet() cursor() Connector Split block1 block2 block3 know request data
  17. RecordSetProvider ~ RecordSetCursor ② • データに含まれるレコードを advanceNextPosition() で読み進める • 設計ポイント

    • データの大きさ • データフォーマット Record Cursor block1 row1 row2 row3 advance advanceNextPosition()
  18. RecordSetProvider ~ RecordSetCursor ③ • ConnectorPageSourceProvider 経由で TableScanOperator から利用される •

    https://github.com/prestodb/presto/blob/0.147/presto-main/src/main/java/com/facebook/presto/operator/TableScanOperator. java#L268 • ConnectorPageSourceProvider を直接実装しても良い • 両方実装した場合は ConnectorPageSourceProvider が優先される Connector PageSourceProvider TableScan Operator PageSource Manager createPageSource() presto-spi presto-main Connector RecordSetProvider createPageSource()
  19. Table Scan Flow Connector SplitManager Connector RecordSetProvider Connector Metadata Data

    Source RecordSet getRecordSet() request data Connector SplitSource Connector Split getSplits() 0..* Config request table layout Connector TableLayout getTableLayout() request data locations Data Source API
  20. どのように実装したか • DataSource からどのようにデータを取得するかがキモ • RecordSetProvider ~ RecordSetCursor から着手 •

    DataSource との連携を確認しながらの テストが書きやすい • その後 SplitManager ~ Metadata と 扱うデータがメタになっていく方向で実装した • その他細かいクラスが必要になるが 特段難しいところは無い • データソースにアクセスするクライアント • 設定ファイルを扱うクラス etc.
  21. 設計ポイント • データの配置 • うまく Split できるようにする • オブジェクトストレージであればキーの設計 •

    ファイルフォーマットとデータサイズ • Metadataの取り扱い • Schema, Table をどのように定義するか • 設定ファイルから取得 • 外部リソースからAPI 経由で取得 etc.
  22. テストについて • 開発環境と CI 環境にDockerで ストレージのモックを立ち上げ • lphoward/fake-s3 etc. •

    Integration Test • AbstractTestDistributedQueries • DDL も含めた Query が定義されている • SELECT のみ実装したため利用せず • 負荷検証はBig Data Benchmark を利用 • https://amplab.cs.berkeley.edu/benchmark/ • 既存のベンチマーク結果があり比較できる
  23. はまったポイント • 意外とはまらなかった • ドキュメントがない • ソースを読むことになるが コメントもあまりない • 負荷検証時に

    discover に失敗することがあった • task.max-worker-threads を下げると安定 • データ依存なので Presto 一般のチューニング
  24. Summary • Connector を自作 • 自社オブジェクトストレージ向け • Connector Plugin について紹介

    • Metadata の操作 • SELECT の実装 • 実装方針やテストについて共有 • ドキュメントがない以外は書きやすい