@trishchuk/redlock-toolkit
v0.9.1
Published
Advanced Redis distributed locking library with Redlock algorithm, Circuit Breaker pattern, automatic extension and optimistic locking support
Maintainers
Readme
Redlock Toolkit - Advanced Redis Distributed Locking Library
Redlock Toolkit is a powerful TypeScript library for distributed locking that implements the Redlock algorithm with advanced features for fault tolerance, monitoring, and performance.
🚀 Features
- Redlock Algorithm - Reliable distributed locks with consensus support
- Circuit Breaker - Automatic prevention of cascading failures
- Automatic Lock Extension - Prevents premature termination of long-running operations
- Comprehensive Metrics - Detailed metrics with Prometheus export
- Fault Tolerance - Resilient to network failures and Redis disconnections
- TypeScript Support - Full typing and IntelliSense
- Flexible Configuration - Customize all aspects of operation
- AbortSignal Integration - Controlled operation cancellation
- Optimistic Locking - Version-based conflict detection
- Hybrid Locking Strategies - Combine pessimistic and optimistic approaches
- Lock Caching - Performance optimization through intelligent caching
📦 Installation
npm install @trishchuk/redlock-toolkit🔧 Quick Start
import RedlockToolkit from '@trishchuk/redlock-toolkit';
import Redis from 'ioredis';
// Create Redis clients
const clients = [
new Redis({ host: 'redis1.example.com', port: 6379 }),
new Redis({ host: 'redis2.example.com', port: 6379 }),
new Redis({ host: 'redis3.example.com', port: 6379 })
];
// Initialize Redlock Toolkit
const redlockToolkit = new RedlockToolkit({
clients,
defaultLockOptions: {
ttl: 30000, // 30 seconds
retryCount: 10, // 10 attempts
retryDelay: 200, // 200ms delay
retryJitter: 100 // ±100ms jitter
}
});
// Basic usage
async function basicExample() {
try {
// Acquire lock
const lock = await redlockToolkit.acquire('user:123');
// Perform critical section
await performCriticalWork();
// Release lock
await lock.release();
} catch (error) {
console.error('Lock operation failed:', error);
}
}
// Using automatic lock management
async function autoManagedExample() {
const result = await redlockToolkit.using(
'payment:order:456',
async (signal) => {
// Check for abort
if (signal.aborted) throw signal.error;
// Your critical code here
const result = await processPayment();
// Lock is automatically extended and released
return result;
},
{
ttl: 60000,
autoExtendThreshold: 5000
}
);
}🎯 Advanced Features
Optimistic Locking
// Acquire with version control
const result = await redlockToolkit.acquireOptimistic('document:789', {
expectedVersion: 0,
ttl: 30000
});
if (result.success) {
// Update with conflict detection
const updateResult = await redlockToolkit.updateOptimistic(
'document:789',
result.currentVersion!,
{
expectedValue: { status: 'processing' }
}
);
}Hybrid Locking Strategy
// Combine optimistic and pessimistic approaches
const lock = await redlockToolkit.acquireHybrid('inventory:item:123', {
primaryStrategy: 'optimistic',
fallbackStrategy: 'pessimistic',
expectedVersion: 0,
ttl: 30000
});Circuit Breaker Pattern
const redlockToolkit = new RedlockToolkit({
clients,
circuitBreaker: {
failureThreshold: 5, // Open circuit after 5 failures
resetTimeout: 60000, // Try to recover after 60 seconds
maxRetries: 3, // Maximum retries in half-open state
operationTimeout: 5000 // Operation timeout
}
});Monitoring & Metrics
// Get current metrics
const metrics = redlockToolkit.getMetrics();
console.log(`Active locks: ${metrics.activeLocks}`);
console.log(`Success rate: ${metrics.locksAcquired / metrics.failedAcquisitions}`);
// Export Prometheus metrics
const prometheusMetrics = redlockToolkit.exportMetrics();
// Get performance summary
const summary = redlockToolkit.getPerformanceSummary();
console.log(`Average acquisition time: ${summary.averageAcquisitionTime}ms`);Event Handling
redlockToolkit.on('lock:acquired', (resources, identifier) => {
console.log(`Lock acquired: ${resources.join(', ')}`);
});
redlockToolkit.on('lock:failed', (resources, error) => {
console.error(`Lock failed: ${error.message}`);
});
redlockToolkit.on('circuit:stateChanged', (newState) => {
console.log(`Circuit breaker state: ${newState}`);
});🏗️ Architecture
Core Components
- RedlockToolkit - Main class implementing the distributed locking logic
- Lock - Lock instance with auto-extension and signal support
- CircuitBreaker - Fault tolerance through circuit breaker pattern
- MetricsCollector - Comprehensive performance and operational metrics
- Lua Scripts - Atomic Redis operations for lock management
Algorithm Implementation
The library implements the Redlock algorithm as described in the Redis documentation:
- Acquire Phase: Attempts to set lock on majority of Redis nodes
- Validation Phase: Verifies lock validity considering clock drift
- Extension Phase: Automatic extension for long-running operations
- Release Phase: Atomic release across all nodes
🔒 Security Considerations
- Clock Drift Handling: Configurable drift factor (default 1%)
- Lock Validation: Continuous validation of lock ownership
- Secure Identifiers: Cryptographically secure lock identifiers
- Atomic Operations: All Redis operations use Lua scripts for atomicity
🎨 Configuration Options
interface RedlockToolkitConfig {
clients: RedisClient[]; // Redis client instances
defaultLockOptions?: {
ttl?: number; // Lock time-to-live (ms)
retryCount?: number; // Number of retry attempts
retryDelay?: number; // Base retry delay (ms)
retryJitter?: number; // Random jitter (ms)
driftFactor?: number; // Clock drift factor
autoExtendThreshold?: number; // Auto-extend threshold (ms)
};
circuitBreaker?: CircuitBreakerConfig; // Circuit breaker settings
enableMetrics?: boolean; // Enable metrics collection
keyPrefix?: string; // Redis key prefix
}📊 Performance
Benchmarks
| Operation | Avg Time | Throughput | |-----------|----------|------------| | Acquire (3 nodes) | 2.5ms | 400 ops/s | | Release | 1.2ms | 830 ops/s | | Extend | 1.8ms | 555 ops/s | | With Auto-Extension | 3.1ms | 320 ops/s |
Optimization Tips
- Use Connection Pooling: Configure Redis clients with appropriate pool sizes
- Enable Lock Caching: For frequently accessed resources
- Adjust Retry Parameters: Based on your workload characteristics
- Monitor Circuit Breaker: Tune thresholds based on failure patterns
🧪 Testing
# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Run specific test suite
npm test -- --grep "circuit breaker"🤝 Contributing
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
Development Setup
# Clone repository
git clone https://github.com/x51xxx/redlock-toolkit.git
cd redlock-toolkit
# Install dependencies
npm install
# Run tests
npm test
# Build
npm run build📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Salvatore Sanfilippo for the Redlock algorithm
- Mike Marcacci for the original node-redlock implementation
- All contributors who have helped improve this library
📚 Resources
🔗 Related Projects
- ioredis - Redis client for Node.js
- node-redlock - Original Redlock implementation
- redis-semaphore - Semaphore implementation
📈 Roadmap
- [ ] Support for Redis Cluster
- [ ] Distributed tracing integration
- [ ] WebAssembly support
- [ ] Lock priority queues
- [ ] Deadlock detection
- [ ] Multi-region support
💬 Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Stack Overflow: Tag with
redlock-toolkit
Built with ❤️ by Taras Trishchuk
