paint-brush
The Thundering Herd Problem: Taming the Stampede in Distributed Systemsby@rashmesh
243 reads

The Thundering Herd Problem: Taming the Stampede in Distributed Systems

by October 8th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

The thundering herd problem occurs when numerous processes simultaneously access a shared resource, overwhelming distributed systems. Jitter, which introduces controlled randomness in timing, effectively mitigates this issue. Java developers can implement jitter using standard libraries or third-party solutions. For REST clients and IoT devices, custom interceptors, retry policies, and circuit breakers with jitter can prevent recurring stampedes. Implementing jitter is crucial for creating resilient and scalable distributed systems.
featured image - The Thundering Herd Problem: Taming the Stampede in Distributed Systems
undefined HackerNoon profile picture

The thundering herd problem is a critical challenge in distributed systems that can bring even robust architectures to their knees. This article explores the nature of this issue, its recurring variant, and how jitter serves as a crucial defense mechanism. We'll also examine practical solutions for Java developers, including standard libraries and customization options for REST-based clients.

Understanding the Thundering Herd

The thundering herd problem occurs when a large number of processes or clients simultaneously attempt to access a shared resource, overwhelming the system. This can happen in various scenarios:


  • After a service outage, when all clients try to reconnect at once
  • When a popular cache item expires, causing multiple requests to hit the backend
  • During scheduled events or cron jobs that trigger at the same time across many servers


The impact can be severe, leading to:

  • Increased latency
  • Service unavailability
  • Cascading failures across dependent systems

Recurring Thundering Herd: A Persistent Threat

While a single thundering herd event can be disruptive, recurring instances pose an even greater danger. This phenomenon happens when:

  • Clients use fixed retry intervals, causing repeated traffic spikes
  • Periodic tasks across multiple servers align over time
  • IoT devices or smart home appliances check for updates on a fixed schedule

Jitter: The Unsung Hero of Distributed Systems

Jitter introduces controlled randomness into timing mechanisms, effectively dispersing potential traffic spikes. Here's why it's crucial:

  1. Prevents synchronization: By adding small random delays, jitter keeps processes from aligning their actions.
  2. Smooths traffic: Instead of sharp spikes, jitter creates a more even distribution of requests over time.
  3. Improves resilience: Systems with jitter can better handle load variations and recover from failures.

Implementing Jitter in Java

Java developers have several options for implementing jitter:

Standard Libraries

  1. java.util.concurrent.ThreadLocalRandom:

    javalong jitter = ThreadLocalRandom.current().nextLong(0, maxJitterMs);
    
    


  2. java.util.Random:

    javaRandom random = new Random();
    long jitter = random.nextLong(maxJitterMs);
    
    

Third-Party Libraries

  1. Guava's ExponentialBackOff:

    javaExponentialBackOff backoff = ExponentialBackOff.builder()
        .setInitialIntervalMillis(500)
        .setMaxIntervalMillis(1000 * 60 * 5)
        .setMultiplier(1.5)
        .setRandomizationFactor(0.5)
        .build();
    
    
  2. Resilience4j's Retry:

    javaRetryConfig config = RetryConfig.custom()
        .waitDuration(Duration.ofMillis(1000))
        .maxAttempts(3)
        .build();
    Retry retry = Retry.of("myRetry", config);
    
    

Customizing REST Clients with Jitter

When working with REST clients, you can incorporate jitter in several ways:

  1. Custom Interceptors: Implement an interceptor that adds a random delay before each request.
  2. Retry Policies: Use libraries like OkHttp or Apache HttpClient that allow custom retry policies with jitter.
  3. Circuit Breakers: Implement circuit breakers with jittered retry mechanisms using libraries like Hystrix or Resilience4j.

IoT and Smart Home Devices: A Special Case

The thundering herd problem is particularly relevant for IoT and smart home devices. These devices often use a common pattern of periodically checking for updates or sending data to a central server. To mitigate potential issues:


  1. Implement device-side jitter for update checks and data transmissions.
  2. Use push notifications instead of frequent polling when possible.
  3. Stagger initial boot times and update schedules across device fleets.

Conclusion

The thundering herd problem remains a significant challenge in distributed systems, but with proper understanding and implementation of jitter, developers can create more resilient and scalable applications. By leveraging Java's built-in libraries and third-party solutions, along with custom REST client configurations, you can effectively tame the herd and ensure your systems remain stable under heavy load. Remember, in the world of distributed systems, a little randomness goes a long way in maintaining order and preventing chaos.

References:

[1] Distributed Systems Horror Stories: The Thundering Herd Problem https://encore.dev/blog/thundering-herd-problem [2] Retry policy to avoid Thundering Herd Problem - Temporal Community https://community.temporal.io/t/retry-policy-to-avoid-thundering-herd-problem/790 [3] This is known generally as the "Thundering Herd" problem https://news.ycombinator.com/item?id=1722213 [4] Using the REST Client - Quarkus https://quarkus.io/guides/rest-client [5] Thundering Herd Problem and How not to do API retries - YouTube https://www.youtube.com/watch?v=8sTuCPh3s0s [6] YouTube Strategy: Adding Jitter isn't a Bug - High Scalability - https://highscalability.com/youtube-strategy-adding-jitter-isnt-a-bug/ [7] Timeouts, retries and backoff with jitter - AWS https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/ [8] Connect to a REST API - Jitterbit Documentation https://success.jitterbit.com/design-studio/design-studio-reference/sources-and-targets/http/rest-api-tutorial/connect-to-a-rest-api/

[9] Figure 1: Figure 1: The thundering herd problem : Image generated using DALL-E 3 from the prompt "The Thundering Herd Problem: Taming the Stampede in Distributed Systems" (OpenAI, 2023)