如何在 NestJs 的 Typeorm 缓存配置中重用 Redis 连接

How to reuse Redis connection inside Typeorm cache config in 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
    }
};

我正在为 Redis 使用 @svtslv/nestjs-ioredis 包:

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 class 使用:

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

在对 TypeORM 代码库进行一些挖掘之后,我遇到了两个解决方案(一个有点老套,而且我的案例有问题)

ORM 自定义查询结果缓存

根据文档,您可以实现自己的缓存处理程序,请参阅:https://github.com/typeorm/typeorm/blob/master/docs/caching.md

由于需要实现接口,这是更好但更难的解决方案https://github.com/typeorm/typeorm/blob/master/src/cache/QueryResultCache.ts

此外,您需要使用 forRootAsync 注册 TypeOrmModule 才能首先连接到 Redis。

Hacky 欢乐时光

根据代码库,您应该能够访问 TypeORM 正在创建的 Redise 客户端(连接)。

在类型 ORM connection 上有一个名为 connection.queryResultCache 的成员用于管理缓存。 但是在 queryResultCache (connection.queryResultCache.client)

上还有一个成员名称 client

参见 TypeORM redis 缓存说明: 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 耦合,这对于 future-proofing 您的代码库来说并不合适。

我的诚实意见

根据 关注点分离 的想法,我建议坚持使用两个连接而不是一个连接,只是为了保持 DB query Cache 和标准 Cache分开了。

这将使您在未来进行集成测试和重构时更加灵活。

参见:https://github.com/nestjs/typeorm/issues/59