Spread the word.

Share the link on social media.

Share
  • Facebook
Have an account? Sign In Now

Sign Up Sign Up


Have an account? Sign In Now

Sign In Sign In


Forgot Password?

Don't have account, Sign Up Here

Forgot Password Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.


Have an account? Sign In Now

You must login to ask a question.


Forgot Password?

Need An Account, Sign Up Here

You must login to add post.


Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

RTSALL Logo RTSALL Logo
Sign InSign Up

RTSALL

RTSALL Navigation

  • Home
  • Tools
    • Run Code
    • JSON Beautifier
    • Regex Tester
    • Diff Checker
    • JWT Decoder
    • UUID Generator
    • .htaccess Generator
    • YAML/JSON Converter
    • SQL Formatter
    • Cron Generator
    • JSON to CSV/Excel
    • System Design Estimator
  • DSA
    • All DSA Problems
    • Online C++ Runner
    • Arrays, Strings & Cache
    • Two Pointers & Sliding Window
    • Linked Lists & Custom Allocators
    • Stacks, Queues & Ring Buffers
    • Trees, BSTs & Indexes
    • Tries & Prefix Search
    • Heaps & Priority Schedulers
    • Hashing & Collision Resolution
    • Graphs & Network Topologies
    • Dynamic Programming
    • Advanced Bitmask & Tree DP
    • Greedy & Resource Allocation
    • Binary Search & State Spaces
    • Bit Manipulation & Low-Level
    • System-Scale & Probabilistic
  • AI Utilities
    • Token Counter
    • JSON Schema Compiler
    • Fine-Tuning JSONL Converter
    • Vector RAG Playground
    • Prompt Optimizer & Architect
    • LLM GPU VRAM Calculator
  • Finance Tools
    • Compound Interest Calculator
    • Simple Interest Calculator
    • Present Value (PV) Calculator
    • Future Value (FV) Calculator
    • NPV Calculator
    • IRR Calculator
    • CAGR Calculator
    • Dividend Income Calculator
    • Yield on Cost Calculator
    • Dividend Payout Ratio
    • WACC Calculator
    • CAPM & Cost of Equity
    • Cost of Debt Calculator
    • DCF Valuation Calculator
    • Enterprise Value Calculator
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Tools
    • Run Code
    • JSON Beautifier
    • Regex Tester
    • Diff Checker
    • JWT Decoder
    • UUID Generator
    • .htaccess Generator
    • YAML/JSON Converter
    • SQL Formatter
    • Cron Generator
    • JSON to CSV/Excel
    • System Design Estimator
  • DSA
    • All DSA Problems
    • Online C++ Runner
    • Arrays, Strings & Cache
    • Two Pointers & Sliding Window
    • Linked Lists & Custom Allocators
    • Stacks, Queues & Ring Buffers
    • Trees, BSTs & Indexes
    • Tries & Prefix Search
    • Heaps & Priority Schedulers
    • Hashing & Collision Resolution
    • Graphs & Network Topologies
    • Dynamic Programming
    • Advanced Bitmask & Tree DP
    • Greedy & Resource Allocation
    • Binary Search & State Spaces
    • Bit Manipulation & Low-Level
    • System-Scale & Probabilistic
  • AI Utilities
    • Token Counter
    • JSON Schema Compiler
    • Fine-Tuning JSONL Converter
    • Vector RAG Playground
    • Prompt Optimizer & Architect
    • LLM GPU VRAM Calculator
  • Finance Tools
    • Compound Interest Calculator
    • Simple Interest Calculator
    • Present Value (PV) Calculator
    • Future Value (FV) Calculator
    • NPV Calculator
    • IRR Calculator
    • CAGR Calculator
    • Dividend Income Calculator
    • Yield on Cost Calculator
    • Dividend Payout Ratio
    • WACC Calculator
    • CAPM & Cost of Equity
    • Cost of Debt Calculator
    • DCF Valuation Calculator
    • Enterprise Value Calculator
  • About Us
  • Blog
  • Contact Us
Home/Questions/Q 3529
Next
In Process

RTSALL Latest Articles

Ahmedelkomy
Ahmedelkomy
Asked: September 11, 20262026-09-11T09:52:37-05:00 2026-09-11T09:52:37-05:00In: Data Structures & Algorithms, Hashing & Collision Resolution

How to implement Consistent Hashing with Virtual Nodes to eliminate hot spots in distributed caches?

When sharding key-value data across distributed cache nodes (like Redis or Memcached clusters), the naive approach is hash(key) % N, where N is the number of servers.

The fatal flaw is that adding or removing a single server changes N, causing almost 100% of all keys to remap, completely evicting caches and triggering database downtime. We need Consistent Hashing. But on a basic hash ring, servers end up with non-uniform key distributions (hot spots). How do Virtual Nodes solve this mathematically, and how do we implement it cleanly?

  • 0
  • 2 2 Answers
  • 0 Followers
  • 0
  • Share
    Share
    • Share on Facebook
    • Share on Twitter
    • Share on LinkedIn
    • Share on WhatsApp

Leave an answer
Cancel reply

You must login to add an answer.


Forgot Password?

Need An Account, Sign Up Here

2 Answers

  • Voted
  • Oldest
  • Recent
  • Random
  1. Anonymous
    Anonymous Begginer
    2026-09-11T09:52:40-05:00Added an answer on September 11, 2026 at 9:52 am

    Consistent Hashing is one of the foundational building blocks of distributed systems (used in Apache Cassandra, Amazon DynamoDB, Akamai CDN, and Envoy Proxy).

    1. The Problem with Naive Modulo Hashing

    If you have 4 servers and use hash(key) % 4, when server 4 crashes, you now compute hash(key) % 3. Because almost every number changes its remainder modulo 3, nearly 100% of cached keys instantly miss, hammering your backend database in a catastrophic thundering herd.

    In Consistent Hashing, when a server is added or removed, only $1/N$ of keys need to be remapped on average. All other keys stay on their existing servers!


    2. The Hash Ring & Why Virtual Nodes are Mandatory

    Imagine a circular ring of numbers from $0$ to $2^{32} – 1$ (the output space of a 32-bit hash function like Murmur3 or MD5).

    • Each physical server is hashed onto a point on this ring.
    • To find where a key belongs, you hash the key, find its coordinate on the ring, and walk clockwise until you hit the first server!

    The Hot Spot Problem: If you only place 3 physical servers on the ring, their hash positions might be clustered close together (e.g. at 10 degrees, 25 degrees, and 280 degrees). Server 3 will end up handling 70% of all traffic, causing a massive hot spot!

    The Solution (Virtual Nodes): Instead of hashing Server A once, we hash it 100 or 200 times under different labels ("server-A#1", "server-A#2", …, "server-A#200"). By distributing hundreds of virtual replicas uniformly across the 360-degree ring, standard deviations drop to near zero, and load is balanced evenly across all physical hardware.


    Production Python 3.12 Implementation with bisect

    import bisect
    import hashlib
    
    class ConsistentHashRing:
        def __init__(self, replicas: int = 150):
            self.replicas = replicas  # Virtual nodes per physical server
            self.ring: list[int] = [] # Sorted list of virtual node hash keys
            self.node_map: dict[int, str] = {} # hash_key -> physical_node_id
    
        def _hash(self, key: str) -> int:
            """Returns 32-bit integer hash using MD5."""
            return int(hashlib.md5(key.encode('utf-8')).hexdigest()[:8], 16)
    
        def add_node(self, node: str) -> None:
            """Adds a physical node by creating virtual replicas across the ring."""
            for i in range(self.replicas):
                v_key = f"{node}#vn_{i}"
                h = self._hash(v_key)
                idx = bisect.bisect_left(self.ring, h)
                self.ring.insert(idx, h)
                self.node_map[h] = node
    
        def remove_node(self, node: str) -> None:
            """Removes all virtual replicas belonging to the physical node."""
            for i in range(self.replicas):
                v_key = f"{node}#vn_{i}"
                h = self._hash(v_key)
                idx = bisect.bisect_left(self.ring, h)
                if idx < len(self.ring) and self.ring[idx] == h:
                    self.ring.pop(idx)
                    del self.node_map[h]
    
        def get_node(self, key: str) -> str | None:
            """Finds the physical server responsible for the given key in O(log(V * N))."""
            if not self.ring:
                return None
    
            h = self._hash(key)
            # Binary search clockwise to the nearest virtual node
            idx = bisect.bisect_right(self.ring, h)
            
            # If we walked past the end of the ring, wrap around to index 0
            if idx == len(self.ring):
                idx = 0
    
            return self.node_map[self.ring[idx]]
    

    Complexity Breakdown

    • Key Lookup: O(log(R * N)) using binary search, where R is replicas (e.g. 150) and N is physical servers (e.g. 10). Searching an array of 1,500 numbers takes 11 comparisons (< 1 microsecond).
    • Node Add/Remove: O(R * log(R * N)). Adding a server only migrates keys from its immediate clockwise neighbor!
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  2. Abhishek
    Abhishek Begginer
    2026-09-11T21:26:57-05:00Added an answer on September 11, 2026 at 9:26 pm

    Here is a modern C++ implementation of Consistent Hashing with Virtual Nodes using std::map (Red-Black Tree) for logarithmic ring lookups.

    Modern C++20 Solution (Fully Runnable)

    #include <iostream>
    #include <string>
    #include <map>
    #include <functional>
    
    class ConsistentHashRing {
        int replicas;
        std::map<uint32_t, std::string> ring; // Sorted hash ring
        std::hash<std::string> hasher;
    
    public:
        ConsistentHashRing(int r = 100) : replicas(r) {}
    
        void addServer(const std::string& server) {
            for (int i = 0; i < replicas; ++i) {
                std::string vnode = server + "#" + std::to_string(i);
                uint32_t h = static_cast<uint32_t>(hasher(vnode));
                ring[h] = server;
            }
        }
    
        void removeServer(const std::string& server) {
            for (int i = 0; i < replicas; ++i) {
                std::string vnode = server + "#" + std::to_string(i);
                uint32_t h = static_cast<uint32_t>(hasher(vnode));
                ring.erase(h);
            }
        }
    
        std::string getServer(const std::string& key) const {
            if (ring.empty()) return "";
            uint32_t h = static_cast<uint32_t>(hasher(key));
            
            // Find first server with hash >= key's hash
            auto it = ring.lower_bound(h);
            if (it == ring.end()) {
                it = ring.begin(); // Wrap around
            }
            return it->second;
        }
    };
    
    int main() {
        ConsistentHashRing cluster(100);
        cluster.addServer("cache-node-1.prod");
        cluster.addServer("cache-node-2.prod");
        cluster.addServer("cache-node-3.prod");
    
        std::cout << "user_session_4829 -> " << cluster.getServer("user_session_4829") << "n";
        std::cout << "order_item_9102   -> " << cluster.getServer("order_item_9102") << "n";
        return 0;
    }
    

    Complexity: O(log(R * N)) lookup speed via Red-Black tree binary search.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp

Sidebar

Ask A Question
  • Popular
  • Answers
  • Queryiest

    What is a database?

    • 3 Answers
  • Anonymous

    How to rotate an array in-place with O(1) space and ...

    • 3 Answers
  • hannah

    What steps can businesses take to identify the most valuable ...

    • 2 Answers
  • Vikram
    aarav0 added an answer Direct Technical Solution: Unlike IVFFlat (which partitions vector spaces with… September 11, 2026 at 9:57 pm
  • Abhishek
    Abhishek added an answer Direct Technical Solution: In C++20, range view adaptors (like std::views::filter,… September 11, 2026 at 9:57 pm
  • Sneha Patel
    Anonymous added an answer Direct Technical Solution: torch.cuda.empty_cache() releases only cached (unallocated) blocks back… September 11, 2026 at 9:57 pm

Related Questions

  • pgvector: HNSW index build fails with out-of-memory or high swap: ...

    • 1 Answer
  • Why does std::views::filter on temporary containers trigger undefined behavior and ...

    • 1 Answer
  • PyTorch RuntimeError: CUDA out of memory: Why torch.cuda.empty_cache() fails & ...

    • 1 Answer
  • Next.js 15: Error: Route used "params" without awaiting it (Asynchronous ...

    • 1 Answer
  • Task Scheduler with Cooldowns: Closed-form mathematical formula vs Priority Queue ...

    • 2 Answers

Top Members

Queryiest

Queryiest

  • 201 Questions
  • 295 Points
Enlightened
Anonymous

Anonymous

  • 11 Questions
  • 42 Points
Begginer
paperubofficial

paperubofficial

  • 0 Questions
  • 22 Points
Begginer

Trending Tags

ai asp.net aws basics aws certification aws console aws free tier aws login aws scenario-based questions c++ career cyber security cyber security interview git java javascript jobs jquery net core net core interview questions sql

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • DSA Problems
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • New Questions
  • Trending Questions
  • Must read Questions
  • Hot Questions

Footer

About Us

  • Meet The Team
  • Blog
  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy
  • Disclaimer
  • Terms & Conditions

Help

  • Knowledge Base
  • Support

Follow

© 2023-25 RTSALL. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.