17:55 deal with concurrency, use locks on waiting linked lists 20:29 sharding by locality or events 21:16 write-back cache for waiting list , to update to the database which contains bookings.
Good point! I'll consider that when I remake this one, ticketmaster was perhaps a poor name for it and should have just said generic movie booking site. But I'll incorporate this next time around.
Hi Jordan, thanks for the great content series! Regarding this exercise, I have some doubt. Does your design allow parallel booking of different unrelated seats for the same show? If yes, could you maybe share highlight how it's done? In video things skip to active/waiting bookings but not relate seats too much. Regarding solution, it feels kinda complex, especially with Redis in-memory objects and 2PC to the DB. Due to not so high volume of reservations per show, a slow booking pace that spans over many hours, and easy sharding by show_id (so indeed scalable too), it does feel to make much sense to have an async working singleton service that contains all the logic regarding booking states manipulation. That is, once per every N seconds service loop happens which loads each of the shows, handles booking states updates, and saves it to DB. Single thread, no concurrency, super-testable, much more visible for engineers as opposed to Redis+DB. Plus, as it is single logic-executing actor, a much more complex seat-level logic may be implemented without risks of deadlocks etc.
1) No, it does not allow for atomic booking for seats in different sections 2) Totally understand your point here, I think that if you do want to have "claims" on a given seat where claims last a certain amount of time, a DB is enough. I have a 2.0 series of these designs and try to iron this one out more there.
It's helpful if you actually draw the design while describing it. Otherwise, it's hard to understand/think about some of the concepts while also trying to visualize the design diagram in mind.
Hey, just thinking. Why don't we simply use a relational table (postgres or mysql) to manage Bookings? Like you can have a table for Active bookings and Waiting to book. Then when a user is no longer actively booking or waiting to book, we purge them off the tables via an offline process (batch parallel processing). 🤔. There could also be a separate notifications service that would notify customers based on a change in status (waiting -> active-> purchase etc.)
#suggestion I think Airline/Train reservation system would be the harder and more interesting version of this. We will need to think about range queries/updates for routes.
@@jordanhasnolife5163 For trains, it will have multiple stops and some fixed capacity. If you want to book from A to B, we will have to make sure that there is at least 1 empty seat for all stops between A and B. But now that I think about it, its probably more of an algorithmic question than sys design question.
@@shubhamnagaria3742 Ah yeah, that really is a tough one haha! It gets difficult because you're looking at deadlocks unless you make sure to always tiebreak locks in the same order I believe, I'll think about it more. It's a similar concept to ticketmaster but you can pick the individual seat, not just the section. Then the two of us may try to book overlapping seats but my seats also overlap with someone else's.
Nice video, Jordan! Love the "Jordan's Sex Tape" gag. I had one question, wouldn't sharding based on event lead to a hot shard problem? Some events have a lot more people trying to book them and some have normal traffic.
hey Jordan super quick question, was a bit confused with the in-memory data structure, are you suggesting to use Redis to keep that information and handle the locking on the node side? I was thinking of using Dynamo + locking and wonder why Redis?
I think it's just a question of whether you can have a queue lock on dynamo, we want to maintain priority if someone were to bail on their seats hence the queue in redis
another great video! thanks! could you help me sort out some thoughts. i feel like most of ticketmaster like system do need to book specific seat, which means we do need to somehow lock in the per seat grabularity, and there probably will be a queue per seat. but these concept probably will be handled by relational database, when they handle concurrent transactions, and probably use hash linked list. but i feel like they probably wont be handled by application code. as for updating how many seats left, it is more like an eletronic commerce thing, where we care about amount, not location/adjacency. would love to discuss with you!
Hi! Yeah if you're booking per seat this is going to become extremely complicated due to deadlocks. E.g. you and I want seat 1 and seat 2 but I'm before you for seat 1 and you're before me for seat 2 - we'd need some sort of system to detect deadlocks and remove them or sort them somehow
Thanks for the video! Quick question about the linked hash lists as a way to implement queues - how are these instantiated? I'm guessing there's software that creates this data structure every time the booking API is called but the corresponding lock is held? In that case we would return a response to the user and follow up with a SSE when there's an update (your turn to book, seats are unavailable)?
@jordanhasnolife5163 every time a 2pc sends a prepare request or commit request , it appends to a wal persisted In a local DB When a crashed server recovers back , it looks at all the previous logs to find current state of 2pc and issues roll back to systems that has committed already and abort the transaction Disadvantages of 2pc 1. Having to deal with fault tolerance like the above 2. Not all systems / services/ DBs support 2 pc Better alternative to do 2pc to implement distributed transactions : sagas - which can be implemented in 2 patterns a) choreography pattern b) orchestrator pattern
17:55 deal with concurrency, use locks on waiting linked lists
20:29 sharding by locality or events
21:16 write-back cache for waiting list , to update to the database which contains bookings.
I feel syncing with the theater's database to keep track of live seat availability was missed! Ticketmaster is not the only way to book tickets!
Good point! I'll consider that when I remake this one, ticketmaster was perhaps a poor name for it and should have just said generic movie booking site. But I'll incorporate this next time around.
Perfect man! It was detailed and realistic design. Thank you!
Hi Jordan, thanks for the great content series!
Regarding this exercise, I have some doubt. Does your design allow parallel booking of different unrelated seats for the same show? If yes, could you maybe share highlight how it's done? In video things skip to active/waiting bookings but not relate seats too much.
Regarding solution, it feels kinda complex, especially with Redis in-memory objects and 2PC to the DB. Due to not so high volume of reservations per show, a slow booking pace that spans over many hours, and easy sharding by show_id (so indeed scalable too), it does feel to make much sense to have an async working singleton service that contains all the logic regarding booking states manipulation.
That is, once per every N seconds service loop happens which loads each of the shows, handles booking states updates, and saves it to DB. Single thread, no concurrency, super-testable, much more visible for engineers as opposed to Redis+DB. Plus, as it is single logic-executing actor, a much more complex seat-level logic may be implemented without risks of deadlocks etc.
1) No, it does not allow for atomic booking for seats in different sections
2) Totally understand your point here, I think that if you do want to have "claims" on a given seat where claims last a certain amount of time, a DB is enough. I have a 2.0 series of these designs and try to iron this one out more there.
It's helpful if you actually draw the design while describing it. Otherwise, it's hard to understand/think about some of the concepts while also trying to visualize the design diagram in mind.
Yup that's why I'm remaking all of these videos
Hey, just thinking. Why don't we simply use a relational table (postgres or mysql) to manage Bookings? Like you can have a table for Active bookings and Waiting to book. Then when a user is no longer actively booking or waiting to book, we purge them off the tables via an offline process (batch parallel processing). 🤔. There could also be a separate notifications service that would notify customers based on a change in status (waiting -> active-> purchase etc.)
Yeah you could do something like that definitely, as long as you're making sure to use the write back cache to deal with the wait list
#suggestion I think Airline/Train reservation system would be the harder and more interesting version of this. We will need to think about range queries/updates for routes.
Sorry can you elaborate a bit? Trying to see how this involves rage queries
@@jordanhasnolife5163 For trains, it will have multiple stops and some fixed capacity. If you want to book from A to B, we will have to make sure that there is at least 1 empty seat for all stops between A and B. But now that I think about it, its probably more of an algorithmic question than sys design question.
@@shubhamnagaria3742 Ah yeah, that really is a tough one haha! It gets difficult because you're looking at deadlocks unless you make sure to always tiebreak locks in the same order I believe, I'll think about it more. It's a similar concept to ticketmaster but you can pick the individual seat, not just the section. Then the two of us may try to book overlapping seats but my seats also overlap with someone else's.
Nice video, Jordan! Love the "Jordan's Sex Tape" gag. I had one question, wouldn't sharding based on event lead to a hot shard problem? Some events have a lot more people trying to book them and some have normal traffic.
Yep fair - I think that if you had to you could re-partition on the individual sections of a given super popular event
hey Jordan super quick question, was a bit confused with the in-memory data structure, are you suggesting to use Redis to keep that information and handle the locking on the node side? I was thinking of using Dynamo + locking and wonder why Redis?
I think it's just a question of whether you can have a queue lock on dynamo, we want to maintain priority if someone were to bail on their seats hence the queue in redis
another great video! thanks! could you help me sort out some thoughts. i feel like most of ticketmaster like system do need to book specific seat, which means we do need to somehow lock in the per seat grabularity, and there probably will be a queue per seat. but these concept probably will be handled by relational database, when they handle concurrent transactions, and probably use hash linked list. but i feel like they probably wont be handled by application code. as for updating how many seats left, it is more like an eletronic commerce thing, where we care about amount, not location/adjacency. would love to discuss with you!
Hi! Yeah if you're booking per seat this is going to become extremely complicated due to deadlocks. E.g. you and I want seat 1 and seat 2 but I'm before you for seat 1 and you're before me for seat 2 - we'd need some sort of system to detect deadlocks and remove them or sort them somehow
Thanks for the vid Jordan! Preciate the runthrough 👍
Yessir, hope it helps 💪🏻
Thanks for the video! Quick question about the linked hash lists as a way to implement queues - how are these instantiated? I'm guessing there's software that creates this data structure every time the booking API is called but the corresponding lock is held? In that case we would return a response to the user and follow up with a SSE when there's an update (your turn to book, seats are unavailable)?
Yep that seems right to me!
what if the server crashes during 2PC ? how does it recover (Fault tolerance)?
In two phase commit the point is that you don't recover unfortunately - that's the price of heterogenous distributed transactions
@jordanhasnolife5163 every time a 2pc sends a prepare request or commit request , it appends to a wal persisted In a local DB
When a crashed server recovers back , it looks at all the previous logs to find current state of 2pc and issues roll back to systems that has committed already and abort the transaction
Disadvantages of 2pc
1. Having to deal with fault tolerance like the above
2. Not all systems / services/ DBs support 2 pc
Better alternative to do 2pc to implement distributed transactions : sagas - which can be implemented in 2 patterns
a) choreography pattern
b) orchestrator pattern
Why not use sagar pattern istead of 2 phase commit?
How do you see this working?
getShowTimes should take movieId as a parameter, not just theaterId
Good catch
is not ticketmaster for shows instead movies ? lol....
Same thing lol