Node.js + Redis 实战:实现高效分布式缓存与限流策略

Node.js + Redis 实战:实现高效分布式缓存与限流策略

在这里插入图片描述

前言

在高并发 Web 应用中,数据库查询、API 请求、并发操作 是影响系统性能和稳定性的关键因素。Redis 作为一个高性能的内存数据库,可以有效缓解这些问题,为 Web 应用提供 缓存、限流、分布式锁、消息队列 等功能。

本篇文章将通过大量代码示例,深入剖析如何使用 Node.js + Redis 实现:
高效缓存:减少数据库查询,提升 API 响应速度
会话存储(Session):支持用户状态管理
分布式锁:防止超卖等并发问题
API 限流:防止恶意请求,保障系统稳定
数据淘汰策略(TTL + LRU):优化 Redis 内存使用
Redis 连接池优化:提高系统吞吐量

👉 适用场景:高并发 Web 应用、微服务、API 网关、IoT 设备等。
🚀 通过实战代码,全面掌握 Redis 在 Node.js 高并发系统中的应用!


一、环境准备

1.1 安装 Redis

使用 Docker 快速安装:

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

本地安装(适用于 macOS/Linux):

brew install redis  # macOS
sudo apt install redis  # Ubuntu

验证 Redis 运行

redis-cli ping  # 预期返回:PONG

1.2 安装 Node.js 依赖

npm init -y
npm install express ioredis express-session connect-redis

二、Redis 作为缓存层(加速数据库查询)

2.1 连接 Redis

const Redis = require("ioredis");
const redis = new Redis(); // 连接本地 Redis

2.2 基于 Redis 缓存 API 响应

const express = require("express");
const app = express();

const fetchUserFromDB = async (id) => {
    console.log("查询数据库...");
    return { id, name: `User${id}`, age: Math.floor(Math.random() * 30) + 20 };
};

app.get("/user/:id", async (req, res) => {
    const { id } = req.params;
    const cacheKey = `user:${id}`;

    // 先查 Redis
    const cachedUser = await redis.get(cacheKey);
    if (cachedUser) {
        return res.json({ source: "cache", data: JSON.parse(cachedUser) });
    }

    // 数据库查询
    const user = await fetchUserFromDB(id);

    // 存入 Redis,过期时间 10 分钟
    await redis.setex(cacheKey, 600, JSON.stringify(user));

    res.json({ source: "database", data: user });
});

app.listen(3000, () => console.log("Server running on port 3000"));

效果

  • 第一次请求:查询数据库,并将结果缓存到 Redis
  • 之后的请求:直接从 Redis 读取,加速 API 响应

三、Redis 作为会话存储(Session 管理)

3.1 安装 express-sessionconnect-redis

npm install express-session connect-redis

3.2 使用 Redis 存储 Session

const session = require("express-session");
const RedisStore = require("connect-redis").default;

app.use(
    session({
        store: new RedisStore({ client: redis }),
        secret: "super-secret-key",
        resave: false,
        saveUninitialized: false,
        cookie: { secure: false, maxAge: 60000 }
    })
);

// 登录接口
app.get("/login", (req, res) => {
    req.session.user = { id: 1, name: "Alice" };
    res.send("登录成功");
});

// 获取 Session
app.get("/profile", (req, res) => {
    res.json(req.session.user || "未登录");
});

效果

  • 用户登录信息存入 Redis
  • 其他 API 直接读取 Session

四、Redis 分布式锁(防止超卖)

4.1 传统超卖问题

在高并发情况下,多个用户同时购买商品,可能导致库存变成负数

let stock = 5;
app.get("/buy", (req, res) => {
    if (stock > 0) {
        stock--;
        res.send(`购买成功!剩余库存:${stock}`);
    } else {
        res.send("库存不足");
    }
});

并发请求可能会让 stock 变成负数!

4.2 使用 Redis 实现分布式锁

const acquireLock = async (lockKey, expireTime = 5) => {
    return await redis.set(lockKey, "LOCKED", "NX", "EX", expireTime);
};

const releaseLock = async (lockKey) => {
    await redis.del(lockKey);
};

app.get("/buy", async (req, res) => {
    const lockKey = "lock:product";

    if (!await acquireLock(lockKey)) {
        return res.status(429).send("系统繁忙,请稍后再试");
    }

    let stock = await redis.get("product_stock") || 10;
    if (stock > 0) {
        stock--;
        await redis.set("product_stock", stock);
        res.send("购买成功!剩余库存:" + stock);
    } else {
        res.send("库存不足");
    }

    await releaseLock(lockKey);
});

效果

  • 防止多个请求同时修改库存
  • 避免超卖问题

五、Redis 实现 API 限流

5.1 限流策略

算法说明
固定窗口每分钟最多 N 次请求
滑动窗口根据时间动态调整
令牌桶允许突发流量,但受限于令牌速率

5.2 使用 Redis 计数器进行限流

const rateLimit = async (ip) => {
    const key = `rate:${ip}`;
    const count = await redis.incr(key);

    if (count === 1) {
        await redis.expire(key, 60); // 60s 过期
    }

    return count > 10; // 限制 10 次请求/分钟
};

app.get("/api/data", async (req, res) => {
    if (await rateLimit(req.ip)) {
        return res.status(429).send("请求过多,请稍后重试");
    }
    res.send("数据返回成功");
});

效果

  • 同一 IP 每分钟最多 10 次请求
  • 超出限制返回 429 Too Many Requests

六、总结

功能实现方式
缓存查询redis.get() / redis.setex()
Session 存储connect-redis
分布式锁SETNX + EX
API 限流INCR + EXPIRE
数据淘汰TTL + LRU
连接优化ioredis 连接池

本篇文章介绍了 Node.js + Redis缓存、会话存储、分布式锁、限流 等方面的应用,并提供了大量高质量代码。希望对你的高并发系统开发有所帮助!🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈探索者chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值