跳转至内容
There is a version suitable for your browser's language settings. Would you like to go to the english language of the site?
主页文档

Redis

H1

Redis 是一个久经考验的分布式缓存数据库。它可以临时缓存某些数据,并在适当的时候自动失效。

巧妙地运用它,能够显著提升你的应用性能。

入门

我们需要安装 Milkio 与 Redis 所结合的包:

终端窗口
bun i milkio-redis

在你的 /src/uses 目录中,创建一个 redis.ts,并将下面的代码粘贴进去。其中的 url 不要忘记修改哦。如果你不知道 url 该设置为什么,请询问你的 Redis 服务提供商。

/src/uses/redis-client.ts
import { defineRedisClient } from "milkio-redis";
import { configRedis } from "../config/redis";
export const redisClient = defineRedisClient({
url: "redis://127.0.0.1:6379",
initTimeout: 3000,
});

位置

通常,我们建议,你可以创建一个 /src/caches 目录,并将你所使用的缓存放置在这里。这样也方便你在多个 API 之间共享缓存。

缓存

你可以使用 defineCache 方法来定义一个缓存。比如,你可以缓存一个布尔值,用于表示是否开启了维护模式。

import { defineCache } from "milkio-redis";
import { redisClient } from "../uses/redis-client";
const cache = defineCache<boolean>(redisClient, "enable-maintenance-mode");
await cache.set(true, 100);
console.log(await cache.get());
// 输出: true

命名空间缓存

有时候,我们需要存储集合数据的场景,比如为每个用户的个人信息创建缓存。这样可以方便地以用户为单位进行数据缓存,提高读取效率。

import { defineNamespaceCache } from "milkio-redis";
const cache = defineNamespaceCache<UserInfo>(redisClient, "user-info");
type UserInfo = {
age: number;
email: string;
};
await cache.set("alice", { age: 18, email: "alice@gmail.com" }, 100);
console.log(await cache.get("alice"));
// 输出: { age: 18, email: 'alice@gmail.com' }
await cache.del();
console.log(await cache.get());
// 输出: undefined

结果缓存

结果缓存可以缓存函数执行的结果。例如,我们可以缓存 SQL 查询的结果,或者缓存一些耗时的计算,以减少重复工作并加快响应速度。下面的代码中,我们传递了 4 个参数,分别是键名、缓存过期时间、缓存的实际过期时间以及函数作为参数。在缓存未过期之前,函数将不会被重复执行,而是从缓存中获取结果。

由于结果缓存通常和代码逻辑是强关联的,所以,我们一般不会将结果缓存放在 /src/caches 目录中。

const result = defineResultCache(redisClient, "your-key", 60, 60, async () => {
const now = new Date().getTime();
await new Promise((resolve) => setTimeout(resolve, 1000)); // 等待 1 秒
return now;
});
console.log(await newYAML.getResult());

当执行 defineResultCache 代码时,若缓存未过期,则从缓存中读取结果。如果缓存过期,则会运行方法获取结果,并重新缓存起来。

为了减少缓存雪崩的概率,你需要设置两个过期时间:TTLrealTTL

TTL 未过期时,进入正常缓存阶段,所有结果都来自缓存。

TTL 过期后,进入缓存过期阶段,此时 Milkio 允许执行一个请求重新计算结果。在重新计算阶段期间,其他请求仍获取旧的缓存数据,直到重新计算阶段结束并更新缓存,回到正常缓存阶段。

重新计算有可能失败,导致回到缓存过期阶段。下一个到达的请求将重新进入重新计算阶段。默认情况下,重新计算阶段持续 6 秒。若超过此时间,则认为重新计算失败。可以通过 options.realGetInterval 修改超时时间。

若在相当一段时间内没有请求获取结果,或持续获取失败,直到达到 TTL + realTTL 的过期时间后,缓存结果将被彻底删除。

获取原生 Redis 客户端

我们可以直接使用原生的 Redis 客户端 来操作 Redis,你可以使用所有的 Redis 命令。像这样:

(await redisClient).HSET("key", "field", "value");

我们推荐使用经过 Milkio 精心封装后的缓存功能,因为这样将拥有完整的类型支持,代码写起来更加高效简单,并且无需关注所存储的值的类型。Milkio 会自动帮你将值使用 TSON 序列化,并在取出时反序列化。而对于原生 Redis 客户端,你需要手动处理这些事情。