株式会社クリアコード > ククログ

ククログ


フリーソフトウェアの法人向けサポートの一環で行った開発元へのフィードバックの事例紹介

当社の法人向けサポートサービスでは、企業のお客様がフリーソフトウェアを使われていて遭遇されたトラブルの解決や原因究明、文書化されていない技術情報の調査などを有償にて行っています。「特殊な労働力を提供してお客様の役に立ち、その対価としてお金を頂く」ということで、ビジネスモデルとしてはシンプルです。

ところで、当社の理念は「自由と稼ぐの両立」です。前述のビジネスモデルから「稼ぐ」は容易に読み取れますが、これがどのように「自由」に繋がっているかは見えにくいかもしれません。

まず単純に、「ユーザーが増える事が自由なソフトウェアの推進になる」という事が言えます。それは「そのソフトウェアを使うと開発チームに広告収入が入る」といった直接的な還元に限りません。例えば、そのソフトウェアのユーザーが増えると、業界内でのそのソフトウェアの影響力が増すので、プロプライエタリな製品にとってはそのデータ形式やプロトコルを無視しにくくなり、ユーザーが特定の製品に囲い込まれるリスクが低減する、という効果が期待できるでしょう。

また、こちらがこの記事の本題なのですが、このビジネスの中で実際の使用環境で見つかった不具合を報告したり、実際の使用環境でのニーズを汲み取った提案をしたりという形で、そのソフトウェアの改善に寄与できます

ということで、以下、Mozilla製品の法人向けサポート由来のフィードバックの事例を4つご紹介します。

Bug 1540943 - Broken message body on forwarding a mail including invalid character(Mozilla Thunderbird)

これは、メールの本文にエンコーディング上不正な文字が含まれていると転送メールの本文が文字化けしてしまうという問題です。法人利用では様々なメールが頻繁に・大量にやり取りされるため、このような「普通は起こらないエッジケース」が起こる事があり、また、それがビジネス上の支障になってしまう場合もあります。この現象に遭遇されたお客さまの場合、取引先からのメールを転送しようとすると文字化けしてしまうという事でお困りでした。

原因と回避策を調査した結果、本文として転送する場合には発生を避けられない問題である事が分かったため、お客さまには「添付として転送」などの別の操作を使って回避して頂く事をお薦めし、開発元には上記のBugの通り、その時点で判明していた発生条件などの情報を報告しました。

その後、開発者の方の目に留めて頂き調査が進んで、最終的にはソースコード中の1行をピンポイントで修正(呼び出す関数を変更)して問題を解消するパッチが投入されました。変更点が少なかった事から、この修正はThunderbird 60のメンテナンスリリースにも反映される結果となっています。

Bug 1563665 - Replied mails are not marked as "replied" if the folder has a comma (,) in its substance file name(Mozilla Thunderbird)

これは、メールフォルダに対応するローカルディスク上のファイルの名前に , (半角コンマ)が含まれているとそのフォルダ内のメールに返信などの操作をしても「返信済み」のようなマークが付かないという問題です。Thunderbirdではメールフォルダ1つがディスク上の1ファイルとなるmbox形式が初期設定となっており、ファイル名はフォルダ名そのままではなくMUTF-7という特殊なエンコーディング方式で英数字に変換されているのですが、台北 のような特定の文字列で変換結果が &U,BTFw- となり , が含まれる事になって、全く予想もしていなかった所でこの不具合に遭遇してしまう場合があるという状況でした。

お客さまには、MUTF-7でのエンコーディング結果に , が含まれないようにフォルダ名を工夫するという回避策をご案内していますが、どんな文字列がエンコーディング後にこのパターンになるのかについては事前の予想が難しいため、残念ながら万全とは言えない回答となってしまいました。

この問題は原因そのものは判明したものの、古くからある設計上の判断に起因する問題ということで、どのような方向で対処するのが妥当かという技術的判断の落とし所が見つかるまで、修正にはまだしばらく時間がかかりそうです。

Bug 1569089 - The "-version" ("-v") command line option doesn't report version information when using cmd.exe(Mozilla Firefox)

これは、Firefoxの起動オプションの一部が特定の状況下で動作しなくなっているという問題です。Firefoxは実は firefox.exe -v という風に -v オプションを指定して起動すると一般的なコマンドと同様にバージョン情報を文字列として出力するようになっており、これを使って現在インストール済みのFirefoxのバージョンを確認するという運用を取られているお客さまがいらっしゃったのですが、FirefoxをESR68に更新するとバージョン情報が出力されなくなったために運用に支障が生じている、という事でお問い合わせを頂きました。

