From 7d0110097ebe275a983e6924a49d5a6f122efb5e Mon Sep 17 00:00:00 2001 From: happybell80 Date: Mon, 25 Aug 2025 23:53:39 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20rb8001=20=EC=9D=B4=EC=A4=91=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=ED=8A=B8=EB=9F=AC=EB=B8=94=EC=8A=88=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PostgreSQL 직접 연결 구현 - State Service 의존성 제거 - ChromaDB + PostgreSQL 이중 저장 - SSH 터널 재설정 (main_db) --- ...6_happybell80_rb8001_이중저장구현.md | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 troubleshooting/250826_happybell80_rb8001_이중저장구현.md diff --git a/troubleshooting/250826_happybell80_rb8001_이중저장구현.md b/troubleshooting/250826_happybell80_rb8001_이중저장구현.md new file mode 100644 index 0000000..70052a6 --- /dev/null +++ b/troubleshooting/250826_happybell80_rb8001_이중저장구현.md @@ -0,0 +1,222 @@ +# rb8001 대화 이중 저장 시스템 구현 + +## 작성일: 2025-08-26 +## 작성자: happybell80 +## 관련 서비스: rb8001, PostgreSQL, ChromaDB + +--- + +## 문제 상황 + +### 기존 문제점 +1. **State Service 의존성** + - rb8001이 State Service (포트 8507) API 호출 + - State Service가 auth_db로 잘못 연결되어 500 에러 발생 + - 대화가 ChromaDB에만 저장되고 PostgreSQL 저장 실패 + +2. **데이터 불일치** + - ChromaDB: 대화 저장 성공 + - PostgreSQL: State Service 오류로 저장 실패 + - 단일 실패 지점(SPOF) 존재 + +3. **네트워크 오버헤드** + - 불필요한 HTTP API 호출 + - State Service 중간 단계로 인한 지연 + +--- + +## 조사 과정 + +### 1. 로컬 코드 분석 +```bash +# rb8001 대화 저장 로직 확인 +grep -r "save_conversation\|store_memory" rb8001/ + +# 결과: +# - router.py:309: _save_conversation() 메서드 +# - ChromaDB 직접 저장 + State Service API 호출 +``` + +### 2. 서버 상태 확인 (51124) +```bash +# PostgreSQL 연결 테스트 +PGPASSWORD=robeings psql -h 192.168.219.45 -U robeings -d main_db -c "\dt" + +# 결과: +# - conversation_logs 테이블 존재 ✅ +# - robeing_stats 테이블 존재 ✅ +# - 직접 연결 가능 +``` + +### 3. SSH 터널 문제 발견 +```bash +# 기존 터널 (잘못된 설정) +localhost:5433 → 124.55.18.179:5432/auth_db (존재하지 않음) + +# 수정된 터널 +localhost:5433 → 192.168.219.45:5432/main_db ✅ +``` + +--- + +## 해결 방안 + +### 1. DATABASE_URL 수정 +```diff +# rb8001/.env +- DATABASE_URL=postgresql://robeings:robeing2025!@localhost/rb8001_db ++ DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db +``` + +### 2. 직접 DB 저장 구현 +```python +# rb8001/app/router/router.py:309 +async def _save_conversation(self, message: str, response: str, user_id: str, + channel: str, intent: str = None, confidence: float = None): + """대화를 PostgreSQL과 ChromaDB에 직접 저장""" + chroma_saved = False + postgres_saved = False + + # 1. ChromaDB에 저장 시도 + try: + await self.memory_manager.store_memory(...) + chroma_saved = True + logger.info(f"ChromaDB: Conversation saved for user {user_id}") + except Exception as e: + logger.error(f"ChromaDB save failed: {e}") + + # 2. PostgreSQL에 직접 저장 시도 + try: + from app.state.database import SessionLocal + db = SessionLocal() + try: + conversation_log = ConversationLog( + robeing_id=settings.ROBEING_ID, + user_id=user_id, + channel_id=channel, + message=message, + response=response, + intent=intent, + confidence=confidence + ) + db.add(conversation_log) + db.commit() + postgres_saved = True + logger.info(f"PostgreSQL: Conversation saved for user {user_id}") + finally: + db.close() + except Exception as e: + logger.error(f"PostgreSQL save failed: {e}") + + # 최소 하나는 성공해야 함 + if not chroma_saved and not postgres_saved: + logger.error("Failed to save conversation to both storages") + elif chroma_saved and postgres_saved: + logger.info(f"Conversation saved to both storages for user {user_id}") +``` + +### 3. State Service 의존성 제거 +- HTTP API 호출 코드 제거 +- 직접 SQLAlchemy 사용 +- 트랜잭션 처리 추가 + +--- + +## 구현 결과 + +### 장점 +1. **안정성 향상** + - 한쪽 저장소 실패해도 다른 쪽 저장 보장 + - 트랜잭션 단위 에러 처리 + +2. **성능 개선** + - State Service API 호출 제거 + - 네트워크 지연 감소 + - 직접 DB 연결로 빠른 저장 + +3. **관리 단순화** + - State Service 별도 관리 불필요 + - 단일 서비스 내 모든 로직 포함 + +### 데이터 흐름 +```mermaid +graph LR + A[Slack 메시지] --> B[rb8001] + B --> C{저장 로직} + C --> D[ChromaDB
벡터 저장] + C --> E[PostgreSQL
구조화 저장] + D --> F[저장 결과 로깅] + E --> F +``` + +--- + +## 모니터링 + +### 로그 확인 +```bash +# 51124 서버에서 +docker logs rb8001 --tail 100 | grep -E "ChromaDB|PostgreSQL|saved" + +# 성공 로그 예시: +# ChromaDB: Conversation saved for user U092HLS6BKL +# PostgreSQL: Conversation saved for user U092HLS6BKL +# Conversation saved to both storages for user U092HLS6BKL +``` + +### DB 확인 +```sql +-- PostgreSQL 저장 확인 +SELECT COUNT(*) FROM conversation_logs +WHERE robeing_id = 'rb8001' +AND timestamp > NOW() - INTERVAL '1 hour'; + +-- 최근 대화 확인 +SELECT user_id, message, response, timestamp +FROM conversation_logs +WHERE robeing_id = 'rb8001' +ORDER BY timestamp DESC +LIMIT 5; +``` + +--- + +## 교훈 + +### 1. 아키텍처 단순화 +- **문제**: 불필요한 중간 서비스로 인한 복잡도 +- **해결**: 직접 연결로 단순화 +- **교훈**: KISS 원칙 - Keep It Simple, Stupid + +### 2. 이중 저장의 중요성 +- **ChromaDB**: 벡터 검색용 (의미 기반 검색) +- **PostgreSQL**: 구조화 데이터 (통계, 분석) +- **교훈**: 각 저장소의 장점을 활용한 하이브리드 접근 + +### 3. 에러 처리 전략 +- **부분 실패 허용**: 한쪽만 성공해도 서비스 계속 +- **명확한 로깅**: 어느 저장소가 실패했는지 구분 +- **교훈**: Graceful degradation 구현 + +### 4. SSH 터널 관리 +- **문제**: 잘못된 터널 설정으로 auth_db 연결 시도 +- **해결**: main_db로 터널 재설정 +- **교훈**: 인프라 설정 문서화 필수 + +--- + +## 관련 파일 +- `/home/happybell/projects/ivada/rb8001/.env` - DATABASE_URL 설정 +- `/home/happybell/projects/ivada/rb8001/app/router/router.py` - 저장 로직 +- `/home/happybell/projects/ivada/rb8001/app/state/database.py` - DB 모델 +- `/home/happybell/projects/ivada/rb8001/app/memory/manager.py` - ChromaDB 관리 + +--- + +## 참고 문서 +- [일일 브리핑 시퀀스](/home/happybell/projects/ivada/DOCS/300_architecture/sequences/daily_briefing_sequences.md) +- [로빙 상태 표시 문제](/home/happybell/projects/ivada/DOCS/troubleshooting/250825_robeing_stats_display_issue.md) + +--- + +**문서 끝** \ No newline at end of file