この記事は MicroAd Advent Calendar 2023 と Distributed computing (Apache Spark, Hadoop, Kafka, ...) Advent Calendar 2023 の25日目の記事です。
アドカレも今日で最後になりました。会社の方は全部埋まって記事も投稿出来てるので一安心ですが、Distributed computing アドカレの方は寂しい状態です。とは言え、参加してくれた皆さんには感謝しかないし、どの記事も良かった!
ただ、せっかくなので、出来るだけ空いてるところを埋めていきたいところ。
では、今日のお題に入っていきます。
前提
TL;DR
- データ分析でテーブルを用いる場合に最適なファイルシステム向けに最適化したOzoneのバケットレイアウト FSOは利用出来た
- OzoneのバケットにネイティブにアクセスできるofsプロトコルをIcebergのLocationに利用するには、Cloudera Data Platform (CDP)を使うか、Ozone側にIcebergのFileIO1の対応を待つしか無い( HDDS-7629 )
前ふり
Storage User Group Meetup というイベント(下はそのアーカイブ)でOzoneやIcebergを取り上げていて、そこで、Icebergのデータ層にS3じゃなくて、Apache Ozoneのofsを利用できるよって教えてもらいました2。
その記事がこちら。
Ozoneについては以下に関連情報をまとめてるので、そちらを参照ください(追加の情報もあれば是非お待ちしています)。
ofs?FSO?🙃
まずは、FSOについて。
Ozoneは、データの格納先であるOzoneのバケットのレイアウトについて、ファイルシステム最適化(FSO)またはオブジェクトストア(OBS)の両方に対応しており、ファイルまたはオブジェクトに適したバケットにレイアウトをサポートしてます。
ファイルシステムとオブジェクトストアは下図のようにデータのメタデータの管理方法が異なります。
オブジェクトストアはファイルシステムに比べて、再帰的なディレクトリ削除やディレクトリ移動、リネームの操作は高価になってしまう3ので、データ分析の場合、ファイルシステムが適しています。なので、データ分析でOzoneを利用するならFSOのレイアウトを選択するのが適しています。
次に、ofsについて。
Ozoneは、データにアクセスするために、以下の複数のインターフェイスに対応しています。
- s3:Amazon S3互換のS3プロトコル。OzoneのS3 Gatewayを使用することで変更なしにS3 CLIやS3 SDKから利用できます
- o3:Ozoneシェルから使用できるオブジェクトストアのインターフェイス。
- ofs:Hadoop互換のファイルシステム(HCFS)のプロトコル
例えば、ロケーションにofsを指定したHiveテーブルに対してaws s3 CLIからデータを読み込んだり、aws s3 CLIでデータを書き込んでofsつかってHiveテーブルで読み込むということも出来ます。
この辺りについては、以下のブログを参照ください。
ただ、Icebergテーブルを使う場合、たいていデータ層にs3を使うので、S3 Gatewayが間に入ることや、S3プロトコルを使う際のリネームや削除のアトミックに関する課題があるので、ofsを使う事でそれらの課題を解決出来ます。
Icebergでofs/FSOは使えるのか?
ofsは利用できるかについて。
以下の記事では、ClouderaのCDPでは、HiveからIcebergテーブルを利用しています。 この場合、Hive Metasoreが必要になります。既存でHadoopクラスタがある場合は良いですが、これだけのために、Hadoopクラスタを構築するのは微妙です。
RESTカタログを使いたいところですが、その場合、ofsプロトコルにおけるIcebergテーブルに対するメタデータやデータの操作といったIcebergネイティブな対応が必要です。
実際にIcebergの実装を見るに、ofsの対応はありません。
ただ、その辺りの実装については、Iceberg側は柔軟に対応出来るように設計されているようです。また、Ozone ofsはHadoop互換ファイルシステムであるので、HadoopFileIOを拡張する事で対応が出来るらしい。IcebergのFileIOについては、以下のブログに詳しく説明されています。
OzoneのJIRAを確認したところ、 HDDS-7629 にて、FileIOについて検討するIssueがあったが、Ozone v1.4.0をターゲットにしているものの動きはなさそう。誰か実装してくれないものか…。私のJava力の無さよ😢
FSOレイアウトは利用できるかについて。
以下のドキュメントにあるように、デフォルトで作成されるS3互換のボリュームのバケットとして、別のボリュームにあるFSOレイアウトのバケットに対してリンクする事が出来ます。
FSOレイアウトのバケットを作成して、S3互換のバケットとしてリンクさせてみます。
# FSOレイアウトのバケット /ozone-vol/ofs-bucket を作成 bash-4.2$ ozone sh bucket create --layout FILE_SYSTEM_OPTIMIZED /ozone-vol/ofs-bucket bash-4.2$ ozone sh bucket info /ozone-vol/ofs-bucket { "metadata" : { }, "volumeName" : "ozone-vol", "name" : "ofs-bucket", "storageType" : "DISK", "versioning" : false, "usedBytes" : 0, "usedNamespace" : 0, "creationTime" : "2023-12-24T18:54:04.099Z", "modificationTime" : "2023-12-24T18:54:04.099Z", "quotaInBytes" : -1, "quotaInNamespace" : -1, "bucketLayout" : "FILE_SYSTEM_OPTIMIZED", "owner" : "hadoop", "link" : false } # S3互換のバケット/s3v/common-bucket として、/ozone-vol/ofs-bucket にリンクする bash-4.2$ ozone sh bucket link /ozone-vol/ofs-bucket /s3v/common-bucket bash-4.2$ ozone sh bucket info /s3v/common-bucket { "volumeName" : "s3v", "bucketName" : "common-bucket", "sourceVolume" : "ozone-vol", "sourceBucket" : "ofs-bucket", "creationTime" : "2023-12-24T18:55:26.121Z", "modificationTime" : "2023-12-24T18:55:26.121Z", "owner" : "hadoop" }
実際に、aws s3 CLIを使って、/s3v/common-bucket
に対してデータを書き込んでみます。
❯ aws s3 cp --endpoint-url http://s3gw.internal:9878 --profile ozone ./test.csv s3://common-bucket/ upload: ./test.csv to s3://common-bucket/test.csv ❯ aws s3 ls --endpoint http://s3gw.internal:9878 --profile ozone s3://common-bucket 2023-12-25 04:00:47 7 test.csv
FSOレイアウトのバケット /ozone-vol/ofs-bucket/
側を見てみると書き込まれていることが分かります。
bash-4.2$ ozone fs -ls ofs:///ozone-vol/ofs-bucket/ Found 1 items -rw-rw-rw- 1 hadoop hadoop 7 2023-12-24 19:00 ofs:///ozone-vol/ofs-bucket/test.csv
どうやらうまく行きそうです。
試しに、 s3://common-bucket
を指定してIcebergテーブルを作成してデータを追加してみたら以下の様に、OFS側のボリュームのバケットにデータが書き込まれてました。
bash-4.2$ ozone fs -ls ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/ Found 2 items drwxrwxrwx - hadoop hadoop 0 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data drwxrwxrwx - hadoop hadoop 0 2023-12-24 19:32 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/metadata bash-4.2$ ozone fs -ls ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/ Found 8 items -rw-rw-rw- 1 hadoop hadoop 2362 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00000-0-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet -rw-rw-rw- 1 hadoop hadoop 2347 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00001-1-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet -rw-rw-rw- 1 hadoop hadoop 2374 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00002-2-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet -rw-rw-rw- 1 hadoop hadoop 2374 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00003-3-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet -rw-rw-rw- 1 hadoop hadoop 2362 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00004-4-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet -rw-rw-rw- 1 hadoop hadoop 2362 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00005-5-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet -rw-rw-rw- 1 hadoop hadoop 2368 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00006-6-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet -rw-rw-rw- 1 hadoop hadoop 2375 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/data/00007-7-9acf600a-988a-427b-9bc9-c85526f504e7-00001.parquet bash-4.2$ ozone fs -ls ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/metadata/ Found 4 items -rw-rw-rw- 1 hadoop hadoop 1856 2023-12-24 19:32 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/metadata/00000-63752b02-b1f9-4756-a10d-d41c8a2bdddd.metadata.json -rw-rw-rw- 1 hadoop hadoop 2955 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/metadata/00001-c7c5371c-d685-4916-a0fa-83bfc320c30f.metadata.json -rw-rw-rw- 1 hadoop hadoop 7715 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/metadata/30598e1e-0b27-454c-9ae7-e6cd26d2a318-m0.avro -rw-rw-rw- 1 hadoop hadoop 4273 2023-12-24 19:33 ofs:///ozone-vol/ofs-bucket/test_ofs_db/example_table_ice/metadata/snap-6515350754690444878-1-30598e1e-0b27-454c-9ae7-e6cd26d2a318.avro
補足)お試し環境 ※ここを押下するとサンプルの環境が出てきます
compose.yaml
--- version: "3" services: spark-iceberg: image: tabulario/spark-iceberg:3.5.0_1.4.2 networks: iceberg_net: depends_on: - iceberg-rest volumes: - ./spark-conf:/opt/spark/conf ports: - 8888:8888 - 8080:8080 - 4040:4040 - 10000:10000 - 10001:10001 environment: - AWS_ACCESS_KEY_ID=any - AWS_SECRET_ACCESS_KEY=any - AWS_REGION=us-east-1 iceberg-rest: image: tabulario/iceberg-rest:0.12.0 networks: iceberg_net: ports: - 8181:8181 environment: - AWS_ACCESS_KEY_ID=any - AWS_SECRET_ACCESS_KEY=any - AWS_REGION=us-east-1 - CATALOG_WAREHOUSE=s3a://common-bucket - CATALOG_IO__IMPL=org.apache.iceberg.aws.s3.S3FileIO - CATALOG_S3_ENDPOINT=http://s3gw.internal:9878 - CATALOG_S3_PATH__STYLE__ACCESS=true networks: iceberg_net:
spark-defaults.conf
spark.sql.session.timeZone Asia/Tokyo
spark.sql.extensions org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
spark.sql.hive.metastore.jars maven
spark.sql.defaultCatalog rest
spark.eventLog.enabled true
spark.eventLog.dir /home/iceberg/spark-events
spark.history.fs.logDirectory /home/iceberg/spark-events
spark.sql.catalogImplementation in-memory
spark.hadoop.fs.s3a.access.key any
spark.hadoop.fs.s3a.secret.key any
# REST Catalog
spark.sql.catalog.rest org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.rest.type rest
spark.sql.catalog.rest.uri http://iceberg-rest:8181
spark.sql.catalog.rest.warehouse s3a://common-bucket
spark.sql.catalog.rest.io-impl org.apache.iceberg.aws.s3.S3FileIO
spark.sql.catalog.rest.s3.endpoint http://s3gw.internal:9878
spark.sql.catalog.rest.s3.path-style-access true
Ozone側は、Apache OzoneのバイナリをDLして、 ozone-1.3.0/compose/ozone
にあるdocker-compose.yaml
を利用。
# ozone-1.3.0/compose/ozone に移動後に実施 # 一旦、各コンポーネントを起動 ./run.sh -d # DataNodeだけ、3つまでスケール export OZONE_REPLICATION_FACTOR=3 ./run.sh -d
最後に
いかがだったでしょうか。
Storage User Group Meetupで教えてもらった記事を読んで「いけるんじゃね?」って安直に考えたのは失敗でした。。。
HDDS-7629 でOzone FileIOが爆誕するのを心待ちにしてます。
以上、MicroAd Advent Calendar 2023](https://qiita.com/advent-calendar/2023/microad) と Distributed computing Advent Calendar 2023 の25日目の記事でした。