![]() |
Har en massa trevliga community-funktioner på Sockerdricka men de kräver en sjujäkla massa av databasservern så nu när det är lite över 500 samtidigt inloggade användare så kämpar den för sitt liv den stackaren. Jag tänkte då naturligtvis replikera databasen och enklast vore att ha flera masters eftersom varje sidvisning kräver ett antal SELECT och kör minst en UPDATE och/eller INSERT.
Allt var frid och fröjd och jag skulle just beställa ytterligare en maskin när jag kom att tänka på att jag i alla tabeller använder mig av auto-increment-kolumner för primärnycklar. Om en master gör en INSERT i messages-tabellen till exempel och den andra gör det samtidigt så kommer det finnas två meddelanden med samma PK och båda servrarna kommer att kasta BAD_PRIMARY_KEY när de exekverar den andras INSERT. Är det någon som löst det här problemet? Jag har boken High Performance MySQL och författarna föreslår ett antal sätt att lösa problemet men de kräver alla ett oerhört jobb i att ändra hur skripten använder primärnycklar. |
Jag vet inte hur replikeringen ser ut i senare versioner (säg 4.1 här), men du borde bara ha två saker att välja mellan. Antingen ha en master som tar hand om alla inserts och en massa slavar, då slipper du problemen med autoincrement. Det är när du ska ha INSERT och UPDATEs spridda på flera servrar som det strular till sig. Då är det ett måste att ha någon slags funktion som håller reda på högsta id oavsett vilken server som vill sätta in raden i tabellen.
Om det är någon som vet mer så dela gärna med er, är intresserad av sådan lösning också. Har aldrig hittat något vettigt på nätet angående detta. |
Om ni har en handler för alla sql-frågor så borde det inte vara en alltför avancerad historia att tex köra ett regexp på frågorna för att ta reda på vad som är en INSERT/UPDATE och köra dom mot en server medans andra frågor går mot en annan server (och då kan ni juh redan där ha någon slags round-robin för att sprida frågorna mellan olika select-servrar).
|
Vad har du för hårdvara nu? 500 inloggade samtidigt låter inte så farligt. Jag känner till ett community som också kör MySQL och har 5000 samtidigt inloggade och klarar sig med dual opteron. Visst, det är en krallig burk men nu har den siten 10 gånger fler samtidigt aktiva besökare och efter en snabb titt på Sockerdricka så ser den inte så farligt tung ut heller.
Edit: Helt utan erfarenhet av replikerade databaser kommer jag och tänka på en lösning. Låt den ena mastern insert:a jämna auto increment-värden och den andra ojämna. Jag tror inte det finns inställning för att göra det automatiskt i MySQL dock, så du måste kontrollera detta manuelt vilket iofs kan bli tungt... En annan lösning vore att skapa en till primary key av typen bool. Defautlvärdet får vara 0 på ena servern och 1 på andra. Efter lite snabbt grubblande låter det hyssat fungerande i mitt huvud. Förmodligen en dum idé ändå =) |
Citat:
|
Jag håller med om att 500 samtidigt inloggade användare inte låter speciellt mycket. För de 500 lär ju knappast accessa databasen exakt samtidigt.
Innan jag viftade med lastbalanseringsplakatet skulle jag nog: 1) KOlla över att all DB access (select, insert, delete, update) är optimerad. Finns de rätta indexen etc. 2) Sedan handlar det om att kika på vad som görs. Låses tabeller när det inte behövs osv. Går det att göra de "slöa" sakerna på ett bättre sätt. Du kanske redan gjort detta och kommit fram till att visst koden är dålig ut prestandasynpunkt och det kostar för mycket at skriva om saker så de är snällare mot databasen. Och även om vi tittar på ett mer generellt fall så är det ju så att förr eller senare vill man ju kanske lastbalansera. Fast då kanske inte MySql bör vara ett förstahandsval. |
Citat:
|
Citat:
|
Citat:
Citat:
Citat:
Citat:
Jag skulle mycket uppskatta hjälp med problemet jag har, dvs att replikera över flera masters men ändå använda auto_increment. |
Detta är ett välldigt intressant ämne men även komplicerat tyvär.
Är själv intresserad av replication men inte pga performance utan vill istället ha hög availability och det är ju inget direkt problem om man jämför med ditt. Har läst http://dev.mysql.com/doc/mysql/en/Replication_FAQ.html och har inte hittat något som svarar på din fråga men hittada detta. Citat:
|
Inte för att det är ett svar på frågan.
Men cachar ni de mest besökta/ mest databas- intensiva sidorna ? |
Citat:
Citat:
|
Då kommer replication inte att ge någon bost i performance enligt vad dom själva anger i sin faq utan det kan istället bli tvärtom pga man lägger till en kommunikations overhead. Detta är ju inte särskilt konstigt eftersom alla update alter måste gå ut till alla servrar så det är endast fördelningen ev reads som ger lättnad åt servern och en read kräver sällan mer än en write så lättnaden blir inte så stor. Detta är ju egentligen inte din fråga så ursäkta om det blev för mycket off topic.
Det du borde kolla på är deras cluster lösning som jag inte känner till men som verkar intresant, tror att den redan är släppt eller så kommer den att släppas snart, kanske någon här som vet mer om den? |
Citat:
|
Om du postar strukturen över databasen kanske någon kan hitta en strukturoptimering. En metod är att dela upp vissa tabeller som innehåller mycket text till två (där texten hamnar i en tabell och resten i en annan). Då kan du ha fixed length på huvudtabellen och sedan med relation hämta den stora texten från den andra tabellen.
Du sa att du redan optimerat alla SQL-queries. Har du kontrollerat hur stor del av frågorna som inte använder sig av index fullt ut? Ses enklast i MySQL Administrator. Vilken typ av tabeller använder du sig av? MyISAM låser hela tabellen vid skrivning (som någon redan sagt) medans InnoDB klarar av att låsa endast den aktuella posten. Kanske du kan använda mer heap-tabeller som buffert mellan "den riktiga" taballen. Låt sedan den riktiga tabellen uppdateras av heap-tabellen regelbundet. Eftersom du har en rätt så slö propp i burken skulle jag gissa på att det är bättre att lägga pengar på snabbare dator än att lägga ner tid på allt som har med replikering att göra. Du ska ju ändå hur som helst skaffa en till burk om du ska köra replikering. Släng på lite extra krut på den burken om möjligt och låt den ersätta den gamla. Nu var det inte en sådan lösning du verkade intresserad av, men det är åtminstonde ett tips. |
Som sagt, frågorna är optimerade och tabellerna är normaliserade. Index används alltid. Det är myisam-tabeller men jag har inte vågat byta till InnoDB för att jag inte vet hur de klarar stressen.
|
Som någon tidigare påpekade så är det maskinvara i db-servern du ska byta ut, inte köpa ny och lägga till.
En server med två cpu:s arbetar mycket snabbare, speciellt när flera kommandon ska köras samtidigt. Vi körde Silverplanet.se(som hade som mest ~500-600 online) på en cpu med dubbla MP 1600+, scsi och apache&mysql på samma maskin. ett försök att göra samma sak på en dator med bara en processor(även om den var mycket snabbare) gick som förväntat, åt h3v3te. Nåväl, då bråkade mysql med apache så det är ju en del av förklaringen. Men fortf. Dubbla processorer, mer cache och snabba sånna :) så har du nog en lösning som håller sig ett tag in på framtiden iaf. "Krångla inte till det mer än nödvändigt" som någon vis man sa ^^ |
Att replikera över flera servrar är mycket billigare än att köpa en superdupermaskin - och mer skalbart. Jag kör bara MySQL på maskinen jag nämnde. Om det är någon som skulle vilja hjälpa till med min ursprungliga fråga så vore jag tacksam, det är mycket prat om annat.
|
Citat:
Och jag kan inte hålla mig och jag måste påpeka att en normaliserad databas är inte alltid det mest effektiva. Teori och praktik går tyvärr isär här ibland... Men jag sökte lite snabbt och: http://dev.mysql.com/books/hpmysql-excerpts/ch07.html säger bl.a: "If you attempt to use replication to set up a load-balancing system, you may be disappointed." Man rekommenderar snarare att man i så fall skall segmentera sitt data och lastbalansera så. dvs, flytta vissa tabeller till en annan DB server och kör frågor mot två olika servrar. |
Fråga råd hos dom du har maskinen vad dom tycker och kanske får fram en bra lösning på det.
Amd Opteron maskin med SATA disk rullar nog rätt så bra om du idag kör en vanlig maskin med ide. Scsi är väl alltid bäst men sata ligger nog inte så långt ifrån. |
Allt jag ville var att hitta en lösning på auto_increment-problemet vid replikering. Om det inte är någon som har något att säga om det så kan vi lägga ner.
|
Citat:
Och angående cachning så är ju det definitivt att rekommendera, om man kan cacha de mest trafikerade sidorna. Det kanske inte funkar på din site,men tex när man klickar på "LÄSA" så skulle ju de senaste dikterna kunna cachas 1 minut exempelvis,eller rättare sagt den "output" som sidan genererar |
Jag antar att den enda lösningen är att du ser till att beräkna en egen primary key istället för att använda AUTO_INCREMENT. En variant skulle ju vara att du kombinerar server-id med ett ökande id och lägger ihop till en BIGINT.
Kod:
$id = $server_id << 32 + $next_id; 1. Att skriva till en RAID5-array med 3 diskar är _SLÖTT_, sätt dit en disk till och kör RAID10 istället. 2. Hur stor är databasen? Se till att så mycket som möjligt ryms i RAM så att du slipper läsa från disk så mycket som möjligt. 3. Hur hanteras sessioner? Se till att de inte skrivs mot disk utan direkt till t.ex. ramdisk. 4. Nästa gång du uppgraderar servern, se till att köra SCSI-diskar med en raidkontroller som har inbyggt cacheminne (med batteribackup). |
Alla tider är GMT +2. Klockan är nu 17:41. |
Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson