2021/12/04

Ozoneを試す

Apache Ozoneを試してみます。Dockerを事前に使えるようにしておいてください。

準備


Ozoneの立ち上げは https://ozone.apache.org/docs/1.1.0/start/startfromdockerhub.html に従って進めます。

といっても、

$ docker run -p 9878:9878 -p 9876:9876 apache/ozone
を実行するだけです。

操作にはawsコマンドを使用しますので、Ubuntuの場合であれば、

$ apt install awscli
インストールします。また、設定ファイルを作成する必要があるため、例えば、
$ aws configure
AWS Access Key ID [None]: default
AWS Secret Access Key [None]: default
Default region name [None]: default
Default output format [None]: text
のようにします。今dockerで立ち上げたOzoneは ozone.security.enabled=false となっているため、適当な設定でもアクセスできるようです。今は試したいだけなので、このままで進めます。

バケット作成


最初にデータを保管するためのバケットを作る必要があります。バケットの説明は https://www.ipswitch.com/jp/blog/understanding-how-aws-s3-buckets-work が参考になりました。

以下のコマンドでbucket1という名前のバケットを作成できます。

$ aws s3api --endpoint http://localhost:9878/ create-bucket --bucket=bucket1

オブジェクトの格納


データをバケットに格納します。まずコピーするファイル test.txt を作ります。
$ echo "test test" > test.txt
次に、このファイルをバケット内にコピーします。
$ aws s3 --endpoint http://localhost:9878 cp test.txt  s3://bucket1/test.txt
upload failed: ./test.txt to s3://bucket1/test.txt An error occurred (500) when calling the PutObject operation (reached max retries: 4): Internal Server Error
すると、エラーが発生します。今立ち上げているOzoneがシングルコンテナであるため、エラーが発生するようです。そこで、
$ aws s3 --endpoint http://localhost:9878 cp --storage-class REDUCED_REDUNDANCY test.txt  s3://bucket1/test.txt
upload: ./test.txt to s3://bucket1/test.txt
とすると成功します。
$ aws s3 --endpoint http://localhost:9878 ls s3://bucket1/test.txt
2021-12-04 22:20:53         10 test.txt
でファイルが存在することが確認できました。また、
$ aws s3 --endpoint http://localhost:9878 cp s3://bucket1/test.txt -
test test
でファイルの中身を表示できます。出力ファイル名を-にすることで標準出力に流してくれるようです。 これで正しくコピーできていることが確認できました。

Pythonから利用


boto3というライブラリを用いるとPythonからアクセスできます。
$ pip3 install boto3
でインストールします。

次のコード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import boto3

s3 = boto3.resource('s3', endpoint_url="http://localhost:9878")
for b in s3.buckets.all():
    print(" 1:", b)
    print(" 2:", b.name)
    for obj in b.objects.all():
        print(" 3:", obj.key)
        print(" 4:", obj.size)
        print(" 5:", obj.get()["Body"])
        print(" 6:", obj.get()["Body"].read())
        body = obj.get()["Body"]
        print(" 7:", body.read().decode("utf-8"))
        print(" 8:", body.read())
    print(" 9:", b.Object("test.txt").get()["Body"].read())
print("10:", s3.Object("bucket1", "test.txt").get()["Body"].read())
をpython3で実行すると、
 1: s3.Bucket(name='bucket1')
 2: bucket1
 3: test.txt
 4: 10
 5: <botocore.response.StreamingBody object at 0x7f9ae2a71d00>
 6: b'test test\n'
 7: test test

 8: b''
 9: b'test test\n'
10: b'test test\n'
という結果が出力されます。キーをリストアップしてオブジェクトの中身を表示することも、キーを指定してオブジェクトの中身を表示することもできます。 なお、取得したbodyに対して2回readすると、1回目で読み終わっているため、2回目は空が返ってきます。

参考


https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html
https://botocore.amazonaws.com/v1/documentation/api/latest/reference/response.html#botocore.response.StreamingBody
https://medium.com/towards-data-engineering/get-keys-inside-an-s3-bucket-at-the-subfolder-level-7be42d858372

0 件のコメント :