consistent hashing.excalidraw

highscalability blog systemdesign.one blog

  • to distribute requests/data across servers for horizontal scaling
  • rehashing problem?
    • happens when adding new servers or removing existing servers if still using current hash function
  • consistent hashing is a technique where only k/n keys need to be remapped on average when a hash table is resized, where k is the number of keys and n is the number of slots

basic approach

  • map servers and keys (requests) to the ring by using a uniform distribution hash function—the same hash function for both servers and requests (impossible to keep same size partitions of ring due to adding/removing servers)
  • A popular hashing function is MD5
  • to find the server for each key, go clockwise until the first server is found
  • add virtual nodes for each server (a server can serve multiple partitions of the ring)
  • when adding/removing a server, a fraction of the data needs to be redistributed (move counter-clockwise from the removed server to the first running server)

dynamic hashing for partitioning

static hash partitioning

  • using a hash function with a fixed number of nodes (N) to locate the index, collisions may occur when multiple nodes have the same position
  • not horizontally scalable; adding/removing nodes needs rehashing of cached data -> massive data movement between nodes

consistent hashing

  • consistent hashing distributes hashing positions on a virtual hash ring (finite fixed circular space) -> reduce re-hashing
  • use the same uniform and independent hashing function for both nodes and data
  • the first node with a greater position than the key’s position (following the clockwise direction) stores the key’s data

delete an existing node

add a new node

  • consistent hashing aids cloud computing by minimizing the movement of data when the number of nodes changes due to scaling
  • nodes may not be uniformly distributed -> virtual nodes -> improve load balancing and prevent hotspots (receive too many requests). The nodes with higher capacity will have more positions (or virtual nodes) on the hash ring

optimization

  • multi-probe
    • Linear space complexity for storing a node’s position on the hash ring -> no virtual node, a node is assigned only one position on hash ring
    • use multiple hashing functions at the same time to find nearest node for each request -> slower lookup
  • bounded loads
    • set an upper limit on the load received by a node -> average load of whole hash ring -> node is not overloaded (hotspots)
    • the list of fallback nodes is similar for same request’s hash -> request is redistributed among the available nodes instead of only fallback node

implementation

  • Use a self-balancing binary search tree (BST), each node on BST is a node on hash ring

  • insert data object (key)

  • add new node

  • remove node

  • complexity of consistent hashing

    • add/remove a node: O(k/n + logn) - O(k/n) for redistribution of keys
    • add/remove a key: O(logn) - BST traversal

modulo hashing

  • hash id to number, and apply modulo operation to find target server server_id = hash(id) % number_of_servers
  • disadvantages
    • when the number of servers changes, the data needs to be redistributed -> massive data movement

consistent hashing

  • arrange both the data and the servers on a fixed-size hash ring
  • adding a new server: some data needs to be redistributed (instead of whole data)
  • removing server