List functional requirements for the system (Ask the chat bot for hints if stuck.)...
List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
Define what APIs are expected from the system...
POST /putKV
Request Body : { Key, Value, TTL }
Response 200 if succeeded. 503 if unable to succeed.
UPDATE /updateKV
Request Body : { Key, Value, TTL, condition }
Response 200 if succeeded. 503 if unable to succeed.
GET /getKV
Request Body : { Key }
Response 200 if succeeded. 404 if no key is present. 503 if unable to succeed.
DELETE /deleteKV
Request Body : { Key }
Response 200 if succeeded. 404 if no key is present. 503 if unable to succeed.
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
.there is a load balancer that sits on front, accepting client requests. It is a L7 LB handling api requests. Based on the user id for the request and the key, which is unique, consistent hashing is used to find N (N replicas) backend master servers where this key can always be found.master server will always deal with writes. there are slave servers to it and master, based on configuration settings if strong consistency or eventual consistency is preferred, master service would either wait for write acknowledgements from slaves before sending a ack or immediately send it and asynchronously sync with replicas.number of master server depends on the number of volume of data to be handled at any given time. updates follow the same path as putKV, but does it only when condition meets. same with /deleteKVgetKV gets redirected to replicas where the hash range fall under and it queries any one of the replica based on load. Masters also commit to a WAL for every write/object storage as dump every few minutes.
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
.there is a load balancer that sits on front, accepting client requests. It is a L7 LB handling api requests. Based on the user id for the request and the key, which is unique, consistent hashing is used to find a backend master server where this key can always be found.master server will always deal with writes. there are slave servers to it and master, based on configuration settings if strong consistency or eventual consistency is preferred, master service would either wait for write acknowledgements from slaves before sending a ack or immediately send it and asynchronously sync with replicas.number of master server depends on the number of volume of data to be handled at any given time. updates follow the same path as putKV, but does it only when condition meets. same with /deleteKVgetKV gets redirected to replicas where the hash range fall under and it queries any one of the replica based on load.
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
The master and replicas.
Persistence:
For persistence, based on accuracy of persistence, they can choose either a WAL to which each master service would log before committing a write, would be useful to exactly roll out events and get back to the previous state as it was. But this would take a longer
Master service:
Explain any trade offs you have made and why you made certain tech choices...
For persistence, based on accuracy of persistence, they can choose either a WAL to which each master service would log before committing a write, would be useful to exactly roll out events and get back to the previous state as it was. But this would take a longer
based on configuration settings if strong consistency or eventual consistency is preferred, master service would either wait for write acknowledgements from slaves before sending a ack or immediately send it and asynchronously sync with replicas.number
I have chosen In mem to store kv values because in memory data access is around 100ns latency and also hash map would be a good choice for storing values since they operate in O(1) time.
Try to discuss as many failure scenarios/bottlenecks as possible.
in case of strong consistency, latency would take hit since it has to replicate across all replicas.
if there is a master failure, writes would have to get suspended until a new master comes up.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?
there is async configuration to tradeoff consistency for lower latency.
LB can enqueue pending requests to a queue until a new master is elected and then process them.