← กลับ
RedisDatabaseCacheมือใหม่

Redis คืออะไร ใช้ทำอะไรได้บ้าง

ทุก app ที่ traffic เริ่มเยอะจะเข้ามาเจอ Redis ทำได้ทั้ง cache, session, queue, rate limit อ่านครั้งเดียวเข้าใจหลักทั้งหมด

2025-11-28อ่าน 5 นาทีใหม่

Redis คืออะไร

ถ้าให้สรุปสั้นที่สุด — Redis คือ "key-value store ใน RAM"

ทำงานเร็วระดับ submillisecond เพราะข้อมูลอยู่ใน memory ไม่ใช่ disk เหมือน PostgreSQL/MySQL

ใช้ทำได้หลายอย่าง:

  • Cache — เก็บผลลัพธ์ของ query ที่ช้า ไม่ต้อง hit database ทุกครั้ง
  • Session — เก็บ session ของ user แทน in-memory ของ app
  • Queue — ส่ง job ไปทำ background
  • Rate limit — นับ request ต่อ user ต่อเวลา
  • Pub/Sub — broadcast event ระหว่าง service
  • Leaderboard — sorted set เก็บคะแนนแล้ว query rank ได้เร็วมาก

Data type ที่ใช้บ่อย

Redis เก็บได้หลาย type ไม่ใช่แค่ string:

# String — basic key-value
SET name "John"
GET name
SET counter 0
INCR counter           # เพิ่ม 1 — atomic
EXPIRE name 60         # ลบใน 60 วินาที

# List — queue / stack
LPUSH queue "task1"
LPUSH queue "task2"
RPOP queue             # = "task1" (FIFO ถ้าใช้ RPOP)

# Hash — เหมือน object
HSET user:1 name "John" email "[email protected]"
HGET user:1 name
HGETALL user:1

# Set — collection ที่ unique
SADD tags "redis" "cache" "redis"
SMEMBERS tags          # = {"redis", "cache"}

# Sorted Set — เก็บพร้อม score เรียงตาม score
ZADD leaderboard 100 "alice" 85 "bob" 95 "carol"
ZRANGE leaderboard 0 -1 WITHSCORES   # เรียง score น้อย→มาก
ZREVRANGE leaderboard 0 2            # top 3

ติดตั้ง

วิธีง่ายสุด — Docker:

docker run -d --name redis -p 6379:6379 redis:7-alpine

# หรือใน compose
services:
  redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redisdata:/data
    ports:
      - "6379:6379"
volumes:
  redisdata:

ทดสอบ:

docker exec -it redis redis-cli
> AUTH yourpassword
> PING
PONG

ใช้กับ Node.js

npm install ioredis
import Redis from 'ioredis'

const redis = new Redis({
  host: 'localhost',
  port: 6379,
  password: process.env.REDIS_PASSWORD,
})

await redis.set('foo', 'bar', 'EX', 60)   // ลบใน 60 วินาที
const value = await redis.get('foo')

Pattern 1: Cache database query

ถ้า query ช้า เก็บผลใน Redis ครั้งแรก ครั้งถัดไปอ่านจาก Redis:

async function getUser(id: string) {
  const cacheKey = `user:${id}`

  // ลอง cache ก่อน
  const cached = await redis.get(cacheKey)
  if (cached) return JSON.parse(cached)

  // ถ้าไม่มี — query database
  const user = await db.user.findUnique({ where: { id } })
  if (!user) return null

  // เก็บใน cache 5 นาที
  await redis.set(cacheKey, JSON.stringify(user), 'EX', 300)
  return user
}

อย่าลืม invalidate cache ตอนข้อมูลเปลี่ยน:

async function updateUser(id: string, data: any) {
  const user = await db.user.update({ where: { id }, data })
  await redis.del(`user:${id}`)   // invalidate
  return user
}

Pattern 2: Session store

แทนที่ใช้ in-memory session (หายตอน restart, ใช้กับ scale ไม่ได้) เก็บใน Redis:

import session from 'express-session'
import RedisStore from 'connect-redis'

app.use(session({
  store: new RedisStore({ client: redis }),
  secret: process.env.SESSION_SECRET!,
  resave: false,
  saveUninitialized: false,
  cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 },
}))

