ククログ

株式会社クリアコード > ククログ > Apache ArrowでAzure Blob Storage上のデータを読み書き

Apache ArrowでAzure Blob Storage上のデータを読み書き

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

1年とか半年とか前の話になりますがAzure Blob Storage関連のこともがんばっていたことを思い出したので紹介します。

Apache Arrowとオブジェクトストレージ

Apache Arrowがデータフォマートのことだけに注力しているならどこにデータが置かれているかに関してなにかすることは範囲外のことになりますが、Apache Arrowはデータフォーマットに限らず大量データを高速に処理することに取り組んでいるのでどこにデータが置かれているかについても対応しています。

Apache Arrowが想定しているデータは大量データなので、大量のデータを置く場所が必要になることが多いです。どこに置くかというと、最近はオブジェクトストレージに置くことが増えている感じがします。比較的安価で大量のデータを扱えるからです。オブジェクトストレージ上にあるデータを直接処理するクエリーエンジンも増えている気がします。

よく使われているオブジェクトストレージサービスにはAmazon Web ServicesのS3や、Google CloudのCloud StorageやMicrosoft AzureのAzure Blob Storageなどがあります。いろいろな選択肢はあるのはよいことですが、それぞれAPIが違うため、簡単に乗り換えることはできません。そこで、各種オブジェクトストレージサービスのAPIを抽象化して統一したAPIで扱えるようにするライブラリーがあります。直接特定のオブジェクトストレージサービス用のAPIを使わず、抽象化されたAPIを使うことで、開発コストを抑えたままポータビリティを高めることができます。RDBMSに対して行われていることと同じですね。

Apache Arrowが提供するライブラリーでもそのような各種オブジェクトストレージサービスのAPIを抽象化した機能を提供しています。Rust実装ではobject_store crateがそれで、C++実装およびそのバインディング(Rubyバインディングも含む)では、filesystem APIがそれです。Apache Arrow以外でもPythonのfsspecなどは同じ機能を提供しています。

余談:C++実装は「ファイルシステム」として抽象化していますが、Rust実装では「オブジェクトストレージ」として抽象化しています。「オブジェクトストレージ」の方が「ファイルシステム」よりも必要な機能は少ないのですが、実際の用途では「オブジェクトストレージ」レベルの抽象化で十分かも?という話があります。(dev@arrow.apache.arrowでそういう話があったはずなんだけど見つからない。。。)実際、オブジェクトストレージをベースに「ファイルシステム」を実現しようとすると難しいとかコストが高いとかムリじゃね?という機能もある(あった気がする)ので、「オブジェクトストレージ」レベルの抽象化で十分ならそっちでがんばった方がいいかもしれません。

Apache Arrow C++とAzure Blob Storage

C++実装ではS3とCloud StorageとAzure Blob Storageに対応しています。最初にS3に対応し、その後Cloud Storageに対応し、さらにその後にAzure Blob Storageに対応しました。

Azure Blob Storage対応への要望は前からありましたが、なかなか継続的に取り組む人が現れずに進んでいませんでした。しかし、去年の夏くらいから継続的に取り組んでくれる人が現れて徐々に対応が進みました。当初は私はレビューとそれに付属してこの変更も試してもらえます?くらいのコードを書くレベルで開発に関わっていましたが、去年の冬くらいから私も機能の実装に参加し始めました。

今年の4月にリリースされたApache Arrow 16.0.0から、まぁ、だいたい使えるよね、くらいになって、7月にリリースされた17.0.0やそろそろリリースされる18.0.0にもちょいちょい改良が入っています。18.0.0からはRubyからも使えるようになる予定です。18.0.0からはArrow::Table.load(URI("abfs://#{account}.blob/core.windows.net/#{container}/test.parquet"))とかで直接Azure Blob Storage上のApache ParquetデータをApache Arrowオブジェクトとしてロードしたり、それをtable.save(URI("gcs://#{bucket}/test.parquet"))でCloud StorageにApache Parquet形式で保存したりできるようになります。

オブジェクトストレージを使う場合、いかにAPI呼び出し回数を減らすかとか並列に処理するか(並列にアップロードとか)とかがパフォーマンスに大きな影響を与えやすいです。まだ、そこらへんの最適化はあまり入っていないので、ここらへんに興味がある人はぜひ取り組んでみてください。

いろいろissueがあった気がするんですけど、今ざっと見たらGH-40035くらいしか見つからないですね。。。S3/Cloud Storageバックエンドでやっている最適化がAzure Blob Systemバックエンドではやっていないということもある気がするので、そういうのを確認してissueにして取り組むのもアリです。

まとめ

そういえば、ちょっと前はAzure Blob Storage関連もがんばっていたなということを思い出したので、Apache Arrow開発者を増やすネタとして紹介しました。仲間が増えるといいな。

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

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