Redis缓存实战总结:从入门到踩坑再到优化的全过程

Designer°江洁 优化 阅读 2,677
赞 56 收藏
二维码
手机扫码查看
反馈

先看效果,再看代码

最近在项目里折腾Redis缓存,发现这玩意儿确实能提升性能。今天就来聊聊我是怎么用的,以及踩过的坑。

Redis缓存实战总结:从入门到踩坑再到优化的全过程

最常用的场景:缓存数据库查询结果

首先,我们来看一个最常见的场景:缓存数据库查询结果。比如你有一个用户列表,每次请求都要查数据库,那性能肯定不行。这时候用Redis缓存一下,简直不要太爽。

核心代码就这几行:

const redis = require('redis');
const client = redis.createClient();

client.on('error', (err) => {
  console.error(Error: ${err});
});

async function getUsers() {
  const cacheKey = 'userList';
  return new Promise((resolve, reject) => {
    client.get(cacheKey, async (err, data) => {
      if (data) {
        // 如果缓存中有数据,直接返回
        resolve(JSON.parse(data));
      } else {
        // 如果缓存中没有数据,从数据库中获取
        const users = await fetchUsersFromDB();
        // 将数据存入缓存,设置过期时间为1小时
        client.setex(cacheKey, 3600, JSON.stringify(users));
        resolve(users);
      }
    });
  });
}

async function fetchUsersFromDB() {
  // 这里是你的数据库查询逻辑
  const response = await fetch('https://jztheme.com/api/users');
  return response.json();
}

踩坑提醒:这三点一定注意

好了,代码有了,但别急着跑起来,我这里有几点要注意:

  • 序列化问题: Redis存储的是字符串,所以你需要把对象序列化成JSON字符串。记得用JSON.parseJSON.stringify
  • 过期时间设置: 设置合理的过期时间很重要,太短会频繁打数据库,太长会导致数据不一致。亲测有效,1小时左右是个不错的选择。
  • 错误处理: Redis客户端连接可能会出错,务必加上错误处理。否则一旦Redis挂了,你的应用也跟着挂。

这个场景最好用:缓存API响应

除了数据库查询,API响应也是个常见的缓存场景。特别是那些第三方API,响应慢得要命。缓存一下,性能立马飞起来。

核心代码就这几行:

const express = require('express');
const app = express();
const redis = require('redis');
const client = redis.createClient();

client.on('error', (err) => {
  console.error(Error: ${err});
});

app.get('/api/data', async (req, res) => {
  const cacheKey = 'apiData';
  return new Promise((resolve, reject) => {
    client.get(cacheKey, async (err, data) => {
      if (data) {
        // 如果缓存中有数据,直接返回
        res.json(JSON.parse(data));
      } else {
        // 如果缓存中没有数据,从API中获取
        const apiData = await fetchDataFromAPI();
        // 将数据存入缓存,设置过期时间为1小时
        client.setex(cacheKey, 3600, JSON.stringify(apiData));
        res.json(apiData);
      }
    });
  });
});

async function fetchDataFromAPI() {
  // 这里是你的API调用逻辑
  const response = await fetch('https://jztheme.com/api/data');
  return response.json();
}

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

高级技巧:使用Lua脚本进行原子操作

有时候我们需要在Redis中进行一些复杂的操作,而且这些操作需要保证原子性。这时候可以考虑用Lua脚本。比如你想在更新缓存的同时删除旧的数据,就可以用Lua脚本来实现。

核心代码就这几行:

const redis = require('redis');
const client = redis.createClient();

client.on('error', (err) => {
  console.error(Error: ${err});
});

const luaScript = 
  local key = KEYS[1]
  local oldValue = redis.call("GET", key)
  local newValue = ARGV[1]
  redis.call("SET", key, newValue)
  return oldValue
;

function updateCacheWithLua(key, newValue) {
  return new Promise((resolve, reject) => {
    client.eval(luaScript, 1, key, newValue, (err, result) => {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    });
  });
}

(async () => {
  try {
    const oldValue = await updateCacheWithLua('myKey', 'newValue');
    console.log(Old value: ${oldValue});
  } catch (err) {
    console.error(Error: ${err});
  }
})();

总结一下,继续踩坑

以上就是我用Redis缓存的一些经验,希望对你有帮助。其实Redis还有很多高级功能,比如发布订阅、事务处理等,以后有机会再聊。如果你有更好的实现方式,欢迎评论区交流。

这个技术的拓展用法还有很多,后续会继续分享这类博客。加油,前端小伙伴们!

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论
♫克培
♫克培 Lv1
这篇文章让我意识到,优秀的技术分享不仅是知识的传递,更是经验的传承。
点赞 6
2026-02-04 10:25