я пытаюсь создать небольшое экспресс-приложение, которое возвращает данные из запроса 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.info(`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.info(`SENDING DB tile_${z}_${x}_${y}, took ${(t1 - t0) / 1000}s`);
setHeader()
res.send(compressedData);
}
у меня странное поведение - браузер говорит мне, что мне следует проверить подключение к Интернету
но это происходит только с обожженной плиткой. Если доступного кеша нет, плитка загружается правильно.
Проверка сервера Redis с помощью Redis Insight показывает, что мои кэшированные плитки находятся в двоичной форме. (но все равно слева написано строка... так и должно быть?)
@SufailKalathil Я обновил вопрос и добавил снимок экрана из Redis Insight. Это помогает?





Кэшируются ли данные в двоичном виде или функция brotliCompressSync возвращает обычный текст? Для меня это похоже на двоичные данные.
Если это верно, вам нужно использовать Buffers, когда вы записываете двоичные данные в Redis, и немного дополнительного синтаксиса, когда вы читаете, чтобы он знал, что нужно возвращать 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
);
Надеюсь это поможет!
идеальный! действительно стоит прочитать инструкцию ;) Спасибо!
ржу не могу. Когда все остальное терпит неудачу, верно?
Пожалуйста, проверьте данные и их тип в базе данных кэша Redis с помощью инструмента графического интерфейса. redis.io/insight