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

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;


multiupload
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;


download
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;

ちなみにdownloadは
$key = 'test';
$url = $client->getObjectUrl($bucket, $key);

とURLを発行することもできます。
$key = 'test';
$url = $client->getObjectUrl($bucket, $key, '+100 minutes');

として100分間有効なURLを発行することもできますし、
ダウンロードするファイル名を変えたいときは
$key = 'hoge';
$url = $client->getObjectUrl($bucket, $key, '+100 minutes', array(
    'ResponseContentDisposition' => 'attachment; filename="moge"',
));

とすればできますが、Object Storageでは未対応です。

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

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

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