Estimate the scale of the system. Consider daily active users, read/write ratio, storage requirements, bandwidth, and any relevant QPS calculations...
Define the APIs expected from the system. This is your chance to analyze and define the read and write paths so that you can come up with the high-level design...
POST /api/v1/Insert
PUT /api/v1/Update
GET /api/v1/Get
DELETE /api/v1/Delete
PUT /api/v1/CompareAndSwap
READ PATH: Client -> CDN -> API Gateway -> Load Balancer -> Retrieval Service -> Rabbit MQ -> Redis Cluster -> Dynamo DB
WRITE PATH: Client -> CDN -> API Gateway -> Load Balancer -> Insertion Service -> Rabbit MQ -> Redis Cluster -> Dynamo DB
UPDATE PATH: Client -> CDN -> API Gateway -> Load Balancer -> Updation Service -> Rabbit MQ -> Redis Cluster -> Dynamo DB
Data is replicated by having multi az replicas and cross region replicas. We will be synchronous replicating the data to these replicas. This make the system fault tolerant.
Since we are using replication we might as well use the read replicas for performing reads and for writes they directly come to the main db. Since writes happen at one place consistency is achieved while the data is synchronously replicated consistency in read is also achieved.
We can setup the replication setup to promote a read replica as the master if the master goes down making it resilient.
We are using both CDN and redis cluster for caching where CDN handles most of the reads and if there is a miss we will go to redis cluster first and in case that misses which is very rare will we go to the DB.
Since the entries in the db can fill up the space and we have ttl for these entries we can immediately remove the entries once their ttl expires and then clean up the cache to keep them from going stale. This not only helps in reclaiming the space also keeps the cache clean and up to date.
Define the data model. Identify the main entities, their attributes, and relationships. Consider the choice of database type (SQL vs NoSQL) and justify your decision based on access patterns...
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.
Insertion Service inserts the data into the Dynamo DB and redis.
Updation Service updates the entries. It can do direct updates or compare and swap the entries as well.
Retrieval service retrieves the key values. It can get one entry or can get batch entries at a time.
We have a cleanup service which cleansup the redis cache and the CDN cache when ever an entry is dropped after its TTL is finished.
We will be using idempotency keys to make sure duplicate writes are avoided.
When a user reads a value most of the response is handled by CDN it self. But when a cache miss happens at CDN level the request first reaches the redis cluster which handles most of the miss cases. But in case both are missed it is read from Dynamo DB subsequently making an entry in redis cache and CDN's Cache.
When a nodefailure occurs we have cache available. These can take care of the requests until the reader node gets promoted into the main node and starts taking the requests.