問題
AzureStorageのBLOB/TABLEのバックアップをWorkerRoleなどから取る際、データ容量がデカイとBackUpに失敗する。
エラー内容.
Manifest file for this export operation is: "xxx.manifest".
[ERROR] Failed to export Azure table. Detailed error: There is not enough space on the disk.
原因
worker または Web ロールの既定の一時ディレクトリの最大サイズは 100 MB
クラウド サービスの Web/worker ロールに対する既定の一時フォルダーのサイズが小さすぎる
対応策
ストレージ テーブル エンティティをストレージの Blob にエクスポートするとき、AzCopy はまずテーブル エンティティをローカルの一時データ ファイルにエクスポートし、次にそれらのファイルを Blob にアップロードします。このような一時データ ファイルは、既定のパス “%LocalAppData%\Microsoft\Azure\AzCopy” を持つジャーナル ファイル フォルダーに格納されます。/Z:[journal-file-folder] を指定すれば、ジャーナル ファイル フォルダーの場所を変更して、一時データ ファイルの場所を変更することができます。
AzCopy コマンド ライン ユーティリティを使用してデータを転送するファイルの書き込みまたは読み取りが必要な場合に、インスタンスで実行されるコードからローカル ストレージ リソースにアクセスできるように、仮想マシンのインスタンスに情報を格納できます。
ローカル ストレージ リソースを構成する
実際のソース
ここではTableのバックアップ処理を例に
ServiceDefinition.csdf
<LocalResources>
<LocalStorage name="AzWork" cleanOnRoleRecycle="true" sizeInMB="100000" />
</LocalResources>
workerrole.cs
public override bool OnStart()
{
//念の為にいれたが、いらないと思う。
customTempLocalResourcePath = RoleEnvironment.GetLocalResource("AzWork").RootPath;
Environment.SetEnvironmentVariable("TMP", customTempLocalResourcePath);
Environment.SetEnvironmentVariable("TEMP", customTempLocalResourcePath);
return base.OnStart();
}
call.cs
//Workerの場合
azpath = Path.Combine(Environment.GetEnvironmentVariable("RoleRoot") + @"\", @"approot\AzCopy\AzCopy.exe");
manifestname = table + DateTime.Today.ToString("yyyyMMdd") + ".manifest";
BkTable(table,azpath,manifestname,customTempLocalResourcePath);
run.cs
public void BkTable(string table, string azpath,string manifestname,string _path)
{
StringBuilder arguments = new StringBuilder();
arguments.Append(@"/source:" + [sourcetable] + "/" + [targettable]);
arguments.Append(@" /dest:" + [destblob] + "/" + [destcontainer]);
arguments.Append(@" /sourcekey:" + [sourcekey]);
arguments.Append(@" /destkey:" + [destkey]);
arguments.Append(@" /SplitSize:" + "100000"); //Roleに従う
arguments.Append(@" /Z:" + _path ); //←ここでLocalStorageを指定
arguments.Append(@" /manifest:" + manifestname);
ProcessStartInfo info = new ProcessStartInfo
{
FileName = azpath,
Arguments = arguments.ToString(),
UseShellExecute = false,
RedirectStandardInput = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
ErrorDialog = false,
CreateNoWindow = true
};
using (Process proc = new Process())
{
//エラー処理など割愛
proc.StartInfo = info;
proc.Start();
}
}