Как правильно подойти к вопросу: redis можно использовать с TypeORM?

Ссылка скопирована
1 ответ

Нужно понять: redis можно использовать как драйвер для кэширования запросов?

import { TypeOrmModule } from '@nestjs/typeorm'; import { ConfigModule, ConfigService } from '@nestjs/config'; // Используем ConfigModule для переменных окружения @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), TypeOrmModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: async (configService: ConfigService) => ({ type: 'postgres', // или 'mysql', 'mariadb' и т.д. host: configService.get<string>('DB_HOST'), port: configService.get<number>('DB_PORT'), username: configService.get<string>('DB_USERNAME'), password: configService.get<string>('DB_PASSWORD'), database: configService.get<string>('DB_NAME'), entities: [__dirname + '/../**/*.entity{.ts,.js}'], synchronize: true, // Внимание: false для production logging: false, // --- Настройки кэширования Redis --- cache: { type: 'ioredis', // Используем установленный ioredis duration: 60000, // Время жизни кэша по умолчанию (в миллисекундах) options: { host: configService.get<string>('REDIS_HOST'), port: configService.get<number>('REDIS_PORT'), password: configService.get<string>('REDIS_PASSWORD'), // Если требуется }, }, }), }), ], // ... }) export class AppModule {}
// В вашем сервисе (например, product.service.ts) import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Product } from './product.entity'; @Injectable() export class ProductService { constructor( @InjectRepository(Product) private readonly productRepository: Repository<Product>, ) {} async findAll() { // Этот запрос будет закэширован в Redis на указанное в конфиге время return this.productRepository.find({ cache: true, }); } async findOne(id: number) { // Или с определенным ключом и временем жизни return this.productRepository.findOne({ where: { id }, cache: { id: `product-cache-${id}`, milliseconds: 30000 // 30 секунд }, }); } }
import { WebSocketGateway, SubscribeMessage, MessageBody, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect, ConnectedSocket, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; import { RedisService } from '../redis/redis.service'; import { Logger } from '@nestjs/common'; @WebSocketGateway({ cors: { origin: '*', // Настройте CORS под ваш Angular-клиент }, }) export class StatusGateway implements OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() server: Server; private readonly logger = new Logger(StatusGateway.name); constructor(private readonly redisService: RedisService) {} // Этот метод вызывается при подключении нового пользователя async handleConnection(client: Socket) { // В реальном приложении здесь вы бы аутентифицировали клиента по токену/кукам // и получили его реальный userId. const userId = client.handshake.query.userId as string; if (userId) { await this.redisService.setUserOnline(userId); this.logger.log(`User ${userId} connected.`); // Отправляем всем друзьям (или всем подключенным клиентам) уведомление об изменении статуса this.server.emit('friendStatusChanged', { userId, status: 'online' }); } } // Этот метод вызывается при отключении пользователя async handleDisconnect(client: Socket) { const userId = client.handshake.query.userId as string; if (userId) { await this.redisService.setUserOffline(userId); this.logger.log(`User ${userId} disconnected.`); // Отправляем всем друзьям уведомление об изменении статуса this.server.emit('friendStatusChanged', { userId, status: 'offline' }); } } // Пример обработки пользовательского сообщения (опционально) @SubscribeMessage('sendMessage') handleMessage(@ConnectedSocket() client: Socket, @MessageBody() payload: any): void { // Обработка сообщений и возможное сохранение через TypeORM this.server.emit('receiveMessage', payload); } }
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Анна SEO Ответ

Redis можно использовать с TypeORM как кэш для запросов, но не как “драйвер базы данных” вместо Postgres/MySQL. TypeORM работает с основной БД через обычный драйвер, а Redis может быть подключён как query result cache, чтобы временно хранить результат SELECT-запросов.

В TypeORM включается cache. В старых версиях был встроенный вариант через ioredis/redis, в новых версиях детали зависят от версии TypeORM и установленного cache provider. Концептуально конфигурация выглядит так:

TypeOrmModule.forRootAsync({
  inject: [ConfigService],
  useFactory: (configService) =&gt; ({
    type: 'postgres',
    host: configService.get('DB_HOST'),
    port: Number(configService.get('DB_PORT')),
    username: configService.get('DB_USERNAME'),
    password: configService.get('DB_PASSWORD'),
    database: configService.get('DB_NAME'),
    entities: [__dirname + '/**/*.entity{.ts,.js}'],
    cache: {
      duration: 30000
    }
  })
})

TypeOrmModule.forRootAsync({ inject: [ConfigService], useFactory: (configService) =&gt; ({ type: 'postgres', host: configService.get('DB_HOST'), port: Number(configService.get('DB_PORT')), username: configService.get('DB_USERNAME'), password: configService.get('DB_PASSWORD'), database: configService.get('DB_NAME'), entities: [__dirname + '/**/*.entity{.ts,.js}'], cache: { duration: 30000 } }) })

Если нужен именно Redis, проверьте документацию вашей версии TypeORM. В некоторых проектах проще сделать кэш на уровне сервиса через Nest CacheModule и Redis store, а не полагаться на query cache TypeORM.

Пример более контролируемой логики: сервис сначала проверяет Redis по ключу, если данных нет — делает запрос в Postgres, кладёт результат в Redis с TTL и возвращает ответ. Так проще инвалидировать кэш и понимать, что именно хранится.

Важно: кэш запросов не должен заменять индексы и нормальную оптимизацию SQL. Если запрос медленный из-за отсутствия индекса, Redis только временно скрывает проблему и может отдавать устаревшие данные.

Итог: да, Redis можно использовать рядом с TypeORM для кэширования результатов, но основная БД остаётся Postgres/MySQL. Для NestJS часто практичнее делать кэш на уровне сервисов через Redis и TTL, а TypeORM оставить для работы с реляционной БД.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно