WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Replikering av MySQL-databaser (https://www.wn.se/forum/showthread.php?t=4720)

David 2004-11-30 14:05

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.

SkyNet 2004-11-30 15:42

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.

grazzy 2004-11-30 21:25

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).

kullervo 2004-11-30 23:33

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å =)

kullervo 2004-11-30 23:40

Citat:

Originally posted by grazzy@Nov 30 2004, 22:25
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).
Finns inte det redan inbyggd i MySQL? Då är det master-servern som får ta hand om alla insert och slave-servern kan hantera selects.

eg0master 2004-12-01 09:13

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.

SkyNet 2004-12-01 10:59

Citat:

Originally posted by grazzy@Nov 30 2004, 22:25
... (och då kan ni juh redan där ha någon slags round-robin för att sprida frågorna mellan olika select-servrar).
När jag en gång i tiden körde två mindre servrar så hade jag en liten snutt kod som uppdaterade belastningen för varje server i en tabell och sedan skickade användaren till den minst belastade servern...

SkyNet 2004-12-01 11:02

Citat:

Originally posted by eg0master@Dec 1 2004, 10:13
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.
Frågan är ju bara hur man definierar antal samtidigt inloggade användare?

David 2004-12-01 12:26

Citat:

Originally posted by grazzy@Nov 30 2004, 22:25
och köra dom mot en server medans andra frågor går mot en annan server
Som sagt, det är ingen större idé att ha en master och många slavar eftersom varje sidanrop innebär ett antal av varje. Jag vill därför ha två eller fler masters som potentiellt har vardera en eller fler webservrar mot sig.

Citat:

snabb titt på Sockerdricka så ser den inte så farligt tung ut heller
Det ser inte så tungt ut men all information på varje sida måste komma någonstansifrån och den kommer från databasen.

Citat:

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.

Tack, det är gjort för länge sedan.

Citat:

Vad har du för hårdvara nu?
Db-servern är AMD Sempron 2600+ med 1,5GB RAM och 3 x 80 GB hårddiskar i RAID5.

Jag skulle mycket uppskatta hjälp med problemet jag har, dvs att replikera över flera masters men ändå använda auto_increment.

Edvard 2004-12-01 14:03

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:

MySQL replication is most beneficial for a system with frequent reads and infrequent writes. In theory, by using a single-master/multiple-slave setup, you can scale the system by adding more slaves until you either run out of network bandwidth, or your update load grows to the point that the master cannot handle it.
Det ser ju inte direkt bra ut för dig, dom skriver även om förhållandet mellan read/write så hur månge writes har du per read?

danjel 2004-12-01 15:43

Inte för att det är ett svar på frågan.
Men cachar ni de mest besökta/ mest databas- intensiva sidorna ?

David 2004-12-01 16:12

Citat:

Originally posted by Edvard@Dec 1 2004, 15:03
Det ser ju inte direkt bra ut för dig, dom skriver även om förhållandet mellan read/write så hur månge writes har du per read?
Hade det varit bara några få writes och mest reads så hade det ju varit en idé att skala upp med bara en master. Men det är mycket fler writes än så, varför bara writes-delen av anropen behöver skalas om du förstår vad jag menar.

Citat:

Men cachar ni de mest besökta/ mest databas- intensiva sidorna?
Det är ingen idé att cacha eftersom datan ändras mellan varje sidvisning.

Edvard 2004-12-01 16:30

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?

David 2004-12-01 18:38

Citat:

Originally posted by Edvard@Dec 1 2004, 17:30
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.
Huh? Som jag förstår det kräver utförandet av instruktioner i den binära loggen mycket mindre av maskinen och att använda den för att replikera data till övriga servrar är bättre än att utföra SQL-frågorna på var och en av dem?

kullervo 2004-12-01 18:54

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.

David 2004-12-01 19:07

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.

Joel 2004-12-01 20:13

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 ^^

David 2004-12-01 20:22

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.

eg0master 2004-12-01 21:17

Citat:

Originally posted by David@Dec 1 2004, 21:22
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.
Det är ju det vi gör.. :-) Jag tror liksom så många andra att du ska satsa på en bättre burk i första hand.

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.

vroom 2004-12-01 21:20

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.

David 2004-12-02 03:35

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.

danjel 2004-12-02 13:24

Citat:

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.
Det väsentliga är väl att problemet med prestandan.
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

Crotalus 2004-12-03 18:55

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;
Dock, om du har problem med prestandan pga att databasen uppdateras kan du inte räkna med att replikering är den rätta medicinen. Alla noder i ett kluster måste ju skriva samma data. Några tips, utan att veta exakt vad som är flaskhalsen, som gör att du kan fördröja behovet att replikera din databas:

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