update docs

This commit is contained in:
Kohaku-Blueleaf
2025-10-11 22:28:24 +08:00
parent 614211b493
commit a023ba593b
4 changed files with 160 additions and 29 deletions

View File

@@ -22,15 +22,15 @@ graph TB
subgraph "Storage Backend"
LakeFS["LakeFS<br/>- Git-like versioning<br/>- Branch management<br/>- Commit history"]
DB["PostgreSQL/SQLite<br/>- User data<br/>- Metadata<br/>- Deduplication"]
DB["PostgreSQL/SQLite<br/>- User data<br/>- Metadata<br/>- Deduplication<br/>- Synchronous with db.atomic()"]
S3["MinIO/S3<br/>- Object storage<br/>- LFS files<br/>- Presigned URLs"]
end
Client -->|HTTP/Git/LFS| Nginx
Nginx -->|Static files| Client
Nginx -->|/api, /org, resolve| FastAPI
FastAPI -->|REST API| LakeFS
FastAPI -->|Queries| DB
FastAPI -->|REST API (async)| LakeFS
FastAPI -->|Sync queries with db.atomic()| DB
FastAPI -->|Async wrappers| S3
LakeFS -->|Stores objects| S3
@@ -771,6 +771,18 @@ Examples:
LakeFS repo: "hf-dataset-johndoe-dataset"
```
### Implementation Notes
**Database Operations:**
- **Synchronous:** Uses Peewee ORM with synchronous operations
- **Transactions:** `db.atomic()` ensures ACID compliance across concurrent workers
- **Multi-Worker Safe:** Designed for horizontal scaling (4-8 workers recommended)
- **Future:** Migration to peewee-async planned for improved concurrency
**LakeFS Operations:**
- **Pure Async:** All operations use REST API via httpx (no thread pools!)
- **No Deprecated Library:** Uses direct REST API instead of lakefs-client
### Key Operations
**All LakeFS operations use pure async REST API via httpx (no thread pools!):**

View File

@@ -911,9 +911,10 @@ def parse_git_credentials(authorization: str | None) -> tuple[str | None, str |
### Token Validation
```python
from datetime import datetime, timezone
from kohakuhub.auth.utils import hash_token
from kohakuhub.db import Token, User
from kohakuhub.db_async import execute_db_query
from kohakuhub.db import Token, User, db
async def get_user_from_git_auth(authorization: str | None) -> User | None:
"""Authenticate user from Git Basic Auth."""
@@ -924,31 +925,22 @@ async def get_user_from_git_auth(authorization: str | None) -> User | None:
# Hash and lookup token
token_hash = hash_token(token_str)
def _get_token():
return Token.get_or_none(Token.token_hash == token_hash)
# Database operations are synchronous with transactions
with db.atomic():
token = Token.get_or_none(Token.token_hash == token_hash)
if not token:
return None
token = await execute_db_query(_get_token)
if not token:
return None
# Get user
user = User.get_or_none(User.id == token.user_id)
if not user or not user.is_active:
return None
# Get user
def _get_user():
return User.get_or_none(User.id == token.user_id)
user = await execute_db_query(_get_user)
if not user or not user.is_active:
return None
# Update last used
from datetime import datetime, timezone
def _update_token():
# Update last used
Token.update(last_used=datetime.now(timezone.utc)).where(
Token.id == token.id
).execute()
await execute_db_query(_update_token)
return user
```
@@ -1032,12 +1024,12 @@ async def git_head(
Since we don't know if a repo is a model/dataset/space from the URL alone:
```python
from kohakuhub.db import Repository
from kohakuhub.db_async import execute_db_query
from kohakuhub.db import Repository, db
async def find_repository(namespace: str, name: str) -> Repository | None:
"""Find repository by trying all types."""
def _get_repo():
# Database operations are synchronous
with db.atomic():
for repo_type in ["model", "dataset", "space"]:
repo = Repository.get_or_none(
Repository.namespace == namespace,
@@ -1047,8 +1039,6 @@ async def find_repository(namespace: str, name: str) -> Repository | None:
if repo:
return repo
return None
return await execute_db_query(_get_repo)
```
### Registering the Router

View File

@@ -181,7 +181,11 @@ npm run dev --prefix ./src/kohaku-hub-ui
**Backend** (port 48888):
```bash
# Single worker (development with hot reload)
uvicorn kohakuhub.main:app --reload --port 48888
# Multi-worker (production-like testing)
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
```
**Client Access:**
@@ -200,6 +204,69 @@ uvicorn kohakuhub.main:app --reload --port 48888
- **Everything:** http://localhost:28080 (Web UI + API)
- Swagger Docs (dev): http://localhost:48888/docs (if port exposed)
## Multi-Worker Deployment
KohakuHub supports horizontal scaling with multiple worker processes.
### Database Architecture
**Synchronous Database Operations:**
- Uses Peewee ORM with synchronous operations
- `db.atomic()` transactions ensure consistency across workers
- No async database wrappers needed
- Safe for multi-worker deployments
**Why Synchronous?**
- PostgreSQL and SQLite handle concurrent connections internally
- Atomic transactions prevent race conditions
- Simpler code without async/await complexity
- Better compatibility with multi-worker setups
**Future:** Migration to peewee-async is planned for improved concurrency.
### Running Multi-Worker
**Development/Testing:**
```bash
# 4 workers (recommended for testing)
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
# 8 workers (production-like load)
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 8
```
**Docker Deployment:**
```yaml
# docker-compose.yml
services:
hub-api:
command: uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
```
### Worker Recommendations
| Deployment | Workers | CPU | Memory | Notes |
|------------|---------|-----|--------|-------|
| Development | 1 | 2 cores | 2GB | Hot reload enabled |
| Small | 2-4 | 4 cores | 4GB | For <100 users |
| Medium | 4-8 | 8 cores | 8GB | For <1000 users |
| Large | 8-16 | 16+ cores | 16GB+ | For >1000 users |
**Formula:** Workers = (2 × CPU cores) + 1
### Benefits of Multi-Worker
1. **Horizontal Scaling:** Handle more concurrent requests
2. **High Availability:** Worker crashes don't affect others
3. **Better Resource Utilization:** Leverage multiple CPU cores
4. **Load Distribution:** Requests distributed across workers
### Limitations
- Cannot use `--reload` with multiple workers
- Shared state must use database or external cache
- Log aggregation recommended for debugging
## Security Best Practices
### Production Deployment

View File

@@ -305,6 +305,68 @@ docker-compose up -d --build
**Note:** Check CHANGELOG for breaking changes before updating.
## Multi-Worker Deployment
For production deployments, running multiple workers improves performance and availability.
### Database Architecture
KohakuHub uses **synchronous database operations** with Peewee ORM:
- `db.atomic()` transactions ensure data consistency
- Safe for concurrent access from multiple workers
- PostgreSQL and SQLite handle connection pooling internally
- No async database wrappers needed
**Future:** Migration to peewee-async planned for better concurrency.
### Running with Multiple Workers
**Development Testing:**
```bash
# 4 workers (recommended for testing)
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
# Test with load
ab -n 1000 -c 10 http://localhost:48888/health
```
**Docker Deployment:**
Edit your `docker-compose.yml`:
```yaml
services:
hub-api:
image: kohakuhub-api
command: uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
environment:
- KOHAKU_HUB_BASE_URL=http://localhost:28080
# ... other env vars
```
### Worker Scaling Guide
| Deployment Size | Workers | CPU Cores | Memory | Concurrent Users |
|----------------|---------|-----------|--------|------------------|
| Development | 1 | 2 | 2GB | <10 |
| Small | 2-4 | 4 | 4GB | <100 |
| Medium | 4-8 | 8 | 8GB | <1000 |
| Large | 8-16 | 16+ | 16GB+ | >1000 |
**Recommended Formula:** Workers = (2 × CPU cores) + 1
### Benefits
- **Horizontal Scaling:** Handle more concurrent requests
- **High Availability:** One worker crash doesn't affect others
- **CPU Utilization:** Leverage multiple cores efficiently
- **Load Balancing:** Uvicorn distributes requests automatically
### Limitations
- Cannot use `--reload` flag with multiple workers
- In-memory caches are per-worker (use Redis for shared cache)
- Log output from all workers (use log aggregation)
## Uninstall
```bash