Etikettarkiv: prestanda

Bättre prestanda med Unix domain sockets

Ett sätt att öka prestandan när det gäller kommunikation internt inom ditt eget system är att använda Unix domain sockets. Istället för att använda TCP för att kommunicera internt mellan processer på ditt system så bör du med fördel använda Unix-sockets då detta påverkar prestandan positivt.

Några exempel på där du kan använda Unix-sockets är i Redis samt om du använder Nginx och PHP-FPM. För att använda Unix-sockets i Redis behöver du enbart lägga till följande rad i redis.conf:

unixsocket /tmp/redis.sock

Och för att använda denna socket när du ansluter kan variera lite beroende på vilken klient du använder, men på följande sätt gör jag:

$redis->connect(‘/tmp/redis.sock’);

Glöm inte att rättigheterna på /tmp/redis.sock måste vara så att både Redis samt klienten kan läsa. Nu över till hur man konfigurerar Nginx och PHP-FPM att använda sockets.

Första steget är att konfigurera FPM att lyssna på en socket, och detta görs i konfigurationsfilen. Min återfinnes här:

/etc/php5/fpm/pool.d/www.conf

Och i denna fil ändrar jag där raden listen återfinnes så det ser ut något i stil med:

listen = /var/run/php5-fpm.sock

Och nästa steg är att ändra så att Nginx vet att vi har en Unix-socket för PHP-exekvering och det kan göras genom att lägga till eller ändra din ”upstream” om du använder en sådan:

upstream php {
        server unix:/var/run/php5-fpm.sock;
}

Och sedan använda fastcgi_pass php på följande sätt till varje server:

     location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include /etc/nginx/fastcgi_params;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
        }

Vill du fördjupa dig ännu mer gällande Unix sockets kan du läsa här. MySQL och PHP skall enligt manualsidan automatiskt välja Unix sockets om det finns tillgängligt vilket det bör göra standardmässigt.

Snabbare Redis

Du som följer denna blogg sedan en tid tillbaka vet kanske att jag har en liten förkärlek till Redis som är en key-value storage mjukvara. Jag har tidigare genomfört prestandatester som visat på att Redis är sjukt snabbt för både läsning och skrivning, eller som de själva beskriver:

Redis is pretty fast!, 110000 SETs/second, 81000 GETs/second in an entry level Linux box. Check the benchmarks.

Och eftersom jag använder Redis i mer eller mindre alla mina nya projekt så testade jag huruvida det är möjligt att få upp hastigheten ytterligare, och det visade sig vara möjligt. Enligt följande så kan du minska minnesförbrukning och få upp hastigheten mellan 20-90%.

Först och främst så bör du installera Redis 2.2 RC1 som bl.a. stödjer Unix sockets vilket gör att du inte behöver ta en extra omväg över TCP/IP-stacken.

Sedan så måste du se till att det klientbibliotek du använder mot Redis stödjer Unix sockets, py-redis gör det med en patch (se längst ner) samt så stödjer phpredis Unix-sockets. Ändra även i redis.conf genom att lägga till följande:

unixsocket /ebs/redis.sock

Vilket pekar ut sökvägen till den socket som skall användas för kommunikation, konfigureras även när du ansluter i ditt klientbibliote på följande sätt när det gäller PHP (phpredis):

if(!$redis->connect('/ebs/redis.sock'))
     die("Can't connect to redis socket\n");

Och för Python:

r = redis.Redis(host='/ebs/redis.sock', port=0, db=0)

Om du vill vara ännu våghalsig så kan du ställa in hur ofta Redis skall skriva till disken och där har jag bortkommenterat så att skrivningar ej görs allt för ofta. Detta leder dock till att du kan förlora information:

#save 900 1
#save 300 10
save 60 10000
rdbcompression no

Uppdatering: Ett annat sätt att få upp prestandan är att använda pipelines vilket gör att kommandon  ej exekveras direkt och väntar på att din pipe skall exekveras istället. Montera även filsystemet med noatime vilket kan snabba upp diskskrivningar.

Testa svarstiderna på din webbplats med Apache Benchmark

ab (ApacheBenchmark) är ett programm som följer med webbservern Apache som används för att testa svarstider på webbplatser. ab är mycket lätt att använda.

"ab is a tool for benchmarking your Apache Hypertext Transfer Protocol (HTTP) server. It is designed to give you an impression of how your current Apache installation performs. This especially shows you how many requests per second your Apache installation is capable of serving.”

Dess argument är enligt följande:

Usage: ab [options] [http[s]://]hostname[:port]/path

Options are:
-n requests     Number of requests to perform
-c concurrency  Number of multiple requests to make
-t timelimit    Seconds to max. wait for responses
-p postfile     File containing data to POST
-T content-type Content-type header for POSTing

-v verbosity    How much troubleshooting info to print

-w              Print out results in HTML tables

-i              Use HEAD instead of GET

-x attributes   String to insert as table attributes

-y attributes   String to insert as tr attributes

-z attributes   String to insert as td or th attributes

-C attribute    Add cookie, eg. 'Apache=1234. (repeatable)

-H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'Inserted after all normal header lines. (repeatable)

-A attribute    Add Basic WWW Authentication, the attributes
are a colon separated username and password.
-P attribute    Add Basic Proxy Authentication, the attributes
are a colon separated username and password.
-X proxy:port   Proxyserver and port number to use
-V              Print version number and exit
-k              Use HTTP KeepAlive feature
-d              Do not show percentiles served table.

-S              Do not show confidence estimators and warnings.

-g filename     Output collected data to gnuplot format file.

-e filename     Output CSV file with percentages served

-h              Display usage information (this message)

-Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)

-f protocol     Specify SSL/TLS protocol (SSL2, SSL3, TLS1, or ALL)

Så för att göra ett prestandatest med 10 stycken webbförfrågningar mot webbservern på download11.com så skriver jag:

$ ab -n 10 -v 2 http://download11.com/

Och från detta kommer en mängd utdata och det som är intressant är följande rader:

[..]
Connection Times (ms)min  mean[+/-sd] median   max
[..]
Total:         46   50   7.9     48      68

Här ser vi ovan att median för svarstiderna är 50 ms vilket är helt ok, svarstiderna bör befinna sig under 100ms vilket är anses vara acceptabelt.

Testar jag i stället webbsajten bloggz.se med en sökfråga på följande sätt:

$ ab -n 10 http://bloggz.se/search?q=tore

Så ser vi följande svarstider istället:

[..]
Connection Times (ms)min  mean[+/-sd] median   max[..]

Total:        278  415 141.2    366     695

Här är svarstiden 415 ms vilket inte är acceptabelt och betyder att jag måste optimera PHP-koden mer vilket jag kommer att återkomma till.