🎯 Рекомендуемые коллекции

Балансированные коллекции примеров кода из различных категорий, которые вы можете исследовать

Redis Samples

Comprehensive Redis cache solution examples including basic operations, pub/sub patterns, clustering, and performance optimization

💻 Redis Basic Operations

🟢 simple ⭐⭐

Essential Redis operations including string, hash, list, set, and sorted set data types

⏱️ 15 min 🏷️ redis, cache, database
Prerequisites: Redis basics, JavaScript/TypeScript, Node.js
// Redis Basic Operations Examples
const redis = require('redis');
const client = redis.createClient({
    host: 'localhost',
    port: 6379,
    password: 'your-password'
});

async function basicOperations() {
    await client.connect();

    // String operations
    await client.set('user:1:name', 'John Doe');
    const name = await client.get('user:1:name');

    // Hash operations
    await client.hSet('user:1', {
        'name': 'John Doe',
        'email': '[email protected]',
        'age': '30'
    });
    const user = await client.hGetAll('user:1');

    // List operations
    await client.lPush('notifications', 'Welcome!');
    await client.lPush('notifications', 'New message');
    const notifications = await client.lRange('notifications', 0, -1);

    // Set operations
    await client.sAdd('tags:post:1', 'javascript', 'redis', 'database');
    const tags = await client.sMembers('tags:post:1');

    // Sorted set operations
    await client.zAdd('leaderboard', [
        { score: 100, value: 'user1' },
        { score: 85, value: 'user2' }
    ]);
    const topUsers = await client.zRange('leaderboard', 0, 2, { REV: true });

    await client.quit();
}

💻 Advanced Caching Patterns

🟡 intermediate ⭐⭐⭐⭐

Implement cache-aside, write-through, write-behind, and read-through caching strategies

⏱️ 25 min 🏷️ redis, caching, performance
Prerequisites: Redis basics, Caching concepts, JavaScript
// Advanced Redis Caching Patterns
const redis = require('redis');
const client = redis.createClient();

class CacheService {
    constructor(ttl = 3600) {
        this.client = client;
        this.ttl = ttl;
    }

    // Cache-aside pattern
    async get(key, fetchFunction) {
        const cached = await this.client.get(key);
        if (cached) return JSON.parse(cached);

        const data = await fetchFunction();
        await this.client.setEx(key, this.ttl, JSON.stringify(data));
        return data;
    }

    // Write-through pattern
    async set(key, data, persistFunction) {
        await persistFunction(data);
        await this.client.setEx(key, this.ttl, JSON.stringify(data));
    }

    // Write-behind pattern
    async setDelayed(key, data, persistFunction, delay = 5000) {
        await this.client.setEx(key, this.ttl, JSON.stringify(data));

        setTimeout(async () => {
            try {
                await persistFunction(data);
            } catch (error) {
                console.error('Failed to persist data:', error);
            }
        }, delay);
    }

    // Cache invalidation
    async invalidate(pattern) {
        const keys = await this.client.keys(pattern);
        if (keys.length > 0) {
            await this.client.del(keys);
        }
    }
}

💻 Pub/Sub Messaging

🟡 intermediate ⭐⭐⭐

Redis publish/subscribe messaging system for real-time communication

⏱️ 20 min 🏷️ redis, messaging, real-time
Prerequisites: Redis basics, Event-driven programming, JavaScript
// Redis Pub/Sub Implementation
const redis = require('redis');

class PubSubService {
    constructor() {
        this.publisher = redis.createClient();
        this.subscriber = redis.createClient();
        this.subscriptions = new Map();
    }

    async initialize() {
        await this.publisher.connect();
        await this.subscriber.connect();

        this.subscriber.on('message', (channel, message) => {
            const handlers = this.subscriptions.get(channel);
            if (handlers) {
                handlers.forEach(handler => {
                    try {
                        handler(JSON.parse(message));
                    } catch (error) {
                        console.error('Failed to parse message:', error);
                    }
                });
            }
        });
    }

    async subscribe(channel, handler) {
        if (!this.subscriptions.has(channel)) {
            this.subscriptions.set(channel, new Set());
            await this.subscriber.subscribe(channel);
        }
        this.subscriptions.get(channel).add(handler);
    }

    async unsubscribe(channel, handler) {
        const handlers = this.subscriptions.get(channel);
        if (handlers) {
            handlers.delete(handler);
            if (handlers.size === 0) {
                this.subscriptions.delete(channel);
                await this.subscriber.unsubscribe(channel);
            }
        }
    }

