Porównanie wydajności Windows Server 2012 i Linux Debian testing

Jak obiecałem proste porównanie wydajności najpopularniejszych technologii webowych (php i mysql) w realizacji Windows i Linux. Wszystko na możliwie domyślnych ustawieniach, opis instalacji jest w poprzednich wpisach mojego blogu.

PHP

Użyłem tego skryptu.

Windows

--------------------------------------
|        PHP BENCHMARK SCRIPT        |
--------------------------------------
Start : 2012-12-29 16:24:43
Server : 10.1.1.9@
PHP version : 5.4.9
Platform : WINNT
--------------------------------------
test_math                 : 2.487 sec.
test_stringmanipulation   : 4.039 sec.
test_loops                : 1.363 sec.
test_ifelse               : 0.926 sec.
--------------------------------------
Total time:               : 8.815 sec.

--------------------------------------
|        PHP BENCHMARK SCRIPT        |
--------------------------------------
Start : 2012-12-29 16:24:59
Server : 10.1.1.9@
PHP version : 5.4.9
Platform : WINNT
--------------------------------------
test_math                 : 2.607 sec.
test_stringmanipulation   : 4.039 sec.
test_loops                : 1.424 sec.
test_ifelse               : 0.953 sec.
--------------------------------------
Total time:               : 9.023 sec.

--------------------------------------
|        PHP BENCHMARK SCRIPT        |
--------------------------------------
Start : 2012-12-29 16:25:18
Server : 10.1.1.9@
PHP version : 5.4.9
Platform : WINNT
--------------------------------------
test_math                 : 2.581 sec.
test_stringmanipulation   : 3.936 sec.
test_loops                : 1.532 sec.
test_ifelse               : 0.957 sec.
--------------------------------------
Total time:               : 9.006 sec.

Linux

--------------------------------------
|        PHP BENCHMARK SCRIPT        |
--------------------------------------
Start : 2012-12-29 16:47:00
Server : 10.1.1.9@10.1.1.9
PHP version : 5.4.4-10
Platform : Linux
--------------------------------------
test_math                 : 1.537 sec.
test_stringmanipulation   : 1.526 sec.
test_loops                : 1.212 sec.
test_ifelse               : 0.867 sec.
--------------------------------------
Total time:               : 5.142 sec.

--------------------------------------
|        PHP BENCHMARK SCRIPT        |
--------------------------------------
Start : 2012-12-29 16:47:13
Server : 10.1.1.9@10.1.1.9
PHP version : 5.4.4-10
Platform : Linux
--------------------------------------
test_math                 : 1.532 sec.
test_stringmanipulation   : 1.541 sec.
test_loops                : 1.212 sec.
test_ifelse               : 0.867 sec.
--------------------------------------
Total time:               : 5.152 sec.

--------------------------------------
|        PHP BENCHMARK SCRIPT        |
--------------------------------------
Start : 2012-12-29 16:47:21
Server : 10.1.1.9@10.1.1.9
PHP version : 5.4.4-10
Platform : Linux
--------------------------------------
test_math                 : 1.571 sec.
test_stringmanipulation   : 1.568 sec.
test_loops                : 1.218 sec.
test_ifelse               : 0.867 sec.
--------------------------------------
Total time:               : 5.224 sec.

Widać znaczącą, prawie dwukrotną różnicę. Ciekawe, że jest ona głównie spowodowana operacjami na ciągach tekstowych.

MySQL

Żeby mieć dostęp do MySQL z osobnego komputera który wykonywał test, chwilowo wyłączyłem zaporę Windows, w Linuksie zmienił adres bindowania na używany przez serwer adres IP:

jak również zezwoliłem na dostęp do MySQL z tego komputera:

mysql> GRANT ALL ON *.* to root@'10.0.0.11' IDENTIFIED BY 'your-mysql-root-password'; 

mysql> FLUSH PRIVILEGES;

Test wykonano przy użyciu sysbench w następujący sposób:

sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=5t6y7u* prepare --mysql-host=10.1.1.9

sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=5t6y7u* --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 --mysql-host=10.1.1.9 run 

sysbench --test=oltp --mysql-db=test --mysql-user=root --mysql-password=5t6y7u* --mysql-host=10.1.1.9 cleanup 

Windows

$ sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=5t6y7u* --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 --mysql-host=10.1.1.9 run 
sysbench 0.4.12:  multi-threaded system evaluation benchmark

No DB drivers specified, using mysql
Running the test with following options:
Number of threads: 8

Doing OLTP test.
Running mixed OLTP test
Doing read-only test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Threads started!
Time limit exceeded, exiting...
(last message repeated 7 times)
Done.

OLTP test statistics:
    queries performed:
        read:                            86324
        write:                           0
        other:                           12332
        total:                           98656
    transactions:                        6166   (102.69 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 86324  (1437.67 per sec.)
    other operations:                    12332  (205.38 per sec.)

Test execution summary:
    total time:                          60.0445s
    total number of events:              6166
    total time taken by event execution: 480.1353
    per-request statistics:
         min:                                 30.02ms
         avg:                                 77.87ms
         max:                                638.93ms
         approx.  95 percentile:             176.30ms

Threads fairness:
    events (avg/stddev):           770.7500/8.36
    execution time (avg/stddev):   60.0169/0.01



$ sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=5t6y7u* --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 --mysql-host=10.1.1.9 run 
sysbench 0.4.12:  multi-threaded system evaluation benchmark

No DB drivers specified, using mysql
Running the test with following options:
Number of threads: 8

Doing OLTP test.
Running mixed OLTP test
Doing read-only test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Threads started!
Time limit exceeded, exiting...
(last message repeated 7 times)
Done.

OLTP test statistics:
    queries performed:
        read:                            92540
        write:                           0
        other:                           13220
        total:                           105760
    transactions:                        6610   (110.09 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 92540  (1541.29 per sec.)
    other operations:                    13220  (220.18 per sec.)

Test execution summary:
    total time:                          60.0405s
    total number of events:              6610
    total time taken by event execution: 480.0557
    per-request statistics:
         min:                                 31.50ms
         avg:                                 72.63ms
         max:                                575.66ms
         approx.  95 percentile:             150.75ms

Threads fairness:
    events (avg/stddev):           826.2500/7.07
    execution time (avg/stddev):   60.0070/0.01

Linux

$ sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=5t6y7u* --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 --mysql-host=10.1.1.9 run 
sysbench 0.4.12:  multi-threaded system evaluation benchmark

No DB drivers specified, using mysql
Running the test with following options:
Number of threads: 8

Doing OLTP test.
Running mixed OLTP test
Doing read-only test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Threads started!
Time limit exceeded, exiting...
(last message repeated 7 times)
Done.

OLTP test statistics:
    queries performed:
        read:                            105588
        write:                           0
        other:                           15084
        total:                           120672
    transactions:                        7542   (125.61 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 105588 (1758.53 per sec.)
    other operations:                    15084  (251.22 per sec.)

Test execution summary:
    total time:                          60.0432s
    total number of events:              7542
    total time taken by event execution: 480.1444
    per-request statistics:
         min:                                 27.44ms
         avg:                                 63.66ms
         max:                               1148.64ms
         approx.  95 percentile:             104.79ms

Threads fairness:
    events (avg/stddev):           942.7500/9.23
    execution time (avg/stddev):   60.0180/0.01




$ sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=5t6y7u* --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 --mysql-host=10.1.1.9 run 
sysbench 0.4.12:  multi-threaded system evaluation benchmark

No DB drivers specified, using mysql
Running the test with following options:
Number of threads: 8

Doing OLTP test.
Running mixed OLTP test
Doing read-only test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Threads started!
Time limit exceeded, exiting...
(last message repeated 7 times)
Done.

OLTP test statistics:
    queries performed:
        read:                            27202
        write:                           0
        other:                           3886
        total:                           31088
    transactions:                        1943   (32.35 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 27202  (452.87 per sec.)
    other operations:                    3886   (64.70 per sec.)

Test execution summary:
    total time:                          60.0660s
    total number of events:              1943
    total time taken by event execution: 480.2274
    per-request statistics:
         min:                                 50.11ms
         avg:                                247.16ms
         max:                                931.82ms
         approx.  95 percentile:             531.09ms

Threads fairness:
    events (avg/stddev):           242.8750/1.05
    execution time (avg/stddev):   60.0284/0.01

Tu również mamy drobną różnicę na korzyść Linuksa, choć mniejszą niż w przypadku PHP.
Ciekawe, że choć przeciętne czasy Linuks ma lepsze, w obu testach maksymalnego czasu wygrywa Windows.

Wnioski

Wszystkie testy zostały wykonane na tym samym komputerze i według mnie dowodzą pewnej przewagi Linuksa. Oczywiście, możliwe jest poprawianie konfiguracji tak PHP jak i MySQL w celu osiągnięcia lepszych wyników, ale nie robiłem tego, jako że znam Linuksa zdecydowanie lepiej i mogła by wyjść pewna "stronniczość".
Czy zatem Linuksa należy używać na każdym serwerze? Niekoniecznie. Różnice choć duże nie powinny być znaczące w skali pojedynczych serwerów, zaś cześć administratorów bardziej znających Windowsa może lepiej wykorzystać swój czas niż na poznawanie innego systemu. Ponadto, na Windows Server możemy uruchomić różne środowiska, jak PHP, Python, ASP.NET (jak dobreprogramy.pl :), czego nie możemy powiedzieć o Linuksie, na którego chyba nie istnieją dobre serwery technologii Microsoftu.