28 Nov 2017, 08:45

Azure Blob アップローダーをGoで書いた、そしてその理由

Azure Blob アップローダーをGoで書いた

ふたつほど理由があり、GolangでAzure Blobのファイルアップローダーを書きました。

ひとつめの理由: SDKが新しくなったから

最近公式ブログで紹介された通り、Azure Storage SDK for Goが再設計され、プレビューが始まりました。GoはDockerやKubernetes、Terraformなど最近話題のプラットフォームやツールを書くのに使われており、ユーザーも増えています。再設計してもっと使いやすくしてちょ、という要望が多かったのも、うなずけます。

ということで、新しいSDKで書いてみたかった、というのがひとつめの理由です。ローカルにあるファイルを読んでBlobにアップロードするコードは、こんな感じ。

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"

	"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
)

var (
	accountName    string
	accountKey     string
	containerName  string
	fileName       string
	blockSize      int64
	blockSizeBytes int64
)

func init() {
	flag.StringVar(&accountName, "account-name", "", "(Required) Storage Account Name")
	flag.StringVar(&accountKey, "account-key", "", "(Required) Storage Account Key")
	flag.StringVar(&containerName, "c", "", "(Required - short option) Blob Container Name")
	flag.StringVar(&containerName, "container-name", "", "(Required) Blob Container Name")
	flag.StringVar(&fileName, "f", "", "(Required - short option) Upload filename")
	flag.StringVar(&fileName, "file", "", "(Required) Upload filename")
	flag.Int64Var(&blockSize, "b", 4, "(Optional - short option) Blob Blocksize (MB) - From 1 to 100. Max filesize depends on this value. Max filesize = Blocksize * 50,000 blocks")
	flag.Int64Var(&blockSize, "blocksize", 4, "(Optional) Blob Blocksize (MB) - From 1 to 100. Max filesize depends on this value. Max filesize = Blocksize * 50,000 blocks")
	flag.Parse()

	if (blockSize < 1) || (blockSize) > 100 {
		fmt.Println("Blocksize must be from 1MB to 100MB")
		os.Exit(1)
	}
	blockSizeBytes = blockSize * 1024 * 1024
}

func main() {
	file, err := os.Open(fileName)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	fileSize, err := file.Stat()
	if err != nil {
		log.Fatal(err)
	}

	u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s/%s", accountName, containerName, fileName))
	blockBlobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))

	ctx := context.Background()

	fmt.Println("Uploading block blob...")
	putBlockList, err := azblob.UploadStreamToBlockBlob(ctx, file, fileSize.Size(), blockBlobURL,
		azblob.UploadStreamToBlockBlobOptions{
			BlockSize: blockSizeBytes,
			Progress: func(bytesTransferred int64) {
				fmt.Printf("Uploaded %d of %d bytes.\n", bytesTransferred, fileSize.Size())
			},
		})
	if err != nil {
		log.Fatal(err)
	}
	_ = putBlockList // Avoid compiler's "declared and not used" error

	fmt.Println("Done")
}

以前のSDKと比較し、スッキリ書けるようになりました。進行状況もPipelineパッケージを使って、楽に取れるようになっています。ブロック分割のロジックを書く必要もなくなりました。ブロックサイズを指定すればOK。

ちなみにファイルサイズがブロックサイズで割り切れると最終ブロックの転送がエラーになるバグを見つけたのですが、修正してもらったので、次のリリースでは解決していると思います。

ふたつめの理由: レガシー対応

Blobのアップロードが目的であれば、Azure CLIをインストールすればOK。以上。なのですが、残念ながらそれができないケースがあります。

たとえば。Azure CLI(2.0)はPythonで書かれています。なので、Pythonのバージョンや依存パッケージの兼ね合いで、「ちょっとそれウチのサーバーに入れるの?汚さないでくれる?ウチはPython2.6よ」と苦い顔をされることが、あるんですね。気持ちはわかります。立場の数だけ正義があります。Docker?その1歩半くらい前の話です。

ですが、オンプレのシステムからクラウドにデータをアップロードして処理したい、なんていうニーズが急増している昨今、あきらめたくないわけであります。どうにか既存環境に影響なく入れられないものかと。そこでシングルバイナリーを作って、ポンと置いて、動かせるGoは尊いわけです。

