2011年4月4日

TableストレージにおけるExpect100ContinueとUseNagleAlgorithmの効果(1)~1件のエンティティ追加の場合

Windows AzureのTableストレージに関するホワイトペーパー「Windows Azure Table – テーブルストレージのプログラミング」(http://www.microsoft.com/japan/windowsazure/whitepapers/)では、ストレージのパフォーマンス向上のために、Expect100ContinueおよびUseNagleAlgorithmをfalseにすることが推奨されている(p67-68あたり)。

ただ実際のところ、この設定がどの程度パフォーマンスに影響を及ぼすか不明だったため、試してみた。

計測プログラムのソースコード(一部)

以下のプログラムを用いて、今回のパフォーマンス計測を行った。計測する処理は、1件のエンティティを作成するパターン(simple)と10件のエンティティをEntity Group Transactionを用いて作成するパターンの二通りを計測する。

またコード中のWorkUnit.Inspect内部では、引数で与えられたラムダ式部分のパフォーマンス計測を行っている。

		public override void Run() {
			var account = CloudStorageAccount.Parse(
				RoleEnvironment.GetConfigurationSettingValue("Cirrus.DemoApp.ConnectionString"));
			var client = account.CreateCloudTableClient();

			client.CreateTableIfNotExist("Person");

			while ( true ) {
				FabricContext.NewContext(); //毎ループごとにコンテキストを新しくする

				{
					var ctx = GetTargetContext(client, 1);

					WorkUnit.Inspect("simple", () => {
						ctx.SaveChangesWithRetries();
					});
				}

				{
					var ctx = GetTargetContext(client, 10);

					WorkUnit.Inspect("batch", () => {
						ctx.SaveChangesWithRetries(System.Data.Services.Client.SaveChangesOptions.Batch);
					});
				}
			}
		}

		public TableServiceContext GetTargetContext(CloudTableClient client, int count) {
			var ctx = client.GetDataServiceContext();

			for ( int i = 0; i < count; i++ ) {
				ctx.AddObject("Person", new Person() {
					PartitionKey = "Partition",
					RowKey = Guid.NewGuid().ToString("N"),
					Name = "はまちちゃん",
					Profile = "ぼくはまちちゃん!こんにちはこんにちは!!",
					Age = 15,
					Birthday = DateTime.UtcNow
				});
			}

			return ctx;
		}


		public override bool OnStart() {
			ServicePointManager.UseNagleAlgorithm = true;
			ServicePointManager.Expect100Continue = true;

			ServicePointManager.DefaultConnectionLimit = 12;

			var wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
			var account = CloudStorageAccount.Parse(
				RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));

			var roleInstanceDiagnosticManager = account.CreateRoleInstanceDiagnosticManager(
				RoleEnvironment.DeploymentId, RoleEnvironment.CurrentRoleInstance.Role.Name, 
				RoleEnvironment.CurrentRoleInstance.Id);

			var config = roleInstanceDiagnosticManager.GetCurrentConfiguration();
			if ( null == config ) {
				config = DiagnosticMonitor.GetDefaultInitialConfiguration();
			}

			config.Logs.ScheduledTransferPeriod = TimeSpan.FromSeconds(10);
			config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Undefined;

			roleInstanceDiagnosticManager.SetCurrentConfiguration(config);

			return base.OnStart();
		}

1件のエンティティ追加に関するパフォーマンス測定結果

ベースライン

まずはベースラインとして、Expect100ContinueおよびUseNagleAlgorithmを両方共trueにした場合のパフォーマンスを測ってみると、以下の結果が得られた。

平均値や90%ラインなどは10分単位で集計した値(単位は全てms)。

Time Avg 80% 90% 95% Min Max
20110404-0400 208.475 228 255 302 113 754
20110404-0410 213.608 232 271 310 118 747
20110404-0420 207.101 226 247 287 114 742

image

見てわかる通り、1件のエンティティ作成にかかる時間が平均200msもかかっており、非常に遅い。

Expect100Continue=falseの測定結果

引き続き、Expect100Continueをfalseにした場合の測定を行う。

測定に使用したソースコードは上記ソースコードにおいて、ServicePointManager.Expect100Continue=trueの部分をfalseに書き換えたものである。

Time Avg 80% 90% 95% Min Max
20110404-0400 218.12 237 270 307 121 1572
20110404-0410 217.817 234 266 298 122 841
20110404-0420 215.147 234 263 301 120 1417

image

この結果をベースラインと比較すると、パフォーマンスが劣化しているもしくはほとんど変わらない程度の結果となり、少なくともパフォーマンスの向上は確認できなかった。

UseNagleAlgorithm=falseの測定結果

引き続き今度は、UseNagleAlgorithmをfalseにした場合のパフォーマンス測定を行う。

測定に使用したソースコードは上記で示したソース中のServicePointManager.UseNagleAlgorithm=trueの部分をfalseに書き換えたのみである。

Time Avg 80% 90% 95% Min Max
20110404-0400 38.974 38 54 93 18 682
20110404-0410 38.227 38 52 80 17 685
20110404-0420 37.488 39 51 78 17 682

image

ベースラインおよびExpected100Continue=falseの場合の測定結果と比較すると、かなりのパフォーマンス向上が確認できた(ベースラインと比較して、1件あたり1/5程度の時間)。このパフォーマンス向上の原因は、元のベースラインの場合ではNagleアルゴリズムによるWAITがあったが、UseNagleAlgorithm=falseとしたことでNagleアルゴリズムが適用されなくなったためと考えられる。

まとめ

以上の結果をまとめると、

  • 小さなリクエストではNagleアルゴリズムによるパフォーマンス劣化が発生する
  • UseNagleAlgorithmをfalseに設定することによって、上記のパフォーマンス劣化を回避できる
  • Expected100Continueによるパフォーマンス向上は確認できず

といった結論が得られた。

エンティティグループトランザクションを利用した場合の結果については別記事にて。

0 件のコメント:

コメントを投稿