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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Zetian.Storage.Redis" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zetian.Storage.Redis" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Zetian.Storage.Redis" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Zetian.Storage.Redis --version 1.0.3
                    
#r "nuget: Zetian.Storage.Redis, 1.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Zetian.Storage.Redis@1.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Zetian.Storage.Redis&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Zetian.Storage.Redis&version=1.0.3
                    
Install as a Cake Tool

Zetian.Storage.Redis - Redis Storage

NuGet-Version NuGet-Download License

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

📄 License

MIT License - see LICENSE


Built with ❤️ for the .NET community

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.3 95 11/1/2025
1.0.2 185 10/29/2025
1.0.1 139 10/25/2025
1.0.0 184 10/25/2025

All changes are detailed at https://zetian.soferity.com/changelog.