サーバ同時数法則研究


Webサーバのパフォーマンステストでは、コンカレント数は多くの人が関心を持っている話題の一つであり、Webサーバソフトウェアにもコンカレント数が設定されている場所がたくさんあります.しかし,どのような同時数設定が合理的なのか,これは同時数調整にかかわる.本文は先人が研究した合併数法則に基づいてjmeterの圧力測定実践を行い,この法則を検証した.
CPUリソースを十分に活用するためには、一般的には、適切なスレッド数がCPU数+1またはCPU数-1に等しいと考えられるかもしれないが、淘宝蒋江偉氏はQCon 2011の講演PPT(点此查看)で、スレッド数=(CPU時間+CPU待ち時間)/CPU時間)*CPU数を指摘した.この公式はCPUに対してだけであり,正確には機械のボトルネック資源がCPUである場合である.より一般的には、ボトルネックリソースのスレッド並列数=ボトルネックリソースの合計部数/単一リクエストがボトルネックリソースの部数を占有します.
これについて、次の簡単なservletテストを行います.
(jmeter要求端とtomatサービス端は同一マシン上;テストマシンCPUはintelデュアルコア;servlet容器:tomat 5.5,jvm xmin=xmax=256 m;
1.シミュレーションはIO操作を行うが、ボトルネックリソースはCPUであり、sleepでシミュレーションIOを行うため、IOに性能ボトルネックは存在しない.
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws 
            ServletException,IOException {
        long t = System.nanoTime();
        long a = 0;
        long times = Long.valueOf(req.getParameter("times"));
        for (int i = 0; i < times; i++) {
            a = a + 1;
        }
        long timeCost = (System.nanoTime() - t) / 1000000;


        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            logger.warning(e.getMessage());
        }
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("success.times:" + times + ",cpuTimeCost(ms):" + timeCost);
        out.flush();
        out.close(); //        close,         ,           ,   java.net.SocketException:Connect reset
    }
上記servletのdoGetメソッドでは、スレッドsleep 100ミリ秒だけ、IO動作をシミュレートする.ここでservletはtimes=1000000を参照します.jmeterテストの結果は以下の通りです.
スレッドループ数
スレッド数
≪平均レスポンス時間(ミリ秒)|Average Response Time|emcore≫
tps
cpu
2000
2
114
17.4
15%~20%
2000
5
113
43.7
>50%
2000
10
107
92
60%程度
2000
15
107
137.5
<80%
2000
20
109
176.1
90%前後
2000
25
112
212.3
<100%
2000
30
118
237.4
100%
2000
35
130
238.4
100%
統計データから見ると、10同時までの平均応答時間はまだ最高に達しておらず、cpu負荷は高くない.(しかし、なぜか応答時間が最も理想的ではない)10~20同時では、平均応答時間は110 ms未満であり、cpu負荷は比較的旺盛であり、これまでtpsは着実に向上してきた.30同時以降,平均応答時間は長くなり始め,tpsには上昇空間がなくなった.
以前に与えられた式と比較すると,最も速いのは107 ms程度であり,シミュレーションIOは100 msを占めるため,cpu演算時間は7 msであり,式によればスレッド数=(100+7)/7*2=30.5である.統計データでは、30同時以降、基本的にボトルネックに達している.期待の法則を満たす.
2.CPU密集要求をシミュレーションする.ボトルネックリソースはCPUのままです.
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws 
            ServletException, IOException {
        long t = System.nanoTime();
        long a = 0;
        long times = Long.valueOf(req.getParameter("times"));
        for (int i = 0; i < times; i++) {
            a = a + 1;
        }
        long timeCost = (System.nanoTime() - t) / 1000000;
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("success.times:" + times + ",cpuTimeCost(ms):" + timeCost);
        out.flush();
        out.close(); //        close,         ,           ,   java.net.SocketException:Connect reset
    }
上記servletのdoGetメソッドでは、sleepシミュレーションIOはありません.ここでservletはtimes=1000000を参照します.jmeterテストの結果は以下の通りです.
スレッドループ数
スレッド数
≪平均レスポンス時間(ミリ秒)|Average Response Time|emcore≫
tps
cpu
100
1
84
11.6
100%
100
2
84
22.4
100%
100
3
129
22.5
100%
統計の結果、2つの同時状況で機械資源がいっぱいになった.3つの同時でtpsはもう上昇空間がない.
式によると、スレッド数=84/84*2=2で、2つのスレッドのときにリソースの最高利用に達します.
上記の2つの例はいずれもcpuをボトルネックとするシーンであり,データベースがボトルネックであれば式の項目を応答的に調整するが,原理は同じであり,ここでは例を挙げて検証しない.したがって,システムの同時数チューニングでは,cpuの数だけ1を増やしたり減らしたりするのではなく,ボトルネックリソースから角度まで相応の判断を行う.もちろん、実際の同時チューニングはhttpサーバ、webコンテナのパラメータ、jvm設定など、多くの要因の影響を受けています.本稿では、ボトルネックリソースの観点から同時数を見るだけです.引き続き検討します.