Files
AIclinicalresearch/docs/07-运维文档/08-Postgres-Only 全能架构解决方案.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

22 KiB
Raw Blame History

Postgres-Only <20><EFBFBD><E588BB><EFBFBD><EFBFBD><E996AB><EFBFBD><EFBFBD>

*<EFBFBD><EFBFBD>?<3F><EFBFBD>敺桀<E695BA> AI <20><EFBFBD><EFBD81><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E888AB><EFBFBD><EFBFBD><EFBFBD>鞉𧋦<E99E89><F0A78BA6><EFBFBD><EFBFBD><E88880>?

<EFBFBD><EFBFBD>𧋦嚗鯝1.0
<0A><><EFBFBD>箸艶嚗?-2鈭箏<E988AD><E7AE8F>𥕦𣪧<F0A595A6><EFBFBD><E9BA84>ode.js/Fastify <20><><EFBFBD><EFBFBD><E88880><EFBFBD><EFBFBD><EFBFBD> SAE <20>函蔡<E587BD><EFBFBD>
<0A><EFBFBD><E8A9A8><EFBFBD>嚗𡁜銁銝滚<E98A9D><E6BB9A>?Redis <20><><EFBFBD><EFBFBD>𣂷<EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>銝𡁶漣<F0A181B6><E6BCA3><EFBFBD><EFBFBD><E28ABF>𨰜<EFBFBD><F0A8B09C><EFBFBD>摮䀝<E691AE>隡朞<E99AA1>蝞∠<E89D9E>嚗䔶<E59A97><E494B6>?2撠𤩺𧒄+ <20>蹂遙<E8B982><EFBFBD>蝏嘥笆<E598A5><EFBFBD><E888AB><EFBFBD>?

1. <20><EFBFBD><E689AF><EFBFBD> (Executive Summary)

