2

Azure SQL を使用して Azure Cloud Services 用に開発された Web アプリケーションがあります。1 つのデータベースから開始し、JMeter を使用して、同じ Azure データセンター内の専用仮想マシンから負荷テストを実行しました。テスト計画は、1 つのページのみをテストし、そのページへの投稿のみを行うように設定されました (最初の get 要求は無視されます)。

私の目標は、アプリが 1 秒間に処理できるデータベース トランザクションの最大数を決定することでした。私の最初の一連のテストでは、このテスト計画を使用して平均 300 リクエスト/秒という結果になりました。

問題のページは、次のテーブルにアクセスしています。

create table [dbo].[Entries]
(
    [Id]                   int                 not null        identity(1,1)
    /* other columns here, about 10 in total */ 
);

alter table [dbo].[Entries] add constraint [PK_Entries] primary key ([Id]);
alter table [dbo].[Entries] add constraint [DF_Entries_Created] default(getutcdate()) for [Created];

create index [IX_Entries_EmailAddress] on [dbo].[Entries] ([EmailAddress]);
create index [IX_Entries_NACSZ] on [dbo].[Entries] 
(
     [FirstName]
    ,[LastName]
    ,[Address1]
    ,[City]
    ,[State]
    ,[Postal]
);

ページは次の 2 つのクエリのみを実行します。

select 1 where exists 
(
    select 1 from Entries
     where EmailAddress = @EmailAddress
        or (
                    FirstName       = @FirstNAme
                and LastName        = @LastName
                and Address1        = @Address1
                and City            = @City
                and State           = @State
                and Postal          = @Postal
           ) 
);

insert into Entries
(
    ...
)
values
(
    ...
);

select cast(scope_identity() as int);

私のマシン (クアッド コア、8GB RAM、ローカル SQL 2012 Express インストール) でのパフォーマンス テストでは、最大 800 要求/秒が得られたので、Azure のサーバーで約 300 要求/秒のピークを見てかなりショックを受けました。これをデータベース サーバーでのリソースの競合に結びつけ、シャーディングをサポートするために必要なコードを追加しました。シャーディング メカニズムは、キー フィールドの 1 つで一貫したハッシュを使用して、使用する接続文字列を決定します (現在、3 つの可能性から)。ここでの目標は、データベースの負荷を 3 つの Azure SQL データベースに分割し、アプリの同時実行係数を上げることでした。

シャーディング メカニズムが機能することを確認し (最終的に各データベースにほぼ同数のエントリが作成される)、ページから不要なコードをすべて取り除き、上記の 2 つのクエリだけが実行されるようにしました。トランザクションでデフォルトの分離レベル (読み取りコミット) を使用しています。最終的なコードは次のようになります。

using (var db = ConnectToShard(keyToHash))
using (var tx = db.BeginTransaction(IsolationLevel.ReadCommitted))
{
    // execute query 1
    // if result from query 1 is null, 
    //     execute query 2

    tx.Commit();
}

ただし、この余分な作業をすべて行っても、リクエスト/秒を 500 程度以上にプッシュすることはできないようです。私の理想的な目標は 1000 です。Azure SQL のパフォーマンスに関して何かが欠けていると思いますが、それが何かはわかりません。リクエスト/秒を改善するための考えや提案はありますか?

4

0 に答える 0