Phase 8 Production Hardening with complete governance infrastructure: - Vault integration with tiered policies (T0-T4) - DragonflyDB state management - SQLite audit ledger - Pipeline DSL and templates - Promotion/revocation engine - Checkpoint system for session persistence - Health manager and circuit breaker for fault tolerance - GitHub/Slack integrations - Architectural test pipeline with bug watcher, suggestion engine, council review - Multi-agent chaos testing framework Test Results: - Governance tests: 68/68 passing - E2E workflow: 16/16 passing - Phase 2 Vault: 14/14 passing - Integration tests: 27/27 passing Coverage: 57.6% average across 12 phases Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
404 lines
15 KiB
JSON
404 lines
15 KiB
JSON
{
|
|
"plan_id": "plan-20260123-214700-spark-logging-pipeline",
|
|
"title": "Spark Cluster Logging Aggregation Pipeline",
|
|
"description": "Production-grade logging aggregation system for Spark cluster using Lambda architecture with Kafka, Flink, and ClickHouse",
|
|
"version": "1.0.0",
|
|
"type": "ground_truth",
|
|
"target": "localhost",
|
|
"source": {
|
|
"generated_by": "multi-agent-orchestrator",
|
|
"task_id": "task-zfwla3-mkretltd",
|
|
"model": "anthropic/claude-sonnet-4",
|
|
"proposal_id": "t2aiqzohmkreue73",
|
|
"evaluation": {
|
|
"score": 0.85,
|
|
"feasibility": 0.88,
|
|
"completeness": 0.82,
|
|
"evaluator": "BETA"
|
|
}
|
|
},
|
|
"architecture": {
|
|
"pattern": "Lambda Architecture",
|
|
"components": {
|
|
"ingestion": {
|
|
"technology": "Apache Kafka",
|
|
"purpose": "High-throughput log ingestion with partitioning",
|
|
"features": ["Schema Registry", "Topic-per-source", "Compression"]
|
|
},
|
|
"stream_processing": {
|
|
"technology": "Apache Flink",
|
|
"purpose": "Real-time processing, enrichment, and transformation",
|
|
"features": ["Checkpointing", "Exactly-once semantics", "Backpressure handling"]
|
|
},
|
|
"storage": {
|
|
"technology": "ClickHouse",
|
|
"purpose": "Columnar storage optimized for analytics queries",
|
|
"features": ["Materialized views", "ReplicatedMergeTree", "Tiered storage"]
|
|
},
|
|
"schema_management": {
|
|
"technology": "Confluent Schema Registry",
|
|
"purpose": "Schema evolution and format governance",
|
|
"formats": ["JSON", "Avro", "Protobuf"]
|
|
}
|
|
}
|
|
},
|
|
"requirements": {
|
|
"performance": {
|
|
"query_latency": "<100ms",
|
|
"ingestion_throughput": "high-volume",
|
|
"data_freshness": "near-real-time"
|
|
},
|
|
"constraints": [
|
|
"Must use open-source technologies where possible",
|
|
"Latency < 100ms for query responses",
|
|
"Support for multiple data formats (JSON, Avro, Protobuf)",
|
|
"Cost-effective for variable workloads"
|
|
],
|
|
"success_criteria": [
|
|
"Complete architecture design with component diagrams",
|
|
"Data flow specifications",
|
|
"Scalability analysis",
|
|
"Fault tolerance mechanisms documented",
|
|
"Cost estimation provided"
|
|
]
|
|
},
|
|
"phases": [
|
|
{
|
|
"phase_id": "phase-1-ingestion",
|
|
"name": "Design High-Performance Ingestion Layer",
|
|
"complexity": "high",
|
|
"estimated_effort": "3-4 days",
|
|
"owner": "ALPHA",
|
|
"key_decisions": [
|
|
"Partitioning strategy",
|
|
"Schema registry setup",
|
|
"Format conversion pipeline"
|
|
],
|
|
"steps": [
|
|
{
|
|
"step_id": "1.1",
|
|
"action": "deploy_kafka",
|
|
"description": "Deploy Kafka cluster with Zookeeper",
|
|
"command": "docker-compose -f kafka-cluster.yml up -d",
|
|
"artifacts": ["kafka-cluster.yml"]
|
|
},
|
|
{
|
|
"step_id": "1.2",
|
|
"action": "deploy_schema_registry",
|
|
"description": "Deploy Confluent Schema Registry",
|
|
"command": "docker run -d --name schema-registry --network spark-net -p 8081:8081 -e SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS=kafka:9092 confluentinc/cp-schema-registry:latest"
|
|
},
|
|
{
|
|
"step_id": "1.3",
|
|
"action": "create_topics",
|
|
"description": "Create Kafka topics for Spark logs",
|
|
"command": "kafka-topics.sh --create --topic spark-driver-logs --partitions 12 --replication-factor 2 --bootstrap-server localhost:9092"
|
|
},
|
|
{
|
|
"step_id": "1.4",
|
|
"action": "configure_spark_log_forwarding",
|
|
"description": "Configure Spark to forward logs to Kafka",
|
|
"config": {
|
|
"spark.driver.extraJavaOptions": "-Dlog4j.configuration=file:/opt/spark/conf/log4j-kafka.properties",
|
|
"spark.executor.extraJavaOptions": "-Dlog4j.configuration=file:/opt/spark/conf/log4j-kafka.properties"
|
|
}
|
|
}
|
|
],
|
|
"verification": {
|
|
"command": "kafka-console-consumer.sh --topic spark-driver-logs --bootstrap-server localhost:9092 --max-messages 5",
|
|
"expected": "Log messages flowing"
|
|
}
|
|
},
|
|
{
|
|
"phase_id": "phase-2-storage",
|
|
"name": "Optimize Storage and Query Performance",
|
|
"complexity": "high",
|
|
"estimated_effort": "4-5 days",
|
|
"owner": "ALPHA",
|
|
"key_decisions": [
|
|
"Storage engine selection",
|
|
"Index design",
|
|
"Query routing logic"
|
|
],
|
|
"steps": [
|
|
{
|
|
"step_id": "2.1",
|
|
"action": "deploy_clickhouse",
|
|
"description": "Deploy ClickHouse cluster",
|
|
"command": "docker run -d --name clickhouse-server --network spark-net -p 8123:8123 -p 9000:9000 -v clickhouse-data:/var/lib/clickhouse clickhouse/clickhouse-server:latest"
|
|
},
|
|
{
|
|
"step_id": "2.2",
|
|
"action": "create_log_table",
|
|
"description": "Create optimized log table with ReplicatedMergeTree",
|
|
"sql": "CREATE TABLE spark_logs (timestamp DateTime64(3), level String, logger String, message String, spark_app_id String, executor_id String, host String) ENGINE = MergeTree() PARTITION BY toYYYYMMDD(timestamp) ORDER BY (spark_app_id, timestamp) TTL timestamp + INTERVAL 30 DAY"
|
|
},
|
|
{
|
|
"step_id": "2.3",
|
|
"action": "create_materialized_views",
|
|
"description": "Create materialized views for common query patterns",
|
|
"sql": "CREATE MATERIALIZED VIEW spark_logs_by_level ENGINE = SummingMergeTree() ORDER BY (level, toStartOfHour(timestamp)) AS SELECT level, toStartOfHour(timestamp) as hour, count() as count FROM spark_logs GROUP BY level, hour"
|
|
},
|
|
{
|
|
"step_id": "2.4",
|
|
"action": "configure_tiered_storage",
|
|
"description": "Configure hot-warm-cold tiered storage",
|
|
"config": {
|
|
"hot_tier": "7 days on NVMe SSD",
|
|
"warm_tier": "30 days on SSD",
|
|
"cold_tier": "90+ days on S3/object storage"
|
|
}
|
|
}
|
|
],
|
|
"verification": {
|
|
"command": "clickhouse-client --query 'SELECT count() FROM spark_logs'",
|
|
"expected": "Query returns in <100ms"
|
|
}
|
|
},
|
|
{
|
|
"phase_id": "phase-3-processing",
|
|
"name": "Implement Real-time Processing Pipeline",
|
|
"complexity": "medium-high",
|
|
"estimated_effort": "3-4 days",
|
|
"owner": "BETA",
|
|
"key_decisions": [
|
|
"Processing framework choice",
|
|
"State management",
|
|
"Backpressure handling"
|
|
],
|
|
"steps": [
|
|
{
|
|
"step_id": "3.1",
|
|
"action": "deploy_flink",
|
|
"description": "Deploy Apache Flink cluster",
|
|
"command": "docker run -d --name flink-jobmanager --network spark-net -p 8082:8081 flink:latest jobmanager"
|
|
},
|
|
{
|
|
"step_id": "3.2",
|
|
"action": "deploy_flink_taskmanager",
|
|
"description": "Deploy Flink TaskManager",
|
|
"command": "docker run -d --name flink-taskmanager --network spark-net flink:latest taskmanager"
|
|
},
|
|
{
|
|
"step_id": "3.3",
|
|
"action": "deploy_log_processor_job",
|
|
"description": "Deploy Flink job for log processing",
|
|
"job_config": {
|
|
"source": "Kafka spark-driver-logs topic",
|
|
"transformations": [
|
|
"Parse log format",
|
|
"Extract structured fields",
|
|
"Enrich with metadata",
|
|
"Handle format conversion (JSON/Avro/Protobuf)"
|
|
],
|
|
"sink": "ClickHouse spark_logs table",
|
|
"checkpointing": "10 seconds",
|
|
"parallelism": 4
|
|
}
|
|
}
|
|
],
|
|
"verification": {
|
|
"command": "curl http://localhost:8082/jobs",
|
|
"expected": "Log processor job RUNNING"
|
|
}
|
|
},
|
|
{
|
|
"phase_id": "phase-4-fault-tolerance",
|
|
"name": "Implement Comprehensive Fault Tolerance",
|
|
"complexity": "medium-high",
|
|
"estimated_effort": "3-4 days",
|
|
"owner": "BETA",
|
|
"key_decisions": [
|
|
"Replication strategies",
|
|
"Failure detection",
|
|
"Recovery procedures"
|
|
],
|
|
"steps": [
|
|
{
|
|
"step_id": "4.1",
|
|
"action": "configure_kafka_replication",
|
|
"description": "Configure Kafka replication and ISR",
|
|
"config": {
|
|
"replication.factor": 2,
|
|
"min.insync.replicas": 1,
|
|
"unclean.leader.election.enable": false
|
|
}
|
|
},
|
|
{
|
|
"step_id": "4.2",
|
|
"action": "configure_flink_checkpointing",
|
|
"description": "Enable Flink checkpointing for exactly-once",
|
|
"config": {
|
|
"execution.checkpointing.interval": "10s",
|
|
"execution.checkpointing.mode": "EXACTLY_ONCE",
|
|
"state.backend": "rocksdb",
|
|
"state.checkpoints.dir": "file:///opt/flink/checkpoints"
|
|
}
|
|
},
|
|
{
|
|
"step_id": "4.3",
|
|
"action": "configure_clickhouse_replication",
|
|
"description": "Configure ClickHouse replication",
|
|
"config": {
|
|
"engine": "ReplicatedMergeTree",
|
|
"zookeeper_path": "/clickhouse/tables/{shard}/spark_logs",
|
|
"replica_name": "{replica}"
|
|
}
|
|
},
|
|
{
|
|
"step_id": "4.4",
|
|
"action": "setup_dead_letter_queue",
|
|
"description": "Create DLQ for failed log entries",
|
|
"command": "kafka-topics.sh --create --topic spark-logs-dlq --partitions 3 --replication-factor 2 --bootstrap-server localhost:9092"
|
|
}
|
|
],
|
|
"verification": {
|
|
"test": "Kill one Kafka broker, verify no data loss",
|
|
"expected": "System continues processing with <5s recovery"
|
|
}
|
|
},
|
|
{
|
|
"phase_id": "phase-5-scaling",
|
|
"name": "Design Cost-Effective Scaling Strategy",
|
|
"complexity": "medium",
|
|
"estimated_effort": "2-3 days",
|
|
"owner": "BETA",
|
|
"key_decisions": [
|
|
"Tiering policies",
|
|
"Auto-scaling triggers",
|
|
"Resource allocation"
|
|
],
|
|
"steps": [
|
|
{
|
|
"step_id": "5.1",
|
|
"action": "configure_autoscaling",
|
|
"description": "Configure Kubernetes HPA for Flink",
|
|
"config": {
|
|
"min_replicas": 2,
|
|
"max_replicas": 10,
|
|
"target_cpu_utilization": 70,
|
|
"scale_up_stabilization": "60s",
|
|
"scale_down_stabilization": "300s"
|
|
}
|
|
},
|
|
{
|
|
"step_id": "5.2",
|
|
"action": "configure_kafka_tiering",
|
|
"description": "Enable Kafka tiered storage",
|
|
"config": {
|
|
"remote.log.storage.system.enable": true,
|
|
"remote.log.storage.manager.class.name": "org.apache.kafka.server.log.remote.storage.LocalTieredStorage",
|
|
"local.retention.ms": 86400000
|
|
}
|
|
},
|
|
{
|
|
"step_id": "5.3",
|
|
"action": "setup_monitoring",
|
|
"description": "Deploy Prometheus + Grafana monitoring",
|
|
"dashboards": [
|
|
"Kafka lag per topic/partition",
|
|
"Flink throughput and backpressure",
|
|
"ClickHouse query latency p50/p95/p99",
|
|
"Storage utilization per tier"
|
|
]
|
|
}
|
|
],
|
|
"verification": {
|
|
"test": "Generate 10x load spike",
|
|
"expected": "System scales up within 2 minutes, scales down within 10 minutes"
|
|
}
|
|
}
|
|
],
|
|
"rollback_strategy": {
|
|
"checkpoints": [
|
|
"After each phase completion",
|
|
"Before any destructive operation"
|
|
],
|
|
"procedures": [
|
|
{
|
|
"trigger": "Kafka cluster failure",
|
|
"action": "Failover to standby cluster, replay from checkpoint"
|
|
},
|
|
{
|
|
"trigger": "Flink job failure",
|
|
"action": "Restart from last checkpoint, resume processing"
|
|
},
|
|
{
|
|
"trigger": "ClickHouse corruption",
|
|
"action": "Restore from replica, rebuild materialized views"
|
|
},
|
|
{
|
|
"trigger": "Full system rollback",
|
|
"action": "Stop all components, restore from backup, replay Kafka from offset"
|
|
}
|
|
]
|
|
},
|
|
"monitoring": {
|
|
"metrics": [
|
|
{
|
|
"name": "ingestion_lag",
|
|
"source": "Kafka consumer lag",
|
|
"threshold": "<1000 messages",
|
|
"alert": "PagerDuty if >5000 for 5 minutes"
|
|
},
|
|
{
|
|
"name": "query_latency_p99",
|
|
"source": "ClickHouse query logs",
|
|
"threshold": "<100ms",
|
|
"alert": "Slack if >200ms for 1 minute"
|
|
},
|
|
{
|
|
"name": "processing_throughput",
|
|
"source": "Flink metrics",
|
|
"threshold": ">10000 events/sec",
|
|
"alert": "Email if <5000 for 10 minutes"
|
|
}
|
|
],
|
|
"dashboards": [
|
|
"System Overview",
|
|
"Kafka Health",
|
|
"Flink Jobs",
|
|
"ClickHouse Performance",
|
|
"Cost Analysis"
|
|
]
|
|
},
|
|
"cost_estimation": {
|
|
"infrastructure": {
|
|
"kafka_cluster": "$200-400/month (3 brokers)",
|
|
"flink_cluster": "$150-300/month (1 JM + 2 TM)",
|
|
"clickhouse_cluster": "$300-600/month (3 nodes)",
|
|
"monitoring": "$50-100/month"
|
|
},
|
|
"total_monthly": "$700-1400",
|
|
"optimization_notes": [
|
|
"Use spot instances for Flink TaskManagers",
|
|
"Tiered storage reduces ClickHouse costs by 40%",
|
|
"Auto-scaling minimizes idle capacity"
|
|
]
|
|
},
|
|
"strengths": [
|
|
"Excellent technology selection - Kafka/Flink/ClickHouse is a proven stack for log analytics",
|
|
"Sub-100ms query performance through ClickHouse's columnar engine and materialized views",
|
|
"Comprehensive tiered storage strategy optimizes costs while maintaining performance",
|
|
"Schema Registry integration provides robust data governance and evolution",
|
|
"Strong fault tolerance with Kafka replication and Flink checkpointing",
|
|
"Auto-scaling capabilities address variable load patterns effectively",
|
|
"Unified query API abstracts complexity from end users"
|
|
],
|
|
"known_limitations": [
|
|
"Lambda architecture complexity requires significant DevOps expertise",
|
|
"Data consistency reconciliation between real-time and batch layers needs monitoring",
|
|
"Flink memory management under high throughput scenarios needs careful tuning"
|
|
],
|
|
"implementation_notes": "Start with a pilot deployment focusing on a single log source to validate the architecture. Implement comprehensive monitoring before scaling. Pay special attention to Flink job tuning and ClickHouse table engine selection. Consider using ClickHouse's ReplicatedMergeTree for high availability. Plan for gradual migration from existing systems with parallel running during transition period.",
|
|
"created_at": "2026-01-23T21:47:00.000000+00:00",
|
|
"agent_id": "tier0-agent-001",
|
|
"agent_tier": 0,
|
|
"status": "approved",
|
|
"requires_approval": true,
|
|
"approved_by": "multi-agent-consensus",
|
|
"executed": false,
|
|
"priority": "high",
|
|
"tags": ["spark", "logging", "kafka", "flink", "clickhouse", "lambda-architecture", "ground-truth"]
|
|
}
|