ククログ

株式会社クリアコード > ククログ > Apache Arrowで統計情報

Apache Arrowで統計情報

Apache Arrowの開発に参加している須藤です。現時点でapache/arrowのコミット数は1位です。私はRubyでデータ処理できるようになるといいなぁと思ってApache Arrowの開発に参加し始めました。同じような人が増えるといいなぁと思ったりなにか試したりしましたが、あいかわらず、今でも実質1人でApache ArrowのRuby対応をしています。何度目かの「もっと仲間を増やさないと!」という気持ちになったので、最近の活動を紹介して仲間を増やそうと試みます。

統計情報関連のこともがんばっていたことを思い出したので紹介します。

Apache Arrowと統計情報

データフォーマットとしてのApache Arrowには統計情報は入っていません。いくつかメタデータとして任意の情報を入れられる箇所があるのでそこに統計情報を入れることもできますが、独自仕様で入れても相互運用性がなくて使いにくそうです。ということで、現状では統計情報を活用しにくいです。

そもそも、どういうときに統計情報が欲しいかというと、高速にデータ処理したいときです。たとえば、統計情報を使って高速に処理できそうな実行計画を作ることができます。Apache Arrowがやりたいことは「インメモリーデータを高速に処理したい!」なので、いい感じに統計情報を扱えるとうれしそうですよね。

Apache Arrowの高速データ処理のためのアプローチの1つはゼロコピーでのデータ交換です。モジュールAからモジュールBにデータを渡してもオーバーヘッドが小さいということです。

A →データ→ B
(オーバーヘッドが小さい==速い)

もし、Aが統計情報を持っていたとしたらそれもBに渡したいです。統計情報があるとBはより高速な実行計画を作れるかもしれないからです。

A →データ+統計情報→ B(高速な実行計画を作れるかも!)

しかし、現状は統計情報を渡す標準的な手段がないため、統計情報を渡したければ独自の方法で実現しないといけません。ということで、なにかいい感じの方法を標準化しようとしています。

Apache Arrowのデータ交換経路

実は、Apache Arrowデータを交換する方法はたくさんあります。よく使われているのはApache Arrow IPCファイルフォーマットでファイルに保存して交換する方法と、Apache Arrow IPCストリーミングフォーマットでソケット経由で交換する方法です。その他には、Apache Arrow Flight RPCというRPCフレームワークを使って交換する方法(内部的にはApache Arrow IPCストリーミングフォーマットを使っている)やApache Arrow Cデータインターフェイスで同一プロセス内で交換する方法などがあります。

それぞれの方法で適切な統計情報の交換方法が違いそうだったので、今は、Apache Arrow Cデータインターフェイスに絞って検討しています。DuckDBで使いたそうというユースケースがあったことも大きいです。検討の詳細に興味がある人はここらへんを参照してください。英語ばかりで大変でした。。。

Apache Arrow Cデータインターフェイスで統計情報

現状でどんな感じに議論が収束しているかというと、こんな感じです。

  • 統計情報を1つのApache Arrowの配列として表現しよう
  • 統計情報用のApache Arrowの配列のスキーマを標準化しよう
  • 標準化されたスキーマで表現されたApache Arrowの配列形式の統計情報をApache Arrow Cデータインターフェイスで普通のApache Arrowデータとして交換しよう

あらゆるユースケースに対応できるような統計情報を一発で標準化できる気はしないので、拡張可能な仕様になっています。たとえば、標準化された統計情報項目(たとえば「レコード数」とか)を使えるだけでなく、アプリケーション固有の統計情報項目を追加できるようになっています。

拡張可能ともちょっと違う気がするのですが、少しゆるいスキーマ定義にもなっています。たとえば、統計情報の値の型(たとえば、レコード数なら符号付き64bit整数とか)には好きな型を使っていいよとなっています。

具体的にどんなスキーマなのか気になる人は https://github.com/apache/arrow/pull/43553/files#diff-f3758fb6986ea8d24bb2e13c2feb625b68bbd6b93b3fbafd3e2a03dcdc7ba263R77-R145 あたりを読んでください。

今はこのような統計情報データを便利に使うための機能を実装しています。実装に興味がある人は https://github.com/apache/arrow/pull/44252 をどうぞ。実装してみて思ったことは、「このスキーマはコンパクトで柔軟なのはわかるけど、このスキーマのデータを作るの面倒かも。。。?」です。興味がある人はApache Arrowの開発に参加してね。

これに加えて、Apache Parquetデータについている統計情報を紐付けた状態でインメモリーのApache Arrowデータを構築できる機能も作っています。今は、数値とかタイムスタンプ値とかの統計情報だけに対応していて、他の型もおいおいという感じです。興味がある人は https://github.com/apache/arrow/issues/43549 をどうぞ。

という感じでまだ途中なんですが、これが実用的になると、Apache Arrow C++(とか、そのバインディングであるPyArrowとかRed Arrow)でApache Parquetのデータを統計情報付きで読み込んで、DuckDBに統計情報付きで渡してなんかゴニョゴニョみたいなこともできるようになるはずです。

そんな未来に興味がある人はApache Arrowの開発に参加してね!

統計情報はApache Arrow C++ではarrow::ArrayStatisticsとして表現されていますが、まだRubyから使えるようになっていません。Rubyからも使えるようにしたい人は https://github.com/apache/arrow/issues/44435 とかRed Data Toolsのチャットに来てください!実はまだPythonからも使えません。Pythonから使えるようにしたい人は https://github.com/apache/arrow/issues/44436 とかRed Data Toolsのチャットに来てください!

まとめ

そういえば、最近は統計情報もがんばっていたなということを思い出したので、Apache Arrow開発者を増やすネタとして紹介しました。仲間が増えるといいな。

Apache ArrowのRuby対応を一緒にやりたい人も、Ruby以外のApache Arrow関連のこと(統計情報まわりとか)をやりたい人もRed Data Toolsのチャットでサポートします。その気になった人は来てください!

それはそうとして、apache/arrowコミット数1位の私にApache Arrow関連のサポートを頼みたいという場合はクリアコードのApache Arrowサービスをどうぞ。