Basic personligt

Daniel Brahneborgs blogg

Connection Pool

På jobbet hamnade jag i en situation som skulle kunna göra att våra stackars kunder skulle få tusentals samtidiga uppkopplingar till sin MySQL-databas. Tio kanske är ok, i bästa fall hundra, men därefter tror jag inte att databasen blir så glad längre. Alltså behövdes en “connection pool”,  så att det bara behövdes så många uppkopplingar som faktiskt användes samtidigt. Om det behövdes för många uppkopplingar, fick de trådarna helt enkelt ställa sig på kö. Så långt var det det ju inget konstigt.

Tyvärr är vår applikation skriven i C, så alla färdiga paket för sådant här, som nästan alltid är skrivna i Java, går inte att använda. Istället för att ägna halva dagen åt att leta upp något existerande som gick att använda från C, bedöma om licensen gjorde det användbart, fundera över prislappen, anpassa till vår produkt osv, så satte vi oss ner och skissade på en egen implementation.

Först behövs en struct för poolen.

  • int size // antalet skapade resurser (uppkopplingar)
  • int maxsize // det maximala antalet tillåtna resurser, typiskt 10 eller så
  • lock // lås, så att inte flera trådar försöker komma åt poolen samtidigt
  • list available // lediga resurser
  • list waiting // lås för trådar som väntar på en ledig resurs
  • creator // funktion som skapar en ny resurs

Sedan behövs två små algoritmer. Först den för att hämta en resurs ur poolen.

  1. Lås pool.lock.
  2. Om det finns något i available-listan:
    1. Plocka ut första objektet i available-listan.
  3. Annars, om size < maxsize, dvs vi kan skapa fler resurser:
    1. Anropa creator-funktionen, och låt det objektet bli det som ska returneras.
    2. Räkna upp size.
  4. Annars:
    1. Hämta trådens lås från treadlocal.
    2. Lås trådens lås, och lägg det sist i waiting-listan.
  5. Lås upp pool.lock.
  6. Om vi ska vänta:
    1. Lås trådens lås igen, vilket gör att tråden hänger.
    2. När låset släpps, börja om från början.
  7. Returnera resursen.

Det behövs självklart också en liten algoritm för att lämna tillbaka resursen när den inte längre behövs.

  1. Lås pool.lock.
  2. Lägg tillbaka resursen i available-listan.
  3. Om waiting-listan inte är tom:
    1. Plocka ut första låset ur waiting-listan, och lås upp det.
  4. Lås upp pool.lock.

Om det finns lediga objekt krävs därför bara ett lås, annars två. Eftersom man plockar ut låsen ur en ordnad lista, är den helt rättvis. Det sker ingen busywait. Det skulle enkelt gå att öka maxsize i ett körande system, och med ett litet tillägg vid återlämnandet kan maxsize även minskas. Själva implementationen, inklusive några justeringar av algoritmen, var klar strax efter lunch.

Läs även andra bloggares åsikter om datorer, programmering, teknik, databas, mysql, connection pool.

pixelstats trackingpixel

August 26th, 2009 Posted by Daniel Brahneborg | blogg | no comments

No Comments »

No comments yet.

Leave a comment

CommentLuv Enabled
Please leave these two fields as-is:

Protected by Invisible Defender. Showed 403 to 487 bad guys.