Toon posts:

[php/mysql] master-slave incrementele waardes gegroepeerd

Pagina: 1
Acties:

  • Saven
  • Registratie: december 2006
  • Laatst online: 23-01 14:22

Saven

Administrator

Topicstarter
Ik ben bezig met een hobbyproject om daarin vooral meer te leren over grote webapplicaties die server scaling vereisen. Niet voor productie, puur zelfeducatie.

Lang verhaal kort. Stel ik heb een app waar mensen een online shop kunnen beginnen (SaaS) en waarin dus orders worden geplaatst. Elke ordertabel heeft natuurlijk een autoincrement voor order.ID. Stel dat er meerdere shops draaien, dan moet elke shop order ook zijn eigen order.number hebben. Incrementeel per order.shop_id dus. Zodat shop A ordernummers 1.2.3.4 etc. heeft, maar shop B ook deze 1,2,3,4,5.. waardes.

Nu kun je bij het maken van een nieuwe order normaliter gewoon de laatste shop order ophalen, daar +1 bij optellen, en de waarde in order.number van de nieuwe record zetten.

Maarr, in een master-slave geval zit er natuurlijk lag tussen de write en read server. Stel dat er via een API tientallen orders tegelijkertijd worden aangemaakt (bijv. wanneer iemand een import draait). Hoe zou je dit dan op kunnen lossen? Rekening houdend met dat er tijdens de import ook orders door klanten kunnen worden geplaatst.

Standaard leeglaten van order.number en via een cron/task achteraf invullen lijkt me ook niet sjiek, en weinig haalbaar aangezien orders bijvoorbeeld direct gemailt moeten worden naar de klant, en daarin ook het nummer aanwezig moet zijn.

Je zou die query om het laatste ordernummer op te halen kunnen uitvoeren op de master server, mja dan ga je misschien tientallen queries per seconde uitvoeren op die server terwijl die daar eigenlijk niet voor bedoeld is.

Suggesties? :)

  • Saven
  • Registratie: december 2006
  • Laatst online: 23-01 14:22

Saven

Administrator

Topicstarter
Merethil schreef op zaterdag 29 februari 2020 @ 12:44:
Wat is er mis met auto_increment? Die doet het automatisch juist, ook in een master-slave-opstelling. Of eventueel UUIDs, dan heb je "nooit" problemen hiermee maar zijn ze ook niet oplopend.
RobIII schreef op zaterdag 29 februari 2020 @ 13:50:
[...]

Want? Wat is er mis met één "globale" auto-increment voor die tabel? Een order-id is niet 'tzelfde als een ordernummer.


[...]

Oh, nee, nóóit doen! Dat geeft alleen maar race conditions. Laat 't over aan je RDBMS alsjeblieft. Of gebruik iets als een GUID/UUID, ULID of snowflake ID o.i.d. als je toch bezig bent horizontaal te schalen.


[...]

Daar heb je toch juist een master en een zwik slaves voor? De slaves gebruik je gewoon read-only en de master voor de writes en dan laat je 't ID over aan de auto-increment die je RDBMS biedt.


[...]

Again, dit ga je niet werkend krijgen en al helemaal niet op schaal; dit is een disaster waiting to happen. Want race-conditions.


[...]

UUID's zijn inderdaad een bitch voor je indexen, maar dat is vooral afhankelijk van welke versie je gebruikt; elke versie heeft weer z'n eigen voor/nadelen (V4 is bijvoorbeeld aardig funest doorgaans). Maar er zijn ook, zoals ik hierboven al linkte, nog alternatieven die bijv. efficiënter zijn qua opslag (64 bits vs 128 bits bijv), toch (voornamelijk) oplopend of op andere manieren voordelen bieden. Ik zou ze in ieder geval eens overwegen ;)
Aah thanks voor de replies jongens, maar ik denk dat jullie me niet goed hebben begrepen.

Uiteraard is de primary key (id) gewoon big unsigned autoincrement. Maar je moet het zo zien, elke shop plaatst orders in de database. Maar voor 'hun referentie' hebben ze een 'meer leesbaar' nummer (met bijv. prefix ORD) in plaats van de database ID.

Dus bijv:
ORD00001
ORD00002
ORD00003
ORD00004
.....
ORD00365

En dezelfde reeks geldt dus ook voor alle andere shops. Die beginnen met ordernummer ORD00001 voor hun eerste order. Op die manier kunnen zij en hun klanten refereren naar een ordernummer in plaats van het ID in de database.

Zowel shop A als shop B hebben dus ordernummers beginnend bij ORD00001 t/m ORD99999 en verder.

Hoop dat het zo wat duidelijker is :) Iets dergelijks is vrij veelvoorkomend bij dergelijke software.

Dat als ze een lijst met orders opvragen, ze hun eigen ordernummers te zien krijgen (opeenvolgend zonder duplicates)

Voorbeeld tabel in de front-end
code:
1
2
3
4
5
order   |   klant   |   datum      |
--------------------------------------
ORD001  | Jansen    |  01-01-2010  |
ORD002  | Peters    |  02-01-2010  |
ORD003  | de Jong   |  03-01-2010  |

[Voor 6% gewijzigd door Saven op 29-02-2020 14:10]


  • Saven
  • Registratie: december 2006
  • Laatst online: 23-01 14:22

Saven

Administrator

Topicstarter
Kalentum schreef op zaterdag 29 februari 2020 @ 15:41:
Als ik zo'n systeem zou ontwerpen, zou ik ook de ordernummertjes laten op lopen per shop. Het is ook niet dat het juridisch moet. Maar het lijkt me gewoon een productkeuze. En als die ordernummertjes zo belangrijk zijn dan moet de code gewoon de master raadplegen om 'het hoogste nummertje per shop' op te vragen.

Je kan het veilig krijgen door een unieke index op shop_id en ordernummer aan te maken. Je code doet dan ongeveer dit:
- Start een database transactie
- Vraag het hoogste nummertje voor een gegeven shop op
- Maak een nieuwe order aan
- UNIQUE_KEY violation exception? rollback de transactie en probeer het nog een keer
- Anders commit de transactie
Wat ik dus idd al dacht :) Dan is't niet anders.

Maar stapje verder dan: wat als je twee masters(?) naast elkaar hebt draaien :o als je bijv. aan het limiet van diskspace zit. Op een gegeven moment heb je niet genoeg ruimte meer. Of ga je dan meer richting sharding.

Wellicht allemaal niet aan de order van de dag, maar vind 't wel interessant om erachter te komen
RobIII schreef op zaterdag 29 februari 2020 @ 16:27:
[...]


Omdat elke shop/klant natuurlijk zijn/haar eigen factuurreeks heeft.


[...]


Jawel ;)

[...]


[...]

Klopt, maar dat wordt een heel ander verhaal als je 't hebt over "grote webapplicaties die server scaling vereisen" (zie topicstart). Dan heb je telkens hele dure locks op je tabel voor het bepalen van een factuurnummertje...
Having said that: zolang je geen Facebook / Google / Twitter / whatever bent werkt dat natuurlijk prima. Maar dat was de insteek van 't topic niet. En on that note: ik heb daar inhoudelijk ook nog niet op geantwoord want ik las 't in eerste instantie als 't bepalen van PK ID's maar het gaat hier om (verschillende reeksen) factuurnummers. In dat geval zou ik een generator per webshop (of per "tenant") hanteren. Oracle biedt zoiets als sequence aan volgens mij maar je zou ook een service kunnen maken met als enig doel verschillende (tenant) reeksen bij te houden en delegeren/orchestreren.
Haha. Zeker geen FB of Twitter nee :P Hoe zie je zo'n generator voor je als je niet zuiver kunt bepalen wat het laatste nummer uit de reeks is? In dit geval 't liefst allemaal mysql georiënteerd.

[Voor 35% gewijzigd door Saven op 29-02-2020 17:23]


Acties:
  • 0Henk 'm!

  • Saven
  • Registratie: december 2006
  • Laatst online: 23-01 14:22

Saven

Administrator

Topicstarter
Kalentum schreef op zaterdag 29 februari 2020 @ 22:15:
[...]


@Saven zit Shopify opnieuw uit te vinden. Dat hangt er tussen in. Overigens is een database als SPOF op te vangen met master-master replicatie. Master 1 is live en Master 2 is een hotstandby die functioneert als een slave totdat master1 omvalt.
Hehe Shopify was inderdaad een goed voorbeeld geweest :) Thanks voor alle replies iedereen!
Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2022 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee