Detailed component design
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...
- Auto scaling:
- to achieve the goal of minimizing the key mapping to servers when adding/removing server, we use consistent hashing for servers. First we determine the hash space, whatever we take the hashing method. The we can have a hashing ring by connecting the last and first hashing value of the hashing space. The virtual nodes (from physical nodes) evenly spreading on the hashing ring. The key can walk clockwise to find the virtual node when it mapped to the hash ring. This virtual node is the node to store the key-value.
- Data Partition
- For a large application, we are not able to store the whole data set into a single server. We need to partition the data set into multiple data servers. We can use above mentioned consistent hashing to achieve the key and node mapping.
- Data Replication
- To avoid data loss if a server crashed, we need to replicate one data onto multiple nodes.
- When a key is mapped onto the hash ring, walk clockwise to find N virtual nodes and store the copied data onto them. These N virtual nodes must be on different physical nodes.
- Consistency
- To ensure all clients get the same data when reading the same key from different nodes, the data needs to propagate to other nodes when this data is changed or newly created. There are following consistency models:
- strong consistency: all read/write operation will be blocked until all replicas agree on this write. This will lower the system performance. It is usually used in the scenario when the high consistency is needed, like bank system.
- weak consistency: the client may get the outdated data from other nodes after the write on one node.
- eventual consistency: it is a specific weak consistency. Given enough time, the new data will be propagated to other nodes. Based on the requirements, we will use this consistency model.
- Consistency Resolution
- when two clients write to the same key-value on different nodes, their value will be conflict.
- We can use vector clock [ServerNumber, DataVersion] to get the final value by determining the preceding / succeeding relationship of the two data.
- downside of the vector clock:
- add complicated logic
- the vector clock may grow rapidly. This can be solved by removing the outdated [server, version] pair by a predefined threshold.
- Failure Detection
- usually we can't consider a node down from a single source. We need to get it from at least two independent source.
- Decentralized Failure Detection (Gossip Protocol):
- Each node maintains a node member list which has the memberID and heartbeat counter.
- each node periodically increment the heartbeat counter
- Each node periodically sends the heartbeat to a set of random other nodes which in turn propagate to other nodes.
- If a node heartbeat counter was not incremented for a predefined period, it is considered as offline.
- Handling failure:
- if a node is down, another nodes will handle the requests temporarily. When the node is up, changes will be pushed back to it to achieve data consistency. This is called "hinted handoff"
- Read Path
- [Cache Hit]: client -----> memory cache (Memory)
- 1. client sends a request to read from memory cache. If the data is in cache, it is returned to client.
- [Cache Miss]: client -> memory cache (memory) ---->> bloom filter ----> SSTable ---> Data Result -> Client
- 1. if the requested data is not in cache, it has to be queried from disk (SSTable)
- 2. the bloom filter is used to determine which SSTable partition might have the requested data.
- 3. When the requested data is found in SSTable, it is returned back to client.
- Write Path
- client --------(1)-> commit log
|(2)
cache------(3)--->SStable
(1). client sends a request to write data. The write first persists to commit log
(2). the data is saved to cache.
(3). the the data is flushed from cache to SSTable.