从redis(作为缓存)发送数据不会返回相同的数据

问题描述 投票:0回答:1

我正在尝试制作一个小型快速应用程序,它从 postgres 查询返回数据。 查询结果应缓存在 Redis 数据库中。我所做的是这样的:

app.get('/query_tile/:z/:x/:y', async (req: Request, res: Response) => {
    const client = new Client(connection);
    await client.connect();
    const setHeader = () => {
        res.set('Content-Encoding', 'br');
        res.set('Content-Type', 'application/x-protobuf');
        res.set('Vary', 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers');
        res.set('Content-Disposition', `attachment; filename=tile_${z}_${x}_${y}.mvt`);
    }
    const { z, x, y } = req.params;
    const cacheKey = `tile_${z}_${x}_${y}`;
    const cachedData = await redis.get(cacheKey);

    if (cachedData) {
        
        setHeader()
        res.send(brotliCompressSync(cachedData));

    } else {

        const { rows } = await client.query('SELECT query_tile($1, $2, $3)', [z, x, y]);
        const data = rows[0];
        const compressedData = brotliCompressSync(data.query_tile);
        await redis.set(cacheKey, data.query_tile);
                
        setHeader()
        res.send(compressedData);
    }
    client.end()
});

我遇到的问题是,缓存的结果与未缓存的结果不同。 我在这里缺少什么?

两个返回都包含一些数据,但缓存中的数据不可读。至少不是我所需要的。

非常感谢您的帮助!

编辑:如果我尝试将压缩数据保存到 Redis 服务器,如下所示:

    let cachedData = null;
    if (useCache) {
        cachedData = await redis.get(cacheKey);
    }

    if (cachedData) {
         const t1 = performance.now()
        console.log(`SENDING CACHED tile_${z}_${x}_${y}, took ${(t1 - t0) / 1000}s`);
        setHeader()
        res.send(cachedData);

    } else {
        const { rows } = await client.query('SELECT query_tile($1, $2, $3)', [z, x, y]);
        const data = rows[0];
        const compressedData = brotliCompressSync(data.query_tile);
        await redis.set(cacheKey, compressedData);
        
        const t1 = performance.now()
        console.log(`SENDING DB tile_${z}_${x}_${y}, took ${(t1 - t0) / 1000}s`);
        
        setHeader()
        res.send(compressedData);
    }

我确实遇到了奇怪的行为 - 浏览器告诉我应该检查我的互联网连接

但这仅发生在磨损的瓷砖上。如果没有可用的缓存,它会正确下载图块。

使用“Redis Insight”检查redis服务器,它显示有我的二进制形式的chached磁贴。 (但它仍然在左边说字符串......这应该是这样的吗?)

node.js typescript express caching redis
1个回答
0
投票

您正在缓存的数据是二进制数据还是 brotliCompressSync 函数返回纯文本?对我来说看起来像是二进制数据。

如果这是正确的,则在将二进制数据写入 Redis 时需要使用 Buffer,并且在读取时需要使用一点额外的语法,以便它知道返回 Buffer。

默认情况下,它将返回 ASCII 编码的文本,如下所示:

\xff\x00\xd8\xae\xa5x\x80J\xd2\x1c\x0c\x1ay\x89RZ\xd1\x1a\x029\xb7\x1a\xf3\xc5\xd4\x11s(...

您的代码可能如下所示:

// setting binary data, assumes that brotliCompressSync returns a Buffer
const compressedData: Buffer = brotliCompressSync(data.query_tile);
await redis.set(cacheKey, compressedData);

// getting binary data
const cachedData = await redis.get(
  commandOptions({ returnBuffers: true }),
  cacheKey
);

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.