ویژگی تصویر

اتصال Node.js به Redis — راهنمای کامل و عملی

  /  Node.js   /  اتصال Node.js به Redis
بنر تبلیغاتی الف
NodeJS - Node.js

Redis یک پایگاه داده در حافظه (in-memory) با کارایی بسیار بالا است که برای کش، صف‌ها، شمارشگرها و pub/sub بسیار مناسب است. در این مقاله به زبان فارسی و به‌صورت کاربردی به نحوه اتصال و استفاده از Redis در محیط Node.js می‌پردازیم، مزایا، مثال‌های عملی، پیکربندی اتصال، نکات امنیتی و بهینه‌سازی‌های متداول را پوشش می‌دهیم.

پیش‌نیازها

  • Node.js (نسخه 14+ توصیه می‌شود)
  • نصب Redis روی سرور محلی یا سرویس managed مانند Redis Labs / AWS ElastiCache
  • کتابخانه کلاینت: node-redis (official) یا ioredis

نصب کتابخانه

npm install redis
# یا برای ioredis
npm install ioredis

این دستورها کتابخانه‌های محبوب را نصب می‌کنند. node-redis از نسخهٔ 4 به بعد API مدرن و Promise-based ارائه می‌دهد و ioredis قابلیت‌های پیشرفته‌ای مثل کلستر و Sentinel را دارد.

نمونه اتصال ساده با node-redis (نسخه مدرن)

const { createClient } = require('redis');

async function main() {
  const client = createClient({
    url: 'redis://:password@localhost:6379'
  });

  client.on('error', (err) => console.error('Redis Client Error', err));

  await client.connect();

  await client.set('visits', 0);
  const visits = await client.incr('visits');
  console.log('Visits:', visits);

  await client.quit();
}

main().catch(console.error);

در این کد، یک کلاینت Redis ساخته و به سرور وصل می‌شویم. سپس یک کلید ‘visits’ مقداردهی اولیه و با incr مقدار آن افزایش می‌یابد. در پایان اتصال بسته می‌شود. از رویکرد async/await و event ‘error’ برای دریافت خطاها استفاده شده است.

اتصال با ioredis و پشتیبانی از کلستر/Sentinel

const Redis = require('ioredis');

// اتصال به Sentinel
const client = new Redis({
  sentinels: [{ host: '127.0.0.1', port: 26379 }],
  name: 'mymaster',
  password: 'password'
});

// یا اتصال به کلستر
// const cluster = new Redis.Cluster([
//   { host: '127.0.0.1', port: 7000 },
//   { host: '127.0.0.1', port: 7001 },
// ]);

ioredis برای محیط‌های production با نیاز به High Availability مناسب است. در مثال بالا اتصال به Sentinel نشان داده شده که به صورت خودکار مستر را پیدا و مدیریت می‌کند. نمونهٔ کلستر نیز نشان دهنده اتصال به چند نود است.

مثال: استفاده از Redis به‌عنوان cache در Express

const express = require('express');
const { createClient } = require('redis');

const client = createClient();
client.connect();

const app = express();

async function cacheMiddleware(req, res, next) {
  const key = `cache:${req.originalUrl}`;
  const cached = await client.get(key);
  if (cached) {
    return res.send(JSON.parse(cached));
  }
  res.sendResponse = res.send;
  res.send = (body) => {
    client.setEx(key, 60, JSON.stringify(body)); // cache for 60s
    res.sendResponse(body);
  };
  next();
}

app.get('/data', cacheMiddleware, async (req, res) => {
  const data = { time: Date.now(), value: Math.random() };
  res.send(data);
});

app.listen(3000);

این میدل‌ور یک خروجی را برای 60 ثانیه کش می‌کند. ابتدا از Redis برای خواندن کش استفاده می‌شود و در صورت نبود، پاسخ اصلی تولید و در Redis با TTL ذخیره می‌گردد.

پایپلاین، تراکنش و اجرای چند فرمان

const { createClient } = require('redis');

async function pipelineExample() {
  const client = createClient();
  await client.connect();

  const pipeline = client.multi(); // یا pipeline() در بعضی کلاینت‌ها
  pipeline.set('a', 1);
  pipeline.incr('a');
  pipeline.get('a');
  const results = await pipeline.exec();

  console.log(results);
  await client.quit();
}

