Ik ben een beetje op zoek naar input voor wat een mooie manier zou zijn om een event sourced backend te maken. Vorig jaar heb ik de backend opgeleverd voor een game waar ik uit kon gaan van deze dingen:
- Single player
- Client push only (client stuurt request, krijgt response, nooit push van server naar client)
- Event sourced
Wat we gemaakt hebben was een PHP app gebouwd op Symfony Framework die gebruik maakt van Redis shards (tijdens registratie kom je op een shard uit, daar blijft de data) om het profiel van de speler op te slaan. De events schrijven we weg naar de event store (in ons geval Amazon Kinesis Firehose). Dit heeft voor die app enorm goed gewerkt en een ruim jaar later hebben we rond de 6 miljoen accounts. Groot nadeel qua architectuur hierin is dat we aan t eind van de request de events wegschrijven naar de event store en als dat gelukt is updaten we de speler z'n profiel dmv 1 (pipelined) call naar Redis. Hiermee is een 2 Generals Problem ontstaan.
Voor een nieuwe backend heb ik echter ook de requirement dat er ondersteuning voor multiplayer moet komen en dan kom ik niet meer weg met de shards in Redis zoals dit nu geimplementeerd is, dan maak ik het probleem namelijk nog groter door te moeten schrijven naar meerdere shards. Ook wil ik in het geheel af van het 2 Generals Problem. Er is ook al bekend dat bepaalde events bijvoorbeeld push messages of mailtjes moeten gaan versturen.
De oplossing zoals ik het zie is om gebruik te maken van een event store (ik kijk nu naar Apache Kafka, Redis Streams klinkt ook ideaal maar is nog niet beschikbaar) met daar aan gekoppeld meerdere consumers die de events verwerken. Daarbij ben ik echter bang dat het (vaak) zal gebeuren dat de consumers de events nog niet verwerkt hebben en de client dus acties probeert uit te voeren die de backend (nog) niet kan valideren. Deze backend zal met veel meer players te maken krijgen dan de app die we hebben opgeleverd dus schaalbaarheid is echt enorm belangrijk maar daarbij moet betrouwbaarheid niet worden vergeten.
Ik heb natuurlijk al best wel wat gelezen over event sourcing en ook CQRS maar hou een beetje deze vragen:
- Hoe voorkom ik het 2 generals problem waarbij ik in 1 request naar meerdere DB's moet schrijven?
- Hoe zit het in praktijk met latency als je enkel werkt met events/consumers?
Is er iemand die antwoord kan geven op bovenstaande vragen of ervaring heeft met dergelijke architectuur en me in een andere/betere richting kan duwen?
- Single player
- Client push only (client stuurt request, krijgt response, nooit push van server naar client)
- Event sourced
Wat we gemaakt hebben was een PHP app gebouwd op Symfony Framework die gebruik maakt van Redis shards (tijdens registratie kom je op een shard uit, daar blijft de data) om het profiel van de speler op te slaan. De events schrijven we weg naar de event store (in ons geval Amazon Kinesis Firehose). Dit heeft voor die app enorm goed gewerkt en een ruim jaar later hebben we rond de 6 miljoen accounts. Groot nadeel qua architectuur hierin is dat we aan t eind van de request de events wegschrijven naar de event store en als dat gelukt is updaten we de speler z'n profiel dmv 1 (pipelined) call naar Redis. Hiermee is een 2 Generals Problem ontstaan.
Voor een nieuwe backend heb ik echter ook de requirement dat er ondersteuning voor multiplayer moet komen en dan kom ik niet meer weg met de shards in Redis zoals dit nu geimplementeerd is, dan maak ik het probleem namelijk nog groter door te moeten schrijven naar meerdere shards. Ook wil ik in het geheel af van het 2 Generals Problem. Er is ook al bekend dat bepaalde events bijvoorbeeld push messages of mailtjes moeten gaan versturen.
De oplossing zoals ik het zie is om gebruik te maken van een event store (ik kijk nu naar Apache Kafka, Redis Streams klinkt ook ideaal maar is nog niet beschikbaar) met daar aan gekoppeld meerdere consumers die de events verwerken. Daarbij ben ik echter bang dat het (vaak) zal gebeuren dat de consumers de events nog niet verwerkt hebben en de client dus acties probeert uit te voeren die de backend (nog) niet kan valideren. Deze backend zal met veel meer players te maken krijgen dan de app die we hebben opgeleverd dus schaalbaarheid is echt enorm belangrijk maar daarbij moet betrouwbaarheid niet worden vergeten.
Ik heb natuurlijk al best wel wat gelezen over event sourcing en ook CQRS maar hou een beetje deze vragen:
- Hoe voorkom ik het 2 generals problem waarbij ik in 1 request naar meerdere DB's moet schrijven?
- Hoe zit het in praktijk met latency als je enkel werkt met events/consumers?
Is er iemand die antwoord kan geven op bovenstaande vragen of ervaring heeft met dergelijke architectuur en me in een andere/betere richting kan duwen?