[java] Socket programming - Performance

Pagina: 1
Acties:

  • B-Man
  • Registratie: Februari 2000
  • Niet online
Ik ben al een paar dagen bezig met het optimaliseren van een een aantal classes van me die over een socket met een MySQL server praten. Ik loop tegen een "probleem" aan in de vorm van onnodige wachttijd bij het uitlezen van een reactie van de MySQL server.

Ik gebruik een Socket, met een BufferedInputStream om de inputstream van deze socket. Mijn java code is efficient m.b.t. method calls voor het uitlezen van response packets: ik lees een return header uit, die de lengte van de payload bevat, en lees vervolgens de rest van het packet in een keer.

Soms duurt het een aantal ms voordat ik een reactie heb. Wat andere data: de belasting van de machine is miniem, ook als ik mijn test prog draai. Mijn classes draaien op dezelfde machine als de MySQL server.

java -Xprof ... op een test class van me die een aantal updates verzend naar MySQL (dezelfde update query, behoort aan de MySQL kant dus snel afgehandeld te worden). Een packet dat een SQL UPDATE query bevat, resulteert in een enkel return packet dat uitgelezen moet worden.

profiler output:
code:
1
2
3
 79.7%     0  +   204    java.io.FileInputStream.readBytes
 15.6%     0  +    40    java.net.SocketInputStream.socketRead0
  0.8%     0  +     2    java.net.PlainSocketImpl.socketConnect


Zijn er zaken die ik over het hoofd zie, of instellingen waar ik eens naar moet kijken?
Ik heb al gespeeld met de input en output buffer op het socket, zonder veel verschil. Heb ook al gekeken naar TCP_NODELAY, zonder al te veel resultaat.

Aangezien de packets die ik verzend evenredig zijn aan de packets die ik ontvang, vind ik het vreemd dat java.io.FileInputStream.readBytes er zo gigantisch uitschiet.

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 30-07 16:33
Kijk eens met een sniffer zoals Ethereal (www.ethereal.com) naar de packetjes die over de loopback interface gaan en op welke tijdstippen.

Als er nogal een tijdverschil zit tussen de tijd dat jij TCP pakketjes van MySQL ontvangt en wanneer jij ze uit de inputstream kan halen zou de vertraging dus aan jouw programma of Java liggen, maar ik heb zo'n vermoeden dat MySQL gewoon niet zo snel reageert.

  • B-Man
  • Registratie: Februari 2000
  • Niet online
Zal ik eens doen, mogelijk biedt dat uitsluitsel...

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
Yo B-Man good idee van nieuwe post. :) ivm data-fetching worden er op alle grote sites altijd layers gemaakt die eerst nazien of er wel degelijk een nieuwe query moet worden gedaan. Weet al niet meer goed welke app maar je zou dus met 'dirty' flags kunnen werken en alzo die trage calls doen. Zowel Slashdot/Anandtech hebben zo'n layer...

  • Jelmer
  • Registratie: Maart 2000
  • Laatst online: 21:47
hobbit_be, heb jij het toevallig over SQL Relay?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Description: SQL Relay MySQL connection daemon.
 SQL Relay is a persistent database connection pooling, proxying and
 load balancing system for Unix and Linux supporting ODBC, Oracle,
 MySQL, mSQL, PostgreSQL, Sybase, MS SQL Server, IBM DB2, Interbase,
 Lago and SQLite with C, C++, Perl, Perl-DBD, Python, Python-DB, Zope,
 PHP, Ruby and Java APIs, command line clients, a GUI configuration tool
 and extensive documentation. The APIs support advanced database
 operations such as bind variables, multi-row fetches, client side
 result set caching and suspended transactions. It is ideal for speeding
 up database-driven web-based applications, accessing databases from
 unsupported platforms, migrating between databases, distributing access
 to replicated databases and throttling database access.
 .
 Homepage: http://sqlrelay.sourceforge.net/ 
 .
 This package contains the MySQL connection daemon.

edit:
hmm vaag van die url (V)... letterlijk uit de debian description gehaald..

[ Voor 6% gewijzigd door Jelmer op 12-03-2003 10:45 ]


Verwijderd

Jelmer schreef op 12 maart 2003 @ 02:21:
hobbit_be, heb jij het toevallig over SQL Relay?
code:
1
2
3
 .
 Homepage: http://www.firstworks.com/sqlrelay.html
 .
maak daar maar even snel http://sqlrelay.sourceforge.net/ van!

  • B-Man
  • Registratie: Februari 2000
  • Niet online
Bedankt! Zal hier eens naar kijken, het klinkt in ieder geval interessant. Overigens zit de traagheid hem in mijn geval in update queries, die per se naar de db server moeten. select queries gaan altijd erg snel.

Overigens heb ik al een aanpassing bedacht die iedere 15 minuten een aantal update queries als batch naar de MySQL server verzend, ipv per run (iedere 5-15 ms).

Aangezien ik nog druk aan het testen ben, en de tabellen die ik query niet meer dan 25 records bevatten, zal het in ieder geval niet aan de indexen liggen.

  • B-Man
  • Registratie: Februari 2000
  • Niet online
Zojuist Ethereal gecompileerd, en maar eens laten draaien terwijl ik in een lus 25x een select, en vervolgens 25x een update afvuur op mijn MySQL server.

Wat ik alleen nog niet heb kunnen vinden is de verklaring van de output.

Bijvoorbeeld:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  0.107449    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Init Database : data
  0.107954    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.111360    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Ping
  0.112123    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.112598    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : select * from accounts
  0.113419    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.131758    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Ping
  0.132551    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.132945    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : select * from accounts
  0.133612    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.136500    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Ping
  0.136665    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.137427    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : select * from accounts
  0.138090    127.0.0.1 -> 127.0.0.1    MySQL Response OK

en
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  0.242581    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : update accounts set id=2 wher
e id=2
  0.243173    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.244901    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Ping
  0.245042    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.245999    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : update accounts set id=2 wher
e id=2
  0.246602    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.247893    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Ping
  0.247993    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.248586    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : update accounts set id=2 wher
e id=2
  0.249081    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.250175    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Ping
  0.250288    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.250854    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : update accounts set id=2 wher
e id=2
  0.251328    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.252394    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Ping
  0.252508    127.0.0.1 -> 127.0.0.1    MySQL Response OK
  0.253080    127.0.0.1 -> 127.0.0.1    MySQL Request Command: Query : update accounts set id=2 wher
e id=2
  0.253555    127.0.0.1 -> 127.0.0.1    MySQL Response OK


Wat is de tijdseenheid van de eerste kolom bijvoorbeeld?

  • Jelmer
  • Registratie: Maart 2000
  • Laatst online: 21:47
Voor de punt hele seconden :)


Maar laat eens multi-threaded 1000 updates en queries random uitvoeren, dan zul je heel wat anders te zien krijgen qua performance denk ik.

[ Voor 72% gewijzigd door Jelmer op 31-03-2003 16:20 ]


  • B-Man
  • Registratie: Februari 2000
  • Niet online
In mijn eigenlijke app draaien een aantal threads, waarvan er een taken verwerkt. Voor iedere taak worden een aantal selects en updates sequentieel uitgevoerd. Aangezien ik op een aantal single-CPU nodes draai (clustered app), is het niet zinvol om met meer dan een "actieve" thread te werken lijkt me.
Pagina: 1