ดี: scale app เป็นหลาย instance ก็ใช้ session ร่วมกันได้, restart ไม่หาย

Pattern 3: Rate limit

จำกัดให้ user เรียก API ได้ไม่เกิน N ครั้ง/นาที:

async function rateLimit(userId: string, limit = 60, windowSec = 60) {
  const key = `ratelimit:${userId}:${Math.floor(Date.now() / 1000 / windowSec)}`
  const current = await redis.incr(key)
  if (current === 1) await redis.expire(key, windowSec)
  if (current > limit) throw new Error('Too many requests')
}

// ใน middleware
app.use(async (req, res, next) => {
  try {
    await rateLimit(req.user.id, 60, 60)
    next()
  } catch (e) {
    res.status(429).json({ error: 'Too many requests' })
  }
})

Pattern 4: Queue / Background job

ใช้ library อย่าง BullMQ สร้าง queue บน Redis:

import { Queue, Worker } from 'bullmq'

const emailQueue = new Queue('email', {
  connection: { host: 'redis', port: 6379 },
})

// Producer (จากใน API)
await emailQueue.add('welcome', {
  to: '[email protected]',
  subject: 'Welcome!',
})

// Worker (รัน process แยก)
new Worker('email', async (job) => {
  await sendEmail(job.data)
}, {
  connection: { host: 'redis', port: 6379 },
})

ดี: ส่งอีเมลไม่ block API, retry ได้, scale worker แยกได้

Pattern 5: Distributed lock

ป้องกัน 2 process ทำงานเดียวกันพร้อมกัน:

async function withLock(key: string, ttl: number, fn: () => Promise<void>) {
  const lockKey = `lock:${key}`
  const acquired = await redis.set(lockKey, '1', 'EX', ttl, 'NX')
  if (!acquired) throw new Error('Locked')
  try {
    await fn()
  } finally {
    await redis.del(lockKey)
  }
}

// ใช้ใน cron
await withLock('daily-report', 300, async () => {
  await generateDailyReport()
})

SET ... NX = set ถ้ายังไม่มี key — เป็น atomic operation

Persistence — Redis ลืมข้อมูลตอน restart มั้ย

Redis มี 2 mode:

RDB (snapshot) — save full database ลง disk เป็นช่วงๆ (default ทุก 5 นาที ถ้ามี write)

AOF (append-only file) — log ทุก command ลง disk = restore เกือบเหมือนเดิม

production แนะนำเปิด AOF:

redis-server --appendonly yes

แต่ — Redis ไม่ใช่ที่เก็บข้อมูลหลัก data ที่สำคัญต้องอยู่ใน database จริง Redis เป็น cache + helper

ข้อควรระวัง

RAM full = Redis crash ตั้ง maxmemory + eviction policy:

maxmemory 512mb
maxmemory-policy allkeys-lru   # ลบ key เก่าที่ไม่ใช้นาน

Key ใหญ่เกิน = block server (Redis เป็น single-thread) อย่าเก็บ value ขนาด MB

SCAN แทน KEYS เวลามี key เยอะ — KEYS * block server ใช้ SCAN 0 ดีกว่า

ใส่ TTL ทุก key ที่ทำเป็น cache — ไม่งั้น RAM เต็มแน่นอน

Alternative

Memcached — เก่าแต่ยังใช้กัน เร็วกว่านิดถ้าใช้แค่ key-value แต่ feature น้อยกว่า

Valkey — fork ของ Redis หลัง Redis เปลี่ยน license ปี 2024 — API เหมือน Redis เป๊ะ

KeyDB — fork ของ Redis แบบ multi-thread

ทั้งหมดใช้ protocol/command เดียวกันกับ Redis สลับใช้ได้

สรุป

ถ้า project มี user ใช้พอประมาณ Redis เกือบจะ default แล้ว — ตั้ง 5 นาทีบน VPS เดียวกับ app ก็ได้ ไม่ต้องคิดมาก

start จากแค่ใช้เป็น cache → พอเข้าใจ pattern → ใช้ทำ rate limit, session, queue ได้ครบ

อ่านเพิ่ม: Docker Compose ใช้จริง — มี example config Redis ใน production

← ดูบทความอื่น