ファイルのアップロードだけでなく、Azureにちょっとした処理を任せたい、でもそれはいじりづらいシステムの上なのねん、って話は、結構多いんですよね。ということでシングルバイナリーを作って、ポンと置いて、動かせるGoは尊いわけです。大事なことなので2回書きました。

C#やNode、Python SDKと比較してGoのそれはまだ物足りないところも多いわけですが、今後注目ということで地道に盛り上がっていこうと思います。

08 Oct 2017, 10:30

Azure VPN Gateway Active/Active構成のスループット検証(リージョン内)

動機

焦げlogさんで、とても興味深いエントリを拝見しました。

確かにActive/Active構成にはスループット向上を期待したくなります。その伸びが測定されており、胸が熱くなりました。ですが、ちょっと気になったのは

※それと、VpnGw3 よりも VpnGw2 のほうがスループットがよかったのが一番の謎ですが…

ここです。VPN GatewayのSKU、VpnGw3とVpnGw2には小さくない価格差があり、その基準はスループットです。ここは現状を把握しておきたいところ。すごく。

そこで、焦げlogさんの検証パターンの他に、追加で検証しました。それは同一リージョン内での測定です。リージョン内でVPNを張るケースはまれだと思いますが、リージョンが分かれることによる

  • 遅延
  • リージョン間通信に関するサムシング

を除き、VPN Gateway自身のスループットを測定したいからです。焦げlogさんの測定は東日本/西日本リージョン間で行われたので、その影響を確認する価値はあるかと考えました。

検証方針

  • 同一リージョン(東日本)に、2つのVNETを作る
  • それぞれのVNETにVPN Gatewayを配置し、接続する
  • 比較しやすいよう、焦げlogさんの検証と条件を合わせる
    • 同じ仮想マシンサイズ: DS3_V2
    • 同じストレージ: Premium Storage Managed Disk
    • 同じOS: Ubuntu 16.04
    • 同じツール: ntttcp
    • 同じパラメータ: ntttcp -r -m 16,*, -t 300
  • 送信側 VNET1 -> 受信側 VNET2 のパターンに絞る
  • スループットのポテンシャルを引き出す検証はしない

結果

VpnGW1(650Mbps)

パターン  送信側GW構成      受信側GW構成         送信側スループット   受信側スループット  スループット平均  パターン1との比較
パターン1  Act/Stb Act/Stb 677.48Mbps 676.38Mbps 676.93Mbps -
パターン2  Act/Stb Act/Act 674.34Mbps 673.85Mbps 674.10Mbps 99%
パターン3  Act/Act Act/Act 701.19Mbps 699.91Mbps 700.55Mbps 103%

VpnGW2(1Gbps)

パターン  送信側GW構成      受信側GW構成         送信側スループット   受信側スループット  スループット平均  パターン1との比較
パターン1  Act/Stb Act/Stb 813.09Mbps 805.60Mbps 809.35Mbps -
パターン2  Act/Stb Act/Act 1.18Gbps 1.18Gbps 1.18Gbps 149%
パターン3  Act/Act Act/Act 2.03Gbps 2.02Gbps 2.03Gbps 256%

VpnGW3(1.25Gbps)

パターン  送信側GW構成      受信側GW構成         送信側スループット   受信側スループット  スループット平均  パターン1との比較
パターン1  Act/Stb Act/Stb 958.56Mbps 953.72Mbps 956.14Mbps -
パターン2  Act/Stb Act/Act 1.39Gbps 1.39Gbps 1.39Gbps 149%
パターン3  Act/Act Act/Act 2.19Gbps 2.19Gbps 2.19Gbps 234%

SKU視点 パターン1(Act/Stb to Act/Stb)

SKU   スループット平均  VpnGw1との比較
VpnGw1  676.93Mbps -
VpnGw2  809.35Mbps 119%
VpnGw3  956.14Mbps 141%

SKU視点 パターン2(Act/Stb to Act/Act)

SKU   スループット平均  VpnGw1との比較
VpnGw1  674.10Mbps -
VpnGw2  1.18Gbps 179%
VpnGw3  1.39Gbps 211%

SKU視点 パターン3(Act/Act to Act/Act)

SKU   スループット平均  VpnGw1との比較
VpnGw1  700.55Mbps -
VpnGw2  2.03Gbps 297%
VpnGw3  2.19Gbps 320%

