Can we design write heavy system without using traditional database?
Imagine you are developing ticket booking app for an event which is going to get sold out quickly or developing system for a merch drop of a famous artist which is also going to get sold out quickly. In both use cases, we can see , system we are trying to design will be write heavy. Question we need to ask ourselves is — Do we really need to use traditional database?
Disclaimer: This article is based on my current knowledge and understanding. If you have any query or see any improvement, please mention in the comment section
Problem Statement:
Design ticket booking system(can be of event, show or anything) based on first come first serve principle.
Technical Problem Statement:
- Develop storage system to store all ticket bookings from ticket booking app.
- Develop algorithm to give information who reserved the seat/ticket based on first come first serve principle.
Solutions:
Conventional approach:
One can use traditional database or in memory database like redis to store ticket bookings and lock the ticket/seat for all other users once it is reserved by first user. But our use case will come with heavy write traffic which might make traditional DB as bottleneck.
Little different approach:
Use queue instead of DB. This approach may seem little strange in beginning but once you get used to this idea , making queue act as storage actually opens up lot of use cases.
Architecture :
- Client app will add message in kafka queue which seat/ticket they want to reserve via API.
- KSQL is like SQL over kafka. KSQL can create table, fire queries over Kafka and retrieve necessary information for us. In above point when we mention client app will put message in kafka, basically what will happen is using KSQL, we will create stream and record all messages of all users there. This KSQL stream data is actually backed by kafka topic (by single partition)
- Using KSQL , we will create a table which will hold information which user booked a particular ticket/seat first. This table will be created over stream data which we created in the previous step. But Sumit, How does KSQL table know which user event came first? Answer is offset in kafka topic(Id for message in a partition). Message which came first will have lowest offset value in kafka topic
This way we have solved above problem statement. We are storing all user events in KSQL stream based on kafka topic and KSQL table is holding information which user reserved which ticket/seat first. Backend app can query this KSQL table and update end users accordingly.
Demo:
- Screen 1: we created KSQL stream which will hold all user events. This stream will contain which request ids of users is trying to reserve which seats
(KSQL statement to create this stream — CREATE STREAM TICKET_BOOKING_STREAM (REQUESTID VARCHAR, SEAT VARCHAR,TIMESTAMP VARCHAR) WITH (KAFKA_TOPIC = ‘TICKET_BOOKING_TOPIC’,FORMAT = ‘JSON’,TIMESTAMP = ‘TIMESTAMP’, TIMESTAMP_FORMAT = ‘yyyy-MM-dd HH:mm:ss.SSS’,PARTITIONS = 1);)
- Screen 2: we created KSQL table from KSQL stream to hold information which seat was first reserved by which request id of user using EARLIEST_BY_OFFSET function.
- From screen1 and screen2, we can see requests r1, r2 both wanted to reserve seat a1 but r1 request got committed first in kafka topic (partition )due to which it got picked in KSQL table and a1 seat got reserved for request r1 which is desired outcome (first come first serve principle)
~ Happy Coding
Note:
- In kafka, messages are ordered within partition , not across partitions.