Отправка данных из Redis (как кеш) не возвращает те же данные

я пытаюсь создать небольшое экспресс-приложение, которое возвращает данные из запроса 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 показывает, что мои кэшированные плитки находятся в двоичной форме. (но все равно слева написано строка... так и должно быть?)

Пожалуйста, проверьте данные и их тип в базе данных кэша Redis с помощью инструмента графического интерфейса. redis.io/insight

Sufail Kalathil 24.04.2024 13:41

@SufailKalathil Я обновил вопрос и добавил снимок экрана из Redis Insight. Это помогает?

pcace 24.04.2024 16:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кэшируются ли данные в двоичном виде или функция 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
);

Надеюсь это поможет!

идеальный! действительно стоит прочитать инструкцию ;) Спасибо!

pcace 24.04.2024 18:09

ржу не могу. Когда все остальное терпит неудачу, верно?

Guy Royse 25.04.2024 19:12

Другие вопросы по теме