    async publish(channel, message) {
        await this.publisher.publish(channel, JSON.stringify(message));
    }
}

⚙️ Redis Clustering

🔴 complex ⭐⭐⭐⭐⭐

Redis cluster setup and management for high availability and scalability

⏱️ 40 min 🏷️ redis, clustering, scalability
Prerequisites: Redis advanced, Docker, Cluster concepts, System administration
# Redis Cluster Configuration
version: '3.8'

services:
  redis-master-1:
    image: redis:7-alpine
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf
    ports:
      - "7001:6379"
    volumes:
      - redis_master_1_data:/data

  redis-master-2:
    image: redis:7-alpine
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf
    ports:
      - "7002:6379"
    volumes:
      - redis_master_2_data:/data

  redis-master-3:
    image: redis:7-alpine
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf
    ports:
      - "7003:6379"
    volumes:
      - redis_master_3_data:/data

  redis-slave-1:
    image: redis:7-alpine
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf
    ports:
      - "7004:6379"
    depends_on:
      - redis-master-1

  redis-slave-2:
    image: redis:7-alpine
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf
    ports:
      - "7005:6379"
    depends_on:
      - redis-master-2

  redis-slave-3:
    image: redis:7-alpine
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf
    ports:
      - "7006:6379"
    depends_on:
      - redis-master-3

  redis-cluster-init:
    image: redis:7-alpine
    depends_on:
      - redis-master-1
      - redis-master-2
      - redis-master-3
      - redis-slave-1
      - redis-slave-2
      - redis-slave-3
    command: |
      sh -c "
      sleep 10
      redis-cli --cluster create \
        redis-master-1:6379 \
        redis-master-2:6379 \
        redis-master-3:6379 \
        redis-slave-1:6379 \
        redis-slave-2:6379 \
        redis-slave-3:6379 \
        --cluster-replicas 1 --cluster-yes
      "

volumes:
  redis_master_1_data:
  redis_master_2_data:
  redis_master_3_data:

💻 Performance Optimization

🔴 complex ⭐⭐⭐⭐

Redis performance tuning techniques including pipelining, batch operations, and memory optimization

⏱️ 30 min 🏷️ redis, performance, optimization
Prerequisites: Redis advanced, Performance optimization, JavaScript
// Redis Performance Optimization
const redis = require('redis');
const { promisify } = require('util');

class OptimizedRedisClient {
    constructor(config = {}) {
        this.client = redis.createClient({
            host: config.host || 'localhost',
            port: config.port || 6379,
            maxRetriesPerRequest: 3,
            retryDelayOnFailover: 100,
            enableOfflineQueue: false,
            lazyConnect: true
        });

        this.pipeline = this.client.pipeline();
        this.batchSize = config.batchSize || 100;
        this.batchTimeout = config.batchTimeout || 10;
    }

    // Pipelining for bulk operations
    async batchSet(data) {
        const pipeline = this.client.pipeline();

        for (const [key, value] of Object.entries(data)) {
            pipeline.set(key, JSON.stringify(value));
        }

        return pipeline.exec();
    }

    // Batch operations with timeout
    async batchGet(keys) {
        const pipeline = this.client.pipeline();
        keys.forEach(key => pipeline.get(key));

        const results = await pipeline.exec();
        return results.map(([err, value]) =>
            err ? null : (value ? JSON.parse(value) : null)
        );
    }

    // Memory-efficient scanning
    async scanKeys(pattern, count = 100) {
        const keys = [];
        let cursor = '0';

        do {
            const [newCursor, batchKeys] = await this.client.scan(
                cursor, 'MATCH', pattern, 'COUNT', count
            );
            keys.push(...batchKeys);
            cursor = newCursor;
        } while (cursor !== '0');

        return keys;
    }

    // Connection pooling simulation
    async getConnection() {
        if (!this.client.isOpen) {
            await this.client.connect();
        }
        return this.client;
    }

    // Optimized caching strategy
    async optimizedGet(key, fetchFunction) {
        try {
            const cached = await this.client.get(key);
            if (cached) {
                // Update expiration for frequently accessed data
                await this.client.expire(key, 3600);
                return JSON.parse(cached);
            }
        } catch (error) {
            console.error('Cache error:', error);
        }

        const data = await fetchFunction();
        await this.client.setEx(key, 3600, JSON.stringify(data));
        return data;
    }

    async disconnect() {
        await this.client.quit();
    }
}