You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 14应用启动时通过Redis缓存主数据的实现方案

在Next.js 14中启动时预加载主数据到Redis的实现方案

1. 安装Redis客户端依赖

首先安装官方Redis客户端包:

npm install redis

2. 编写数据预加载脚本

在项目根目录创建scripts/preload-redis.js,负责读取主数据并写入Redis:

import { createClient } from 'redis';
// 假设主数据存储在项目的data目录下,可根据实际路径调整
import countries from '../data/countries.json' assert { type: 'json' };
import heights from '../data/heights.json' assert { type: 'json' };
import ages from '../data/ages.json' assert { type: 'json' };
import occupations from '../data/occupations.json' assert { type: 'json' };

async function preloadRedisData() {
  // 初始化Redis客户端,可通过环境变量配置连接地址
  const client = createClient({
    url: process.env.REDIS_URL || 'redis://localhost:6379'
  });

  client.on('error', err => console.error('Redis连接失败:', err));
  await client.connect();

  try {
    // 将各列表序列化为JSON字符串存入Redis
    await Promise.all([
      client.set('countries', JSON.stringify(countries)),
      client.set('heights', JSON.stringify(heights)),
      client.set('ages', JSON.stringify(ages)),
      client.set('occupations', JSON.stringify(occupations))
    ]);
    console.log('所有主数据已成功预加载至Redis');
  } catch (err) {
    console.error('预加载数据出错:', err);
    process.exit(1); // 加载失败时终止启动流程
  } finally {
    await client.disconnect();
  }
}

preloadRedisData();

3. 修改启动脚本,实现启动前自动加载

修改package.json中的dev和start脚本,利用npm的pre前缀钩子,在启动Next.js前自动执行预加载脚本:

{
  "scripts": {
    "predev": "node scripts/preload-redis.js",
    "dev": "next dev",
    "prestart": "node scripts/preload-redis.js",
    "start": "next start"
  }
}

npm会自动执行前缀为pre的脚本,比如执行npm run dev时,会先运行predev,再启动next dev。

4. 封装Redis数据读取工具

创建utils/redis-client.js,封装Redis客户端和数据读取逻辑,避免重复创建连接:

import { createClient } from 'redis';

let redisClient;

async function getClient() {
  if (!redisClient) {
    redisClient = createClient({
      url: process.env.REDIS_URL || 'redis://localhost:6379'
    });
    redisClient.on('error', err => console.error('Redis客户端异常:', err));
    await redisClient.connect();
  }
  return redisClient;
}

export async function getCachedList(key) {
  const client = await getClient();
  const data = await client.get(key);
  return data ? JSON.parse(data) : null;
}

5. 在应用中调用缓存数据

在服务器组件或API路由中直接使用封装好的工具函数获取数据:

import { getCachedList } from '@/utils/redis-client';

export default async function CountriesPage() {
  const countries = await getCachedList('countries');
  
  if (!countries) {
    return <div>数据加载失败</div>;
  }

  return (
    <div>
      <h2>国家列表</h2>
      <ul>
        {countries.map(country => (
          <li key={country.id}>{country.name}</li>
        ))}
      </ul>
    </div>
  );
}

替代方案:首次请求时自动加载

如果不想修改启动脚本,可在App Router的根布局中添加懒加载逻辑——当Redis中无数据时自动写入,首次访问应用时完成预加载:

// app/layout.js
import { getClient } from '@/utils/redis-client';
import countries from '../data/countries.json';
import heights from '../data/heights.json';
import ages from '../data/ages.json';
import occupations from '../data/occupations.json';

export default async function RootLayout({ children }) {
  const client = await getClient();
  
  // 检查是否已有缓存数据
  const [hasCountries, hasHeights, hasAges, hasOccupations] = await Promise.all([
    client.exists('countries'),
    client.exists('heights'),
    client.exists('ages'),
    client.exists('occupations')
  ]);

  if (!hasCountries || !hasHeights || !hasAges || !hasOccupations) {
    await Promise.all([
      client.set('countries', JSON.stringify(countries)),
      client.set('heights', JSON.stringify(heights)),
      client.set('ages', JSON.stringify(ages)),
      client.set('occupations', JSON.stringify(occupations))
    ]);
    console.log('首次访问,预加载数据至Redis');
  }

  return (
    <html lang="zh-CN">
      <body>{children}</body>
    </html>
  );
}

此方案无需修改启动脚本,但数据加载时机为首次请求时,而非应用启动时。


注意事项

  • 确保Redis服务已启动,连接地址配置正确(生产环境建议通过环境变量REDIS_URL配置)。
  • 若主数据需要更新,需添加缓存失效机制(如增加版本号键、定时重新加载)。
  • 预加载脚本中可添加process.exit(1)确保数据加载失败时终止应用启动,避免服务启动后无可用数据。

内容的提问来源于stack exchange,提问作者dasunekanayake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 01:44:57