Recent Posts
Archives

Posts Tagged ‘Redis’

PostHeaderIcon Using Redis as a Shared Cache in AWS: Architecture, Code, and Best Practices

In today’s distributed, cloud-native environments, shared caching is no longer an optimization—it’s a necessity. Whether you’re scaling out web servers, deploying stateless containers, or orchestrating microservices in Kubernetes, a centralized, fast-access cache is a cornerstone for performance and resilience.

This post explores why Redis, especially via Amazon ElastiCache, is an exceptional choice for this use case—and how you can use it in production-grade AWS architectures.

🔧 Why Use Redis for Shared Caching?

Redis (REmote DIctionary Server) is an in-memory key-value data store renowned for:

  • Lightning-fast performance (sub-millisecond)
  • Built-in data structures: Lists, Sets, Hashes, Sorted Sets, Streams
  • Atomic operations: Perfect for counters, locks, session control
  • TTL and eviction policies: Cache data that expires automatically
  • Wide language support: Python, Java, Node.js, Go, and more

☁️ Redis in AWS: Use ElastiCache for Simplicity & Scale

Instead of self-managing Redis on EC2, AWS offers Amazon ElastiCache for Redis:

  • Fully managed Redis with patching, backups, monitoring
  • Multi-AZ support with automatic failover
  • Clustered mode for horizontal scaling
  • Encryption, VPC isolation, IAM authentication

ElastiCache enables you to focus on application logic, not infrastructure.

🌐 Real-World Use Cases

Use Case How Redis Helps
Session Sharing Store auth/session tokens accessible by all app instances
Rate Limiting Atomic counters (INCR) enforce per-user quotas
Leaderboards Sorted sets track rankings in real-time
Caching SQL Results Avoid repetitive DB hits with cache-aside pattern
Queues Lightweight task queues using LPUSH / BRPOP

📈 Architecture Pattern: Cache-Aside with Redis

Here’s the common cache-aside strategy:

  1. App queries Redis for a key.
  2. If hit ✅, return cached value.
  3. If miss ❌, query DB, store result in Redis.

Python Example with redis and psycopg2:

import redis
import psycopg2
import json

r = redis.Redis(host='my-redis-host', port=6379, db=0)
conn = psycopg2.connect(dsn="...")

def get_user(user_id):
    cached = r.get(f"user:{user_id}")
    if cached:
        return json.loads(cached)

    with conn.cursor() as cur:
        cur.execute("SELECT id, name FROM users WHERE id = %s", (user_id,))
        user = cur.fetchone()
        if user:
            r.setex(f"user:{user_id}", 3600, json.dumps({'id': user[0], 'name': user[1]}))
        return user

🌍 Multi-Tiered Caching

To reduce Redis load and latency further:

  • Tier 1: In-process (e.g., Guava, Caffeine)
  • Tier 2: Redis (ElastiCache)
  • Tier 3: Database (RDS, DynamoDB)

This pattern ensures that most reads are served from memory.

⚠️ Common Pitfalls to Avoid

Mistake Fix
Treating Redis as a DB Use RDS/DynamoDB for persistence
No expiration Always set TTLs to avoid memory pressure
No HA Use ElastiCache Multi-AZ with automatic failover
Poor security Use VPC-only access, enable encryption/auth

🌐 Bonus: Redis for Lambda

Lambda is stateless, so Redis is perfect for:

  • Shared rate limiting
  • Caching computed values
  • Centralized coordination

Use redis-py, ioredis, or lettuce in your function code.

🔺 Conclusion

If you’re building modern apps on AWS, ElastiCache with Redis is a must-have for state sharing, performance, and reliability. It plays well with EC2, ECS, Lambda, and everything in between. It’s mature, scalable, and robust.

Whether you’re running a high-scale SaaS or a small internal app, Redis gives you a major performance edge without locking you into complexity.

PostHeaderIcon [PHPForumParis2023] Streams: We All Underestimate Predis! – Alexandre Daubois

Alexandre Daubois, lead Symfony developer at Wanadev Digital, delivered a concise yet impactful session at Forum PHP 2023, spotlighting the power of Predis, a PHP client for Redis. Focusing on his team’s work at Wanadev Digital, Alexandre shared how Predis’s stream capabilities resolved critical performance issues in their 3D home modeling tool, Kozikaza. His talk highlighted practical applications of Redis streams, inspiring developers to leverage this underutilized tool for efficient data handling.

The Power of Redis Streams

Alexandre introduced Redis streams as a lightweight, in-memory data structure ideal for handling large datasets. At Wanadev Digital, the Kozikaza platform, which enables users to design 3D home models in browsers, faced challenges with storing and processing large JSON models. Alexandre explained how Predis’s stream functionality allowed his team to write data incrementally to cloud storage, avoiding memory bottlenecks. This approach enabled Kozikaza to handle massive datasets, such as 50GB JSON files, efficiently.

Solving Real-World Challenges

Detailing the implementation, Alexandre described how Predis’s Lazy Stream feature facilitated piecewise data writing to cloud buckets, resolving memory constraints in Kozikaza’s workflow. He shared user behavior insights, noting that long session times (up to six hours) made initial load times less critical, as users kept the application open. This context allowed Alexandre’s team to prioritize functionality over premature optimization, using Predis to deliver a robust solution under tight deadlines.

Links:

PostHeaderIcon [DevoxxPL2022] Before It’s Too Late: Finding Real-Time Holes in Data • Chayim Kirshen

Chayim Kirshen, a veteran of the startup ecosystem and client manager at Redis, captivated audiences at Devoxx Poland 2022 with a dynamic exploration of real-time data pipeline challenges. Drawing from his experience with high-stakes environments, including a 2010 stock exchange meltdown, Chayim outlined strategies to ensure data integrity and performance in large-scale systems. His talk provided actionable insights for developers, emphasizing the importance of storing raw data, parsing in real time, and leveraging technologies like Redis to address data inconsistencies.

The Perils of Unclean Data

Chayim began with a stark reality: data is rarely clean. Recounting a 2010 incident where hackers compromised a major stock exchange’s API, he highlighted the cascading effects of unreliable data on real-time markets. Data pipelines face issues like inconsistent formats (CSV, JSON, XML), changing sources (e.g., shifting API endpoints), and service reliability, with modern systems often tolerating over a thousand minutes of downtime annually. These challenges disrupt real-time processing, critical for applications like stock exchanges or ad bidding networks requiring sub-100ms responses. Chayim advocated treating data as programmable code, enabling developers to address issues systematically rather than reactively.

Building Robust Data Pipelines

To tackle these issues, Chayim proposed a structured approach to data pipeline design. Storing raw data indefinitely—whether in S3, Redis, or other storage—ensures a fallback for reprocessing. Parsing data in real time, using defined schemas, allows immediate usability while preserving raw inputs. Bulk changes, such as SQL bulk inserts or Redis pipelines, reduce network overhead, critical for high-throughput systems. Chayim emphasized scheduling regular backfills to re-import historical data, ensuring consistency despite source changes. For example, a stock exchange’s ticker symbol updates (e.g., Fitbit to Google) require ongoing reprocessing to maintain accuracy. Horizontal scaling, using disposable nodes, enhances availability and resilience, avoiding single points of failure.

Real-Time Enrichment and Redis Integration

Data enrichment, such as calculating stock bid-ask spreads or market cap changes, should occur post-ingestion to avoid slowing the pipeline. Chayim showcased Redis, particularly its Gears and JSON modules, for real-time data processing. Redis acts as a buffer, storing raw JSON and replicating it to traditional databases like PostgreSQL or MySQL. Using Redis Gears, developers can execute functions within the database, minimizing network costs and enabling rapid enrichment. For instance, calculating a stock’s daily percentage change can run directly in Redis, streamlining analytics. Chayim highlighted Python-based tools like Celery for scheduling backfills and enrichments, allowing asynchronous processing and failure retries without disrupting the main pipeline.

Scaling and Future-Proofing

Chayim stressed horizontal scaling to distribute workloads geographically, placing data closer to users for low-latency access, as seen in ad networks. By using Redis for real-time writes and offloading to workers via Celery, developers can manage millions of daily entries, such as stock ticks, without performance bottlenecks. Scheduled backfills address data gaps, like API schema changes (e.g., integer to string conversions), by reprocessing raw data. This approach, combined with infrastructure-as-code tools like Terraform, ensures scalability and adaptability, allowing organizations to focus on business logic rather than data management overhead.

Links:

PostHeaderIcon [SpringIO2019] Zero Downtime Migrations with Spring Boot by Alex Soto

Deploying software updates without disrupting users is a cornerstone of modern DevOps practices. At Spring I/O 2019 in Barcelona, Alex Soto, a prominent figure at Red Hat, delivered a comprehensive session on achieving zero downtime migrations in Spring Boot applications, particularly within microservices architectures. With a focus on advanced deployment techniques and state management, Alex provided actionable insights for developers navigating the complexities of production environments. This post delves into his strategies, enriched with practical demonstrations and real-world applications.

The Evolution from Monoliths to Microservices

The shift from monolithic to microservices architectures has transformed deployment practices. Alex began by contrasting the simplicity of monolithic deployments—where a single application could be updated during off-hours with minimal disruption—with the complexity of microservices. In a microservices ecosystem, services are interconnected in a graph-like structure, often with independent databases and multiple entry points. This distributed nature amplifies the impact of downtime, as a single service failure can cascade across the system.

To address this, Alex emphasized the distinction between deployment (placing a service in production) and release (routing traffic to it). This separation is critical for zero downtime, allowing teams to test new versions without affecting users. By leveraging service meshes like Istio, developers can manage traffic routing dynamically, ensuring seamless transitions between service versions.

Blue-Green and Canary Deployments

Alex explored two foundational techniques for zero downtime: blue-green and canary deployments. In blue-green deployments, a new version (green) is deployed alongside the existing one (blue), with traffic switched to the green version once validated. This approach minimizes disruption but risks affecting all users if the green version fails. Canary deployments mitigate this by gradually routing a small percentage of traffic to the new version, allowing teams to monitor performance before a full rollout.

Both techniques rely on robust monitoring, such as Prometheus, to detect issues early. Alex demonstrated a blue-green deployment using a movie store application, where a shopping cart’s state was preserved across versions using an in-memory data grid like Redis. This ensured users experienced no loss of data, even during version switches, highlighting the power of stateless and ephemeral state management in microservices.

Managing Persistent State

Persistent state, such as database schemas, poses a significant challenge in zero downtime migrations. Alex illustrated this with a scenario involving renaming a database column from “name” to “full_name.” A naive approach risks breaking compatibility, as some users may access the old schema while others hit the new one. To address this, he proposed a three-step migration process:

  1. Dual-Write Phase: The application writes to both the old and new columns, ensuring data consistency across versions.
  2. Data Migration: Historical data is copied from the old column to the new one, often using tools like Spring Batch to avoid locking the database.
  3. Final Transition: The application reads and writes exclusively to the new column, with the old column retained for rollback compatibility.

This methodical approach, demonstrated with a Kubernetes-based cluster, ensures backward compatibility and uninterrupted service. Alex’s demo showed how Istio’s traffic management capabilities, such as routing rules and mirroring, facilitate these migrations by directing traffic to specific versions without user impact.

Leveraging Istio for Traffic Management

Istio, a service mesh, plays a pivotal role in Alex’s strategy. By abstracting cross-cutting concerns like service discovery, circuit breaking, and security, Istio simplifies zero downtime deployments. Alex showcased how Istio’s sidecar containers handle traffic routing, enabling techniques like traffic mirroring for dark launches. In a dark launch, requests are sent to both old and new service versions, but only the old version’s response is returned to users, allowing teams to test new versions in production without risk.

Istio also supports chaos engineering, simulating delays or timeouts to test resilience. Alex cautioned, however, that such practices require careful communication to avoid unexpected disruptions, as illustrated by anecdotes of misaligned testing efforts. By integrating Istio with Spring Boot, developers can achieve robust, scalable deployments with minimal overhead.

Handling Stateful Services

Stateful services, particularly those with databases, require special attention. Alex addressed the challenge of maintaining ephemeral state, like shopping carts, using in-memory data grids. For persistent state, he recommended strategies like synthetic transactions or throwaway database clusters to handle mirrored traffic during testing. These approaches prevent unintended database writes, ensuring data integrity during migrations.

In his demo, Alex applied these principles to a movie store application, showing how a shopping cart persisted across blue-green deployments. By using Redis to replicate state across a cluster, he ensured users retained their cart contents, even as services switched versions. This practical example underscored the importance of aligning infrastructure with business needs.

Lessons for Modern DevOps

Alex’s presentation offers a roadmap for achieving zero downtime in microservices. By combining advanced deployment techniques, service meshes, and careful state management, developers can deliver reliable, user-focused applications. His emphasis on tools like Istio and Redis, coupled with a disciplined migration process, provides a blueprint for tackling real-world challenges. For teams like those at Red Hat, these strategies enable faster, safer releases, aligning technical excellence with business continuity.

Links: