Skalerbar chat

Tags:    php

Hej igen folkens ;)

Jeg har på det seneste siddet og knækket hovedet med en hjernevrider jeg har påkastet mig selv. Jeg har da selvfølgelig sat mig for at skrive en AJAX chat med PHP ! :)

Indtil nu lader jeg den blot opdatere hvert 2 sekund og når brugeren indsender en besked.

Jeg har så hurtigt ramt en mur. Jeg har valgt at bruge MySQL som backend da det umiddelbart virkede logisk.

Lad os starte med "showchat.php" :
Jeg har en query i toppen der opdaterer den nuværende loggede ind brugers "latestactive" field, så brugeren kan blive logget ud efter 10 sekunders inaktivitet (Det er jo en chat og der skal være fart på.) og så ellers så henter den de seneste 25 beskeder ud fra chatten og returnerer, hvis en session (chat-count) ikke er sat. Og derefter sætter den sessionen til det sidste id den spyttede ud, så næste gang behøves den kun tage beskeder derfra.
- Den opdaterer hvert 2. sekund.

Så har jeg også en "showusers.php"
Den laver noget lignende, den henter bare alle brugere hvor "login" er lige med "true" og så løber dem dem igennem og checker om hver brugers lastactive er inden for 10 sekunder, hvis de er bliver de printet, ellers bliver deres login = false.
- kører hvert 10 sek.



Jeg er ret sikker på jeg har kvajet mig i stor stil mange steder, men det er mit første forsøg på en skalerbar ajax applikation, så bær over med mig :S. Jeg kan trække 20 - 30 brugere før vi rammer 100% cpu på en 1,8GHz single core maskine med 1GB ram (lighttpd og MySQL på FreeBSD)

Jeg er allerede ret sikker på sessions trækker en del tid pga de bruger disken, og at mysql queriesne måske kan optimeres en smule. Jeg har også mistanke til min måde at vise brugere ikke er den bedste, men der er foreslag velkomne. Caching har jeg ikke rigtigt set som en mulighed fordi at en chat (sigter efter 100 bruger mindst på den her maskine - 200 - 300 på produktionsserveren) og det vil gå rigtigt stærkt med så mange i et rum.


Alt kritik og eventuelt hjælp, erfaring, opfordringer osv. er velkomne. Det er bare et hobby projekt det her, men skalerbarhed er altid rart at have lidt erfaring med :P




Det er ultimativ svært at beskrive hvad du gør forkert uden et udgangspunkt - altså noget kode.

30 requests hvert andet sekund er langt fra hvad en server maksimum kan servere.

Så hvis man skal pege uden at have noget at pege på, så vil jeg pege på din måde at du udtrækker data fra databasen og behandler denne igennem din loops.
Stopper du scriptet hvis der ingen opdateringer er, eller fortsætter du gennemløb på noget ligegyldigt?
Kontrollerer du aktivitet med php eller med MySQL?

Lad MySQL håndtere den data du alligevel ikke bruger i PHPen, og hvad lad være med at have PHP til at håndtere noget databasen kan håndtere.
Load så meget du kan i så få requests, og opdater så meget du kan i så få requests.

I princippet vil jeg umiddelbart gætte mig til at en application som den du beskriver vil kunne nøjes med lige omkring 4 requests til databasen.



Det er ultimativ svært at beskrive hvad du gør forkert uden et udgangspunkt - altså noget kode.

30 requests hvert andet sekund er langt fra hvad en server maksimum kan servere.

Så hvis man skal pege uden at have noget at pege på, så vil jeg pege på din måde at du udtrækker data fra databasen og behandler denne igennem din loops.
Stopper du scriptet hvis der ingen opdateringer er, eller fortsætter du gennemløb på noget ligegyldigt?
Kontrollerer du aktivitet med php eller med MySQL?

Lad MySQL håndtere den data du alligevel ikke bruger i PHPen, og hvad lad være med at have PHP til at håndtere noget databasen kan håndtere.
Load så meget du kan i så få requests, og opdater så meget du kan i så få requests.

I princippet vil jeg umiddelbart gætte mig til at en application som den du beskriver vil kunne nøjes med lige omkring 4 requests til databasen.


Tak for svaret jeg poster noget kode herinde senere. Jeg tror jeg vil prøve at bruge json / xml til kommunikation så jeg kan gøre mere pr request som du siger. Frygter ret meget for at mit bruger onlinesystem er den største fejl, måske man kunne bruge cron ?



Ah yes...endnu en chat.

