株式会社コーソル

コーソルDatabaseエンジニアのブログ

技術ブログ

OCIオブジェクトストレージへのマルチパートアップロードとMD5値 (opc-multipart-md5)

渡部です。これは、(全部俺) Oracle Cloud Infrastructure Advent Calendar 2018 の14日目のエントリです。

OCIオブジェクトストレージには、最大10TiBのオブジェクトを保管することができますが、 10TiBを一気にアップロードすることはできません。50GiBよりも大きなデータは、50GiB以下の適切なサイズで分割してからアップロードする必要があります(マルチパートアップロード)。なお、50GiBよりも小さなデータであっても、100MiB以上の場合はマルチプルアップロードを使用することが推奨されています。

OCIオブジェクトストレージのCLIを使用して大きなデータ(ファイル)をアップロードすると、自動的/内部的にマルチプルアップロードでデータがアップロードされるため便利です。分割サイズはデフォルトで128 MiBです。

$ MiB=1048576
$ FILESIZE=$(( 130 * ${MiB} ))
$ FILENAME=testfile01
$ dd if=/dev/zero of=${FILENAME} bs=${FILESIZE} count=1
1+0 records in
1+0 records out
136314880 bytes (136 MB) copied, 0.327818 s, 416 MB/s
$ ls -l ${FILENAME}
-rw-rw-r-- 1 rywatabe wheel 136314880 Nov 24 13:19 testfile01
$ ls -lh ${FILENAME}
-rw-rw-r-- 1 rywatabe wheel 130M Nov 24 13:19 testfile01
$
$ NAMESPACE=cosoltest01
$ BUCKET=bk1
$ oci os object put -ns ${NAMESPACE} -bn ${BUCKET} --name ${FILENAME} --file ${FILENAME}
Upload ID: a375c237-cee5-b33c-7f1e-13b5d7e7edb4
Split file into 2 parts for upload.
Uploading object  [####################################]  100%
{
  "etag": "7B6209783244CDABE053425EC10AFA84",
  "last-modified": "Sat, 24 Nov 2018 04:20:26 GMT",
  "opc-multipart-md5": "HanWpQo/Ax4cLcfrqc+JoQ==-2"
}

ただし、マルチパートアップロードでデータをアップロードすると、MD5値(正確にはMD5値をBASE64エンコードした文字列)の算出方法がマルチパートアップロード特有のものになることに注意が必要です。データ全体に対して単純にMD5値を算出したものにはなりません。

$ openssl md5 -binary ${FILENAME} | base64
GVo4sqytW7QBrN3Oi6XwVg==

上記の例でも、

  • データ全体に対して単純にMD5値を算出したもの: GVo4sqytW7QBrN3Oi6XwVg==
  • Object StorageにマルチパートアップロードでアップロードしたデータのMD5値("opc-multipart-md5") : HanWpQo/Ax4cLcfrqc+JoQ==-2

と、異なる値になっています。

以下に、マルチパートアップロードにおけるMD5値(特有すぎてもはやMD5値と呼んでいいか迷いますが・・・)を算出するシェルスクリプトを記載します。

$ cat calc_multipart_md5.sh
#!/bin/bash

INFILE=$1
#CHUNKSIZE=$2
MiB=1048576
CHUNKSIZE=$(( 128 * ${MiB} ))

FILESIZE=$( wc -c ${INFILE} | awk '{print $1}' )
SPLIT_NUM_MINUS1=$(( ${FILESIZE} / ${CHUNKSIZE} ))

TMPFILE1=mktemp
trap "rm -f ${TMPFILE1}" EXIT

>${TMPFILE1}
for i in $( seq 0 ${SPLIT_NUM_MINUS1} ) ; do
  dd bs=${CHUNKSIZE} count=1 skip=${i}  if=${INFILE} 2>/dev/null | openssl md5 -binary >>${TMPFILE1}
done

echo "$(openssl md5 -binary ${TMPFILE1} |base64)-$(( ${SPLIT_NUM_MINUS1} +1  ))"

ポイントは以下の通りです。

  • アップロード対象データをマルチパートアップロードの分割サイズで分割し、分割後のデータのMD5値を算出する
  • 分割後のデータのMD5値(バイナリデータ)を連結したバイナリデータに対して、MD5値を取得し、BASE64でエンコードする
  • そして、"-(分割数)"の文字列を末尾に付け加える

このシェルスクリプトを使って、大きなサイズのファイルのMD5値を算出し、データの整合性を確認する例を以下に示します。 オブジェクトストレージ側のMD5値とローカルのデータから算出したMD5値が同じことから、正しくデータがアップロードされていることを確かめることができます。

$ ./calc_multipart_md5.sh ${FILENAME}
HanWpQo/Ax4cLcfrqc+JoQ==-2

Object StorageにマルチパートアップロードでアップロードしたデータのMD5値("opc-multipart-md5") である、"HanWpQo/Ax4cLcfrqc+JoQ==-2"が得られていることが分かります。

2020/8/25 追記

Oracle Cloud Infrastructure(OCI)のObjectStorageでマルチパートアップロードされたオブジェクトのMD5ハッシュについては、Oracle Cloudに強いインテグレータのCloudii様(Atomitech様)によるこちらの記事もご覧ください!

プロフィール

On7tWW6m1Ul4

渡部 亮太

・Oracle ACE
・AWS Certified Solutions Architect - Associate
・ORACLE MASTER Platinum Oracle Database 11g, 12c 他多数

カテゴリー

アーカイブ