پایپلاین یا multi باعث می‌شود چند فرمان پشت‌سرهم ارسال شده و در صورت استفاده از multi/exec اتمیک اجرا شوند. این شیوه برای کاهش ترافیک شبکه و افزایش سرعت مناسب است.

Pub/Sub ساده

// Publisher
const { createClient } = require('redis');
const pub = createClient();
await pub.connect();
await pub.publish('channel1', 'hello');

// Subscriber
const sub = createClient();
await sub.connect();
sub.subscribe('channel1', (message) => {
  console.log('Received:', message);
});

Pub/Sub برای اطلاع‌رسانی‌های real-time مفید است، اما توجه کنید که پیام‌ها در Redis ذخیره نمی‌شوند و اگر مشترک قبل از انتشار نباشد، پیام را از دست می‌دهد. برای صف‌های پایدار بهتر است از لیست‌ها یا Stream استفاده کنید.

مقایسه کوتاه node-redis و ioredis

ویژگیnode-redisioredis
سازنده رسمیبلهخیر (پشتیبانی قوی از کلستر)
API مدرنPromise-basedPromise و event-based
پشتیبانی از Cluster/Sentinelمحدودترقوی و کامل

نکات عملی و Best Practices

  • مدیریت اتصال: از reconnect و backoff strategy استفاده کنید تا در مواقع قطع ارتباط، کلاینت به صورت خودکار تلاش به اتصال مجدد کند.
  • TTL مناسب: برای کش از TTL استفاده کنید تا حافظه کنترل شود و استراتژی invalidation مشخص باشد.
  • عدم ذخیره اشیاء بزرگ: سریالایزینگ اشیاء بزرگ می‌تواند حافظه را پر کند؛ به‌جای آن داده‌ها را به اجزاء کوچک‌تر تقسیم کنید.
  • استفاده از هَش‌ها (Hashes): برای ذخیرهٔ آبجکت‌ها که نیاز به دسترسی به فیلدهای جداگانه دارند بهتر است از HSET/HGET استفاده شود.
  • نظارت بر eviction و memory: در محیط تولید از متریک‌ها و ALERT برای اندازهٔ حافظه و policyهای eviction استفاده کنید.
  • امنیت: از AUTH، فایروال و TLS برای محافظت ترافیک استفاده کنید.

نمونهٔ بهبود: reconnect با backoff در node-redis

const { createClient } = require('redis');

function createRedisClient() {
  const client = createClient({
    socket: {
      host: 'localhost',
      port: 6379,
      reconnectStrategy: (retries) => {
        // exponential backoff capped
        if (retries >= 10) return new Error('Too many retries');
        return Math.min(1000 * 2 ** retries, 30000);
      }
    }
  });
  client.on('error', (err) => console.error('Redis error', err));
  return client;
}

در این کد از reconnectStrategy برای پیاده‌سازی backoff نمایی استفاده شده است تا در صورت قطع اتصال، تلاش‌های مجدد با تاخیر افزایشی انجام شود و در نهایت از تلاش بیش از حد جلوگیری گردد.

موارد استفاده عملی

  • کش کردن نتایج API برای کاهش بار دیتابیس
  • صف پیام با استفاده از لیست‌ها (LPUSH/BRPOP) یا Streams
  • شمارنده‌ها و نرخ‌دهی (rate limiting)
  • سیستم‌های real-time با pub/sub
  • ذخیرهٔ نمایش‌های موقت، session و feature flags

جمع‌بندی و توصیهٔ نهایی

اتصال Node.js به Redis ساده و قدرتمند است، اما برای استفادهٔ بهینه باید به مدیریت اتصال، سیاست‌های TTL، انتخاب کلاینت مناسب (node-redis یا ioredis)، و نظارت بر حافظه توجه کنید. در محیط‌های توزیع‌شده از Sentinel یا Cluster و در محیط‌های حساس به تأخیر از pipelining و multi/exec بهره ببرید.

در صورت نیاز می‌توانم نمونهٔ کامل‌تری از پیاده‌سازی کش لایهٔ میانی، مدیریت خطا و مانیتورینگ Redis در پروژهٔ شما تهیه کنم.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: