Как повторно использовать соединение Redis внутри конфигурации кеша Typeorm в NestJs

Я использую Redis для кэширования запросов внутри TypeOrm.

но проблема в том, что пакет TypeOrm и Redis открывает отдельное соединение, я просто хочу повторно использовать одно и то же соединение для обоих.

это конфигурация typeorm:

import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { Constants } from '../utils/Constants';

export const typeOrmConfig: TypeOrmModuleOptions = {
    type: Constants.DB_TYPE,
    host: Constants.DB_HOST,
    port: Constants.DB_PORT,
    username: Constants.DB_USER_NAME,
    password: Constants.DB_PASSWORD,
    database: Constants.DB_NAME,
    entities: [ __dirname + '/../**/*.entity.{js,ts}' ],
    synchronize: true,
    logging: true,
    cache: {
        type: 'ioredis',
        duration: 60000,
        options: {
            host: 'localhost',
            password: 'swapnil',
            port: 6379
        }
    },
    extra: {
        max: 10,
        connectionTimeoutMillis: 2000
    }
};

я использую пакет @svtslv/nestjs-ioredis для Redis:

import { Constants } from '../utils/Constants';

export const config = {
    host: Constants.REDIS_HOST,
    port: parseInt(Constants.REDIS_PORT),
    db: parseInt(Constants.REDIS_DB),
    password: Constants.REDIS_PASSWORD
};

и с помощью этого пакета я могу получить доступ к Redis внутри моего класса обслуживания, используя:

public constructor(@InjectRedis() private readonly redis: Redis,) {}

person Swapnil Gawali    schedule 25.08.2020    source источник


Ответы (1)


После некоторого копания в кодовой базе TypeORM я наткнулся на два решения (одно другое немного хакерское, и у меня проблемы с делом)

ORM CustomQueryResultCache

Согласно документу, вы можете реализовать свой собственный обработчик кеша, см.: https://github.com/typeorm/typeorm/blob/master/docs/caching.md.

Это лучшее, но более сложное решение из-за интерфейса, который необходимо реализовать https://github.com/typeorm/typeorm/blob/master/src/cache/QueryResultCache.ts

Кроме того, вам потребуется зарегистрировать TypeOrmModule с помощью forRootAsync, чтобы сначала иметь возможность для подключения к Redis.

Хакерские веселые времена

В соответствии с кодовой базой вы должны иметь доступ к клиенту (подключению) Redise, который создает TypeORM.

В типе ORM connection есть член с именем connection.queryResultCache для управления кешем. Но, кроме того, в queryResultCache (connection.queryResultCache.client) есть имя члена client.

См. добавление TypeORM redis Cache: https://github.com/typeorm/typeorm/blob/master/src/cache/RedisQueryResultCache.ts

import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
})
export class AppModule {
  constructor(private connection: Connection) {

    connection.queryResultCache.client // <-- Cache client.
  }
}

Но само собой разумеется, что это не предназначено для предполагаемого использования, и это свяжет вашу БД с Redis, что не очень важно для проверки вашей кодовой базы на будущее.

Мое честное мнение

Согласно идее разделения ответственности, я бы рекомендовал использовать два соединения вместо одного, чтобы разделить DB query Cache и стандартное Cache.

Это даст вам больше гибкости в будущем для интеграционного тестирования и рефакторинга.

См.: https://github.com/nestjs/typeorm/issues/59.

person Daniel    schedule 25.08.2020
comment
Открытие нескольких соединений может привести к накладным расходам? - person Swapnil Gawali; 28.08.2020
comment
Я не считаю это накладными расходами из-за того, что каждое Redis соединение серверов выполняет другую работу (хотя они оба размещены вместе). Если вам нужна оптимизация, вам следует выбрать первое решение. - person Daniel; 30.08.2020