diff --git a/_includes/arrow-result-transfer-series-japanese.md b/_includes/arrow-result-transfer-series-japanese.md new file mode 100644 index 000000000000..8918e30bdad6 --- /dev/null +++ b/_includes/arrow-result-transfer-series-japanese.md @@ -0,0 +1,23 @@ + + +シリーズの記事: + +1. [Apache Arrowフォーマットはどのようにクエリー結果の転送を高速にしているのか]({% link _posts/2025-01-10-arrow-result-transfer-japanese.md %}) +1. [データは自由になりたい:Apache Arrowで高速データ交換]({% link _posts/2025-03-10-data-wants-to-be-free-japanese.md %}) diff --git a/_includes/top.html b/_includes/top.html index f31f984f8d22..6e35df6c713d 100644 --- a/_includes/top.html +++ b/_includes/top.html @@ -1,5 +1,5 @@ - +
diff --git a/_posts/2025-01-10-arrow-result-transfer-japanese.md b/_posts/2025-01-10-arrow-result-transfer-japanese.md index b9722a9eb683..3545b297c93e 100644 --- a/_posts/2025-01-10-arrow-result-transfer-japanese.md +++ b/_posts/2025-01-10-arrow-result-transfer-japanese.md @@ -35,6 +35,8 @@ limitations under the License. _この記事はデータベースとクエリーエンジン間のデータ交換フォーマットとしてなぜArrowが使われているのかという謎を解くシリーズの最初の記事です。_ +{% include arrow-result-transfer-series-japanese.md %} + 「どうしてこんなに時間がかかるの?」 diff --git a/_posts/2025-02-28-data-wants-to-be-free.md b/_posts/2025-02-28-data-wants-to-be-free.md index 0d64be85ef00..f75a41eaa2df 100644 --- a/_posts/2025-02-28-data-wants-to-be-free.md +++ b/_posts/2025-02-28-data-wants-to-be-free.md @@ -9,6 +9,9 @@ image: path: /img/arrow-result-transfer/part-1-share-image.png height: 1200 width: 705 +translations: + - language: 日本語 + post_id: 2025-03-10-data-wants-to-be-free-japanese --- + + + +_この記事はデータベースとクエリーエンジン間のデータ交換フォーマットとしてなぜArrowが使われているのかという謎を解くシリーズの2記事目です。_ + +{% include arrow-result-transfer-series-japanese.md %} + +データ技術者として、データが「人質に取られている」とよく感じます。 +データをもらってもすぐに使うことはできません。使えるようになるまでに時間がかかります。 +非効率的でやっかいなCSVファイルを整理する時間だったり、 +型落ちのクエリエンジンが数GBのデータに苦労するのを待つ時間だったり、 +データがソケットを介して受信するのを待つ時間をだったり。 +今回はこの三番目の問題に注目します。 +マルチギガビットネットワークの時代に、そもそもこの問題がまだ起こっているのはどうしてでしょうか? +間違いなく、この問題はまだ起こっています。 +[Mark RaasveldtとHannes Mühleisenの2017年の論文](https://doi.org/10.14778/3115404.3115408)[^freepdf]では、いくつかシステムは10秒しかかからないはずのデータセットの送受信に**10分**以上かかっていると指摘しています[^ten]。 + +[^freepdf]: [VLDB](https://www.vldb.org/pvldb/vol10/p1022-muehleisen.pdf)から論文を無料でダウンロードできます。 +[^ten]: 論文のFigure 1では、ベースラインのnetcatは10秒でCSVファイルを送信し、HiveとMongoDBは600秒以上かかっていること示しています。もちろん、CSVは解析されていないので、この比較は完全に平等ではありません。しかし、問題の規模を把握できます。 + +どうして必要な時間より60倍以上も長い時間がかかるのでしょうか? +[この前に論じていた通り、ツールはデータシリアライズのオーバーヘッドに悩まされています。]({% link _posts/2025-01-10-arrow-result-transfer.md %}) +しかし、この問題はArrowで解消できます。 +それではもっと具体的な話をしましょう。データシリアライズフォーマットの影響を示すために、PostgreSQLとArrowが同じデータをどうやってエンコードするのかを比較しましょう。 +その後、Arrow HTTPやArrow FlightなどのArrowベースのプロトコルを作る色々な方法を説明し、各方法の使い方も説明します。 + +## PostgreSQL対Arrow:データシリアライズ + +[PostgreSQLのバイナリーフォーマット](https://www.postgresql.jp/document/current/html/sql-copy.html#id-1.9.3.55.9.4)と[Arrow IPC](https://arrow.apache.org/docs/format/Columnar.html#serialization-and-interprocess-communication-ipc)を同じデータセットに比較します。 +この比較で、Arrowは(後知恵のおかげで)前任者より適切のトレードオフを行うのを証明します。 + +PostgreSQLでクエリを実行すると、クライアント(すなわちドライバ)はPostgreSQLの通信プロトコルでクエリを送り、結果を受けます。 +そのプロトコルの内に、結果セットはPostgreSQLのバイナリーフォーマットでエンコードされています[^textbinary]。 + +[^textbinary]: テキストフォーマットもあります。クライアントはそのフォーマットをほとんど使っています。この記事でテキストフォーマットを論じません。 + +まず、テーブルを定義し、テーブルにデータを入力します。 + +``` +postgres=# CREATE TABLE demo (id BIGINT, val TEXT, val2 BIGINT); +CREATE TABLE +postgres=# INSERT INTO demo VALUES (1, 'foo', 64), (2, 'a longer string', 128), (3, 'yet another string', 10); +INSERT 0 3 +``` + +それでCOPYコマンドでPostgreSQLから生バイナリーデータをファイルにダンプします。 + +``` +postgres=# COPY demo TO '/tmp/demo.bin' WITH BINARY; +COPY 3 +``` + +そして[文書](https://www.postgresql.jp/document/current/html/sql-copy.html#id-1.9.3.55.9.4)の通り、データの実際のバイトに注釈を付けます。 + +00000000: 50 47 43 4f 50 59 0a ff PGCOPY.. COPYの署名、フラグフィールド、
+00000008: 0d 0a 00 00 00 00 00 00 ........ ヘッダ拡張領域長
+00000010: 00 00 00 00 03 00 00 00 ........ 次の行の値の数
+00000018: 08 00 00 00 00 00 00 00 ........ 次の値長
+00000020: 01 00 00 00 03 66 6f 6f .....foo 値
+00000028: 00 00 00 08 00 00 00 00 ........
+00000030: 00 00 00 40 00 03 00 00 ...@....
+00000038: 00 08 00 00 00 00 00 00 ........
+00000040: 00 02 00 00 00 0f 61 20 ......a
+00000048: 6c 6f 6e 67 65 72 20 73 longer s
+00000050: 74 72 69 6e 67 00 00 00 tring...
+00000058: 08 00 00 00 00 00 00 00 ........
+00000060: 80 00 03 00 00 00 08 00 ........
+00000068: 00 00 00 00 00 00 03 00 ........
+00000070: 00 00 12 79 65 74 20 61 ...yet a
+00000078: 6e 6f 74 68 65 72 20 73 nother s
+00000080: 74 72 69 6e 67 00 00 00 tring...
+00000088: 08 00 00 00 00 00 00 00 ........
+00000090: 0a ff ff ... ストリームの終わり00000000: ff ff ff ff d8 00 00 00 ........ IPCメッセージ長
+00000008: 10 00 00 00 00 00 0a 00 ........ IPCスキーマ
+⋮ (208バイト)
+000000e0: ff ff ff ff f8 00 00 00 ........ IPCメッセージ長
+000000e8: 14 00 00 00 00 00 00 00 ........ IPCレコードバッチ
+⋮ (240バイト)
+000001e0: 01 00 00 00 00 00 00 00 ........ 1つ目の列のデータ
+000001e8: 02 00 00 00 00 00 00 00 ........
+000001f0: 03 00 00 00 00 00 00 00 ........
+000001f8: 00 00 00 00 03 00 00 00 ........ 文字列のオフセット
+00000200: 12 00 00 00 24 00 00 00 ....$...
+00000208: 66 6f 6f 61 20 6c 6f 6e fooa lon 2つ目の列のデータ
+00000210: 67 65 72 20 73 74 72 69 ger stri
+00000218: 6e 67 79 65 74 20 61 6e ngyet an
+00000220: 6f 74 68 65 72 20 73 74 other st
+00000228: 72 69 6e 67 00 00 00 00 ring.... アラインメントのためのパッディング
+00000230: 40 00 00 00 00 00 00 00 @....... 3つ目の列のデータ
+00000238: 80 00 00 00 00 00 00 00 ........
+00000240: 0a 00 00 00 00 00 00 00 ........
+00000248: ff ff ff ff 00 00 00 00 ........ IPCストリームの終わり