RAKSUL TechBlog

ラクスルグループのエンジニアが技術トピックを発信するブログです

Object Storageを使ってみた (その2)

もう8月ですね。にしても暑いです。こんな日にはサーバールームで、、、
さて、先月におこなった前回の投稿でObject Storageについて説明しましたが、採用するにあたってベンチマークと利用上の注意点をまとめてみました。

IDCFとAWSのベンチマーク

さくっととってみました。

サービス名 Disk Write Disk Read bench.php
IDCF Data Disk 327.0MB/sec 137.0MB/sec 2.6sec
IDCF Root Disk 075.8MB/sec 123.7MB/sec -
AWS t1.micro 029.3MB/sec 009.2MB/sec 4.4sec
AWS m3.medium 039.0MB/sec 041.8MB/sec 4.5sec

m3.mediumはOS側で何か制御かかってるのか思ったよりでなかったです。逆にIDCFは良く出過ぎで、、、
※ dd bs=1M count=1024 if=/dev/zero of=test conv=fdatasyncの速度比較
※ echo 3 > /proc/sys/vm/drop_caches && time cat test > /dev/nullの速度比較

サービス名 1G upload 1G multiupload 1G download
IDCF 05.4MB/sec 15.8MB/sec 13.1MB/sec
AWS t1.micro 04.5MB/sec 07.4MB/sec 04.3MB/sec
AWS m3.medium 26.3MB/sec 34.2MB/sec 28.9MB/sec

AWSはspecによって回線の速度が違うのでその影響っぽいです。
AWS S3のサンプルコードはいっぱいあると思うので微々たる違いですが、
IDCF Object Storage版のSampleコードです。

upload
[php] require('AWSSDKforPHP/aws.phar'); use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; use Guzzle\Http\EntityBody; $client = S3Client::factory(array( 'key' => 'key', 'secret' => 'secret', 'base_url' => 'http://ds.jp-east.idcfcloud.com', )); $file = 'test'; $key = 'test'; $time = microtime(true); try { $fopen = fopen($file, 'r'); $result = $client->putObject(array( 'Bucket' => $bucket, 'Key' => $key, 'Body' => EntityBody::factory($fopen), )); } catch (S3Exception $e) { $error = $e->getMessage(); trigger_error($error . ' KEY: ' . $key); } $time = microtime(true) - $time; echo $time . PHP_EOL; [/php]

multiupload
[php] require('AWSSDKforPHP/aws.phar'); use Aws\S3\S3Client; use Aws\S3\Model\MultipartUpload\UploadBuilder; use Aws\S3\Exception\S3Exception; use Guzzle\Http\EntityBody; $client = S3Client::factory(array( 'key' => 'key', 'secret' => 'secret', 'base_url' => 'http://ds.jp-east.idcfcloud.com', )); $file = 'test'; $key = 'test'; $size = 10; $conc = 10; $time = microtime(true); $uploader = UploadBuilder::newInstance() ->setClient($client) ->setSource($file) ->setBucket($bucket) ->setKey($key) ->setMinPartSize($size * 1024 * 1024) ->setOption('ACL', 'public-read') ->setConcurrency($conc) ->build(); try { $uploader->upload(); } catch (MultipartUploadException $e) { $uploader->abort(); echo $e->getMessage() . PHP_EOL; } $time = microtime(true) - $time; echo $time . PHP_EOL; [/php]

download
[php] require('AWSSDKforPHP/aws.phar'); use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; use Guzzle\Http\EntityBody; $client = S3Client::factory(array( 'key' => 'key', 'secret' => 'secret', 'base_url' => 'http://ds.jp-east.idcfcloud.com', )); $key = 'test'; $time = microtime(true); try { $result = $client->getObject(array( 'Bucket' => $bucket, 'Key' => $key, )); $result['Body']->rewind(); while ($data = $result['Body']->read(1024)) { // echo $data; } } catch (Exception $e) { $error = $e->getMessage(); trigger_error($error . ' KEY: ' . $key); } $time = microtime(true) - $time; echo $time . PHP_EOL; [/php]
ちなみにdownloadは
[php] $key = 'test'; $url = $client->getObjectUrl($bucket, $key); [/php]
とURLを発行することもできます。
[php] $key = 'test'; $url = $client->getObjectUrl($bucket, $key, '+100 minutes'); [/php]
として100分間有効なURLを発行することもできますし、
ダウンロードするファイル名を変えたいときは
[php] $key = 'hoge'; $url = $client->getObjectUrl($bucket, $key, '+100 minutes', array( 'ResponseContentDisposition' => 'attachment; filename="moge"', )); [/php]
とすればできますが、Object Storageでは未対応です。

Amazon S3 互換サービスを使う上で注意したいこと

あくまで互換なんでサポートしてない機能が多いです

  • s3fsでmvとかcopyするとデータが消えるしそもそも遅い
  • AWS SDK for PHPでも使えない関数やオプションがある
  • ACLじゃなくてpublic/privateでの管理の為権限の取り扱いが若干違う
  • 低価格な奴が無い (Amazon Glacier)