考察と推奨

  • リージョン間の遅延やサムシングを除くと、SKUによるGatewayのスループット差は測定できる
    • Act/Actでないパターン1(Act/Stb to Act/Stb)で、その差がわかる
  • 公式ドキュメントの通り、GatewayのAct/Act構成は可用性向上が目的であるため、スループットの向上はボーナスポイントと心得る
    • 期待しちゃうのが人情ではありますが
    • VpnGw2がコストパフォーマンス的に最適という人が多いかもしれませんね 知らんけど

05 Sep 2017, 12:00

Azure Event GridでBlobイベントを拾う

Event GridがBlobに対応

Event GridがBlobのイベントを拾えるようになりました。まだ申請が必要なプライベートプレビュー段階ですが、使い勝手の良いサービスに育つ予感がします。このたび検証する機会があったので、共有を。

プレビュー中なので、今後仕様が変わるかもしれないこと、不具合やメンテナンス作業の可能性などは、ご承知おきください。

Event GridがBlobに対応して何がうれしいか

Event Gridは、Azureで発生した様々なイベントを検知してWebhookで通知するサービスです。カスタムトピックも作成できます。

イベントの発生元をPublisherと呼びますが、このたびPublisherとしてAzureのBlobがサポートされました。Blobの作成、削除イベントを検知し、Event GridがWebhookで通知します。通知先はHandlerと呼びます。Publisherとそこで拾うイベント、Handlerを紐づけるのがSubscriptionです。Subscriptionにはフィルタも定義できます。

コンセプト

Event Gridに期待する理由はいくつかあります。

  • フィルタ
    • 特定のBlobコンテナーにあるjpegファイルの作成イベントのみで発火させる、なんてことができます
  • 信頼性
    • リトライ機能があるので、Handlerが一時的に黙ってしまっても対応できます
  • スケールと高スループット
    • Azure Functions BlobトリガーのようにHandler側で定期的にスキャンする必要がありません。これまではファイル数が多いとつらかった
    • 具体的な数値はプレビュー後に期待しましょう
  • ファンアウト
    • ひとつのイベントを複数のHandlerに紐づけられます
  • Azureの外やサードパーティーとの連携
    • Webhookでシンプルにできます

前提条件

  • Publisherに設定できるストレージアカウントはBlobストレージアカウントのみです。汎用ストレージアカウントは対応していません
  • 現時点ではWest Central USリージョンのみで提供しています
  • プライベートプレビューは申請が必要です

Azure CLIの下記コマンドでプレビューに申請できます。

az provider register --namespace  Microsoft.EventGrid
az feature register --name storageEventSubscriptions --namespace Microsoft.EventGrid

以下のコマンドで確認し、statusが”Registered”であれば使えます。

az feature show --name storageEventSubscriptions --namespace Microsoft.EventGrid

使い方

ストレージアカウントの作成からSubscription作成までの流れを追ってみましょう。

リソースグループを作ります。

$ az group create -n blobeventpoc-rg -l westcentralus

Blobストレージアカウントを作ります。

$ az storage account create -n blobeventpoc01 -l westcentralus -g blobeventpoc-rg --sku Standard_LRS --kind BlobStorage --access-tier Hot

ではいよいよEvent GridのSubscriptionを作ります。

$ az eventgrid resource event-subscription create --endpoint https://requestb.in/y4jgj2x0 -n blobeventpocsub-jpg --prov
ider-namespace Microsoft.Storage --resource-type storageAccounts --included-event-types Microsoft.Storage.BlobCreated
-g blobeventpoc-rg --resource-name blobeventpoc01 --subject-ends-with jpg

以下はパラメーターの補足です。

  • –endpoint
    • Handlerのエンドポイントを指定します。ここではテストのためにRequestBinに作ったエンドポイントを指定します
  • –included-event-types
    • イベントの種類をフィルタします。Blobの削除イベントは不要で、作成のみ拾いたいため、Microsoft.Storage.BlobCreatedを指定します
  • –subject-ends-with
    • 対象ファイルをフィルタします。Blob名の末尾文字列がjpgであるBlobのみイベントの対象にしました

では作成したストレージアカウントにBlobコンテナーを作成し、jpgファイルを置いてみましょう。テストにはAzure Storage Explorerが便利です。

RequestBinにWebhookが飛び、中身を見られます。スキーマの確認はこちらから。

[{
  "topic": "/subscriptions/xxxxx-xxxxx-xxxxx-xxxxx/resourceGroups/blobeventpoc-rg/providers/Microsoft.Storage/storageAccounts/blobeventpoc01",
  "subject": "/blobServices/default/containers/images/blobs/handsomeyoungman.jpg",
  "eventType": "Microsoft.Storage.BlobCreated",
  "eventTime": "2017-09-02T02:25:15.2635962Z",
  "id": "f3ff6b96-001e-001d-6e92-23bdea0684d2",
  "data": {
    "api": "PutBlob",
    "clientRequestId": "f3cab560-8f85-11e7-bad1-53b58c70ab53",
    "requestId": "f3ff6b96-001e-001d-6e92-23bdea000000",
    "eTag": "0x8D4F1A9D8A6703A",
    "contentType": "image/jpeg",
    "contentLength": 42497,
    "blobType": "BlockBlob",
    "url": "https://blobeventpoc01.blob.core.windows.net/images/handsomeyoungman.jpg",
    "sequencer": "0000000000000BAB0000000000060986",
    "storageDiagnostics": {
      "batchId": "f3a538cf-5b88-4bbf-908a-20a37c65e238"
    }
  }
}]

.jpgだけじゃなくて.jpegも使われるかもしれませんね。ということで、エンドポイントが同じでフィルタ定義を変えたSubscriptionを追加します。–subject-ends-withをjpegとします。

$ az eventgrid resource event-subscription create --endpoint https://requestb.in/y4jgj2x0 -n blobeventpocsub-jpeg --pro
vider-namespace Microsoft.Storage --resource-type storageAccounts --included-event-types Microsoft.Storage.BlobCreated -
g blobeventpoc-rg --resource-name blobeventpoc01 --subject-ends-with jpeg

すると、拡張子.jpegのファイルをアップロードしても発火しました。

[{
  "topic": "/subscriptions/xxxxx-xxxxx-xxxxx-xxxxx/resourceGroups/blobeventpoc-rg/providers/Microsoft.Storage/storageAccounts/blobeventpoc01",
  "subject": "/blobServices/default/containers/images/blobs/handsomeyoungman.jpeg",
  "eventType": "Microsoft.Storage.BlobCreated",
  "eventTime": "2017-09-02T02:36:33.827967Z",
  "id": "e8b036ee-001e-00e7-4994-23740d06225b",
  "data": {
    "api": "PutBlob",
    "clientRequestId": "883ff7e0-8f87-11e7-bad1-53b58c70ab53",
    "requestId": "e8b036ee-001e-00e7-4994-23740d000000",
    "eTag": "0x8D4F1AB6D1B24F6",
    "contentType": "image/jpeg",
    "contentLength": 42497,
    "blobType": "BlockBlob",
    "url": "https://blobeventpoc01.blob.core.windows.net/images/handsomeyoungman.jpeg",
    "sequencer": "0000000000000BAB0000000000060D42",
    "storageDiagnostics": {
      "batchId": "9ec5c091-061d-4111-ad82-52d9803ce373"
    }
  }
}]

Azure Functionsに画像リサイズファンクションを作って連携してみる

Gvent Grid側の動きが確認できたので、サンプルアプリを作って検証してみましょう。Azure Functions上に画像ファイルのサイズを変えるHandlerアプリを作ってみます。

概要

当初想定したのは、ひとつのファンクションで、トリガーはEventGrid、入出力バインドにBlob、という作りでした。ですが、以下のように設計を変えました。

Bindings

Using Azure Functions Bindings Visualizer

その理由はEvent Grid Blobイベントのペイロードです。Blobファイル名がURLで渡されます。Azure FunctionsのBlob入出力バインド属性、”path”にURLは使えません。使えるのはコンテナー名+ファイル名です。

入出力バインドを使わず、アプリのロジック内でStorage SDKを使って入出力してもいいのですが、Azure Functionsの魅力のひとつは宣言的にトリガーとバインドを定義し、アプリをシンプルに書けることなので、あまりやりたくないです。

そこでイベントを受けてファイル名を取り出してQueueに入れるファンクションと、そのQueueをトリガーに画像をリサイズするファンクションに分けました。

なお、この悩みはAzureの開発チームも認識しており、Functions側で対応する方針とのことです。

Handler