<EFBFBD><EFBFBD><EFBFBD>烐䲮敶枏<EFBFBD>嚗㇈AU < 5000嚗厩<E59A97>銝𡁜𦛚閫<F0A69B9A>芋銝𢛶<E98A9D>𦦵迅摰𡁏<E691B0><EFBFBD><E689BE><EFBFBD><EFBFBD><EFBFBD><E89098>条裦霂㗇<E99C82>嚗峕𧋦<E5B395><EFBFBD>銝餃<E98A9D><E9A483><EFBFBD>"Postgres-Only" (<28><EFBFBD><E588BB>唳旿摨? <20><EFBFBD><E59786>? <0A><EFBFBD><E69C9E>拍鍂 PostgreSQL <20><><EFBFBD>蝥抒鸌<E68A92><EFBFBD>憒?SKIP LOCKED <20><><EFBFBD><EFBFBD><E5979A>SONB 摮睃<E691AE><E79D83><EFBFBD>nlogged Tables嚗㚁<E59A97><E39A81>睲賑<E79DB2>臭誑摰<E8AA91><E691B0><EFBFBD>蹂誨 Redis <20>?*隞餃𦛚<E9A483><EFBFBD><EFBFBD>?*蝻枏<E89DBB><EFBFBD>?*隡朞<E99AA1>摮睃<E691AE>**銝剔<E98A9D>雿𦦵鍂<F0A6A6B5>? *<EFBFBD>条裦<EFBFBD><EFBFBD>嚗?

  1. **<2A><EFBFBD><E59786><EFBFBD><EFBFBD>**嚗𡁶宏<F0A181B6>?Redis 銝剝𡢿隞塚<E99A9E>蝟餌<E89D9F>憭齿<E686AD>摨阡<E691A8>雿?50%<25>?
  2. **<2A>唳旿撘箔<E69298><E7AE94>?*嚗帋<E59A97><E5B88B>⊥㺭<E28AA5><EFBFBD>隞餃𦛚<E9A483><EFBFBD><E59786><EFBFBD><EFBFBD>鈭见𦛚銝剜<E98A9D>鈭歹<E988AD>敶餃<E695B6><E9A483>寥膄<E5AFA5>𨅯<EFBFBD><EFBFBD><E692A3>鈭见𦛚<E8A781><EFBFBD><E597AA><EFBFBD>?
  3. **<2A><EFBFBD>憭𡝗<E686AD><F0A19D97>?*嚗𡁜<E59A97><F0A1819C>函緵<E587BD>?RDS 韏<><E99F8F>嚗峕<E59A97>撟渲<E6929F><E6B8B2><EFBFBD><EFBFBD><E3BAAD><EFBFBD>銝剝𡢿隞嗉晶<E59789><EFBFBD>?
  4. **隡<><E99AA1>蝥批虾<E689B9>?*嚗帋<E59A97><E5B88B>?RDS <20><><EFBFBD><EFBFBD>隞賭<E99A9E> PITR嚗<52>𧒄<EFBFBD><EFBFBD><E6B8A1><EFBFBD>嚗㕑<E59A97><E39591>𨥈<EFBFBD>靽嗪<E99DBD>隞餃𦛚<E9A483><EFBFBD><E7AC94>唳旿<E594B3>𨀣偶銝滢腺憭晦<E686AD><EFBFBD>?

*2. <20><EFBFBD><E6A185>峕艶銝擧<E98A9D><E693A7>?

*2.1 敶枏<E695B6><E69E8F>𤤿<EFBFBD>嚗𡁻鵭隞餃𦛚<E9A483><F0A69B9A><EFBFBD>撘望<E69298>?

<EFBFBD>睲賑<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𪙛<EFBFBD>𨀣<EFBFBD><EFBFBD><EFBFBD>摨栞圾<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𨅯<EFBFBD><EFBFBD>鈭文<EFBFBD>撉諹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>閙活隞餃𦛚<EFBFBD>埈𧒄<EFBFBD><EFBFBD><EFBFBD>輯噢 2撠𤩺𧒄<EFBFBD>?

  • <EFBFBD>啁𠶖嚗帋蝙<EFBFBD><EFBFBD>摮㗛<EFBFBD><EFBFBD><EFBFBD>MemoryQueue嚗剹<EFBFBD>?
  • 憌𡡞埯嚗𡁜銁 Serverless (SAE) <20><EFBFBD>銝页<E98A9D>摰硺<E691B0><E7A1BA><EFBFBD><E888AA><EFBFBD><EFBFBD><E7989A>蝻拙捆<E68B99><E68D86><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E594B3><EFBFBD><EFBFBD><EFBCB7><EFBFBD><E5B1B8><EFBFBD><EFBFBD><E798A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E798A5><EFBFBD><EFBFBD><EFBFBD>銝剔<E98A9D>隞餃𦛚餈𥕦漲<F0A595A6><EFBFBD>仃嚗<E4BB83><EFBFBD>渡鍂<E6B8A1>瑚遙<E7919A>仃韐乓<E99F90>?

2.2 撣貉<E692A3>霂臬躹嚗𡁜蘨<F0A1819C>?Redis <20><EFBFBD><E8B3A3><EFBFBD>

銝𡁶<EFBFBD>撣貉<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>寡恕銝綽<EFBFBD><EFBFBD>𨅯<EFBFBD>憿餃<EFBFBD><EFBFBD>?Redis (BullMQ) <20><EFBFBD>摰䂿緵隞餃𦛚<E9A483><F0A69B9A><EFBFBD><EFBFBD><EFBFBD><E7A194><EFBFBD>?

  • <EFBFBD>漤底嚗朞<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>萘輕<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瓲敹<EFBFBD>糓**<2A>𨀣<EFBFBD><EFBFBD><E98A8B>摮睃<E691AE><E79D83>𩄼**嚗諹<E59A97><EFBFBD> Redis <20>祈澈<E7A588><E6BE88>ostgreSQL <20>峕甅<E5B395><EFBFBD><E79195><EFBFBD><EFBFBD><EFBFBD>𤥁<EFBFBD><F0A4A581>𨥈<EFBFBD>銝𥪜銁鈭见𦛚摰匧<E691B0><E58CA7><EFBFBD>隡䀝<E99AA1> Redis<69>?

3. <20><EFBFBD><EFBFBD><E996AB><EFBFBD><EFBFBD>嚗䥪ostgres-Only <20><EFBFBD>

<EFBFBD>祆䲮獢<EFBFBD><EFBFBD> Redis <20><><EFBFBD>憭扳瓲敹<E793B2><E695B9><EFBFBD><EFBFBD><E8B89D><EFBFBD><E7AC94><EFBFBD><EFBFBD>摮塩<E691AE><E5A1A9><EFBFBD>霂嘅<E99C82><E59885><EFBFBD><E588B8><EFBFBD><E59786>?PostgreSQL<51>?

3.1 <20>蹂誨 Redis <20><EFBFBD>嚗帋蝙<E5B88B>?pg-boss

<EFBFBD>睲賑撘訫<EFBFBD> Node.js 摨?pg-boss<EFBFBD><EFBFBD><EFBFBD>拍鍂 PostgreSQL <20>?FOR UPDATE SKIP LOCKED <20><EFBFBD><EFBFBD>摰䂿緵鈭<E7B7B5><E988AD><EFBFBD><EFBFBD><E689AF><EFBFBD>𦜖<EFBFBD><EFBFBD><E683A9><EFBFBD><E7AC94>?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

  1. **<2A>仿<EFBFBD>**嚗鋫PI <20>交𤣰霂瑟<E99C82><EFBFBD><E59A97>隞餃𦛚<E9A483><F0A69B9A><EFBFBD><EFBFBD>JSON嚗匧<E59A97><E58CA7>?job 銵具<E98AB5>?甇斗<EFBFBD>雿𨅯銁瘥怎<EFBFBD>蝥批<EFBFBD><EFBFBD><EFBFBD><EFBFBD>唳旿蝡见朖摰匧<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
  2. **憭<><E686AD>**嚗阳orker 餈𤤿<E9A488>隞擧㺭<E693A7><EFBFBD><E6A180>𧼮<EFBFBD>隞餃𦛚嚗<F0A69B9A><EFBFBD><E5838E><EFBFBD>霂亥<E99C82>霈啣<E99C88><E595A3>?
  3. **摰寧<E691B0>**嚗𡁜<E59A97><F0A1819C>?SAE 摰硺<E691B0><E7A1BA><EFBFBD><E585B8><EFBFBD><EFBFBD>蝔衤葉撏拇<E6928F><EFBFBD><E59A97> OOM嚗㚁<E59A97><E39A81>唳旿摨㯄<E691A8>隡𡁜銁頞<E98A81>𧒄<EFBFBD>舘䌊<E88898><EFBFBD><E588B8><EFBFBD><E6A998><EFBFBD>摮䀹暑<E480B9>?Worker 摰硺<E691B0>隡𡁶<E99AA1><F0A181B6>單𦻖蝞∟砲隞餃𦛚<E9A483><EFBFBD><E6BBA9>?

<EFBFBD><EFBFBD>摰䂿緵<EFBFBD><EFBFBD><EFBFBD>

import PgBoss from 'pg-boss';

const boss = new PgBoss({
connectionString: process.env.DATABASE_URL,
schema: 'job_queue', // <20><EFBFBD>Schema嚗䔶<E59A97>瘙⊥<E79899>銝𡁜𦛚銵? max: 5 // 撟嗅<E6929F><E59785><EFBFBD>嚗䔶<E59A97><E494B6>?DeepSeek API
});

await boss.start();

// 瘨<><EFBFBD><E699B6><EFBFBD>銋?(Worker)
await boss.work('screening-task', {
// <20>喲睸<E596B2>滨蔭嚗朞挽蝵桅<E89DB5><E6A185><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝?4撠𤩺𧒄
// <20>喃蝙隞餃𦛚頝?3.9撠𤩺𧒄嚗<EFBFBD>蘨閬?Worker 瘣餌<E798A3><EFBFBD>停銝滢<E98A9D>鋡急𦜖韏? // 憒<><E68692> Worker 甇颱<E79487>嚗屸<E59A97><EFBFBD><E9A488>嚗䔶遙<E494B6>∟䌊<E2889F><EFBFBD>霂? expireInSeconds: 14400,
retryLimit: 3
}, async (job) => {
// 銝𡁜𦛚<F0A1819C><EFBFBD>...
});

3.2 <20>蹂誨 Redis 蝻枏<E89DBB>嚗𡁜抅鈭?Table <20>?KV 摮睃<E691AE>

撖嫣<EFBFBD> AI 蝏𤘪<E89D8F>蝻枏<E89DBB><EFBFBD><E59A97><EFBFBD><EFBFBD>憭滩<E686AD><E6BBA9>?LLM嚗㚁<E59A97>Postgres <20><>䰻霂<E99C82>笔漲嚗?-3ms嚗匧笆鈭𡒊鍂<F0A1928A><EFBFBD>撉䕘<E69289>蝘垍漣蝑匧<E89D91>嚗㗇䔉霂游<E99C82><E6B8B8>典虾隞交𦻖<E4BAA4>𨰜<EFBFBD>?

<EFBFBD><EFBFBD>霈箄<EFBFBD>

摰鮋<EFBFBD>撟嗅<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?- 敶枏<E695B6><EFBFBD>芋: 500 MAU
- 撜啣<E6929C>澆僎<E6BE86>? < 50 QPS嚗<53><E59A97>蝡舀<E89DA1><E88880><EFBFBD>
- Postgres<65><EFBFBD>: 5銝? QPS嚗<53><E59A97><EFBFBD>閙䰻霂<E99C82>
- <20><EFBFBD>雿䠷<E99BBF>: 1000<30>?
<0A><EFBFBD><E6BB9A>園𡢿撖寞<E69296>嚗?- Redis: 0.15ms嚗<EFBFBD><EFBFBD>蝏?霂餃<E99C82>嚗?- Postgres: 1.5ms嚗<EFBFBD><EFBFBD>蝏?<3F>亥砭嚗?- 撌桀<E6928C>: 1.35ms
- <20><EFBFBD><E586BD>毺䰻: <20>𩤃<EFBFBD><F0A9A483><EFBFBD>埈𧒄200ms銝剖<E98A9D>瘥?< 1%嚗?
蝏栞捏嚗𡁜銁<F0A1819C>交暑10銝<30>誑銝页<E98A9D>Postgres<65><EFBFBD><EFBFBD><E691B0>憭毺鍂

*<EFBFBD>唳旿摨栞挽霈?

model AppCache {
  id         Int      @id @default(autoincrement())
  key        String   @unique
  value      Json     // 撖孵<E69296> Redis <20>?Value
  expiresAt  DateTime // 撖孵<E69296> Redis <20>?TTL
  createdAt  DateTime @default(now())

  @@index([expiresAt]) // 蝝<E89D9D><EFBCB7><EFBFBD>敹恍<E695B9><E6818D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?  @@index([key, expiresAt]) // 憭滚<E686AD><E89D9D>隡睃<E99AA1><E79D83>亥砭
  @@map("app_cache")
}

*<EFBFBD><EFBFBD> Service嚗<65><E59A97><EFBFBD><EFBFBD>嚗?

// <20><>辣嚗颹ackend/src/common/cache/PostgresCacheAdapter.ts

import { prisma } from '../../lib/prisma';
import type { CacheAdapter } from './types';
import { logger } from '../logging/index';

export class PostgresCacheAdapter implements CacheAdapter {
  
  /**
   * <20><EFBFBD>蝻枏<E89DBB><EFBFBD><EFBFBD><EFBFBD><E59F9D>𣳇膄嚗?   */
  async get<T = any>(key: string): Promise<T | null> {
    try {
      const record = await prisma.appCache.findUnique({
        where: { key }
      });
      
      if (!record) return null;
      
      // 璉<><E79289>交糓<E4BAA4>西<EFBFBD><E8A5BF>?      if (record.expiresAt < new Date()) {
        // <20><EFBFBD><E59F9D>𣳇膄嚗𡁻◇<F0A181BB>𧢲<EFBFBD><F0A7A2B2><EFBFBD><EFBFBD><EFBFBD>郊嚗䔶<E59A97><E494B6><EFBFBD>嚗?        this.deleteAsync(key);
        return null;
      }
      
      return record.value as T;
      
    } catch (error) {
      logger.error('[PostgresCache] 霂餃<E99C82>憭梯揖', { key, error });
      return null;
    }
  }

  /**
   * 霈曄蔭蝻枏<E89DBB>
   */
  async set(key: string, value: any, ttlSeconds: number = 3600): Promise<void> {
    try {
      const expiresAt = new Date(Date.now() + ttlSeconds * 1000);
      
      await prisma.appCache.upsert({
        where: { key },
        create: { key, value, expiresAt },
        update: { value, expiresAt }
      });
      
      logger.debug('[PostgresCache] <20><EFBFBD><E59D94>𣂼<EFBFBD>', { key, ttl: ttlSeconds });
      
    } catch (error) {
      logger.error('[PostgresCache] <20><EFBFBD>憭梯揖', { key, error });
      throw error;
    }
  }

  /**
   * <20>𣳇膄蝻枏<E89DBB>
   */
  async delete(key: string): Promise<boolean> {
    try {
      await prisma.appCache.delete({ where: { key } });
      return true;
    } catch (error) {
      return false;
    }
  }

  /**
   * 撘<><EFBFBD>𣳇膄嚗<E88684><E59A97><EFBFBD><EFBFBD>銝餅<E98A9D>蝔页<E89D94>
   */
  private deleteAsync(key: string): void {
    prisma.appCache.delete({ where: { key } })
      .catch(err => logger.debug('[PostgresCache] <20><EFBFBD><E59F9D>𣳇膄憭梯揖', { key, err }));
  }

  /**
   * <20><EFBFBD><E5AFA5>𣳇膄
   */
  async deleteMany(pattern: string): Promise<number> {
    try {
      const result = await prisma.appCache.deleteMany({
        where: { key: { contains: pattern } }
      });
      return result.count;
    } catch (error) {
      logger.error('[PostgresCache] <20><EFBFBD><E5AFA5>𣳇膄憭梯揖', { pattern, error });
      return 0;
    }
  }

  /**
   * 皜<><EFBFBD><E5BE81><EFBFBD><EFBFBD>摮?   */
  async flush(): Promise<void> {
    try {
      await prisma.appCache.deleteMany({});
      logger.info('[PostgresCache] 蝻枏<E89DBB>撌脫<E6928C>蝛?);
    } catch (error) {
      logger.error('[PostgresCache] <EFBFBD>征憭梯揖', { error });
    }
  }
}

/**
 * <20>臬𢆡摰𡁏𧒄皜<F0A79284><E79A9C>隞餃𦛚嚗<F0A69B9A><E59A97><EFBFBD><EFBFBD><E5AF9E><EFBFBD><EFBFBD><EFBFBD>脫迫<E884AB><EFBFBD>嚗? */
export function startCacheCleanupTask() {
  setInterval(async () => {
    try {
      // 瘥𤩺活<F0A4A9BA><EFBFBD><E88AB8>?000<30><EFBFBD><E2889F><EFBFBD><EFBFBD>?      const result = await prisma.$executeRaw`
        DELETE FROM app_cache 
        WHERE id IN (
          SELECT id FROM app_cache 
          WHERE expires_at < NOW() 
          LIMIT 1000
        )
      `;
      
      if (result > 0) {
        logger.info('[PostgresCache] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>唳旿', { count: result });
      }
      
    } catch (error) {
      logger.error('[PostgresCache] 摰𡁏𧒄皜<EFBFBD><EFBFBD>憭梯揖', { error });
    }
  }, 60000);  // 瘥誩<E798A5><E8AAA9><EFBFBD><EFBFBD>銵䔶<E98AB5>甈?  
  logger.info('[PostgresCache] 摰𡁏𧒄皜<EFBFBD><EFBFBD>隞餃𦛚撌脣鍳<EFBFBD><EFBFBD>瘥誩<EFBFBD><EFBFBD>?000<EFBFBD><EFBFBD>');
}

*<EFBFBD><EFBFBD>隡睃<EFBFBD><EFBFBD><EFBFBD>撌?

  1. **蝝<E89D9D>隡睃<E99AA1>**嚗䫤@@index([key, expiresAt])` 閬<><E996AC><EFBFBD>亥砭嚗峕<E59A97><E5B395><EFBFBD><EFBFBD>噼”
  2. <EFBFBD><EFBFBD><EFBFBD>𣳇膄嚗朞粉<EFBFBD>𡝗𧒄憿箔噶皜<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>頧?3. **<2A><>鸌皜<E9B88C><E79A9C>**嚗𡁏<E59A97>甈‥IMIT 1000嚗峕神蝘垍漣摰峕<E691B0>
  3. **餈墧𦻖瘙惩<E79899><E683A9>?*嚗䥪risma<6D>芸𢆡蝞∠<E89D9E>嚗峕<E59A97>憸嘥<E686B8><EFBFBD><E69298><EFBFBD>

3.3 <20>蹂誨 Redis 隡朞<E99AA1>嚗䬙onnect-pg-simple

雿輻鍂<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>箸䲮獢<EFBFBD><EFBFBD>撠?Session 摮睃<E691AE><E79D83>?Postgres <20>?session 銵其葉<E585B6><E89189>AE 憭𡁜<E686AD>靘钅<E99D98><E99285><EFBFBD>嚗𣬚鍂<F0A3AC9A><EFBFBD><E7919F><EFBFBD><EFBFBD>齿鰵<E9BDBF><EFBFBD><E9A483>?

*4. 瘛勗漲撖寞<E69296>嚗帋蛹隞<E89BB9>銋?Postgres <20>𨅯枂嚗?

蝏游漲 <EFBFBD><EFBFBD> A: 隡删<E99AA1> Redis (BullMQ) <EFBFBD><EFBFBD> B: Postgres (pg-boss) <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*<EFBFBD>唳旿銝<EFBFBD><EFBFBD><EFBFBD>? *撘? (<28><><EFBFBD><EFBFBD><E98A9D><EFBFBD>折𠗕憸? 隞餃𦛚<E9A483>?Redis嚗䔶<E59A97><E494B6>銁 DB<44><42>𥅾 DB 鈭见𦛚<E8A781><EFBFBD>嚗朙edis 隞餃𦛚<E9A483><EFBFBD><E888AA><EFBFBD><E4ADBE><EFBFBD><E5A2A7>? *撘? (鈭见𦛚蝥批<E89DA5>摮鞉<E691AE>? 隞餃𦛚<E9A483>仿<EFBFBD>銝𦒘<E98A9D><F0A69298>⊥㺭<E28AA5><EFBFBD><E6A180>亙銁<E4BA99><EFBFBD>銝?DB 鈭见𦛚銝准<E98A9D><E58786><EFBFBD><EFBFBD><E98A8B><EFBFBD><EFBFBD><EFBFBD><E996AC><EFBFBD>刻揖<E588BB>? Postgres
*餈鞟輕憭齿<EFBFBD>摨? *擃? <20><>蝏湔擪 Redis 摰硺<E691B0><E7A1BA><EFBFBD>PC <20><EFBFBD><E8B3A2>𨰻<EFBFBD><F0A8B0BB><EFBFBD><EFBFBD><EFBFBD>摮条<E691AE><E69DA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E98A8B>蝑𣇉裦<F0A38789>? *<EFBFBD>? 憭滨鍂<E6BBA8><EFBFBD> RDS<44><53><EFBFBD>隞賬<E99A9E><E8B3AC><EFBFBD><EFBFBD><EFBFBD><E689BC><EFBFBD>摰孵<E691B0><E5ADB5>梢燵<E6A2A2><EFBFBD> RDS <20>条恣<E69DA1>? Postgres
*<EFBFBD>遢銝擧<EFBFBD>憭? <EFBFBD>圈𠗕 Redis RDB/AOF <20><EFBFBD><EFBCB7><EFBFBD>隡帋腺憭望<E686AD><E69C9B>𤾸<EFBFBD>蝘垍<E89D98><E59E8D>唳旿<E594B3>? 摰𣬚<EFBFBD> RDS <20><EFBFBD> PITR (<28>㗇𧒄<E39787><EFBFBD><E6B8A1><EFBFBD>)<29><><EFBFBD>牐遙<E78990>虾蝎曄<E69B84><EFBFBD><E5A2A7>?1蝘鍦<E89D98><E98DA6>? Postgres
<EFBFBD>鞉𧋦 *瞼1000+/撟? (Tair <20><EFBFBD><E7AE87>? 瞼0 (韏<><E99F8F>憭滨鍂) Postgres
<EFBFBD><EFBFBD> (TPS) <EFBFBD><EFBFBD><EFBFBD> (10w+) *擃? (5000+) 撖嫣<E69296><E5ABA3><EFBFBD><E4BA99><EFBFBD>甈?AI 靚<><EFBFBD><E98D82><EFBFBD><EFBFBD>Postgres <20><EFBFBD>蝏啁趕<E59581><EFBFBD><E58A90>? Postgres
*<EFBFBD><EFBFBD><EFBFBD>鈭厰䔮憸? 霂航圾 霂餃<E99C82><E9A483><EFBFBD><EFBFBD><E996AC>蝏𨅯<E89D8F>餈䈑<E9A488>擃睃僎<E79D83><EFBFBD>Redis銋煺<E98A8B><E785BA><EFBFBD>鈭? <EFBFBD>毺㮾 SELECT<43>臬翰<E887AC>扯粉嚗䔶<E59A97><E494B6>𣳇<EFBFBD><F0A3B387><EFBFBD>ode.js<6A>閧瑪蝔衤<E89D94><E8A1A4><EFBFBD><EFBFBD>銝箇𣂎憸<F0A3828E><E686B8>? 霂航圾瞉<EFBFBD><EFBFBD>
蝻枏<EFBFBD><EFBFBD><EFBFBD>憌𡡞埯 摮睃銁 <20><><EFBFBD><EFBCB7><E69E82><EFBFBD><E996AC>蝵容viction蝑𣇉裦嚗䔶<E59A97>敶㯄<E695B6>蝵桐<E89DB5>撖潸稲<E6BDB8>唳旿銝 <EFBFBD>舀綉 <20><><EFBFBD>𣳇膄嚗𡿨IMIT 1000嚗? <20><EFBFBD><E59F9D>𣳇膄嚗峕偶餈靝<E9A488>隡𡁻獈憛𠺶<E6869B>? Postgres
摮虫<EFBFBD><EFBFBD>脩瑪 <EFBFBD> <20><><EFBFBD>郎銋袠edis<69><73>ullMQ<4D><51>oredis<69><73><EFBFBD><EFBFBD><E98A8B>蝑𣇉裦<F0A38789><E8A3A6><EFBFBD>摮条恣<E69DA1>? 撟喟<EFBFBD> <20><EFBFBD>摮虫<E691AE>pg-boss嚗㇁PI蝐颱撮BullMQ嚗㚁<E59A97><E39A81><EFBFBD><E597A1>賣糓<E8B3A3><E7B393><EFBFBD><EFBFBD><EFBFBD>ostgres Postgres

撣貉<EFBFBD>霂航圾瞉<EFBFBD><EFBFBD>

*霂航圾1嚗䥪ostgres撟嗅<EFBFBD><EFBFBD><EFBFBD>撌?

鈭见<EFBFBD>嚗?- Postgres<65><EFBFBD><E887AC>?銝? QPS嚗<53><E59A97><EFBFBD>閙䰻霂<E99C82>
- <20><EFBFBD>摰鮋<E691B0>撟嗅<E6929F>: < 50 QPS
- SELECT<43>臬翰<E887AC>扯粉嚗㇈VCC嚗㚁<E59A97><E39A81>𣳇<EFBFBD>蝡硺<E89DA1>
- Node.js<6A>閧瑪蝔页<E89D94>1-2銝𣘗PS銝𢠃<E98A9D>嚗劐<E59A97><E58A90><EFBFBD><EFBFBD>銝箇𣂎憸?
蝏栞捏嚗䥪ostgres銝齿糓<E9BDBF><EFBFBD>

*霂航圾2嚗鋽ELETE隡𡁻<EFBFBD>銵券獈憛?

鈭见<EFBFBD>嚗?- DELETE<54><EFBFBD>蝥折<E89DA5>嚗䔶<E59A97><E494B6>航”<E888AA>?- LIMIT 1000嚗峕神蝘垍漣摰峕<E691B0>嚗ǚ5ms嚗?- <20><EFBFBD><E6BB9A><EFBFBD><E59F9D>𣳇膄嚗<E88684><EFBFBD><EFBFBD><EFBFBD><E9A488><EFBFBD>唳旿<E594B3>刻粉<E588BB>𡝗𧒄撌脣<E6928C><E884A3>?- <20>喃蝙<E59683>厩妖<E58EA9><EFBFBD>瘥誩<E798A5><E8AAA9>?000<30><EFBFBD>1撠𤩺𧒄<F0A4A9BA><EFBFBD><E88880>?銝<>辺

蝏栞捏嚗帋<E59A97>隡𡁻獈憛?```

#### **霂航圾3嚗鑹edis<69><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰𡁜翰**

鈭见<EFBFBD>嚗?- Redis: 蝵𤑳<E89DB5>撱嗉<E692B1>0.1ms + 霂餃<E99C82>0.05ms = 0.15ms

  • Postgres: 蝵𤑳<E89DB5>撱嗉<E692B1>0.5ms + <20>亥砭1ms = 1.5ms
  • 撌桀<EFBFBD>: 1.35ms
  • <EFBFBD><EFBFBD><EFBFBD>摨娍𧒄<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗? 200ms
  • <EFBFBD><EFBFBD><EFBFBD>毺䰻撌桀<EFBFBD>: 0%嚗?.35/200 < 1%嚗? 蝏栞捏嚗𡁏<E59A97><EFBFBD>撌桀<E6928C><E6A180>函鍂<E587BD><EFBFBD>撉䔶葉<E494B6><EFBFBD><E4ADBE>?```

*5. <20><><EFBFBD>?撠𤩺𧒄<F0A4A9BA>蹂遙<E8B982><EFBFBD><EFBFBD><E89098><EFBFBD><E888AB><EFBFBD><E689AF>?

韐函<EFBFBD>嚗䥪ostgres <20><EFBFBD><E6AFBA><EFBFBD>霂?2 撠𤩺𧒄<F0A4A9BA><F0A79284><EFBFBD><EFBFBD>銝剜鱏<E5899C><EFBFBD>
<><E99C82>嚗?

  1. **<2A><><EFBFBD><EFBFBD><EFBFBD><E7A2B6>?*嚗帋遙<E5B88B><EFBFBD><E288A9><EFBFBD>鈭歹<E988AD>API餈𥪜<E9A488> 200 OK嚗㚁<E59A97><E39A81><EFBFBD><E596B3><E4BAA6><EFBFBD><E5A1A9>朖雿?SAE <20><>黎銝衤<E98A9D>蝘鍦<E89D98><E98DA6><EFBFBD>隞餃𦛚霈啣<E99C88>靘萘<E99D98><E89098>冽㺭<E586BD><EFBFBD>銝准<E98A9D>?
  2. **撏拇<E6928F><E68B87><EFBFBD><EFBCB7><EFBFBD>**嚗?
    • **甇<><EFBFBD><E8999C><EFBFBD>**嚗阳orker <20><><EFBFBD>隞餃𦛚 -> <20><EFBFBD> 2 撠𤩺𧒄 -> <20>𣂷漱蝏𤘪<E89D8F> -> <20><>扇摰峕<E691B0><E5B395>?
    • **撘<><EFBFBD><E8999C><EFBFBD> (SAE 蝻拙捆)**嚗阳orker <20><EFBFBD><E689AF>?1 撠𤩺𧒄鋡恍<E98BA1>瘥?-> <20>唳旿摨㯄<E691A8><E3AF84>?4 撠𤩺𧒄<F0A4A9BA><EFBFBD><E88898>?-> pg-boss 摰<>擪餈𤤿<E9A488><EFBFBD>瘚见<E7989A><EFBFBD><E9A488> -> 撠<><EFBFBD><EFBFBD><E28ABF><EFBFBD>霈唬蛹 Pending -> <20>?Worker 憸<><E686B8><EFBFBD><EFBFBD><E6BBA9>?
  3. **<2A><EFBFBD>蝏凋<E89D8F>**嚗阳orker <20><EFBFBD><E887AC><EFBFBD><EFBFBD><EFBFBD><E68692> 10 <20><><EFBFBD>嚗㗇凒<E39787>唳㺭<E594B3><EFBFBD>銝剔<E98A9D> progress 摮埈挾<E59F88><E68CBE><EFBFBD>霂閙𧒄霂餃<E99C82> progress嚗䔶<E59A97><E494B6><EFBFBD>蝏抒賒<E68A92><EFBFBD><E689AF>? 蝏栞捏嚗𡁻<EFBFBD><EFBFBD>?pg-boss <20><>香靽⊿<E99DBD><E28ABF><EFBFBD>Dead Letter嚗匧<E59A97><E58CA7><EFBFBD>蝑𣇉裦嚗<E8A3A6><EFBFBD><EFBFBD><EFBFBD><E68A92>𣬚<EFBFBD><F0A3AC9A><EFBFBD>鈭?Redis嚗<73><E59A97>銝?Redis <20><><EFBFBD>枂憌𡡞埯<F0A1A19E>游之嚗剹<E59A97>?

*6. 摰墧鴌頝舐瑪<E88890>?

*<EFBFBD>嗆挾1嚗帋遙<EFBFBD><EFBFBD><EFBFBD>埈㺿<EFBFBD>𩤃<EFBFBD>Week 1嚗?

*Step 1.1嚗𡁜<EFBFBD><EFBFBD><EFBFBD>韏?

cd backend
npm install pg-boss --save

*Step 1.2嚗𡁜<EFBFBD><EFBFBD>訐gBossQueue<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

// <20><>辣嚗颹ackend/src/common/jobs/PgBossQueue.ts

import PgBoss from 'pg-boss';
import type { Job, JobQueue, JobHandler } from './types';
import { logger } from '../logging/index';
import { config } from '../../config/env';

export class PgBossQueue implements JobQueue {
  private boss: PgBoss;
  private started = false;

  constructor() {
    this.boss = new PgBoss({
      connectionString: config.databaseUrl,
      schema: 'job_queue',  // <20><EFBFBD>schema嚗䔶<E59A97>瘙⊥<E79899>銝𡁜𦛚銵?      max: 5,               // 餈墧𦻖瘙惩之撠?      // <20>喲睸<E596B2>滨蔭嚗朞挽蝵桅<E89DB5><E6A185><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝?撠𤩺𧒄
      // 靽肽<E99DBD>2撠𤩺𧒄隞餃𦛚銝滩◤<E6BBA9>粥嚗䔶<E59A97>摰硺<E691B0>撏拇<E6928F><E68B87><EFBFBD><E88898>芸𢆡<E88AB8><EFBFBD>
      expireInHours: 4,
    });

    // <20>穃𨯬<E7A983>躰秤
    this.boss.on('error', error => {
      logger.error('[PgBoss] <20>躰秤', { error });
    });
  }

  async start(): Promise<void> {
    if (this.started) return;
    
    await this.boss.start();
    this.started = true;
    logger.info('[PgBoss] <20><EFBFBD>撌脣鍳<E884A3>?);
  }

  async push<T = any>(type: string, data: T, options?: any): Promise<Job> {
    await this.start();
    
    const jobId = await this.boss.send(type, data, {
      retryLimit: 3,
      retryDelay: 60,      // 憭梯揖<E6A2AF>?0蝘㘾<E89D98>霂?      expireInHours: 4,    // 4撠𤩺𧒄<F0A4A9BA><EFBFBD><E88898>?      ...options
    });

    logger.info('[PgBoss] 隞餃𦛚<EFBFBD>仿<EFBFBD>', { type, jobId });

    return {
      id: jobId,
      type,
      data,
      status: 'pending',
      createdAt: new Date(),
    };
  }

  process<T = any>(type: string, handler: JobHandler<T>): void {
    this.boss.work(type, async (job: any) => {
      logger.info('[PgBoss] <EFBFBD>憪见<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?, { 
        type, 
        jobId: job.id,
        attemptsMade: job.data.__retryCount || 0
      });

      const startTime = Date.now();

      try {
        const result = await handler({
          id: job.id,
          type,
          data: job.data as T,
          status: 'processing',
          createdAt: new Date(job.createdon),
        });

        logger.info('[PgBoss] 隞餃𦛚摰峕<E691B0>', { 
          type, 
          jobId: job.id,
          duration: `${Date.now() - startTime}ms`
        });

        return result;

      } catch (error) {
        logger.error('[PgBoss] 隞餃𦛚憭梯揖', { 
          type, 
          jobId: job.id,
          error: error instanceof Error ? error.message : 'Unknown'
        });
        throw error;  // <20>𥕦枂<F0A595A6>躰秤閫血<E996AB><E8A180><EFBFBD>
      }
    });

    logger.info('[PgBoss] Worker撌脫釣<E884AB>?, { type });
  }

  async getJob(id: string): Promise<Job | null> {
    const job = await this.boss.getJobById(id);
    if (!job) return null;

    return {
      id: job.id,
      type: job.name,
      data: job.data,
      status: this.mapState(job.state),
      createdAt: new Date(job.createdon),
    };
  }

  async updateProgress(id: string, progress: number, message?: string): Promise<void> {
    // pg-boss<73><73><EFBFBD><EFBFBD><EFBFBD>餈𥕦漲<F0A595A6>湔鰵嚗<E9B0B5><EFBFBD><EFBFBD><E69C9E>湔鰵銝𡁜𦛚銵典<E98AB5><E585B8>?    logger.debug('[PgBoss] 餈𥕦漲<EFBFBD>湔鰵', { id, progress, message });
  }

  async cancelJob(id: string): Promise<boolean> {
    await this.boss.cancel(id);
    return true;
  }

  async retryJob(id: string): Promise<boolean> {
    await this.boss.resume(id);
    return true;
  }

  async cleanup(olderThan: number = 86400000): Promise<number> {
    // pg-boss<73>㕑䌊<E39591><EFBFBD><E586BD><EFBFBD><EFBFBD>?    return 0;
  }

  private mapState(state: string): string {
    switch (state) {
      case 'completed': return 'completed';
      case 'failed': return 'failed';
      case 'active': return 'processing';
      default: return 'pending';
    }
  }

  async close(): Promise<void> {
    await this.boss.stop();
    logger.info('[PgBoss] <EFBFBD><EFBFBD>撌脣<EFBFBD><EFBFBD>?);
  }
}

Step 1.3嚗𡁏凒<EFBFBD>衷obFactory

// <20><>辣嚗颹ackend/src/common/jobs/JobFactory.ts

import { JobQueue } from './types';
import { MemoryQueue } from './MemoryQueue';
import { PgBossQueue } from './PgBossQueue';
import { logger } from '../logging/index';
import { config } from '../../config/env';

export class JobFactory {
  private static instance: JobQueue | null = null;

  static getInstance(): JobQueue {
    if (!this.instance) {
      this.instance = this.createQueue();
    }
    return this.instance;
  }

  private static createQueue(): JobQueue {
    const queueType = config.queueType || 'pgboss';  // 暺䁅恕雿輻鍂pgboss

    switch (queueType) {
      case 'pgboss':
        return new PgBossQueue();
      
      case 'memory':
        logger.warn('[JobFactory] 雿輻鍂<E8BCBB><E98D82><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E59A97><EFBFBD>𤑳㴓憓<E3B493><E68693>');
        return new MemoryQueue();
      
      default:
        logger.warn(`[JobFactory] <20>芰䰻<E88AB0><EFBFBD>蝐餃<E89D90>: ${queueType}嚗䔶蝙<EFBFBD>私gboss`);
        return new PgBossQueue();
    }
  }

  static reset(): void {
    this.instance = null;
  }
}

*Step 1.4嚗𡁏凒<EFBFBD>啁㴓憓<EFBFBD><EFBFBD><EFBFBD>?

# backend/.env
QUEUE_TYPE=pgboss
DATABASE_URL=postgresql://user:password@host:5432/dbname

Step 1.5嚗𡁏<EFBFBD>霂𤏪<EFBFBD>2撠𤩺𧒄<EFBFBD>蹂遙<EFBFBD><EFBFBD>

# <20>𣂷漱1000蝭<30><E89DAD><EFBFBD><EFBFBD><E6A183>劐遙<E58A90>?curl -X POST http://localhost:3001/api/v1/asl/projects/:id/screening

# 蝑匧<E89D91><EFBFBD><E686AD><EFBFBD>?0% <20>?<3F>见𢆡<E8A781>𨀣迫<F0A880A3>滚𦛚嚗㇃trl+C嚗?# <20>滚鍳<E6BB9A>滚𦛚
npm run dev

# <20><EFBFBD>隞餃𦛚<E9A483><EFBFBD>?<3F>?摨磰砲<E7A3B0>芸𢆡<E88AB8><EFBFBD>撟嗥誧蝏剖<E89D8F><E58996>?```

---

### **<2A>嗆挾2嚗𡁶<E59A97>摮䀹㺿<E480B9>𩤃<EFBFBD>Week 2嚗?*

#### **Step 2.1嚗𡁏溶<EFBFBD>蘯risma Schema**
```prisma
// backend/prisma/schema.prisma

model AppCache {
  id         Int      @id @default(autoincrement())
  key        String   @unique
  value      Json
  expiresAt  DateTime
  createdAt  DateTime @default(now())

  @@index([expiresAt])
  @@index([key, expiresAt])
  @@map("app_cache")
}
# <20><><EFBFBD><EFBFBD>
npx prisma migrate dev --name add_app_cache

Step 2.2嚗𡁜<EFBFBD><EFBFBD>訐ostgresCacheAdapter

<EFBFBD><EFBFBD>銝𦠜<EFBFBD>"3.2 <20>蹂誨 Redis 蝻枏<E89DBB>"<22><EFBFBD>嚗?

Step 2.3嚗𡁏凒<EFBFBD>蚓acheFactory

// <20><>辣嚗颹ackend/src/common/cache/CacheFactory.ts

export class CacheFactory {
  static getInstance(): CacheAdapter {
    const cacheType = config.cacheType || 'postgres';
    
    switch (cacheType) {
      case 'postgres':
        return new PostgresCacheAdapter();
      case 'memory':
        return new MemoryCacheAdapter();
      default:
        return new PostgresCacheAdapter();
    }
  }
}

*Step 2.4嚗𡁜鍳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

// <20><>辣嚗颹ackend/src/index.ts

import { startCacheCleanupTask } from './common/cache/PostgresCacheAdapter';

// <20><EFBFBD><E585B8>典鍳<E585B8>冽𧒄
await app.listen({ port: 3001, host: '0.0.0.0' });
startCacheCleanupTask();  // <20>臬𢆡蝻枏<E89DBB><EFBFBD><E79A9C>

*<EFBFBD>嗆挾3嚗锭AE<EFBFBD>函蔡嚗Áeek 3嚗?

  1. **<2A>砍𧑐瘚贝<E7989A><E8B49D><EFBFBD>**嚗㇁SL 1000蝭<30><E89DAD><EFBFBD>?+ DC 100隞賜<E99A9E><E8B39C><EFBFBD><EFBFBD>
  2. **<2A>唳旿摨栞<E691A8><E6A09E>仿<EFBFBD>蝵?*嚗𠄎AE<41><EFBFBD><E887AC><EFBFBD>霈曄蔭DATABASE_URL嚗?3. **<2A>啣漲<E595A3><EFBFBD>**嚗<><E59A97>1銝芸<E98A9D>靘页<E99D98><EFBFBD><E996AB>24撠𤩺𧒄嚗?4. <EFBFBD><EFBFBD>銝羓瑪<EFBFBD><EFBFBD>摰孵<EFBFBD>2-3銝芸<E98A9D>靘页<E99D98>

*7. <20><EFBFBD>颲寧<E9A2B2>銝擧<E98A9D>撅閗楝敺?

7.1 <20><>鍂閫<E98D82>

<EFBFBD><EFBFBD><EFBFBD> Postgres-Only<6C><EFBFBD>銝𢠃<E98A9D> <EFBFBD><EFBFBD>敶枏<EFBFBD><EFBFBD>? 摰匧<EFBFBD>雿䠷<EFBFBD>
<EFBFBD>交暑<EFBFBD><EFBFBD> 10銝? 500 200<EFBFBD>?
撟嗅<EFBFBD>QPS 5000 < 50 100<EFBFBD>?
蝻枏<EFBFBD>摰寥<EFBFBD> 10GB < 100MB 100<EFBFBD>?
<EFBFBD><EFBFBD><EFBFBD>𧼮<EFBFBD> 1000隞餃𦛚/撠𤩺𧒄 < 50隞餃𦛚/撠𤩺𧒄 20<EFBFBD>?

*蝏栞捏嚗𡁜銁<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>芣䔉嚗?-3撟湛<E6929F>嚗峕<E59A97>銝滢<E98A9D><EFBFBD>枂餈嗘葵銝𢠃<E98A9D><F0A2A083>?

*7.2 雿閙𧒄<E99699><F0A79284><EFBFBD>edis嚗?

<EFBFBD><EFBFBD><EFBFBD>其誑銝𧢲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧒄嚗峕<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>撘訫<EFBFBD>Redis嚗?

閫血<EFBFBD><EFBFBD>∩辣嚗㇁NY嚗㚁<EFBFBD>
<0A>?<3F>交暑 > 5銝?<3F>?撟嗅<E6929F>QPS > 1000
<0A>?Postgres CPU雿輻鍂<E8BCBB><E98D82><EFBFBD>蝏?> 70%
<0A>?蝻枏<E89DBB><E69E8F>亥砭撱嗉<E692B1> > 50ms嚗㇊99嚗?<3F>?LLM API<50><49><EFBFBD><EFBFBD>?> 瞼5000嚗<30><E59A97>摮睃𦶢銝剔<E98A9D>雿𠬍<E99BBF><>宏蝑𣇉裦嚗?1. <20><><EFBFBD>蝘腿LM蝻枏<E89DBB><E69E8F>訌edis嚗<73><E59A97>憸𤏸粉嚗?2. 靽脲<E99DBD>隞餃𦛚<E9A483><EFBFBD><E7AC94>沌ostgres嚗<73>撩銝<E692A9><E98A9D><EFBFBD><EFBFBD>
3. 銝𡁜𦛚蝻枏<E89DBB><E69E8F><EFBFBD><EFBFBD><0A>鞉𧋦嚗?- 餈<>宏撌乩<E6928C><E4B9A9>? 2-3憭?- 餈鞟輕憓𧼮<E68693>: <20>舀𦻖<E88880><EFBFBD>撌脫<E6928C>蝏誯<E89D8F>嚗?```

### **7.3 <20><EFBFBD>頝臬<E9A09D>**

<EFBFBD>嗆挾1嚗<EFBFBD><EFBFBD><EFBFBD>?5000<30><EFBFBD>嚗? Postgres-Only <0A><EFBFBD> <20><EFBFBD>: pg-boss <0A><EFBFBD> 蝻枏<E89DBB>: Postgres銵? <20><EFBFBD> <20>鞉𧋦: 瞼0

<EFBFBD>嗆挾2嚗?000-5銝<35><EFBFBD><EFBFBD>: 瘛瑕<E7989B><E79195><EFBFBD> <0A><EFBFBD> <20><EFBFBD>: pg-boss嚗<73><E59A97><EFBFBD><EFBFBD><EFBFBD> <0A><EFBFBD> LLM蝻枏<E89DBB>: Redis嚗<73><E59A97>蝘鳴<E89D98> <0A><EFBFBD> 銝𡁜𦛚蝻枏<E89DBB>: Postgres嚗<73><E59A97><EFBFBD><EFBFBD><EFBFBD> <0A><EFBFBD> <20>鞉𧋦: +瞼1000/撟? <0A>嗆挾3嚗?銝?50銝<30><EFBFBD><EFBFBD>: <20>沖edis <0A><EFBFBD> <20><EFBFBD>: BullMQ + Redis <0A><EFBFBD> 蝻枏<E89DBB>: Redis <0A><EFBFBD> <20>鞉𧋦: +瞼5000/撟?```


8. FAQ嚗<51>虜閫<E8999C><E996AB><EFBFBD><EFBFBD>

*Q1: pg-boss隡帋<E99AA1>隡𡁏<E99AA1><F0A1818F>㎜ostgres嚗?

A: 銝滢<E98A9D><E6BBA2><EFBFBD>g-boss<73><73>䰻霂<E99C82><EFBD81>厩揣撘蓥<E69298><E893A5><EFBFBD><E59094>閙活<E99699>亥砭 < 5ms<6D><73>朖雿?00銝杪orker<65>峕𧒄<E5B395><EFBCB6><EFBFBD>銋笔蘨<E7AC94>?00ms<6D><73><EFBFBD>憭𤥁<E686AD>頧踝<E9A0A7>撖嫣<E69296>5銝𣘗PS<50><53>ostgres<65>亥秩<E4BAA5>臬蕭<E887AC><EFBFBD>?

*Q2: 蝻枏<E89DBB>銵其<E98AB5>銝滢<E98A9D><E6BBA2>𣳇<EFBFBD>憓鮋鵭嚗?

A: 銝滢<E98A9D><E6BBA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E595A3>?+ <20><>鸌皜<E9B88C><E79A9C>嚗諹<E59A97><E8ABB9><EFBFBD><EFBFBD><EFBFBD>鋡怨䌊<E680A8><EFBFBD><E586BD><EFBFBD><EFBFBD><EFBFBD>朖雿踵<E99BBF>蝘臬<E89D98>嚗峕<E59A97><E5B395><EFBFBD><EFBFBD>1000<30><EFBFBD><EFBFBD><E79A9C><EFBFBD>笔漲頞喃誑摨𥪜笆<F0A5AA9C>?

Q3: 憒<><E68692>Postgres<65><73><EFBFBD><EFBFBD>𦒘<EFBFBD><F0A69298><EFBFBD>

A:

  • <EFBFBD><EFBFBD>鈭駵DS嚗𡁻<EFBFBD><EFBFBD>舐鍂<EFBFBD><EFBFBD><EFBFBD>其蜓隞𤾸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> < 30蝘?- **憭<><EFBFBD><EFBFBD>**嚗䥪ITR<54><EFBFBD>憭滚<E686AD>隞餅<E99A9E>蝘𡜐<E89D98><F0A19C90>唳旿銝滢腺憭?- <EFBFBD>滨漣蝑𣇉裦嚗𡁻<EFBFBD><EFBFBD><EFBFBD>蝻枏<EFBFBD><EFBFBD>賢銁DB嚗䔶<EFBFBD>韏瑟<EFBFBD>憭㵪<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <0A><EFBFBD>銋衤<E98A8B>嚗朙edis<69><73><EFBFBD>餈㗛<E9A488><EFBFBD><E996AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E98A9D>湧䔮憸塩<E686B8>?

Q4: 銝箔<E98A9D><EFBFBD><E98A8B><EFBFBD>沖edis嚗<73>㭂霂渲䌊撌望糓鈭穃<E988AD><E7A983><EFBFBD><EFBFBD>

A: 鈭穃<E988AD><E7A983><EFBFBD><E6AFBA><EFBFBD><E8A9A8>?*<2A><EFBFBD><E59786><EFBFBD>蝵?嚗䔶<EFBFBD><EFBFBD>?<EFBFBD><EFBFBD>沖edis<EFBFBD>?

鈭穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>祈捶嚗?<3F>?<3F>删𠶖<E588A0><F0A0B696><EFBFBD><EFBFBD><EFBFBD>銝滢<E98A9D>韏𡝗𧋦<F0A19D97><EFBFBD>摮矋<E691AE>
<0A>?<3F><EFBFBD><E59786><EFBFBD><EFBFBD><E98A8B><EFBFBD><EFBFBD><EFBFBD>仃嚗?<3F>?瘞游像<E6B8B8><EFBFBD><EFBFBD><E59A97>摰硺<E691B0><E7A1BA><EFBFBD>嚗?
Postgres-Only摰<79><E691B0>皛∟雲嚗?<3F>?<3F><EFBFBD><E59786><EFBFBD><EFBFBD>典銁RDS嚗<53><E59A97>蝵殷<E89DB5>
<0A>?隞餃𦛚<E9A483><F0A69B9A><EFBFBD><EFBFBD><EFBFBD>銝滢腺憭梧<E686AD>
<0A>?pg-boss<73><EFBFBD>憭𡁜<E686AD>靘页<E99D98>SKIP LOCKED嚗?
Redis<69>芣糓摰䂿緵<E482BF><EFBFBD>銋衤<E98A8B>嚗䔶<E59A97><E494B6>臬𣈲銝<F0A388B2><E98A9D><EFBFBD><E5ADB5>?```

---

## **9\. 蝏栞祗**

撖嫣<E69296> 1-2 鈭箄<E988AD>璅∠<E79285>蝎曄<E89D8E><E69B84>𥕢<EFBFBD><F0A595A2><EFBFBD>嚗?*<2A><><EFBFBD><EFBFBD><E88880><EFBFBD><EFBFBD>蝻抬<E89DBB>Stack Collapse嚗㗇糓<E39787><EFBFBD><E6BBA2><EFBFBD><E89084><EFBFBD><EFBFBD>雿單<E99BBF>畾?*<2A>?
<0A>㗇𥋘 Postgres-Only 銝齿糓<E9BDBF>牐蛹<E78990>睲賑<E79DB2><E8B391><EFBFBD>航氜<E888AA>𠬍<EFBFBD><F0A0AC8D>峕糓<E5B395>牐蛹<E78990>睲賑撖寞<E69296><E5AF9E><EFBFBD><E88880><EFBFBD><EFBFBD>湔楛<E6B994><EFBFBD><E9A48C><EFBFBD>圾嚗?
- <20>睲賑<E79DB2><E8B391>圾**撟嗅<E6929F><E59785><EFBFBD><EFBFBD>摰噼<E691B0>璅?*嚗<><E59A97><EFBFBD><EFBFBD><E888AA><EFBFBD><E5969F><EFBFBD>QPS嚗?- <20>睲賑<E79DB2><E8B391>圾**Postgres<65><73><EFBFBD><EFBFBD>𥡝器<F0A5A19D>?*嚗<><E59A97><EFBFBD>臬㫲鞊∩葉<E288A9>?<3F>?嚗?- <20>睲賑<E79DB2><E8B391>圾**<2A><EFBFBD><E59786><EFBFBD>瓲敹<E793B2>𤌍<EFBFBD>?*嚗<>迅摰𡁏<E691B0>?> <20><EFBFBD>嚗?- <20>睲賑<E79DB2><E8B391>圾**<2A><EFBFBD><EFBD81><EFBFBD><EFBFBD>摰噼<E691B0><E599BC>?*嚗<><E59A97>蝏渲<E89D8F><E6B8B2>?= 蝔喳<E89D94><E596B3><EFBFBD>

<0A>睲賑<E79DB2>㗇𥋘<E39787>?*<2A><EFBFBD><E59786><EFBFBD><EFBFBD><EFBFBD><E798A3>?*<2A>交揢<E4BAA4>?*餈鞟輕<E99E9F><E8BC95>迅摰𡁏<E691B0>?*嚗𣬚鍂**<2A><EFBFBD><E288AA><EFBFBD>ế<EFBFBD>?*<2A>交揢<E4BAA4>?*銝𡁜𦛚<F0A1819C><F0A69B9A><EFBFBD>蠘翮隞?*<2A>?
**餈嗘<E9A488><E59798>臬戎<E887AC>𧶏<EFBFBD>餈蹱糓<E8B9B1><EFBFBD><E7AEB8>?*