- K8s deployment (2 replicas, PVC, initContainer для server_name) - Streams definitions (MM_ONLINE, MM_OFFLINE, MM_WRITE, MM_EVENTS) - Job payload schema (JSON v1 з idempotency) - Worker contract (capabilities + ack/retry) - Init streams script - Оновлено ARCHITECTURE-150-NODES.md (Control-plane vs Data-plane) TODO: Auth (nkeys), 3+ replicas для prod, worker-daemon implementation
165 lines
4.1 KiB
Markdown
165 lines
4.1 KiB
Markdown
# Worker Contract v1 — Memory Module
|
||
|
||
**Дата:** 2026-01-10
|
||
**Версія:** 1.0.0
|
||
|
||
---
|
||
|
||
## 📋 Capability Registry
|
||
|
||
Кожен воркер реєструється з наступними 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,
|
||
"supported_jobs": ["embed", "summarize", "index"]
|
||
},
|
||
"status": "ready|busy|maintenance",
|
||
"last_heartbeat": "2026-01-10T19:30:00Z"
|
||
}
|
||
```
|
||
|
||
### Реєстрація
|
||
|
||
- **Postgres** (таблиця `worker_capabilities`) або **Consul** (KV store)
|
||
- Heartbeat кожні 30 секунд
|
||
- Якщо heartbeat пропущено > 90 секунд → worker вважається offline
|
||
|
||
---
|
||
|
||
## 🔄 Job Execution Flow
|
||
|
||
### 1. Pull Model
|
||
|
||
Воркер сам вирішує "чи брати job":
|
||
- Підписка на consumer (durable)
|
||
- Перевірка `requirements` vs власні `capabilities`
|
||
- Якщо підходить → бере job, інакше пропускає
|
||
|
||
### 2. Execution
|
||
|
||
```python
|
||
async def execute_job(job: JobPayload):
|
||
# 1. Перевірка requirements
|
||
if not can_fulfill(job.requirements, my_capabilities):
|
||
await msg.nak() # Negative ack, не підходить
|
||
return
|
||
|
||
# 2. Виконання
|
||
try:
|
||
result = await process_job(job)
|
||
|
||
# 3. Запис результату
|
||
await write_result(job, result)
|
||
|
||
# 4. ACK
|
||
await msg.ack()
|
||
|
||
except RetryableError as e:
|
||
await msg.nak(delay=e.backoff)
|
||
except FatalError as e:
|
||
await msg.ack() # ACK щоб не retry
|
||
await log_error(job, e)
|
||
```
|
||
|
||
### 3. ACK/NAK Policy
|
||
|
||
- **ACK** — job виконано успішно
|
||
- **NAK** — job не виконано, потрібен retry
|
||
- **NAK(delay)** — retry з затримкою
|
||
- **Timeout** — якщо `ack_wait` вийшов → автоматичний retry
|
||
|
||
---
|
||
|
||
## 📊 Consumer Policies
|
||
|
||
### Online Consumer (Tier A)
|
||
|
||
```yaml
|
||
stream: MM_ONLINE
|
||
consumer: online-worker-tier-a
|
||
ack_wait: 30s
|
||
max_ack_pending: 5000
|
||
concurrency: 50-200 (per worker)
|
||
filter: tier=A AND needs_gpu=true (для GPU jobs)
|
||
```
|
||
|
||
**Worker Selection:**
|
||
- Тільки `tier=A`
|
||
- `needs_gpu=true` → тільки GPU воркери
|
||
- `max_latency_ms` перевірка
|
||
|
||
### Offline Consumer (Tier B)
|
||
|
||
```yaml
|
||
stream: MM_OFFLINE
|
||
consumer: offline-worker-tier-b
|
||
ack_wait: 5-30 min
|
||
max_ack_pending: 10000
|
||
concurrency: висока, але з backpressure
|
||
```
|
||
|
||
**Backpressure:**
|
||
- Якщо online backlog росте → обмежити offline concurrency
|
||
- Preemption: offline jobs можуть бути призупинені для online
|
||
|
||
---
|
||
|
||
## 🔍 Idempotency
|
||
|
||
**Обов'язково:** кожен job має `idempotency_key` (SHA256 hash).
|
||
|
||
**Перевірка:**
|
||
- Перед виконанням перевірити в Postgres: чи вже виконано?
|
||
- Якщо так → повернути кешований результат
|
||
- Якщо ні → виконати та зберегти результат
|
||
|
||
**TTL:** idempotency keys зберігаються 7 днів.
|
||
|
||
---
|
||
|
||
## 📈 Metrics & Alerts
|
||
|
||
### Worker Metrics
|
||
|
||
- `worker_jobs_processed_total{type, status}`
|
||
- `worker_job_duration_seconds{type, quantile}`
|
||
- `worker_gpu_utilization{node_id}`
|
||
- `worker_vram_usage_bytes{node_id}`
|
||
- `worker_errors_total{type, error_type}`
|
||
|
||
### NATS Metrics
|
||
|
||
- `nats_consumer_lag{stream, consumer}`
|
||
- `nats_redeliveries_total{stream}`
|
||
- `nats_ack_pending{stream, consumer}`
|
||
- `nats_stream_storage_bytes{stream}`
|
||
|
||
### Alerts → Matrix Ops Room
|
||
|
||
- `MM_ONLINE backlog > 1000` (SLO порушення)
|
||
- `redeliveries spike > 100/min`
|
||
- `embed p95 > 500ms` (target: 300ms)
|
||
- `disk > 80%` на JetStream PVC
|
||
- `worker offline > 2 min` (Tier A)
|
||
|
||
---
|
||
|
||
*Документ створено: 2026-01-10 19:30 CET*
|