調査の結果、Bugに記載しているとおりこの問題そのものは回避が不可能という事が分かったため、Firefoxのバージョンを調べるには何かしら別の方法*1を使わなくてはならない旨をお客さまにはお伝えしました。

-v はあまり使われる事の無さそうなオプションで、我々も正直な所、今回の調査を行うまでオプションの存在自体を把握していませんでした。しかし、報告したBugは優先度P2 (クリティカルな問題に対して付けられる P1 の次に高い優先度)と設定されています。本稿執筆時点では未解決ですが、もしかしたら案外早く修正される事になるかもしれません。

Add managed storage support (Duplicate Tabs Closer)

こちらはFirefox本体ではなくアドオンへの改善提案です。「Duplicate Tabs Closer」は同じURLのタブを重複して開く事を制限するアドオンで、重複の検出基準や検出時の挙動について様々な設定ができるようになっています。しかしながら、それらの設定値はローカルストレージ領域を使って保存されており、システム管理者の側では設定を制御できません。ですので、法人利用であらかじめ動作を決めておきたい場合、アドオンのソースコードを編集して組み込みの初期設定を変更する必要があります。

お問い合わせを頂いたお客さまの導入環境向けにそのように改造する事自体は容易ですが、提供開始後にアドオンが更新されたらそれへの追従の必要が生じます。また、その後同様のニーズをお持ちのお客さまから相談を頂く度に改造版を作る必要もあります。

その一方、Firefoxのアドオン向けAPIにはManaged Storageという機能があり、専用のファイルもしくはポリシー設定用の policies.json に書いた設定をアドオン側で読み取る事ができます。もしDuplicate Tabs CloserがManaged Storageに対応していれば、アドオンのソースコードを毎回編集する必要はありません。

以上の事を踏まえて、Managed Storageから設定値を読み込んで反映するという動作を追加する変更を提案した物が、上記のプルリクエストです。こちらは作者の方のご理解を得る事ができ、無事にマージして頂けました。

法人向けサポートからアップストリームへフィードバックする事の意義

アップストリームへのフィードバックは開発の現場に直接関わる事に等しいため、的確なフィードバックには様々な知識が必要になってきます。FirefoxやThunderbirdのように「ソフトウェア開発者でないエンドユーザーも使う物」ではこの点がネックとなりがちなためか、ユーザー自身によってなされた報告にはどうしても、不正確な報告や発生条件の絞り込みが不足した報告が散見されます。また、多くの日本人にとっては英語自体がハードルとなって余計にフィードバックしにくいという問題もあります。当社が法人サポートの中で行っているフィードバックは、これらの点を補ってフリーソフトウェアを推進していく物と言えます。

ビジネス的観点においても、アップストリームへのフィードバックには意義があります。問題点をそのプロダクトの開発元にフィードバックしないで手元での回避だけを行っていると、プロダクトの更新や変更でその回避策が取れなくなる恐れがあり、将来的なリスク要因になります。早め早めにフィードバックしてプロダクト本体側で問題を解決する事によって、その種のリスクが低減され、より安定して運用できるようになる事が期待できます*2。安物買いの銭失いにならなければ、それはサービスの付加価値と言えます。

そうしてプロダクト自体の品質が高まって企業で採用しやすくなると、法人向けサポートの需要の拡大にも期待できます。また、当社内でフィードバック対象のプロダクトへの理解が深まり知見が増えれば、それだけサービスの品質が向上します。

開発プロジェクトにとっても、ユーザーとなるお客さまにとっても、サポートを提供する当社にとっても利益になるという事で、これは「自由と稼ぐの両立」という理念の1つの実践例となっているわけです。

まとめ

以上、当社が法人向けサポートサービスを通じて行ったフィードバックの例を挙げて、会社の理念をどのように実践しているかをご紹介しました。

当社の法人向けサポート事業はいわゆるSI業界の周辺にあり、直接の取引先やその先のお客さまには「お堅い」業界の会社さまも多くあります。そのような業界はオープンさ・自由さと縁遠いという印象を持つ方が多いかもしれませんが、実際にはその内側ではフリーソフトウェアが使われていることは珍しくありません。やり方次第ではその領域のビジネスと自由なソフトウェアの推進を同時に行えるという事例の1つとして、参考にして頂ければ幸いです。

また、業務上でのフリーソフトウェアの使用においてトラブルに遭遇されていて、フリーソフトウェア製品やプロジェクト側の知識の不足でお困りの企業の担当者さまがいらっしゃいましたら、お問い合わせフォームよりお問い合わせ下さい。

*1 Windowsのレジストリの情報を参照する方法が一般的です。

*2 理論上、そうして問題が解消されていった先には全く仕事が無くなるという未来がいずれ訪れる事になりますが、実際にはプロダクトもユーザー側の要件も変化し続けるため、そのような未来がすぐに訪れるという事は、幸か不幸かまだ無さそうです。

2019-09-09

GitLab Runnerを使ったサポートコストの低減

GitLabでCI/CDを行う場合は、GitLabに組み込みのGitLab CI/CDを使用できます。
GitLab CI/CDは、GitLab上のコミットを検知して、GitLab Runnerが指定されたジョブを実行するという仕組みで動いています。

この時に使用されているGitLab RunnerというツールはGitLabからは独立しており、自前のホストにもインストールし実行できます。そのため、これを使ってWindows環境でのCI/CDを簡単に構築できます。

弊社のGroongaのサポートサービスを利用されているお客様の中には、Windows環境でGroongaを動かしているお客様もいらっしゃり、Windows環境でのビルドやテストも実施する必要があります。

以前は、お客様向けのWindowsパッケージを自社のWindows環境へインストールし、テストスクリプトを流して、問題なければリリースノートを書いて提供するという作業フローでした。
しかし、この作業フローではパッケージのインストールやテストスクリプトの実行は手作業で実施しているため、効率が悪いという問題がありました。
また、これらの手順は提供直前に実施していたため、この時点で問題が発覚するとお客様へパッケージ提供が遅れてしまうというリスクも孕んでいました。

GitLab RunnerはWindowsにも簡単にインストールできます。また、GitLab CIは定期的にジョブを実行することができるため、毎晩その時点の最新のGroongaを使って、お客様向けのパッケージをビルドおよびテストするようにもできます。

これらを実施したことにより、手作業で実行する作業がリリースノートの作成のみになり、パッケージ提供までの時間を短縮できました。
また、毎晩テストを実施するので問題を早期に発見しやすくなり、提供前に慌てて修正するというようなことがなくなりました。

では、具体的にどのようにWindow環境でのCI/CDを構築したかを以下に記載します。


インストール
  1. まずは、GitLab Runnerのバイナリーを格納するディレクトリーを作成します。

  2. 公式サイトからGitLab Runnerのバイナリーをダウンロードして、1で作成したディレクトリーに格納します。
    ダウンロードURLは https://docs.gitlab.com/runner/install/windows.html#installation に記載があります。

  3. 格納したバイナリーのファイル名をgitlab-runner.exeにリネームします。

  4. 管理者権限でコマンドプロンプトまたは、PowerShellを実行し、以下のコマンドを実行して、対象のプロジェクトにGitLab Runnerを登録します。

    ./gitlab-runner.exe register
    

    上記のコマンドを実行すると、いくつか質問されるので、順に回答を入力していきます。

    まずは、以下のように対象のGitLabプロジェクトのURLを聞かれるので、対象のプロジェクトのURLを入力します。

    Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
    

    次に gitlab-ci トークンを聞かれるので、入力します。

    gitlab-ci トークンは、GitLabの対象のプロジェクトのSettings -> CI/CD -> Runners の "Set up a specific Runner manually" に記載されています。

    Please enter the gitlab-ci token for this runner
    

    次に登録するGitLab Runnerの説明を記載します。

    Please enter the gitlab-ci description for this runner
    

    次に登録するGitLab Runnerにタグをつけます。

    Please enter the gitlab-ci tags for this runner (comma separated):
    

    次にExecuterを指定します。
    弊社で使用しているテストスクリプトはPowerShellで動くため、shellを指定しました。

    Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
    
  5. 管理者権限でコマンドプロンプトまたは、PowerShellを実行し、以下のコマンドを実行して、WindowsサービスとしてGitLab Runnerをインストールします。

    .\gitlab-runner.exe install
    .\gitlab-runner.exe start
    
  6. GitLabの対象のプロジェクトのページを開いて、Settings -> CI/CD -> Runnersに上記手順で登録したGitLab Runnerが表示されていれば、インストール完了です。

WindowsへのGitLab Runnerのインストールは、以下の公式ドキュメントにも記載されています。

https://docs.gitlab.com/runner/install/windows.html

ジョブの作成

GitLab Runnerに実行させたいジョブは、.gitlab-ci.ymlというファイルにYAML形式で記述し対象のリポジトリのトップレベルにpushします。
この例では、Executorshellを選択したので、実行するスクリプトはWindowsバッチで記述しています。

.gitlab-ci.ymlをpushすると、以後、コミットを契機に.gitlab-ci.ymlに記述したスクリプトがGitLab Runnerをインストールしたホスト上で実行されます。

ジョブの定期実行

ジョブは、リポジトリへのコミットのみを契機に実行されるだけではなく、定期的に実行することもできます。
定期的に実行するには、以下のように実施します。

対象プロジェクトのページを開いて CD/CI -> Schedulesを選択します。
"Scheduling Pipelines"というページに遷移するので、そこで、New scheduleボタンを押下します。

以下の項目を入力する画面に遷移するので、それぞれ適切な値を設定します。

  • Description
    • この定期実行の説明を書きます
  • Interval Pattern
    • どのくらいの間隔で実行するかを指定します。
  • Cron Timezone
    • タイムゾーンを指定します。
  • Target Branch
    • どのブランチを対象にジョブを実行するかを指定します。
  • Variables
    • ある特定のジョブだけ定期的に実行したい場合や、ある特定のジョブだけ実行間隔を変えたい場合に使用します。

    • 例えば、.gitlab-ci.ymlに以下のように記述すると、このVariablesの項目にWEEKLYが指定されているスケジュールに従ってtest regressionのジョブが実行されることになり、Variablesの項目にWEEKLYが指定されていないスケジュールの実行時は、test regressionのジョブは実行されなくなります。

      "test regression":
        stage: test
        tags:
          - xxxx
        only:
          variables:
            - $WEEKLY
      

パッケージ提供のような定期的に発生する作業にかかる時間を減らすことで、別の課題に時間を使うことができ、お客様にとってもメリットになります。また、作業の過程で、GitLab Runnerの不具合を発見したので、以下の内容でアップストリームへ報告しました。

このように、クリアコードではお客さんのメリットになる作業をすると同時に、アップストリームへの問題報告やパッチ提供をして、フリーソフトウェアの推進を日常的に実施しています。

2019-09-26

Apache Arrowの最新情報(2019年9月版)

Apache ArrowPMC(Project Management Commitee、プロジェクト管理チームみたいな感じ)のメンバーの須藤です。

みなさんはApache Arrowを知っていますか?Apache Arrowは数年後にはデータ処理界隈で重要なコンポーネントになっているだろうプロジェクトです。データ処理界隈に興味がある人は知っておくと役に立つはずなので1年ほど前にApache Arrowの最新情報(2018年9月版)をまとめました。この1年ですごくよくなったので2019年9月現在の最新情報を紹介します。

私は、PMCの中では唯一の日本人*1で、コミット数は2番目に多い*2ので、日本ではApache Arrowのことをだいぶ知っている方なはずです。Apache Arrowの情報は日本語ではあまりないので日本語で紹介します。

ちなみに、英語ではいろいろ情報があります。有用な情報源はApache Arrowの公式ブログ公式メーリングリストやそれぞれの開発者のブログ・発表などです。開発者のブログの中ではUrsa Labs Blogの隔月の開発レポートがオススメです。Ursa Labsはスポンサーを集めてフルタイムでApache Arrowの開発をしている非営利の組織です。(という説明でそんなに間違っていないはず。)

この記事ではそれらの情報へのリンクも示しながら最新情報を紹介するので、ぜひ英語の情報も活用してください。

Apache Arrowが実現すること

Apache Arrowが実現することは1年前と変わっていないので、Apache Arrowの必要性から知りたいという方はApache Arrowの最新情報(2018年9月版)を参照してください。まとめると次の通りです。

Apache Arrowは効率的に大量のデータをメモリー上で処理することを目指しています。そのためにしていることは次の通りです。

  1. データ交換・高速処理しやすいApache Arrowフォーマットの仕様を定義
  2. 各種言語用のApache Arrowフォーマットを読み書きするライブラリーを開発
  3. 大量のメモリー上のデータを高速処理するためライブラリーを開発

Apache Arrowが向いている用途は次の通りです。

  • 大量データの交換
  • メモリー上での大量データの分析処理

Apache Arrowの現状

それでは、2019年9月現在、Apache Arrowのデータフォーマットの仕様と実装がどのようになっているかを説明します。

データフォーマットの仕様

データフォーマットの仕様は去年中に固められるといいねと進んでいましたが、まだ固まっていません。しかし、今年中には固まるはずです。

現時点での最新リリースは0.14.1です。10月中に0.15.0がリリースされる予定です。順調にいけば、0.15.0の次が1.0.0になります。

1.0.0をリリースする段階でデータフォーマットの仕様が固まります。固まるというのはどういうことかというと互換性が保証されるということです。

互換性には後方互換性と前方互換性があります。

後方互換性が保証されるというのは新しい実装では新しい仕様のデータだけでなく古い仕様のデータも読めるということです。

前方互換性が保証されるというのは古い実装でも新しい仕様のデータを読めるということです。もし読めなくても読めないことがわかります。中途半端に読めるとか壊れたデータとして読めるということにはなりません。

データフォーマットの互換性は大事なので、今後、仕様を変更するときは、少なくともC++とJavaで実装し、それぞれで相互に正しくやりとりできるかを確認するテストを追加しなければいけなくなりました。そのため、C++でだけ実装しやすいがJavaでは実装しづらいような仕様は入りにくくなります。少なくともC++とJavaとなっているのは今のところC++とJavaの実装が進んでいるからです。今後、他の言語での実装が進んできたらC++とJava以外も候補に入ってくるかもしれません。

参考:[DISCUSS] Format changes: process and requirements

これまで、Apache Arrowフォーマットのデータはストレージに保存するのには向いていないという扱いでした。しかし、仕様が固まったら(1.0.0がリリースされたら)データが失われる心配をせずにストレージに保存することができます。

ただし、Apache Arrowフォーマットよりもストレージ保存に向いたフォーマットはたくさんある(たとえばApache Parquet)ので、ストレージに保存したい場合は、本当にApache Arrowフォーマットが適切なのかを考えてからどのフォーマットにするかを決めてください。たとえば、ストレージにはすごく空きがあるからデータの読み込みをすごく速くしたいということであればApache Arrowフォーマットを使ってもよいでしょうが、書き込むデータ量はApache Parquetなど他のストレージ向けのフォーマットよりも大きくなりがちなので書き込み速度はそこそこ(I/Oネック)になるかもしれません。

データフォーマットのバージョン

1.0.0がリリースされたらデータフォーマットのバージョン付けにはセマンティックバージョニングを採用する予定です。つまり、互換性が壊れるような変更がなければメジャーバージョンは同じまま(1.X.Yのまま)になります。互換性がある仕様変更の場合はマイナーバージョンが上がります。1.0.0のあとに互換性のある仕様変更があったら1.1.0になります。今のところ、パッチバージョンは使う予定はありません。

今までは明示的にデータフォーマットにバージョンを振っていませんでした。振っていませんでしたが、メタデータバージョンというものがありました。これは今のところV1, V2, V3, V4があります。データフォーマットのメジャーバージョンが上がったらここに新しい値が増えます。2.0.0になったらV5が増えます。

少し紛らわしいかもしれませんが、1.0.0以降は「ライブラリーのバージョン」と「データフォーマットのバージョン」は別々に採番されます。ライブラリーのバージョンは2.0.0でデータフォーマットのバージョンは1.0.0というような状況になります。

参考:[VOTE] Adopt FORMAT and LIBRARY SemVer-based version schemes for Arrow 1.0.0

ライブラリーのバージョン

1.0.0からはライブラリーのバージョンもセマンティックバージョニングに従います。つまり、互換性が壊れるような変更があればメジャーバージョンが上がるということです。

現時点ではリリースするたびに互換性が壊れる可能性があるので毎回メジャーバージョンが上がる予定です。2ヶ月くらいごとにリリースする予定なので2ヶ月くらいに1回メジャーバージョンが上がる予定です。

ライブラリーのメジャーバージョンは頻繁に上がりますが、データフォーマットのメジャーバージョンはそんなに上がらないはずです。そのため、次のようにライブラリーのバージョンとデータフォーマットのバージョンはズレます。

  • 1.0.0の次のリリース
    • ライブラリーのバージョン:2.0.0
    • データフォーマットのバージョン:1.0.0
  • 1.0.0の次の次のリリース
    • ライブラリーのバージョン:3.0.0
    • データフォーマットのバージョン:1.0.0

Apache Arrowにはたくさんのプログラミング言語向けのライブラリーがありますが、すべてこのルールで一緒にリリースされます。

扱えるデータ

バージョンの話はこれくらいにして、Apache Arrowが扱えるデータについて説明します。基本的なデータについてはApache Arrowの最新情報(2018年9月版)を参照してください。ここではこの1年で新しく扱えるようになったデータについて説明します。

新しく次のデータを扱えるようになりました。

また、ユーザーが独自に型を追加できるようになりました。これを拡張型と呼びます。

拡張型は次のように実現しています。

  • 生データはApache Arrowが提供するプリミティブ型を使って表現する
  • 生データにメタデータを付与して追加情報を表現する

たとえば、UUID型は次のように実現します。

  • 生データは16バイトの固定長バイナリーデータ型を使って表現する
  • 生データに次のメタデータを付与
    • 拡張型名:uuid
    • UUIDのバージョン:1

この実現方法のメリットは、使っているApache Arrowのライブラリーが対象の拡張型のことを知らなくても(UUID型について知らなくても)データを扱えるという点です。対象の拡張型を知らなかったら単に生データ(UUID型ならただの16バイトの固定長バイナリーデータ)として扱えばよいからです。もちろん、その拡張型固有の操作はできませんが、要素数を数えたり、複数のデータチャンクをまとめて次のデータ処理モジュールにデータを渡すといった基本的な操作はできます。

データ処理

Apache Arrowは各種データ処理ツールが共通で使える高速なデータ処理機能の開発も重視しています。去年の時点ではデータフォーマットの方に注力していたためあまり進んでいませんでした。しかし、この1年でデータ処理部分の実装が進んでいます。

特に進んだのがC++とRustです。C++のバインディングとして実装されているPython、R、Rubyもその恩恵を受けています。

それではそれぞれの言語毎にデータ処理部分がこの1年でどう改良されたかを紹介します。去年の時点で実装されている処理についてはApache Arrowの最新情報(2018年9月版)を参照してください。

C++

C++でこの1年で実装された処理は次の通りです。

  • 指定した値と各要素の比較
    • 結果:真偽値の配列
    • 比較方法:==, !=, <, <=, >, >=
    • 例:Compare([null, 1, 2, 3], 2, >=)[null, false, true, true]
  • 非NULLの要素数のカウント
    • 結果:要素数(数値)
    • 例:Count([null, 1, 2, 3])3
  • 真偽値配列による要素の選択
    • 結果:対応する真偽値配列の要素が偽ではない要素の部分だけが残った配列
    • 例:Filter([null, 1, 2, 3], [true, false, null, true])[null, null, 3]
  • 値ごとの要素数のカウント
    • 結果:構造体({"Values": 入力の配列と同じ型, "Counts": 64ビット整数})の配列
    • 例:ValueCounts([null, "a", "b", "a"])[{"Value": "a", "Counts": 2}, {"Value": "b", "Counts": 1}]
  • 対象の配列の中に指定した配列にある要素が含まれているか
    • 結果:真偽値の配列
    • 例:IsIn([null, 1, 2, 3], [1, 3])[null, true, false, true]
  • 算術平均(NULLを無視)
    • 結果:平均値(64bit浮動小数点数)
    • 例:Mean([null, 1, 2, 3])2.0
  • ソートし、ソート後の各要素がソート前は何番目の要素だったかを返す(NULLは最後になる)
    • 結果:64bit整数の配列
    • 例:SortToIndices([null, 3, 1, 2])[2, 3, 1, 0]
  • 合計(NULLを無視)
    • 結果:合計値(64bit整数または64bit非負整数または64bit浮動小数点数)
    • 例:Sum([null, 1, -2, 3])2
  • 配列から指定したインデックスの要素を抽出
    • 結果:対応する要素だけが残った配列
    • 例:Take([null, "a", "b", "c"], [2, null, 1])["b", null, "a"]

さらにGandivaという名前の式コンパイラーが取り込まれました。Apache Arrowの最新情報(2018年9月版)の段階で取り込まれようとしていたものが正式に取り込まれたということです。

前述の処理は配列単位の処理ですが、Gandivaはレコードバッチ(レコードの集合)に対する処理を扱います。たとえば、「record.column1 > 100 && record.column2 == "XXX"」のような処理を扱います。このような処理をLLVMを使って実行時にネイティブコードにコンパイルしてから実行するので高速に式を評価できます。