Brug memcached til at optimere datatilgangen.

Hvis sessions kræver diskaccess, så er der noget galt, for operativsystemet skulle da meget gerne have en RAM cache af de senest tilgåede filer. MySQL har også en query cache, så resultatet af de seneste søgninger kan findes frem igen hurtigt uden at parse SQL eller tilgå disken.

Ellers må du i gang med en profilering for at finde ud af, hvad der tager tid: http://www.xdebug.org/docs/profiler



Som Robert siger, kør noget xdebug på den og se hvor det går galt. 20-30 simultane brugere burde den snildt kunne trække.

Når det er sagt, så skalerer PHP ikke særligt godt til det her formål. For det første vil du nok gerne på sigt skifte din 2-sekunders opdatering ud med noget long polling, og så begynder PHP først rigtigt at sløve dine processer. Så på den helt store skala vil jeg fraråde at køre chatten med PHP som backend, men den burde som sagt snildt kunne klare 20-30 simultane brugere med dit nævnte hardware.



Hvilket sprog / system vil i da så anbefale? Skal jeg virkelig ud i en vps med egen serversoftware?



Start du bare med PHP, det er rigeligt til de 20-30 simultane brugere du snakker om, og ganske rimeligt henadvejen til flere også -- men hvis det skal være virkelig stort er du under alle omstændigheder nødt til at have en stærkere server end et webhotel kan tilbyde, uanset om det er PHP eller andet.

Hvis du beslutter dig for at køre noget andet end PHP kan du kigge på APE: http://www.ape-project.org/



Hvilket sprog / system vil i da så anbefale? Skal jeg virkelig ud i en vps med egen serversoftware?


Ja. Hvis det skal skalere til mange.
Jeg har lavet backend til chatten på komogvind.dk og der trækker vi nemt 50.000 samtidige brugere (fordelt på flere lande). Det var nok aldrig gået med HTTP polling (eller push for den sags skyld).

Du kan "snyde" lidt ved at bruge en IRC server.



Indlæg senest redigeret d. 17.12.2010 14:38 af Bruger #2695

Du kan "snyde" lidt ved at bruge en IRC server.

Det er også den fremgangsmåde jeg fedter rundt med for tiden. APE har iøvrigt et super fornuftigt library til at bygge IRC-klienter med.



APE ser ret lovende ud, jeg vil kigge ind i det ! :)

Hvilket sprog / system vil i da så anbefale? Skal jeg virkelig ud i en vps med egen serversoftware?


Ja. Hvis det skal skalere til mange.
Jeg har lavet backend til chatten på komogvind.dk og der trækker vi nemt 50.000 samtidige brugere (fordelt på flere lande). Det var nok aldrig gået med HTTP polling (eller push for den sags skyld).

Du kan "snyde" lidt ved at bruge en IRC server.


Må man spørge hvad sprog du brugte og hvordan du greb opgaven an? Altså om du brugte ajax klientside eller java / flash og holdte en TCP forbindelse åben?


Andet spørgsmål. Tror i man ville få bedre ydelse fra cgi?




Må man spørge hvad sprog du brugte og hvordan du greb opgaven an? Altså om du brugte ajax klientside eller java / flash og holdte en TCP forbindelse åben?


Jeg brugte ikke en IRC server. Jeg desinede og kodede serveren fra bunden i Java, og lavede også en Java applet som så bliver brugt via JavaScript til at sende og modtage chat events. En konstant åben TCP forbindelse er den mest optimale, for med HTTP polling skal der oprettes en masse datastrukturer, og der skal sendes TCP handshake og HTTP headere og alt muligt hver gang der tjekkes. Og mange tjek vil være uden resultat fordi der intet er sket. Og hvis der sker meget, så er det ufedt, at der går to sekunder mellem hver opdatering.


Andet spørgsmål. Tror i man ville få bedre ydelse fra cgi?

Næppe.
CGI er ofte ret tungt, da der skal oprettes en ny process af webserveren. PHP og lignende er moduler, som indlæses af webserveren så de bliver en del af serveren. Meget bedre integration. Med CGI skal der oprettes en proces, og al bruger data (GET/POST/headere og andet) skal leveres af andre kanaler (environment variabler og input strømme) end man kan med et modul som PHP.

CGI er nok kun bedre, når selve behandlingen af dataene er ekstremt tungt så et fortolket sprog er for langsomt...medmindre der er en meget god JIT compiler, som JVM'en.



Indlæg senest redigeret d. 17.12.2010 21:44 af Bruger #2695
t