Files
microdao-daarion/ARCHITECTURE-150-NODES.md
Apple 3478dfce5f
Some checks failed
Build and Deploy Docs / build-and-deploy (push) Has been cancelled
🔒 КРИТИЧНО: Видалено паролі/API ключі з документів + закрито NodePort
- Видалено всі паролі та API ключі з документів
- Замінено на посилання на Vault
- Закрито NodePort для Memory Service (тільки internal)
- Створено SECURITY-ROTATION-PLAN.md
- Створено ARCHITECTURE-150-NODES.md (план для 150 нод)
- Оновлено config.py (видалено hardcoded Cohere key)
2026-01-10 09:46:03 -08:00

269 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🏗️ Архітектура для 150 нод — DAARION
**Дата:** 2026-01-10
**Версія:** 1.0.0
---
## 🎯 Принципи архітектури
### Ключова ідея
**Не стандартизувати GPU**, а стандартизувати **контракт виконання**:
- Як задачі розподіляються
- Як воркери звітують
- Як відбувається retry/ack
- Як гарантується однакова якість (модель/версія) та безпека
Різне "залізо" стає різними **tiers** воркерів.
---
## 📊 Поточна структура БД (що правильно, що треба виправити)
### PostgreSQL
**Зараз:**
- NODE1 = CloudNativePG (K8s) ✅
- NODE2/3 = Docker (dev/edge)
**Правильний фундамент:**
- **Один primary Postgres у Tier A** (NODE1/K8s) + репліки
- NODE2/3 Postgres у Docker — залишити як dev/edge, але **не як "другий прод-primary"**
**Що робити:**
- [ ] Якщо NODE3 потрібен як DR/replica: робіть **стрімінг-репліку** з primary (NODE1) на NODE3
- [ ] Для k8s-primary: тримати репліки теж у k8s (CloudNativePG)
- [ ] NODE3 використовувати для backup/restore і окремих offline задач
### Qdrant
**Зараз:** 3 інсталяції (k8s + 2 docker)
**Правильно:**
- [ ] Один **prod Qdrant cluster** (Tier A) на NODE1
- [ ] Edge Qdrant (NODE2/3) — лише для локального тесту або кешу, але не "істина"
### Neo4j
**Зараз:** Neo4j на всіх нодах (k8s + docker)
**Рекомендація:**
- [ ] Тримати **один Neo4j** у Tier A (NODE1) як прод
- [ ] NODE2/3 — dev
- [ ] Кластеризацію Neo4j відкласти, поки не буде реальної потреби в HA саме графа
---
## 🔄 Паралельні обчислення між нодами
### A) Control-plane (людський + командний) = Matrix rooms
**Призначення:**
- Команди
- Статуси
- Ручне керування
- Аудит рішень
**НЕ використовується для:**
- Високочастотної job-шини
- Масових обчислень
### B) Data-plane (масові таски, fan-out) = NATS JetStream
**Вибір:** **NATS JetStream** (легкий, швидкий, простіший за Kafka для старту)
**Переваги:**
- Легкий (менше ресурсів)
- Швидкий (low latency)
- Простіший для старту
- Підтримує at-least-once delivery
- Підтримує idempotency keys
### C) Capability registry (хто що вміє) = Consul або Postgres
**Кожен воркер реєструється з capabilities:**
```json
{
"node_id": "node-123",
"tier": "A|B|C",
"region": "eu-west",
"trust_zone": "internal",
"hardware": {
"cpu_cores": 32,
"ram_gb": 128,
"gpu": true,
"gpu_model": "RTX 3090",
"vram_gb": 24,
"cuda_version": "13.0"
},
"capabilities": {
"max_batch": 1000,
"max_tokens": 8192,
"models": ["embed-multilingual-v3.0", "llama3:8b"],
"embedding_dim": 1024
},
"status": "ready|busy|maintenance",
"last_heartbeat": "2026-01-10T19:30:00Z"
}
```
---
## 🔗 Зв'язок Matrix rooms з паралельними воркерами
### Правильний потік:
```
1. Команда/подія → Matrix room (кімната агента або оркестратора)
2. Matrix Gateway (сервіс або модуль у Memory Service)
- RBAC перевірка в Postgres
- Створює Job у NATS (з idempotency key)
3. Воркер на відповідній ноді
- Бере job з NATS
- Виконує задачу
- Пише результат у Postgres/Qdrant/Neo4j
4. Gateway публікує статус назад у Matrix
- Progress + summary → Matrix
- Детальні логи → система логів (Loki)
```
**Результат:** "Безперервний діалог" і керування через Matrix, але обчислення реально паралеляться через чергу.
---
## 📦 Схема черг (NATS JetStream) під Memory Module
### Мінімум 5 потоків:
1. **`mem.embed.online`** — embeddings для діалогів (пріоритет: high)
2. **`mem.embed.offline`** — бекфіл/індексація (пріоритет: low)
3. **`mem.qdrant.upsert`** — запис векторів
4. **`mem.summarize.rollup`** — rolling summaries
5. **`mem.memory.distill`** — витяг фактів у long-term memory
### Формат Job:
```json
{
"job_id": "uuid",
"idempotency_key": "thread-123-embed-v1",
"org_id": "uuid",
"workspace_id": "uuid",
"user_id": "uuid",
"agent_id": "uuid",
"thread_id": "uuid",
"requirements": {
"needs_gpu": true,
"min_vram_gb": 8,
"priority": "high|normal|low",
"max_latency_ms": 5000,
"tier": "A|B|C"
},
"payload_ref": "s3://bucket/job-123.json",
"payload_inline": {...},
"created_at": "2026-01-10T19:30:00Z",
"deadline": "2026-01-10T19:35:00Z"
}
```
---
## 🎚️ Використання різних нод (Tier A/B/C)
### Поточна класифікація:
| Node | Hardware | Tier | Призначення |
|------|----------|------|-------------|
| **NODE1** | RTX 4000 Ada 20GB | **A** | Online critical, primary DB |
| **NODE3** | RTX 3090 24GB | **A/B** | Online + offline, heavy jobs |
| **NODE2** | Apple M4 | **C** | Orchestration/dev/offline prep |
### Розподіл задач:
- **Online embeddings/LLM** → NODE1 + NODE3
- **Offline backfill** → NODE3 + інші GPU edge ноди
- **NODE2** → Orchestration, тестування, підготовка чанків, локальні агентні сесії
---
## 🔐 Embeddings: Cohere vs BGE-M3
### Правило:
**Одна колекція Qdrant = один embedding space** (модель + версія + dims)
### Поточна ситуація:
- **Cohere embed-multilingual-v3.0** (1024 dim) — використовується
### Якщо переходите на BGE-M3:
- [ ] Створити нову колекцію: `memories_bge_m3_v1` (1024 dim)
- [ ] Або додати `model_version` і фізично рознести колекції
- [ ] **НЕ змішувати** embedding-простори в одній колекції
---
## 📋 Наступні 7 кроків (по порядку)
### 1. ✅ Ротація секретів + прибрати креденшали з документів/репо
- [x] Видалено паролі з документів
- [ ] Ротація Cohere API key
- [ ] Ротація паролів Postgres/Neo4j
- [ ] Оновлення в Vault
### 2. ✅ Закрити зовнішній доступ до NodePort
- [x] NodePort закрито для Memory Service NODE1
- [ ] Додати JWT/mTLS auth
- [ ] NetworkPolicy для internal-only
### 3. Підняти NATS JetStream (Tier A)
- [ ] Встановити NATS на NODE1 (K8s)
- [ ] Налаштувати JetStream
- [ ] Створити streams для Memory Module
- [ ] Налаштувати replication (мінімум 3 ноди або 1+backup)
### 4. Додати worker-daemon на кожну ноду
- [ ] Heartbeat до capability registry
- [ ] Capabilities (hardware, models, tier)
- [ ] Підписка на черги NATS
- [ ] Job execution + результат
### 5. Matrix Gateway
- [ ] Команди/статуси ↔ jobs у NATS
- [ ] RBAC перевірка
- [ ] Публікація результатів назад у Matrix
### 6. Рознести embedding-простори
- [ ] Визначити стратегію (Cohere vs BGE-M3)
- [ ] Створити окремі колекції або міграцію
### 7. Postgres: визначити один primary + репліки
- [ ] NODE1 = primary (CloudNativePG)
- [ ] NODE3 = streaming replica (якщо потрібен DR)
- [ ] Backup/restore стратегія
---
## 📁 Структура файлів
```
infrastructure/
├── nats/
│ ├── deployment.yaml # NATS JetStream в K8s
│ ├── streams.yaml # Конфігурація streams
│ └── accounts.yaml # NATS accounts (якщо потрібно)
├── worker-daemon/
│ ├── deployment.yaml # Worker daemon для кожної ноди
│ ├── capability-registry.py # Реєстрація capabilities
│ └── job-executor.py # Виконання jobs
└── matrix-gateway/
├── deployment.yaml # Matrix Gateway service
├── gateway.py # Matrix ↔ NATS bridge
└── rbac.py # RBAC перевірка
```
---
*Документ створено: 2026-01-10 19:30 CET*