Gandivaは単に条件で絞り込むような簡単な式だけでなく、SQLで記述できるような集約処理や条件分岐(CASE相当)などの複雑な式も扱います。

参考:Gandiva: A LLVM-based Analytical Expression Compiler for Apache Arrow | Apache Arrow

現時点でGandivaはC++だけでなくJava、Python、Rubyから使えます。

現時点では前述の配列単位の処理(内部では計算カーネルと呼んでいます)とGandivaは特に連携していません。算術演算のような基本的な処理はどちらにもあります。では、どうやって使い分けるのかが気になりますね。おそらく、次のような使い分けになるでしょう。

  • 中間結果(最終結果じゃない)のレコードバッチの処理:Gandiva
    • 例:レコードのフィルター
  • 最終結果を生成する処理:計算カーネル
    • 例:合計値の計算

参考:Compute kernels and Gandiva operators

もう少し先になると、ユーザーはもう少し高レベルのAPIを使うことができるようになるはずです。どこかからデータを読み込み、読み込みながら指定したクエリーでデータを絞り込めるようなAPIです。

データ読み込み処理はデータセットAPIとして実装が始まっています。

今のところローカルにあるApache Parquetフォーマットのデータだけ読み込めますが、今後、CSVやJSONフォーマットのデータも読み込めるようになったり、S3上のファイルなどリモートにあるデータも読み込めるようになる予定です。条件のプッシュダウン(指定した条件のデータだけ読み込む)も対応します。プッシュダウンなしで、読み込んだ後に不要なデータを捨てる方法もありますが、それよりも、そもそも読まない方が圧倒的に高速なのです。

参考:

読み込んだデータはクエリーエンジンで処理できるようになる予定です。クエリーエンジンは内部で計算カーネルやGandivaを利用して効率的に処理します。

参考:

ユーザーがより扱いやすいAPIとしてデータフレームAPIも実装する予定です。

参考:

楽しみですね!

Rust

Rustでこの1年で実装された処理は次の通りです。

  • 要素ごとの算術演算(SIMD対応)
  • 要素ごとの論理演算(AND・OR・NOT)
  • 要素ごとの比較(SIMD対応)
  • キャスト(型の変換)
  • 配列から指定したインデックスの要素を抽出
  • 時刻配列の各要素を時間(hour)に変換

Rustでもクエリーエンジンの実装が始まりました。DataFusionという名前です。

C++のクエリーエンジンはSQLなど特定のフロントエンドを用意しない*3設計*4ですが、DataFusionにはSQLのフロントエンドがあります。

まだ簡単なSQLしか処理しかできませんが、より複雑なSQLも処理できるように開発を進めています。

参考:DataFusion: A Rust-native Query Engine for Apache Arrow | Apache Arrow

この1年でRustのApache Parquet実装がApache Arrowに取り込まれたので、Apache Parquetフォーマットのデータもデータソースとして扱えます。

現時点ではすべてRustで実装していますが、どうにかしてGandivaとつなげられないかという検討もしています。

参考:[DISCUSS] [Gandiva] Adding query plan to Gandiva protobuf definition

DataFusionの開発をしている@andygrove73はDataFusionベースの分散計算プラットフォームBallistaの開発をはじめました。PoCのプロジェクトだそうなので、ここでの実験の成果がDataFusionに還元されていくのだと思います。

データ処理のまとめ

データ処理まわりについては、この1年で特に進んだC++実装とRust実装を紹介しました。

Arrow Flight - 高速RPCシステム

この1年Arrow FlightというApache Arrowベースの高速RPCシステムの開発が始まりました。gRPCベースのプロトコルですが、できるだけ高速になるように設計されています。たとえば、データのコピーができるだけ少なくなるようになっています。

ここでもう少しArrow Flightについて紹介できればよかったのですが、私がまだ触っていないのでそんなに説明できることがありません。残念。

Java実装を主に実装したDremioの人たちが書いたArrow Flightの記事Understanding Apache Arrow Flightもあるのですが、ちょっとこれだけだとピンとこないと思います。

現時点でArrow Flightを使えるのはC++とJavaとPythonです。

来年にはRubyでも使えるようにして紹介できるようにしたいな。

追記:Apache Arrow Flightの日本語情報を公開

各言語での実装の完成度

各言語での実装の完成度もApache Arrowの最新情報(2018年9月版)からの差分を紹介します。

