feat: 重构 Docker 配置结构,添加 compute 模块及新增文档
- 将 Dockerfile 和 docker-compose.yml 迁移至 docker/ 目录下统一管理 - 新增 compute 计算模块(API 入口、依赖配置) - 新增 docker/app 和 docker/compute 部署配置 - 新增 demo-development-plan.md 演示开发计划文档 - 更新后端 API 设计、部署计划、架构需求等文档 - 更新 postgres 数据库 schema Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1147,6 +1147,116 @@ CREATE INDEX IF NOT EXISTS idx_gpu_allocations_scope ON gpu_allocations(tenant_i
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_gpu_allocations_active_gpu
|
||||
ON gpu_allocations(gpu_device_id) WHERE released_at IS NULL;
|
||||
|
||||
-- Multi compute-node scheduling and local-cache metadata.
|
||||
-- Each GPU server is modeled as one compute node. Nodes do not call each other;
|
||||
-- the application platform schedules jobs and syncs resources through each node's File Gateway.
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS file_gateway_url text;
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS enabled boolean NOT NULL DEFAULT true;
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS scheduler_status varchar(40) NOT NULL DEFAULT 'online';
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS scheduler_weight integer NOT NULL DEFAULT 100 CHECK (scheduler_weight >= 0);
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS tags text[] NOT NULL DEFAULT '{}';
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS service_token_encrypted text;
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS data_root text NOT NULL DEFAULT '/data/yg-ft';
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS model_root text NOT NULL DEFAULT '/data/yg-ft/models';
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS log_root text NOT NULL DEFAULT '/opt/yg-ft/logs/compute';
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS max_parallel_jobs integer NOT NULL DEFAULT 1 CHECK (max_parallel_jobs >= 0);
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS current_running_jobs integer NOT NULL DEFAULT 0 CHECK (current_running_jobs >= 0);
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS last_health_check_at timestamptz;
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS health_detail jsonb NOT NULL DEFAULT '{}'::jsonb;
|
||||
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS drain_reason text;
|
||||
CREATE INDEX IF NOT EXISTS idx_compute_nodes_scheduler
|
||||
ON compute_nodes(enabled, scheduler_status, scheduler_weight DESC, last_health_check_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_compute_nodes_tags_gin
|
||||
ON compute_nodes USING gin(tags);
|
||||
|
||||
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS scheduler_mode varchar(40) NOT NULL DEFAULT 'auto';
|
||||
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS requested_node_id uuid REFERENCES compute_nodes(id) ON DELETE SET NULL;
|
||||
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS assigned_at timestamptz;
|
||||
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS scheduler_reason text;
|
||||
CREATE INDEX IF NOT EXISTS idx_compute_jobs_requested_node
|
||||
ON compute_jobs(requested_node_id, status, created_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS compute_node_engines (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
compute_node_id uuid NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE,
|
||||
engine_id uuid REFERENCES training_engines(id) ON DELETE SET NULL,
|
||||
engine_code varchar(80) NOT NULL,
|
||||
engine_version varchar(80),
|
||||
home_path text,
|
||||
status varchar(40) NOT NULL DEFAULT 'available',
|
||||
capability jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
last_health_check_at timestamptz,
|
||||
health_detail jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (compute_node_id, engine_code)
|
||||
);
|
||||
SELECT touch_updated_at('compute_node_engines');
|
||||
CREATE INDEX IF NOT EXISTS idx_compute_node_engines_node_status
|
||||
ON compute_node_engines(compute_node_id, status, engine_code);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS resource_replicas (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id uuid REFERENCES tenants(id) ON DELETE SET NULL,
|
||||
project_id uuid REFERENCES projects(id) ON DELETE SET NULL,
|
||||
resource_type varchar(80) NOT NULL,
|
||||
resource_id uuid NOT NULL,
|
||||
storage_object_id uuid REFERENCES storage_objects(id) ON DELETE SET NULL,
|
||||
compute_node_id uuid NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE,
|
||||
local_path text NOT NULL,
|
||||
status varchar(40) NOT NULL DEFAULT 'available',
|
||||
sync_status varchar(40) NOT NULL DEFAULT 'synced',
|
||||
checksum_sha256 char(64),
|
||||
byte_size bigint NOT NULL DEFAULT 0 CHECK (byte_size >= 0),
|
||||
version varchar(120),
|
||||
pinned boolean NOT NULL DEFAULT false,
|
||||
last_verified_at timestamptz,
|
||||
expires_at timestamptz,
|
||||
failure_reason text,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (resource_type, resource_id, compute_node_id)
|
||||
);
|
||||
SELECT touch_updated_at('resource_replicas');
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_replicas_resource
|
||||
ON resource_replicas(resource_type, resource_id, status);
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_replicas_node_status
|
||||
ON resource_replicas(compute_node_id, status, sync_status, updated_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_replicas_scope
|
||||
ON resource_replicas(tenant_id, project_id, resource_type, updated_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS resource_sync_jobs (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id uuid REFERENCES tenants(id) ON DELETE SET NULL,
|
||||
project_id uuid REFERENCES projects(id) ON DELETE SET NULL,
|
||||
target_compute_node_id uuid NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE,
|
||||
source_compute_node_id uuid REFERENCES compute_nodes(id) ON DELETE SET NULL,
|
||||
resource_type varchar(80) NOT NULL,
|
||||
resource_id uuid NOT NULL,
|
||||
storage_object_id uuid REFERENCES storage_objects(id) ON DELETE SET NULL,
|
||||
status task_status NOT NULL DEFAULT 'pending',
|
||||
transfer_mode varchar(40) NOT NULL DEFAULT 'app_proxy',
|
||||
source_uri text,
|
||||
target_path text NOT NULL,
|
||||
byte_size bigint NOT NULL DEFAULT 0 CHECK (byte_size >= 0),
|
||||
checksum_sha256 char(64),
|
||||
progress numeric(5,2) NOT NULL DEFAULT 0 CHECK (progress >= 0 AND progress <= 100),
|
||||
failure_reason text,
|
||||
requested_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
||||
started_at timestamptz,
|
||||
completed_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
SELECT touch_updated_at('resource_sync_jobs');
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_sync_jobs_status
|
||||
ON resource_sync_jobs(status, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_sync_jobs_target
|
||||
ON resource_sync_jobs(target_compute_node_id, status, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_sync_jobs_resource
|
||||
ON resource_sync_jobs(resource_type, resource_id, status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS resource_acl (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id uuid REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
|
||||
Reference in New Issue
Block a user