C#(csx)で、Event GridからのWebhookを受けるHandlerを作ります。PublisherがBlobの場合、ペイロードにBlobのURLが入っていますので、そこからファイル名を抽出します。そして、そのファイル名をQueueに送ります。ファンクション名はBlobEventHandlerとしました。なおEventGridTriggerテンプレートは、現在は[試験段階]シナリオに入っています。

[run.csx]

#r "Newtonsoft.json"
using Microsoft.Azure.WebJobs.Extensions.EventGrid;

public static void Run(EventGridEvent eventGridEvent, out string outputQueueItem, TraceWriter log)
{
    string imageUrl = eventGridEvent.Data["url"].ToString();
    outputQueueItem = System.IO.Path.GetFileName(imageUrl);
}

Event GridのWebJobs拡張向けパッケージを指定します。

[project.json]

{
"frameworks": {
  "net46":{
    "dependencies": {
      "Microsoft.Azure.WebJobs.Extensions.EventGrid": "1.0.0-beta1-10006"
    }
  }
 }
}

トリガーとバインドは以下の通りです。

[function.json]

{
  "bindings": [
    {
      "type": "eventGridTrigger",
      "name": "eventGridEvent",
      "direction": "in"
    },
    {
      "type": "queue",
      "name": "outputQueueItem",
      "queueName": "imagefilename",
      "connection": "AzureWebJobsStorage",
      "direction": "out"
    }
  ],
  "disabled": false
}

Resizer

Queueをトリガーに、Blobから画像ファイルを取り出し、縮小、出力するファンクションを作ります。ファンクション名はResizerとしました。

[run.csx]

using ImageResizer;

public static void Run(string myQueueItem, Stream inputBlob, Stream outputBlob, TraceWriter log)
{
  var imageBuilder = ImageResizer.ImageBuilder.Current;
  var size = imageDimensionsTable[ImageSize.Small];

  imageBuilder.Build(inputBlob, outputBlob,
    new ResizeSettings(size.Item1, size.Item2, FitMode.Max, null), false);

}

public enum ImageSize
{
  Small
}

private static Dictionary<ImageSize, Tuple<int, int>> imageDimensionsTable = new Dictionary<ImageSize, Tuple<int, int>>()
{
  { ImageSize.Small, Tuple.Create(100, 100) }
};

ImageResizerのパッケージを指定します。

[project.json]

{
"frameworks": {
  "net46":{
    "dependencies": {
      "ImageResizer": "4.1.9"
    }
  }
 }
}

トリガーとバインドは以下の通りです。{QueueTrigger}メタデータで、QueueのペイロードをBlobのpathに使います。ペイロードにはファイル名が入っています。

また、画像を保存するBlobストレージアカウントの接続文字列は、環境変数BLOB_IMAGESへ事前に設定しています。なお、リサイズ後の画像を格納するBlobコンテナーは、”images-s”として別途作成しました。コンテナー”images”をイベントの発火対象コンテナーとして、Subscriptionにフィルタを定義したいからです。

[function.json]

{
  "bindings": [
    {
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "imagefilename",
      "connection": "AzureWebJobsStorage"
    },
    {
      "name": "inputBlob",
      "type": "blob",
      "path": "images/{QueueTrigger}",
      "connection": "BLOB_IMAGES",
      "direction": "in"
    },
    {
      "name": "outputBlob",
      "type": "blob",
      "path": "images-s/{QueueTrigger}",
      "connection": "BLOB_IMAGES",
      "direction": "out"
    }
  ],
  "disabled": false
}

Handlerの準備が整いました。最後にEvent GridのSubscriptionを作成します。Azure FunctionsのBlobEventHandlerのトークン付きエンドポイントは、ポータルの[統合]で確認できます。

$ az eventgrid resource event-subscription create --endpoint "https://blobeventpoc.azurewebsites.net/admin/exte
nsions/EventGridExtensionConfig?functionName=BlobEventHandler&code=tokenTOKEN1234567890==" -n blobeventpocsub-jpg --provider-namespace Microsoft.Storage --resource-type storageAccounts --included-event-types "Microsoft.Storage.BlobCreated" -g blobeventpoc-rg --resource-name blobeventpoc01 --subject-begins-with "/blobServices/default/containers/images/"  --subject-ends-with jpg

これで、コンテナー”images”にjpgファイルがアップロードされると、コンテナー”images-s”に、リサイズされた同じファイル名の画像ファイルが出来上がります。

13 Jun 2017, 17:00

Azureでグローバルにデータをコピーするとどのくらい時間がかかるのか

ファイルコピーの需要は根強い

グローバルでAzureを使うとき、データをどうやって同期、複製するかは悩みの種です。Cosmos DBなどリージョン間でデータ複製してくれるサービスを使うのが、楽ですし、おすすめです。

でも、ファイルコピーを無くせないもろもろの事情もあります。となると、「地球の裏側へのファイルコピーに、どんだけ時間かかるのよ」は、課題です。

調べてみた

ということで、いくつかのパターンで調べたので参考までに。測定環境は以下の通り。

ツールと実行環境

  • AzCopy 6.1.0
  • Azure PowerShell 4.1.0
  • Windows 10 1703
  • ThinkPad X1 Carbon 2017, Core i7-7600U 2.8GHz, 16GB Memory

アクセス回線パターン

  1. 一般的な回線

    • 自宅(川崎)
    • OCN光 100M マンションタイプ
    • 宅内は802.11ac(5GHz)
    • 川崎でアクセス回線に入り、横浜(保土ヶ谷)の局舎からインターネットへ
    • ゲートウェイ名から推測
  2. いい感じの回線

    • 日本マイクロソフト 品川オフィス
    • 1Gbps 有線
    • Azureデータセンターへ「ネットワーク的に近くて広帯域」

コピーするファイル

  • 総容量: 約60GB
    • 6160ファイル
    • 1MB * 5000, 10MB * 1000, 100MB * 100, 500MB * 50, 1000MB * 10
  • Linux fallocateコマンドで作成

ファイル形式パターン

  1. ファイル、Blobそのまま送る (6160ファイル)
  2. ディスクイメージで送る (1ファイル)
    • Managed Diskとしてアタッチした100GBの領域にファイルシステムを作成し、6160ファイルを配置
    • 転送前にデタッチ、エクスポート(Blob SAS形式)
    • AzCopyではなくAzure PowerShellでコピー指示 (AzCopyにBlob SAS指定オプションが見当たらなかった)

対象のAzureリージョン

  • 東日本 (マスター、複製元と位置づける)
  • 米国中南部 (太平洋越え + 米国内を見たい)
  • ブラジル南部

転送パターン

  • ユーザー拠点の端末からAzureリージョン: AzCopy Upload
  • Azureリージョン間 (Storage to Storage)
    • ファイル: AzCopy Copy
    • イメージ: PowerShell Start-AzureStorageBlobCopy

結果

形式  コピー元      コピー先         コマンド   並列数  実行時間(時:分:秒)
ファイル  自宅 Azure 東日本 AzCopy Upload 2 07:55:22
ファイル  自宅 Azure 米国中南部 AzCopy Upload 2 10:22:30
ファイル  自宅 Azure ブラジル南部 AzCopy Upload 2 12:46:37
ファイル  オフィス Azure 東日本 AzCopy Upload 16 00:20:47
ファイル  オフィス Azure 米国中南部 AzCopy Upload 16 00:45.11
ファイル  オフィス Azure ブラジル南部 AzCopy Upload 8 02:07.58
ファイル  Azure 東日本 Azure 米国中南部 AzCopy Copy N/A 00:28:55
イメージ  Azure 東日本 Azure 米国中南部 PowerShell N/A 00:11:11
ファイル  Azure 東日本 Azure ブラジル南部 AzCopy Copy N/A 00.25:33
イメージ  Azure 東日本 Azure ブラジル南部 PowerShell N/A 00.09:20

考察

  • アクセス回線の差が大きく影響

    • 自宅パターンでプロバイダから帯域制限されていたかは不明 (自宅からAzure東日本まで16Mbpsくらいは出た)
    • アクセス回線が細い場合はユーザー拠点から「まとめて」送らないほうがいい
    • こまめに送る
    • Azure内でデータを生成する
    • もしくはExpressRouteを引く (自宅で、とは言っていない)
  • アクセス回線が細い場合、AzCopy Uploadの並列数を下げる

    • AzCopyのデフォルト並列数は実行環境のCPUコア数 *8だが、今回実施した端末での並列数(4コア * 8 = 32)ではかえって性能が劣化した
    • アクセス回線に合わせて並列数は調整する
  • Azureのリージョン間コピーは早い

    • Azureバックボーンを通るから
    • 端末よりAzureストレージのほうがリソース的に強いし負荷分散しているから
  • 地理的な距離感覚だけで考えてはダメ

    • 地理的な近さではなく、ネットワーク的な近さと太さ
    • Azureバックボーンを使うと日本とブラジルの間でもそれなりのスループット
  • ファイル数が多いときはイメージで送るのも手

    • ファイル数がコピー時間に影響する (1 vs 6160)
    • そもそもアプリがBlobとして使うのか、ファイルシステムとして使うかにもよるが…
    • もしファイルシステムとして、であれば有効な手段
    • エクスポートのひと手間は考慮
  • Azureバックボーンを使うと、意外にブラジル近い

    • 土管か(ない

Azureバックボーンの帯域にはSLAがありませんが、意識して仕組みを作ると得をします。

09 Apr 2017, 15:15

Azureユーザー視点のLatency測定 2017/4版

関東の片隅で遅延を測る

Twitterで「東阪の遅延って最近どのくらい?」と話題になっていたので。首都圏のAzureユーザー視線で測定しようと思います。

せっかくなので、

計測パターン

  1. 自宅(神奈川) -> OCN光 -> インターネット -> Azure東日本リージョン
  2. 自宅(神奈川) -> OCN光 -> インターネット -> Azure西日本リージョン
  3. 自宅(神奈川) -> OCN光 -> インターネット -> Azure米国西海岸リージョン
  4. Azure東日本リージョン -> Azureバックボーン -> Azure西日本リージョン
  5. Azure東日本リージョン -> Azureバックボーン -> Azure米国西海岸リージョン

もろもろの条件

  • 遅延測定ツール
    • PsPing
    • Azure各リージョンにD1_v2/Windows Server 2016仮想マシンを作成しPsPing
    • NSGでデフォルト許可されているRDPポートへのPsPing
    • VPN接続せず、パブリックIPへPsPing
    • リージョン間PsPingは仮想マシンから仮想マシンへ
  • 自宅Wi-Fi環境
    • 802.11ac(5GHz)
  • 自宅加入インターネット接続サービス
    • OCN 光 マンション 100M
  • OCNゲートウェイ
    • (ほげほげ)hodogaya.kanagawa.ocn.ne.jp
    • 神奈川県横浜市保土ケ谷区の局舎からインターネットに出ているようです
  • 米国リージョン
    • US WEST (カリフォルニア)

測定結果

1. 自宅(神奈川) -> OCN光 -> インターネット -> Azure東日本リージョン

TCP connect statistics for 104.41.187.55:3389:
  Sent = 4, Received = 4, Lost = 0 (0% loss),
  Minimum = 11.43ms, Maximum = 15.66ms, Average = 12.88ms

2. 自宅(神奈川) -> OCN光 -> インターネット -> Azure西日本リージョン

TCP connect statistics for 52.175.148.28:3389:
  Sent = 4, Received = 4, Lost = 0 (0% loss),
  Minimum = 17.96ms, Maximum = 19.64ms, Average = 18.92ms

3. 自宅(神奈川) -> OCN光 -> インターネット -> Azure米国西海岸リージョン

TCP connect statistics for 40.83.220.19:3389:
  Sent = 4, Received = 4, Lost = 0 (0% loss),
  Minimum = 137.73ms, Maximum = 422.56ms, Average = 218.85ms

4. Azure東日本リージョン -> Azureバックボーン -> Azure西日本リージョン

TCP connect statistics for 52.175.148.28:3389:
  Sent = 4, Received = 4, Lost = 0 (0% loss),
  Minimum = 8.61ms, Maximum = 9.38ms, Average = 9.00ms

5. Azure東日本リージョン -> Azureバックボーン -> Azure米国西海岸リージョン

TCP connect statistics for 40.83.220.19:3389:
  Sent = 4, Received = 4, Lost = 0 (0% loss),
  Minimum = 106.38ms, Maximum = 107.38ms, Average = 106.65ms

Azureバックボーンを通すと首都圏からの遅延が半分になりました。Wi-Fiの有無など、ちょっと条件は違いますが。

ひとこと

インターネット、および接続サービスの遅延が性能の上がらない原因になっている場合は、Azureで完結させてみるのも手です。

たとえば、

  • 会社で契約しているインターネット接続サービスが、貧弱
  • シリコンバレーの研究所からインターネット経由でデータを取得しているが、遅い

こんなケースではAzureを間に入れると、幸せになれるかもしれません。なったユーザーもいらっしゃいます。