Posts Tagged ‘AWS’
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:
- App queries Redis for a key.
- If hit ✅, return cached value.
- 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.
AWS S3 Warning: “No Content Length Specified for Stream Data” – What It Means and How to Fix It
If you’re working with the AWS SDK for Java and you’ve seen the following log message:
WARN --- AmazonS3Client : No content length specified for stream data. Stream contents will be buffered in memory and could result in out of memory errors.
…you’re not alone. This warning might seem harmless at first, but it can lead to serious issues, especially in production environments.
What’s Really Happening?
This message appears when you upload a stream to Amazon S3 without explicitly setting the content length in the request metadata.
When that happens, the SDK doesn’t know how much data it’s about to upload, so it buffers the entire stream into memory before sending it to S3. If the stream is large, this could lead to:
- Excessive memory usage
- Slow performance
- OutOfMemoryError crashes
✅ How to Fix It
Whenever you upload a stream, make sure you calculate and set the content length using ObjectMetadata
.
Example with Byte Array:
byte[] bytes = ...; // your content
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(bytes.length);
PutObjectRequest request = new PutObjectRequest(bucketName, key, inputStream, metadata);
s3Client.putObject(request);
Example with File:
File file = new File("somefile.txt");
FileInputStream fileStream = new FileInputStream(file);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.length());
PutObjectRequest request = new PutObjectRequest(bucketName, key, fileStream, metadata);
s3Client.putObject(request);
What If You Don’t Know the Length?
Sometimes, you can’t know the content length ahead of time (e.g., you’re piping data from another service). In that case:
- Write the stream to a
ByteArrayOutputStream
first (good for small data) - Use the S3 Multipart Upload API to stream large files without specifying the total size
Conclusion
Always set the content length when uploading to S3 via streams. It’s a small change that prevents large-scale problems down the road.
By taking care of this up front, you make your service safer, more memory-efficient, and more scalable.
Got questions or dealing with tricky S3 upload scenarios? Drop them in the comments!
[DevoxxFR 2018] Deploying Microservices on AWS: Compute Options Explored at Devoxx France 2018
At Devoxx France 2018, Arun Gupta and Tiffany Jernigan, both from Amazon Web Services (AWS), delivered a three-hour deep-dive session titled Compute options for Microservices on AWS. This hands-on tutorial explored deploying a microservices-based application using various AWS compute options: EC2, Amazon Elastic Container Service (ECS), AWS Fargate, Elastic Kubernetes Service (EKS), and AWS Lambda. Through a sample application with web app, greeting, and name microservices, they demonstrated local testing, deployment pipelines, service discovery, monitoring, and canary deployments. The session, rich with code demos, is available on YouTube, with code and slides on GitHub.
Microservices: Solving Business Problems
Arun Gupta opened by addressing the monolith vs. microservices debate, emphasizing that the choice depends on business needs. Microservices enable agility, frequent releases, and polyglot environments but introduce complexity. AWS simplifies this with managed services, allowing developers to focus on business logic. The demo application featured three microservices: a public-facing web app, and internal greeting and name services, communicating via REST endpoints. Built with WildFly Swarm, a Java EE-compliant server, the application produced a portable fat JAR, deployable as a container or Lambda function. The presenters highlighted service discovery, ensuring the web app could locate stateless instances of greeting and name services.
EC2: Full Control for Traditional Deployments
Amazon EC2 offers developers complete control over virtual machines, ideal for those needing to manage the full stack. The presenters deployed the microservices on EC2 instances, running WildFly Swarm JARs. Using Maven and a Docker profile, they generated container images, pushed to Docker Hub, and tested locally with Docker Compose. A docker stack deploy
command spun up the services, accessible via curl localhost:8080
, returning responses like “hello Sheldon.” EC2 requires manual scaling and cluster management, but its flexibility suits custom stacks. The GitHub repo includes configurations for EC2 deployments, showcasing integration with AWS services like CloudWatch for logging.
Amazon ECS: Orchestrating Containers
Amazon ECS simplifies container orchestration, managing scheduling and scaling. The presenters created an ECS cluster in the AWS Management Console, defining task definitions for the three microservices. Task definitions specified container images, CPU, and memory, with an Application Load Balancer (ALB) enabling path-based routing (e.g., /resources/greeting
). Using the ECS CLI, they deployed services, ensuring high availability across multiple availability zones. CloudWatch integration provided metrics and logs, with alarms for monitoring. ECS reduces operational overhead compared to EC2, balancing control and automation. The session highlighted ECS’s deep integration with AWS services, streamlining production workloads.
AWS Fargate: Serverless Containers
Introduced at re:Invent 2017, AWS Fargate abstracts server management, allowing developers to focus on containers. The presenters deployed the same microservices using Fargate, specifying task definitions with AWS VPC networking for fine-grained security. The Fargate CLI, a GitHub project by AWS’s John Pignata, simplified setup, creating ALBs and task definitions automatically. A curl
to the load balancer URL returned responses like “howdy Penny.” Fargate’s per-second billing and task-level resource allocation optimize costs. Available initially in US East (N. Virginia), Fargate suits developers prioritizing simplicity. The session emphasized its role in reducing infrastructure management.
Elastic Kubernetes Service (EKS): Kubernetes on AWS
EKS, in preview during the session, brings managed Kubernetes to AWS. The presenters deployed the microservices on an EKS cluster, using kubectl
to manage pods and services. They introduced Istio, a service mesh, to handle traffic routing and observability. Istio’s sidecar containers enabled 50/50 traffic splits between “hello” and “howdy” versions of the greeting service, configured via YAML manifests. Chaos engineering was demonstrated by injecting 5-second delays in 10% of requests, testing resilience. AWS X-Ray, integrated via a daemon set, provided service maps and traces, identifying bottlenecks. EKS, later supporting Fargate, offers flexibility for Kubernetes users. The GitHub repo includes EKS manifests and Istio configurations.
AWS Lambda: Serverless Microservices
AWS Lambda enables serverless deployments, eliminating server management. The presenters repurposed the WildFly Swarm application for Lambda, using the Serverless Application Model (SAM). Each microservice became a Lambda function, fronted by API Gateway endpoints (e.g., /greeting
). SAM templates defined functions, APIs, and DynamoDB tables, with sam local start-api
testing endpoints locally via Dockerized Lambda runtimes. Responses like “howdy Sheldon” were verified with curl localhost:3000
. SAM’s package
and deploy
commands uploaded functions to S3, while canary deployments shifted traffic (e.g., 10% to new versions) with CloudWatch alarms. Lambda’s per-second billing and 300-second execution limit suit event-driven workloads. The session showcased SAM’s integration with AWS services and the Serverless Application Repository.
Deployment Pipelines: Automating with AWS CodePipeline
The presenters built a deployment pipeline using AWS CodePipeline, a managed service inspired by Amazon’s internal tooling. A GitHub push triggered the pipeline, which used CodeCommit to build Docker images, pushed them to Amazon Elastic Container Registry (ECR), and deployed to an ECS cluster. For Lambda, SAM templates were packaged and deployed. CloudFormation templates automated resource creation, including VPCs, subnets, and ALBs. The pipeline ensured immutable deployments with commit-based image tags, maintaining production stability. The GitHub repo provides CloudFormation scripts, enabling reproducible environments. This approach minimizes manual intervention, supporting rapid iteration.
Monitoring and Logging: AWS X-Ray and CloudWatch
Monitoring was a key focus, with AWS X-Ray providing end-to-end tracing. In ECS and EKS, X-Ray daemons collected traces, generating service maps showing web app, greeting, and name interactions. For Lambda, X-Ray was enabled natively via SAM templates. CloudWatch offered metrics (e.g., CPU usage) and logs, with alarms for thresholds. In EKS, Kubernetes tools like Prometheus and Grafana were mentioned, but X-Ray’s integration with AWS services was emphasized. The presenters demonstrated debugging Lambda functions locally using SAM CLI and IntelliJ, enhancing developer agility. These tools ensure observability, critical for distributed microservices.
Choosing the Right Compute Option
The session concluded by comparing compute options. EC2 offers maximum control but requires managing scaling and updates. ECS balances automation and flexibility, ideal for containerized workloads. Fargate eliminates server management, suiting simple deployments. EKS caters to Kubernetes users, with Istio enhancing observability. Lambda, best for event-driven microservices, minimizes operational overhead but has execution limits. Factors like team expertise, application requirements, and cost influence the choice. The presenters encouraged feedback via GitHub issues to shape AWS’s roadmap. Visit aws.amazon.com/containers for more.
Links:
Hashtags: #AWS #Microservices #ECS #Fargate #EKS #Lambda #DevoxxFR2018 #ArunGupta #TiffanyJernigan #CloudComputing