Zetian.Storage.Redis
1.0.3
Prefix Reserved
dotnet add package Zetian.Storage.Redis --version 1.0.3
NuGet\Install-Package Zetian.Storage.Redis -Version 1.0.3
<PackageReference Include="Zetian.Storage.Redis" Version="1.0.3" />
<PackageVersion Include="Zetian.Storage.Redis" Version="1.0.3" />
<PackageReference Include="Zetian.Storage.Redis" />
paket add Zetian.Storage.Redis --version 1.0.3
#r "nuget: Zetian.Storage.Redis, 1.0.3"
#:package Zetian.Storage.Redis@1.0.3
#addin nuget:?package=Zetian.Storage.Redis&version=1.0.3
#tool nuget:?package=Zetian.Storage.Redis&version=1.0.3
Zetian.Storage.Redis - Redis Storage
Redis cache and storage provider for Zetian SMTP Server. Delivers ultra-fast, in-memory message caching and temporary storage with advanced features including automatic chunking for large messages, Redis Streams for event-driven architectures, Pub/Sub notifications for real-time updates, sorted set indexing, TTL-based expiration, and built-in compression. Ideal for high-throughput environments requiring lightning-fast message access and real-time event processing.
⚡ Features
- 📊 Sorted Sets - Efficient time-based queries
- ⏱️ TTL Expiration - Automatic cache cleanup
- 🗜️ Compression - Optional GZIP compression
- 📢 Pub/Sub - Real-time message notifications
- 💾 Persistence Options - RDB and AOF support
- 🔄 Pipeline Support - Batch operations for efficiency
- 🌊 Redis Streams - Event-driven message processing
- 🌍 Cluster Support - Horizontal scaling with Redis Cluster
- 📦 Chunking Support - Automatic splitting of large messages
- 🚀 Ultra-Fast Performance - In-memory storage with sub-millisecond latency
📦 Installation
# Install SMTP Server and Storage Provider
dotnet add package Zetian
dotnet add package Zetian.Storage.Redis
🚀 Quick Start
Basic Configuration
using Zetian.Server;
using Zetian.Storage.Redis.Extensions;
// Configure with connection string
var server = new SmtpServerBuilder()
.Port(25)
.WithRedisStorage("localhost:6379")
.Build();
await server.StartAsync();
Advanced Configuration
var server = new SmtpServerBuilder()
.Port(25)
.WithRedisStorage(
"localhost:6379,password=mypassword",
config =>
{
config.DatabaseNumber = 1;
config.KeyPrefix = "smtp:msg:";
config.MessageTTLSeconds = 3600; // 1 hour cache
config.EnableChunking = true;
config.ChunkSizeKB = 64;
config.UseRedisStreams = true;
config.EnablePubSub = true;
config.MaintainIndex = true;
config.CompressMessageBody = true;
})
.Build();
🛠️ Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
ConnectionString |
string | - | Redis connection string (required) |
DatabaseNumber |
int | 0 | Redis database number (0-15) |
KeyPrefix |
string | "smtp:" | Prefix for all Redis keys |
MessageTTLSeconds |
int | 3600 | Message expiration time in seconds |
EnableChunking |
bool | true | Split large messages into chunks |
ChunkSizeKB |
int | 64 | Size of each chunk in KB |
UseRedisStreams |
bool | false | Use Redis Streams for storage |
StreamKey |
string | "smtp:stream" | Key for Redis Stream |
EnablePubSub |
bool | false | Enable Pub/Sub notifications |
PubSubChannel |
string | "smtp:notifications" | Channel for notifications |
MaintainIndex |
bool | true | Maintain sorted set index |
IndexKey |
string | "smtp:index" | Key for sorted set index |
MaxMessageSizeMB |
double | 100 | Maximum message size in MB |
CompressMessageBody |
bool | false | Compress message bodies |
EnableRetry |
bool | true | Enable retry logic |
MaxRetryAttempts |
int | 3 | Maximum retry attempts |
RetryDelayMs |
int | 1000 | Delay between retries |
ConnectionTimeoutSeconds |
int | 30 | Connection timeout |
LogErrors |
bool | true | Whether to log errors |
🎯 Usage Examples
Connection String Options
// Standalone server
.WithRedisStorage("localhost:6379")
// With password
.WithRedisStorage("localhost:6379,password=mypassword")
// Multiple endpoints (replica)
.WithRedisStorage("server1:6379,server2:6379")
// With SSL/TLS
.WithRedisStorage("localhost:6379,ssl=true,sslHost=redis.example.com")
// Redis Sentinel
.WithRedisStorage("sentinel1:26379,sentinel2:26379,serviceName=mymaster")
// Redis Cluster
.WithRedisStorage("cluster1:7000,cluster2:7001,cluster3:7002")
Storage Strategies
Key-Value Storage (Default)
// Messages stored as regular Redis keys
config.UseRedisStreams = false;
// Storage pattern:
// smtp:msg:{messageId} - Message data
// smtp:meta:{messageId} - Message metadata
// smtp:chunk:{messageId}:{n} - Message chunks (if chunked)
Redis Streams
// Use Redis Streams for event-driven architectures
config.UseRedisStreams = true;
config.StreamKey = "smtp:stream";
// Consume messages from stream
var entries = await db.StreamReadAsync("smtp:stream", "0-0");
Chunking for Large Messages
// Automatically chunk large messages
config.EnableChunking = true;
config.ChunkSizeKB = 64; // 64KB chunks
config.MaxMessageSizeMB = 50; // Support up to 50MB messages
📊 Redis Data Structures
Message Storage
-- Key-Value storage
SET smtp:msg:123 "<message_body>"
HSET smtp:meta:123 "from" "sender@example.com" "size" "2048"
-- Chunked storage
SET smtp:chunk:123:0 "<chunk_0>"
SET smtp:chunk:123:1 "<chunk_1>"
HSET smtp:meta:123 "chunks" "2"
-- Sorted Set Index
ZADD smtp:index <timestamp> "123"
-- Redis Stream
XADD smtp:stream * messageId "123" data "<message_data>"
Pub/Sub Notifications
// Enable real-time notifications
config.EnablePubSub = true;
config.PubSubChannel = "smtp:notifications";
// Subscribe to notifications
var subscriber = redis.GetSubscriber();
subscriber.Subscribe("smtp:notifications", (channel, message) =>
{
var notification = JsonSerializer.Deserialize<MessageNotification>(message);
Console.WriteLine($"New message: {notification.MessageId}");
});
// Notification format
{
"Event": "MessageStored",
"MessageId": "msg-123",
"Timestamp": "2024-01-01T12:00:00Z",
"Size": 2048
}
🚀 Performance Optimization
Connection Pooling
config.ConnectionString = "localhost:6379," +
"connectTimeout=5000," +
"syncTimeout=5000," +
"asyncTimeout=5000," +
"keepAlive=60," +
"abortConnect=false";
Pipeline Operations
// Batch multiple operations
var batch = db.CreateBatch();
var tasks = new List<Task>();
foreach (var message in messages)
{
tasks.Add(batch.StringSetAsync($"smtp:msg:{message.Id}", message.Body));
tasks.Add(batch.HashSetAsync($"smtp:meta:{message.Id}", metadata));
}
batch.Execute();
await Task.WhenAll(tasks);
Memory Optimization
// Use compression for large messages
config.CompressMessageBody = true;
// Set appropriate TTL
config.MessageTTLSeconds = 3600; // 1 hour
// Use eviction policies
// In redis.conf: maxmemory-policy allkeys-lru
🌍 Redis Cluster Support
// Configure for Redis Cluster
config.ConnectionString =
"node1:7000,node2:7001,node3:7002," +
"connectTimeout=5000," +
"configCheckSeconds=60";
// Use hash tags for related keys
config.KeyPrefix = "smtp:{msg}:"; // All message keys on same slot
📈 Monitoring & Metrics
Redis INFO Command
// Get Redis server statistics
var info = await db.ExecuteAsync("INFO", "memory");
Console.WriteLine($"Memory usage: {info}");
Custom Metrics
// Track message count
await db.StringIncrementAsync("smtp:stats:message_count");
// Track total size
await db.StringIncrementAsync("smtp:stats:total_size", message.Size);
// Get statistics
var count = await db.StringGetAsync("smtp:stats:message_count");
var totalSize = await db.StringGetAsync("smtp:stats:total_size");
Redis Monitor
# Monitor Redis commands in real-time
redis-cli monitor
# Check memory usage
redis-cli info memory
# Check connected clients
redis-cli client list
☁️ Cloud Redis Services
Azure Cache for Redis
config.ConnectionString =
"myredis.redis.cache.windows.net:6380," +
"password=<access_key>," +
"ssl=True," +
"abortConnect=False";
AWS ElastiCache
config.ConnectionString =
"mycluster.abc123.ng.0001.use1.cache.amazonaws.com:6379";
// With encryption in-transit
config.ConnectionString =
"mycluster.abc123.ng.0001.use1.cache.amazonaws.com:6379," +
"ssl=true";
Google Cloud Memorystore
config.ConnectionString =
"10.0.0.3:6379"; // Internal IP
// With AUTH
config.ConnectionString =
"10.0.0.3:6379,password=AUTH_STRING";
🔐 Security Best Practices
Authentication
// Use strong passwords
config.ConnectionString = "localhost:6379,password=StrongPassword123!";
// Use ACL (Redis 6.0+)
config.ConnectionString = "localhost:6379,user=smtp_app,password=AppPassword";
Encryption
// Enable SSL/TLS
config.ConnectionString =
"localhost:6379," +
"ssl=true," +
"sslHost=redis.example.com," +
"sslProtocols=Tls12";
Network Security
# Bind to specific interface (redis.conf)
bind 127.0.0.1 ::1
# Enable protected mode
protected-mode yes
# Firewall rules
iptables -A INPUT -p tcp --dport 6379 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP
🔧 Troubleshooting
Common Issues
Connection Timeout
// Increase timeout values
config.ConnectionString = "localhost:6379," +
"connectTimeout=10000," +
"syncTimeout=10000";
Memory Issues
# Check memory usage
redis-cli --bigkeys
redis-cli --memkeys
# Set memory limit
CONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru
📋 Requirements
- .NET 6.0, 7.0, 8.0, 9.0, or 10.0
- Zetian SMTP Server package
- Redis 3.2 or later (without Streams)
- Redis 6.0 or later (for ACL support)
- Redis 5.0 or later (for Streams support)
- StackExchange.Redis package (included)
📚 Documentation & Support
- Issues: GitHub Issues
- Examples: GitHub Examples
- Discussions: GitHub Discussions
- Redis Docs: Redis Documentation
- Documentation: Zetian Documentation
📄 License
MIT License - see LICENSE
Built with ❤️ for the .NET community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- StackExchange.Redis (>= 2.9.99-gfe04f9c406)
- Zetian.Storage (>= 1.0.5)
-
net6.0
- StackExchange.Redis (>= 2.9.99-gfe04f9c406)
- Zetian.Storage (>= 1.0.5)
-
net7.0
- StackExchange.Redis (>= 2.9.99-gfe04f9c406)
- Zetian.Storage (>= 1.0.5)
-
net8.0
- StackExchange.Redis (>= 2.9.99-gfe04f9c406)
- Zetian.Storage (>= 1.0.5)
-
net9.0
- StackExchange.Redis (>= 2.9.99-gfe04f9c406)
- Zetian.Storage (>= 1.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
All changes are detailed at https://zetian.soferity.com/changelog.