diff --git a/.gitignore b/.gitignore index 3a95811..d27d9f8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ kvctl server kvctl-new kasoku-server-new +bin/ # Benchmarks (compiled) bench @@ -91,6 +92,9 @@ temp/ Thumbs.db desktop.ini +# IDE/Qwen settings +.qwen/ + # Debug files *.pdb *.idb diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index a071768..ac0c4d5 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -29,35 +29,37 @@ curl http://localhost:9000/health ## Docker Deployment +All Docker files are in `deploy/` directory. + ### Single Node ```bash # Build and run -docker build -t kasoku . +docker build -t kasoku ./deploy docker run -p 9000:9000 kasoku # Or use docker-compose -docker-compose -f docker-compose.single.yml up -d +docker-compose -f deploy/docker-compose.single.yml up -d ``` ### 3-Node Cluster ```bash # Build and start cluster -docker-compose -f docker-compose.yml up -d +docker-compose -f deploy/docker-compose.yml up -d # Check status -docker-compose ps +docker-compose -f deploy/docker-compose.yml ps # View logs -docker-compose logs -f kasoku-node1 +docker-compose -f deploy/docker-compose.yml logs -f kasoku-node1 ``` ### With Monitoring ```bash # Start with Prometheus + Grafana -docker-compose -f docker-compose.yml --profile monitoring up -d +docker-compose -f deploy/docker-compose.yml --profile monitoring up -d # Access services: # - Kasoku: http://localhost:9001, :9002, :9003 diff --git a/bench b/bench deleted file mode 100755 index e95a887..0000000 Binary files a/bench and /dev/null differ diff --git a/bench_results_cluster_batch.txt b/bench_results_cluster_batch.txt deleted file mode 100644 index 012a4e5..0000000 --- a/bench_results_cluster_batch.txt +++ /dev/null @@ -1,96 +0,0 @@ - -╔══════════════════════════════════════════════════════╗ -║ KASOKU — DynamoDB-Style Pressure Benchmark ║ -╚══════════════════════════════════════════════════════╝ - - Nodes : http://localhost:9000 http://localhost:9001 http://localhost:9002 - Workers : 10 goroutines - Batch size : 50 keys/request - Write phase: 20s - Read phase : 20s - -▸ Phase 1 — Write-Only (warming 5s...) - Seeded 450 keys. Starting write measurement... - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  28800  p50 20µs p99 442µs - 2  242400  p50 21µs p99 398µs - 3  182250  p50 22µs p99 473µs - 4  10000  p50 22µs p99 531µs - 5  25300  p50 23µs p99 671µs - 6  22400  p50 24µs p99 831µs - 7  5900  p50 24µs p99 859µs - 8  63500  p50 25µs p99 1.08ms - 9  60250  p50 26µs p99 1.15ms - 10  81950  p50 27µs p99 1.19ms - 11  40150  p50 28µs p99 1.26ms - 12  0  p50 28µs p99 1.26ms - 13  7950  p50 28µs p99 1.31ms - 14  39550  p50 30µs p99 1.32ms - 15  20600  p50 30µs p99 1.40ms - 16  10950  p50 31µs p99 1.63ms - 17  0  p50 31µs p99 1.63ms - 18  400  p50 31µs p99 1.65ms - 19  15000  p50 31µs p99 1.71ms - 20  26000  p50 32µs p99 1.68ms - - ✍ WRITE Results  - ──────────────────────────────────────────────────────────── - Total ops : 883850 - Errors : 12784 - Avg throughput : 44168 ops/sec - p50 throughput : 25300 ops/sec - p99 throughput : 242400 ops/sec - Latency p50 : 32µs - Latency p95 : 596µs - Latency p99 : 1.71ms - Latency p999 : 36.72ms - ──────────────────────────────────────────────────────────── - -▸ Phase 2 — Read-Only (pool: 500000 keys, batch-get: 50 keys/request) - Reads routed to correct nodes via consistent hashing. - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  23938  p50 250µs p99 2.00ms - 2  15450  p50 219µs p99 1.88ms - 3  1500  p50 217µs p99 1.87ms - 4  7937  p50 238µs p99 4.07ms - 5  40732  p50 186µs p99 2.15ms - 6  52029  p50 138µs p99 1.88ms - 7  0  p50 138µs p99 1.88ms - 8  3395  p50 140µs p99 1.90ms - 9  5900  p50 147µs p99 2.03ms - 10  4300  p50 150µs p99 2.03ms - 11  9143  p50 143µs p99 2.15ms - 12  16693  p50 140µs p99 2.20ms - 13  0  p50 140µs p99 2.33ms - 14  5396  p50 142µs p99 2.40ms - 15  15240  p50 145µs p99 2.65ms - 16  8498  p50 146µs p99 2.85ms - 17  1450  p50 148µs p99 2.96ms - 18  3700  p50 149µs p99 2.99ms - 19  6192  p50 154µs p99 4.07ms - 20  7150  p50 158µs p99 4.05ms - - 📖 READ Results  - ──────────────────────────────────────────────────────────── - Total ops : 229136 - Errors : 0 - Avg throughput : 11432 ops/sec - p50 throughput : 7150 ops/sec - p99 throughput : 52029 ops/sec - Latency p50 : 158µs - Latency p95 : 1.20ms - Latency p99 : 6.25ms - Latency p999 : 254.04ms - ──────────────────────────────────────────────────────────── - -╔══════════════════════════════════════════════════════╗ -║ PEAK PERFORMANCE ║ -╚══════════════════════════════════════════════════════╝ - ✍ Writes avg 44168 ops/sec p50 32µs p99 1.71ms - 📖 Reads avg 11432 ops/sec p50 158µs p99 6.25ms - ⚡ Total 55600 ops/sec combined (3-node cluster, RF=3) - diff --git a/bench_results_cluster_single_key.txt b/bench_results_cluster_single_key.txt deleted file mode 100644 index 589731a..0000000 --- a/bench_results_cluster_single_key.txt +++ /dev/null @@ -1,96 +0,0 @@ - -╔══════════════════════════════════════════════════════╗ -║ KASOKU — DynamoDB-Style Pressure Benchmark ║ -╚══════════════════════════════════════════════════════╝ - - Nodes : http://localhost:9000 http://localhost:9001 http://localhost:9002 - Workers : 10 goroutines - Batch size : 1 keys/request - Write phase: 20s - Read phase : 20s - -▸ Phase 1 — Write-Only (warming 5s...) - Seeded 10 keys. Starting write measurement... - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  50  p50 470µs p99 706.98ms - 2  0  p50 470µs p99 706.98ms - 3  0  p50 470µs p99 706.98ms - 4  0  p50 470µs p99 706.98ms - 5  0  p50 470µs p99 706.98ms - 6  0  p50 470µs p99 706.98ms - 7  1  p50 470µs p99 843.01ms - 8  0  p50 470µs p99 843.01ms - 9  0  p50 470µs p99 843.01ms - 10  1  p50 484µs p99 5000.00ms - 11  0  p50 484µs p99 5000.00ms - 12  1  p50 484µs p99 5000.00ms - 13  0  p50 484µs p99 5000.00ms - 14  3  p50 642µs p99 5000.00ms - 15  0  p50 642µs p99 5000.00ms - 16  0  p50 642µs p99 5000.00ms - 17  0  p50 642µs p99 5000.00ms - 18  2  p50 674µs p99 5000.00ms - 19  0  p50 674µs p99 5000.00ms - 20  0  p50 674µs p99 5000.00ms - - ✍ WRITE Results  - ──────────────────────────────────────────────────────────── - Total ops : 68 - Errors : 0 - Avg throughput : 3 ops/sec - p50 throughput : 0 ops/sec - p99 throughput : 50 ops/sec - Latency p50 : 1.26ms - Latency p95 : 5000.00ms - Latency p99 : 5000.00ms - Latency p999 : 5000.00ms - ──────────────────────────────────────────────────────────── - -▸ Phase 2 — Read-Only (pool: 78 keys, batch-get: 50 keys/request) - Reads routed to correct nodes via consistent hashing. - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  94850  p50 64µs p99 643µs - 2  104100  p50 64µs p99 502µs - 3  117600  p50 64µs p99 475µs - 4  73450  p50 68µs p99 545µs - 5  56000  p50 70µs p99 643µs - 6  49300  p50 74µs p99 704µs - 7  36200  p50 80µs p99 763µs - 8  79750  p50 80µs p99 758µs - 9  73950  p50 81µs p99 766µs - 10  71250  p50 80µs p99 778µs - 11  81750  p50 79µs p99 778µs - 12  112650  p50 74µs p99 765µs - 13  62700  p50 76µs p99 795µs - 14  49450  p50 77µs p99 823µs - 15  102800  p50 73µs p99 815µs - 16  138550  p50 69µs p99 780µs - 17  142750  p50 65µs p99 749µs - 18  117200  p50 64µs p99 734µs - 19  34000  p50 65µs p99 751µs - 20  64500  p50 66µs p99 767µs - - 📖 READ Results  - ──────────────────────────────────────────────────────────── - Total ops : 1663350 - Errors : 0 - Avg throughput : 83140 ops/sec - p50 throughput : 79750 ops/sec - p99 throughput : 142750 ops/sec - Latency p50 : 66µs - Latency p95 : 349µs - Latency p99 : 767µs - Latency p999 : 1.81ms - ──────────────────────────────────────────────────────────── - -╔══════════════════════════════════════════════════════╗ -║ PEAK PERFORMANCE ║ -╚══════════════════════════════════════════════════════╝ - ✍ Writes avg 3 ops/sec p50 1.26ms p99 5000.00ms - 📖 Reads avg 83140 ops/sec p50 66µs p99 767µs - ⚡ Total 83143 ops/sec combined (3-node cluster, RF=3) - diff --git a/bench_results_single_node_batch.txt b/bench_results_single_node_batch.txt deleted file mode 100644 index 69ad05c..0000000 --- a/bench_results_single_node_batch.txt +++ /dev/null @@ -1,96 +0,0 @@ - -╔══════════════════════════════════════════════════════╗ -║ KASOKU — DynamoDB-Style Pressure Benchmark ║ -╚══════════════════════════════════════════════════════╝ - - Nodes : http://localhost:9000 http://localhost:9001 http://localhost:9002 - Workers : 10 goroutines - Batch size : 50 keys/request - Write phase: 20s - Read phase : 20s - -▸ Phase 1 — Write-Only (warming 5s...) - Seeded 169200 keys. Starting write measurement... - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  37950  p50 177µs p99 939µs - 2  50700  p50 128µs p99 968µs - 3  9500  p50 130µs p99 976µs - 4  0  p50 130µs p99 976µs - 5  0  p50 130µs p99 976µs - 6  0  p50 130µs p99 976µs - 7  0  p50 130µs p99 976µs - 8  0  p50 130µs p99 976µs - 9  50  p50 131µs p99 1.05ms - 10  0  p50 131µs p99 1.05ms - 11  0  p50 131µs p99 1.05ms - 12  0  p50 131µs p99 1.05ms - 13  0  p50 131µs p99 1.05ms - 14  0  p50 131µs p99 1.05ms - 15  0  p50 131µs p99 1.05ms - 16  0  p50 131µs p99 1.05ms - 17  0  p50 131µs p99 1.05ms - 18  0  p50 131µs p99 1.05ms - 19  100  p50 131µs p99 1.07ms - 20  0  p50 131µs p99 1.07ms - - ✍ WRITE Results  - ──────────────────────────────────────────────────────────── - Total ops : 98800 - Errors : 0 - Avg throughput : 4915 ops/sec - p50 throughput : 0 ops/sec - p99 throughput : 50700 ops/sec - Latency p50 : 132µs - Latency p95 : 667µs - Latency p99 : 1.41ms - Latency p999 : 483.46ms - ──────────────────────────────────────────────────────────── - -▸ Phase 2 — Read-Only (pool: 268000 keys, batch-get: 50 keys/request) - Reads routed to correct nodes via consistent hashing. - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  22321  p50 137µs p99 4.06ms - 2  0  p50 137µs p99 4.06ms - 3  0  p50 137µs p99 4.06ms - 4  0  p50 137µs p99 4.06ms - 5  0  p50 137µs p99 4.06ms - 6  0  p50 137µs p99 4.06ms - 7  0  p50 137µs p99 4.06ms - 8  0  p50 137µs p99 4.06ms - 9  0  p50 137µs p99 4.06ms - 10  0  p50 137µs p99 4.06ms - 11  0  p50 137µs p99 4.06ms - 12  0  p50 137µs p99 4.06ms - 13  0  p50 137µs p99 4.06ms - 14  0  p50 137µs p99 4.06ms - 15  0  p50 137µs p99 4.06ms - 16  0  p50 137µs p99 4.06ms - 17  0  p50 137µs p99 4.06ms - 18  0  p50 137µs p99 4.06ms - 19  0  p50 137µs p99 4.06ms - 20  0  p50 137µs p99 4.06ms - - 📖 READ Results  - ──────────────────────────────────────────────────────────── - Total ops : 22654 - Errors : 0 - Avg throughput : 1116 ops/sec - p50 throughput : 0 ops/sec - p99 throughput : 22321 ops/sec - Latency p50 : 142µs - Latency p95 : 1.65ms - Latency p99 : 825.54ms - Latency p999 : 876.68ms - ──────────────────────────────────────────────────────────── - -╔══════════════════════════════════════════════════════╗ -║ PEAK PERFORMANCE ║ -╚══════════════════════════════════════════════════════╝ - ✍ Writes avg 4915 ops/sec p50 132µs p99 1.41ms - 📖 Reads avg 1116 ops/sec p50 142µs p99 825.54ms - ⚡ Total 6031 ops/sec combined (3-node cluster, RF=3) - diff --git a/bench_results_single_node_single_key.txt b/bench_results_single_node_single_key.txt deleted file mode 100644 index cd55b1a..0000000 --- a/bench_results_single_node_single_key.txt +++ /dev/null @@ -1,96 +0,0 @@ - -╔══════════════════════════════════════════════════════╗ -║ KASOKU — DynamoDB-Style Pressure Benchmark ║ -╚══════════════════════════════════════════════════════╝ - - Nodes : http://localhost:9000 http://localhost:9001 http://localhost:9002 - Workers : 10 goroutines - Batch size : 1 keys/request - Write phase: 20s - Read phase : 20s - -▸ Phase 1 — Write-Only (warming 5s...) - Seeded 5682 keys. Starting write measurement... - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  0  p50 - p99 - - 2  1936  p50 644µs p99 67.80ms - 3  3624  p50 505µs p99 47.14ms - 4  2356  p50 505µs p99 43.45ms - 5  0  p50 505µs p99 43.45ms - 6  0  p50 505µs p99 43.45ms - 7  0  p50 505µs p99 43.45ms - 8  0  p50 505µs p99 43.45ms - 9  0  p50 505µs p99 43.45ms - 10  0  p50 505µs p99 43.45ms - 11  0  p50 505µs p99 43.45ms - 12  0  p50 505µs p99 43.45ms - 13  0  p50 505µs p99 43.45ms - 14  0  p50 505µs p99 43.45ms - 15  2  p50 505µs p99 43.69ms - 16  0  p50 505µs p99 43.69ms - 17  1175  p50 502µs p99 43.49ms - 18  10232  p50 512µs p99 27.20ms - 19  9861  p50 438µs p99 18.59ms - 20  0  p50 438µs p99 18.59ms - - ✍ WRITE Results  - ──────────────────────────────────────────────────────────── - Total ops : 29196 - Errors : 0 - Avg throughput : 1459 ops/sec - p50 throughput : 0 ops/sec - p99 throughput : 10232 ops/sec - Latency p50 : 438µs - Latency p95 : 3.80ms - Latency p99 : 19.58ms - Latency p999 : 1283.68ms - ──────────────────────────────────────────────────────────── - -▸ Phase 2 — Read-Only (pool: 34878 keys, batch-get: 50 keys/request) - Reads routed to correct nodes via consistent hashing. - - SEC OPS/SEC LATENCY - ─────────────────────────────────────────────────────── - 1  284706  p50 21µs p99 228µs - 2  306734  p50 20µs p99 185µs - 3  171585  p50 22µs p99 222µs - 4  93486  p50 23µs p99 220µs - 5  27620  p50 23µs p99 227µs - 6  490849  p50 20µs p99 187µs - 7  470221  p50 18µs p99 161µs - 8  3078  p50 18µs p99 172µs - 9  0  p50 24µs p99 1.49ms - 10  0  p50 42µs p99 1.96ms - 11  0  p50 223µs p99 1.75ms - 12  0  p50 248µs p99 1.82ms - 13  0  p50 263µs p99 2.15ms - 14  0  p50 272µs p99 2.46ms - 15  0  p50 283µs p99 2.63ms - 16  0  p50 293µs p99 2.92ms - 17  0  p50 303µs p99 3.19ms - 18  0  p50 309µs p99 3.62ms - 19  0  p50 311µs p99 3.67ms - 20  0  p50 320µs p99 3.91ms - - 📖 READ Results  - ──────────────────────────────────────────────────────────── - Total ops : 1848279 - Errors : 15610 - Avg throughput : 92414 ops/sec - p50 throughput : 0 ops/sec - p99 throughput : 490849 ops/sec - Latency p50 : 320µs - Latency p95 : 1.48ms - Latency p99 : 3.90ms - Latency p999 : 28.67ms - ──────────────────────────────────────────────────────────── - -╔══════════════════════════════════════════════════════╗ -║ PEAK PERFORMANCE ║ -╚══════════════════════════════════════════════════════╝ - ✍ Writes avg 1459 ops/sec p50 438µs p99 19.58ms - 📖 Reads avg 92414 ops/sec p50 320µs p99 3.90ms - ⚡ Total 93873 ops/sec combined (3-node cluster, RF=3) - diff --git a/demo/replication_demo.go b/demo/replication_demo.go deleted file mode 100644 index deb68dd..0000000 --- a/demo/replication_demo.go +++ /dev/null @@ -1,118 +0,0 @@ -//go:build ignore - -// Run with: go run demo/replication_demo.go -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "os/exec" - "time" -) - -func main() { - // Clean old data - os.RemoveAll("/tmp/kasoku-demo") - - fmt.Println("=== Kasoku 3-Node Replication Demo ===") - fmt.Println() - - // Start 3 nodes as separate processes - nodes := []struct { - id string - port int - }{ - {"node-1", 18081}, - {"node-2", 18082}, - {"node-3", 18083}, - } - - var cmds []*exec.Cmd - for _, n := range nodes { - cmd := exec.Command("go", "run", "cmd/server/main.go", - "--node-id", n.id, - "--port", fmt.Sprintf("%d", n.port), - "--data-dir", fmt.Sprintf("/tmp/kasoku-demo/%s", n.id), - "--cluster-enabled", - "--replication-factor", "3", - "--quorum-size", "2", - ) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Start() - cmds = append(cmds, cmd) - fmt.Printf("✅ Started %s on :%d (pid=%d)\n", n.id, n.port, cmd.Process.Pid) - } - - // Cleanup on exit - defer func() { - for _, c := range cmds { - c.Process.Kill() - } - os.RemoveAll("/tmp/kasoku-demo") - }() - - fmt.Println() - fmt.Println("Waiting for servers to be ready...") - time.Sleep(3 * time.Second) - - nodeURLs := []string{ - "http://localhost:18081", - "http://localhost:18082", - "http://localhost:18083", - } - - // DEMO 1: Write to node-1, read from all - fmt.Println() - fmt.Println("--- Demo 1: Write user:1=Alice to node-1 ---") - - http.Post(nodeURLs[0]+"/keys/user:1", "application/json", - bytes.NewReader([]byte(`{"value":"Alice"}`))) - - time.Sleep(500 * time.Millisecond) - - for i, url := range nodeURLs { - resp, err := http.Get(url + "/keys/user:1") - if err != nil { - fmt.Printf("❌ Node %d unreachable\n", i+1) - continue - } - body, _ := io.ReadAll(resp.Body) - resp.Body.Close() - var r map[string]any - json.Unmarshal(body, &r) - if v, ok := r["value"]; ok { - fmt.Printf("✅ Node %d has user:1 = %v\n", i+1, v) - } else { - fmt.Printf("❌ Node %d missing user:1\n", i+1) - } - } - - // DEMO 2: Delete - fmt.Println() - fmt.Println("--- Demo 2: Delete user:1 via node-2 ---") - - req, _ := http.NewRequest("DELETE", nodeURLs[1]+"/keys/user:1", nil) - http.DefaultClient.Do(req) - - time.Sleep(500 * time.Millisecond) - - for i, url := range nodeURLs { - resp, _ := http.Get(url + "/keys/user:1") - if resp.StatusCode == 404 { - fmt.Printf("✅ Node %d: user:1 deleted\n", i+1) - } else { - fmt.Printf("❌ Node %d still has user:1\n", i+1) - } - resp.Body.Close() - } - - fmt.Println() - fmt.Println("=== Demo Complete ===") - fmt.Println("Servers running. Press Enter to stop all nodes.") - fmt.Scanln() -} diff --git a/demo/run_replication_demo.sh b/demo/run_replication_demo.sh deleted file mode 100755 index 984f621..0000000 --- a/demo/run_replication_demo.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/bash -# Kasoku 3-Node Replication Demo -# Starts 3 separate processes, writes to one, reads from all - -set -e - -DEMO_DIR="/tmp/kasoku-demo" -rm -rf "$DEMO_DIR" -mkdir -p "$DEMO_DIR/node-1" "$DEMO_DIR/node-2" "$DEMO_DIR/node-3" - -echo "=== Kasoku 3-Node Replication Demo ===" -echo "" - -# Create minimal config for each node -for i in 1 2 3; do - cat > "$DEMO_DIR/node-$i.yaml" </dev/null || true - rm -rf "$DEMO_DIR" - exit 0 -} -trap cleanup SIGINT SIGTERM - -echo "" -echo "Waiting for servers..." -sleep 3 - -NODES=("http://localhost:18081" "http://localhost:18082" "http://localhost:18083") - -# DEMO 1 -echo "" -echo "--- Demo 1: Write user:1=Alice to node-1 ---" -curl -s -X POST "${NODES[0]}/api/v1/put/user:1" \ - -H "Content-Type: application/json" \ - -d '{"value":"Alice"}' > /dev/null 2>&1 || true -sleep 1 - -for i in 0 1 2; do - resp=$(curl -s "${NODES[$i]}/api/v1/get/user:1" 2>/dev/null || echo '{"error":"unreachable"}') - val=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('value','MISSING'))" 2>/dev/null || echo "ERROR") - if [ "$val" = "Alice" ]; then - echo "✅ Node $((i+1)) has user:1 = $val" - else - echo "❌ Node $((i+1)) missing user:1 (got: $val)" - fi -done - -# DEMO 2 -echo "" -echo "--- Demo 2: Write order:100 to node-2 ---" -curl -s -X POST "${NODES[1]}/api/v1/put/order:100" \ - -H "Content-Type: application/json" \ - -d '{"value":"ORD-ABC"}' > /dev/null 2>&1 || true -sleep 1 - -for i in 0 1 2; do - resp=$(curl -s "${NODES[$i]}/api/v1/get/order:100" 2>/dev/null || echo '{"error":"unreachable"}') - val=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('value','MISSING'))" 2>/dev/null || echo "ERROR") - if [ "$val" = "ORD-ABC" ]; then - echo "✅ Node $((i+1)) has order:100 = $val" - else - echo "❌ Node $((i+1)) missing order:100 (got: $val)" - fi -done - -# DEMO 3 -echo "" -echo "--- Demo 3: Delete user:1 via node-1 ---" -curl -s -X DELETE "${NODES[0]}/api/v1/delete/user:1" > /dev/null 2>&1 || true -sleep 1 - -for i in 0 1 2; do - status=$(curl -s -o /dev/null -w "%{http_code}" "${NODES[$i]}/api/v1/get/user:1" 2>/dev/null || echo "000") - if [ "$status" = "404" ]; then - echo "✅ Node $((i+1)): user:1 deleted (404)" - else - echo "❌ Node $((i+1)) still has user:1 (status: $status)" - fi -done - -echo "" -echo "=== Demo Complete ===" -echo "Nodes running. Press Ctrl+C to stop." -wait diff --git a/Dockerfile b/deploy/Dockerfile similarity index 100% rename from Dockerfile rename to deploy/Dockerfile diff --git a/docker-compose.single.yml b/deploy/docker-compose.single.yml similarity index 100% rename from docker-compose.single.yml rename to deploy/docker-compose.single.yml diff --git a/docker-compose.yml b/deploy/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to deploy/docker-compose.yml diff --git a/deploy/prometheus/prometheus.yml b/deploy/prometheus/prometheus.yml deleted file mode 100644 index 89e95f5..0000000 --- a/deploy/prometheus/prometheus.yml +++ /dev/null @@ -1,23 +0,0 @@ -global: - scrape_interval: 15s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'kasoku' - kubernetes_sd_configs: - - role: pod - relabel_configs: - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] - action: keep - regex: true - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] - action: replace - target_label: __metrics_path__ - regex: (.+) - - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] - action: replace - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - target_label: __address__ - - action: labelmap - regex: __meta_kubernetes_pod_label_(.+) diff --git a/pressure-tool b/pressure-tool deleted file mode 100755 index bfe862f..0000000 Binary files a/pressure-tool and /dev/null differ diff --git a/run_benchmarks.sh b/run_benchmarks.sh deleted file mode 100755 index bf15f33..0000000 --- a/run_benchmarks.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash -export PATH=$PATH:/usr/local/go/bin - -# 1. Setup -echo "Building server and benchmark..." -go build -o kasoku ./cmd/server/main.go -go build -o bench benchmarks/pressure/pressure.go - -pkill -f "./kasoku" -sleep 1 -rm -rf data/node-* - -start_node() { - id=$1 - port=$2 - addr="http://localhost:$port" - mkdir -p data/$id - KASOKU_NODE_ID=$id KASOKU_DATA_DIR=./data/$id KASOKU_HTTP_PORT=$port \ - KASOKU_NODE_ADDR=$addr KASOKU_CONFIG=configs/cluster.yaml \ - ./kasoku > /tmp/kasoku-$id.log 2>&1 & -} - -echo "Starting 3-node cluster..." -start_node node-1 9000 -sleep 0.5 -start_node node-2 9001 -sleep 0.5 -start_node node-3 9002 -sleep 10 - -run_bench() { - name=$1 - wrk=$2 - shift 2 - echo "Running $name (Workers: $wrk)..." - GOMAXPROCS=4 ./bench -nodes=localhost:9000,localhost:9001,localhost:9002 \ - -write-duration=20s -read-duration=20s \ - -warm=5s -workers=$wrk "$@" > "bench_results_$name.txt" 2>&1 -} - -run_bench "single_node_single_key" 10 -single-node -batch=1 -run_bench "single_node_batch" 10 -single-node -batch=50 -run_bench "cluster_single_key" 10 -batch=1 -run_bench "cluster_batch" 10 -batch=50 - -pkill -f "./kasoku" -echo "Benchmarks completed." diff --git a/scripts/run-benchmark.sh b/scripts/run-benchmark.sh deleted file mode 100755 index 8391712..0000000 --- a/scripts/run-benchmark.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -set -e - -# Kasoku Benchmark Runner -# Usage: ./run-benchmark.sh [single|cluster] - -MODE="${1:-single}" - -echo "==================================" -echo " Kasoku Benchmark Runner" -echo "==================================" - -# Build benchmark tool -echo "[1/3] Building pressure tool..." -go build -o benchmarks/pressure ./benchmarks/pressure/pressure.go - -# Ensure server is running -echo "[2/3] Checking if server is running..." -if ! curl -sf http://localhost:9000/health > /dev/null 2>&1; then - echo "Server not running. Starting single node..." - ./scripts/start-single.sh & - sleep 3 -fi - -# Run benchmark -echo "[3/3] Running $MODE benchmark..." -echo "" - -NODES="localhost:9000" -if [ "$MODE" = "cluster" ]; then - NODES="localhost:9000,localhost:9001,localhost:9002" -fi - -./benchmarks/pressure/pressure -nodes=$NODES -write-duration=20s -read-duration=20s -workers=30 -batch=25 - -echo "" -echo "==================================" -echo " Benchmark complete!" -echo "==================================" diff --git a/scripts/start-cluster.sh b/scripts/start-cluster.sh deleted file mode 100755 index 76b78d9..0000000 --- a/scripts/start-cluster.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash -set -e - -echo "==================================" -echo " Kasoku 3-Node Cluster Starter" -echo "==================================" - -# Build -echo "[1/4] Building kasoku..." -go build -o kasoku ./cmd/server/main.go - -# Clean data -echo "[2/4] Cleaning old data..." -pkill -f "kasoku" 2>/dev/null || true -sleep 1 -rm -rf data/node-1 data/node-2 data/node-3 -mkdir -p data/node-1 data/node-2 data/node-3 - -# Cleanup handler -PIDS=() -cleanup() { - echo "" - echo "Shutting down all Kasoku nodes..." - for pid in "${PIDS[@]}"; do - kill "$pid" 2>/dev/null || true - done - echo "Goodbye!" - exit 0 -} -trap cleanup SIGINT SIGTERM - -# Start nodes -echo "[3/4] Starting 3-node cluster..." - -KASOKU_NODE_ID=node-1 KASOKU_DATA_DIR=./data/node-1 KASOKU_HTTP_PORT=9000 \ - KASOKU_CONFIG=configs/cluster.yaml ./kasoku > /tmp/kasoku-node1.log 2>&1 & -PIDS+=($!) -sleep 0.5 - -KASOKU_NODE_ID=node-2 KASOKU_DATA_DIR=./data/node-2 KASOKU_HTTP_PORT=9001 \ - KASOKU_CONFIG=configs/cluster.yaml ./kasoku > /tmp/kasoku-node2.log 2>&1 & -PIDS+=($!) -sleep 0.5 - -KASOKU_NODE_ID=node-3 KASOKU_DATA_DIR=./data/node-3 KASOKU_HTTP_PORT=9002 \ - KASOKU_CONFIG=configs/cluster.yaml ./kasoku > /tmp/kasoku-node3.log 2>&1 & -PIDS+=($!) -sleep 3 - -# Verify -echo "" -echo "[4/4] Verifying nodes..." -ALL_OK=true -for port in 9000 9001 9002; do - if curl -sf http://localhost:$port/health > /dev/null 2>&1; then - echo " ✓ Node on port $port is healthy" - else - echo " ✗ Node on port $port not responding" - ALL_OK=false - fi -done - -if $ALL_OK; then - echo "" - echo "==================================" - echo " ✓ Cluster running!" - echo " Node 1: http://localhost:9000" - echo " Node 2: http://localhost:9001" - echo " Node 3: http://localhost:9002" - echo "" - echo " Logs: /tmp/kasoku-node{1,2,3}.log" - echo "==================================" - echo "" - echo "Press Ctrl+C to stop all nodes." -else - echo "" - echo "Some nodes failed. Check /tmp/kasoku-node*.log" -fi - -wait diff --git a/scripts/start-single.sh b/scripts/start-single.sh deleted file mode 100755 index 2a9e8d7..0000000 --- a/scripts/start-single.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -set -e - -echo "==================================" -echo " Kasoku Single Node Starter" -echo "==================================" - -# Build -echo "[1/3] Building kasoku..." -go build -o kasoku ./cmd/server/main.go - -# Clean data -echo "[2/3] Cleaning old data..." -rm -rf data/single -mkdir -p data/single - -# Kill old processes -pkill -f "kasoku" 2>/dev/null || true -pkill -f "vite" 2>/dev/null || true -sleep 1 - -# Start -echo "[3/3] Starting single node..." -KASOKU_CONFIG=configs/single.yaml ./kasoku > /tmp/kasoku-single.log 2>&1 & -sleep 2 - -# Verify -if curl -sf http://localhost:9000/health > /dev/null 2>&1; then - echo "" - echo "==================================" - echo " ✓ Single node running at http://localhost:9000" - echo " Log: /tmp/kasoku-single.log" - echo "==================================" - echo "" - echo "Press Ctrl+C to stop." -else - echo "✗ Node failed to start. Check /tmp/kasoku-single.log" -fi - -trap 'pkill -f "kasoku"; echo "Stopped."' SIGINT SIGTERM -wait diff --git a/scripts/stop.sh b/scripts/stop.sh deleted file mode 100755 index 89743ce..0000000 --- a/scripts/stop.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -echo "Stopping all Kasoku processes..." -pkill -f "kasoku" 2>/dev/null || true -pkill -f "vite" 2>/dev/null || true -echo "Done." diff --git a/setup.sh b/setup.sh index acc0c3a..2135e08 100644 --- a/setup.sh +++ b/setup.sh @@ -3,6 +3,9 @@ set -e # Kasoku Production Setup Script # Usage: ./setup.sh [single|cluster|kubernetes] +# Note: Docker files are in deploy/ directory + +DEPLOY_DIR="$(dirname "$0")/deploy" MODE=${1:-single} @@ -11,7 +14,7 @@ echo "🚀 Setting up Kasoku - $MODE mode" case $MODE in single) echo "📦 Starting single-node Kasoku..." - docker-compose -f docker-compose.single.yml up -d + docker-compose -f "$DEPLOY_DIR/docker-compose.single.yml" up -d echo "✅ Kasoku running at http://localhost:9000" echo " Health check: http://localhost:9000/health" echo " Put key: curl -X PUT http://localhost:9000/kv/mykey -d 'value'" @@ -20,7 +23,7 @@ case $MODE in cluster) echo "📦 Starting 3-node Kasoku cluster..." - docker-compose -f docker-compose.yml up -d + docker-compose -f "$DEPLOY_DIR/docker-compose.yml" up -d echo "✅ Cluster running:" echo " Node 1: http://localhost:9001" echo " Node 2: http://localhost:9002" @@ -32,7 +35,7 @@ case $MODE in cluster-with-monitoring) echo "📦 Starting Kasoku cluster with monitoring..." - docker-compose -f docker-compose.yml --profile monitoring up -d + docker-compose -f "$DEPLOY_DIR/docker-compose.yml" --profile monitoring up -d echo "✅ Cluster running with monitoring:" echo " Node 1: http://localhost:9001" echo " Node 2: http://localhost:9002" @@ -43,7 +46,7 @@ case $MODE in kubernetes) echo "☸️ Deploying to Kubernetes..." - kubectl apply -f deploy/kubernetes/ + kubectl apply -f "$DEPLOY_DIR/kubernetes/" echo "✅ Kasoku deployed to Kubernetes" echo " Check status: kubectl get pods -n kasoku" echo " Access: kubectl port-forward svc/kasoku-http 9000:80" @@ -51,15 +54,15 @@ case $MODE in stop) echo "🛑 Stopping Kasoku..." - docker-compose -f docker-compose.single.yml down 2>/dev/null || true - docker-compose -f docker-compose.yml down 2>/dev/null || true + docker-compose -f "$DEPLOY_DIR/docker-compose.single.yml" down 2>/dev/null || true + docker-compose -f "$DEPLOY_DIR/docker-compose.yml" down 2>/dev/null || true echo "✅ Stopped" ;; clean) echo "🧹 Cleaning up..." - docker-compose -f docker-compose.single.yml down -v 2>/dev/null || true - docker-compose -f docker-compose.yml down -v 2>/dev/null || true + docker-compose -f "$DEPLOY_DIR/docker-compose.single.yml" down -v 2>/dev/null || true + docker-compose -f "$DEPLOY_DIR/docker-compose.yml" down -v 2>/dev/null || true echo "✅ Cleaned up" ;;