まず、次の言語が増えました。

  • C#
  • R
  • MATLAB

C#はネイティブ実装で、RとMATLABはC++実装のバインディングです。

C#実装は基本的な型にだいたい対応しています。前述の新しく扱えるようになったデータはまだ対応していません。NuGetでインストールできます。

参考:NuGet Gallery | Apache.Arrow

R実装はかなりC++実装をカバーしています。Python実装やRuby実装ほどではありませんが、完成度が高めです。Apache Parquetの読み込みもサポートしました。RからApache Parquetを読み込めるとうれしい人が多いはずです。CRANからインストールできます。

参考:CRAN - Package arrow

MATLAB実装はFeatherフォーマットを読み書きできるだけです。今後、開発が活発になるかどうかはよくわかりません。

Apache Arrow利用者

Apache Arrowの利用者が増えています。

TensorFlowはApahche Arrowフォーマットのデータをデータセットとして使えるようにしました。

参考:TensorFlow with Apache Arrow Datasets

BigQuery Storage APIもApache Arrowフォーマットのデータをサポートしました。

参考:

PG-StromというPostgreSQLの拡張モジュールもApache Arrowフォーマットのデータをサポートしました。PG-StromはGPUを使って高速にデータ処理するための拡張モジュールです。PG-Stromの関連モジュールとしてArrow_Fdwがあり、これを使うとストレージに置いてあるApache ArrowフォーマットのデータをPostgreSQLから読み込めます。読み込んだデータはPG-Stromで高速に処理できます。

参考:PostgreSQLをどこまで高速化できるのか?〜ハードウェアの限界に挑むPG-Stromの挑戦〜

PG-StromにはPostgreSQLに接続して結果をApache Arrowフォーマットのデータとして保存するpg2arrowというコマンドもあります。この機能はC++のデータセットAPIで実現しようとしている機能の1つでもあります。この機能をApache Arrow本体に取り込まないか?という話もあるので楽しみですね。

参考:Contributing to Apache Arrow? · Issue #9 · heterodb/pg2arrow

1.0.0がリリースされたらもっとApache Arrowの利用者が増えるでしょう。

Apache Arrowの今後

ここまででApache Arrowのこの1年の最新情報を説明しました。最後に今後のことを説明します。

1.0.0リリース

前日の通り、近いうちに1.0.0がリリースされます。

去年、Apache Arrow東京ミートアップ2018というApache Arrowイベントを開催しましたが、1.0.0に合わせて今年もApache Arrowイベントを開催する予定です。楽しみにしていてください!

Apache Arrow利用者の増加

1.0.0がリリースされるとこれまで「様子見」だった人たちが使うようになるはずです。そうするといろんなところでApache Arrowを利用した高速なデータ交換ができるようになります。

次の1年でApache Arrow対応プロダクト・サービスはたくさん増えるでしょう。

データ処理機能の拡充

前述の通りC++実装ではデータセット・クエリーエンジン・データフレームなどデータ処理機能の実装に注力していきます。次の1年で使える機能がかなり増えるでしょう。

まとめ

2019年9月時点のApache Arrowの最新情報を、2018年9月からの差分という形でまとめました。Apache Arrowは数年後にはデータ処理界隈で重要なコンポーネントになっているだろうプロジェクトです。日本でもApache Arrowのことを知っている人が増えるといいと思うので日本語でまとめました。Apache Arrowを使う人が増えるといいなぁと思います。さらに言えば開発に参加する人も増えるといいなぁと思います。

私が知っていることはまとめたつもりですが、もしかしたらカバーできていない話があるかもしれません。もし、「○○についても知りたい!」という方がいたらApache Arrowのことを日本語で話せるチャットで声をかけてください。この記事に追加します。

Apache Arrowについて講演して欲しいという方はお問い合わせフォームからご連絡ください。

私はデータ処理ツールの開発という仕事をしたいと思っています。その中にはもちろんApache Arrowの開発も含まれています。一緒に仕事をしたい!(自社サービスをApache Arrow対応したいとか)という方はお問い合わせフォームからご連絡ください。

*1 去年はPMCメンバー・コミッター含めて日本人は私だけでしたが、今は私の他に2人日本人がいます。

*2 去年は3番目でした。

*3 そのようなフロントエンドのバックエンドになる

*4 前述の設計文書の「Non-goals」を参照。少なくとも今のところはそうしない設計。

2019-09-30

«前月 最新記事 翌月»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|