Distributed Database เป็นระบบฐานข้อมูลที่กระจายข้อมูลไปยังหลายๆ เซิร์ฟเวอร์หรือ node ที่อยู่ในตำแหน่งทางกายภาพที่แตกต่างกัน แต่ทำงานร่วมกันเสมือนเป็นระบบเดียว โดยมีเป้าหมายหลักดังนี้:
CockroachDB เป็น distributed SQL database ที่ออกแบบมาเพื่อให้มีความทนทาน (resilient) ปรับขนาดได้อย่างง่ายดาย (scalable) และมีความสอดคล้องของข้อมูลแบบ strong consistency โดยได้รับแรงบันดาลใจจาก Google Spanner
จุดเด่นของ CockroachDB:
| คุณสมบัติ | CockroachDB | PostgreSQL | MySQL | MongoDB | Cassandra |
|---|---|---|---|---|---|
| Architecture | Distributed SQL | Single-node/Replica | Single-node/Replica | Distributed Document | Distributed Wide-Column |
| Consistency Model | Strong Consistency | Strong (single-node) | Strong (single-node) | Eventual/Tunable | Eventual/Tunable |
| ACID Transactions | ✅ Full ACID | ✅ Full ACID | ✅ Full ACID | ⚠️ Limited | ❌ No |
| SQL Support | ✅ PostgreSQL compatible | ✅ Full SQL | ✅ Full SQL | ❌ No (uses MQL) | ⚠️ CQL (limited) |
| Horizontal Scaling | ✅ Automatic | ❌ Manual (via sharding) | ❌ Manual (via sharding) | ✅ Automatic | ✅ Automatic |
| Auto-Sharding | ✅ Yes | ❌ No | ❌ No | ✅ Yes | ✅ Yes |
| Multi-Region | ✅ Built-in | ⚠️ Via extensions | ⚠️ Via replication | ✅ Yes | ✅ Yes |
| Automatic Failover | ✅ Yes | ⚠️ Requires setup | ⚠️ Requires setup | ✅ Yes | ✅ Yes |
| Schema Management | Fixed Schema (SQL) | Fixed Schema (SQL) | Fixed Schema (SQL) | Flexible Schema | Flexible Schema |
| Join Operations | ✅ Full Support | ✅ Full Support | ✅ Full Support | ⚠️ Limited | ⚠️ Limited |
| Learning Curve | Medium | Low | Low | Medium | Medium-High |
| Use Case | Global apps, Strong consistency | General purpose | General purpose | Document storage | Time-series, IoT |
สรุป:
graph TB
subgraph "Docker Swarm Cluster"
subgraph "Manager Node"
SW[Swarm Manager]
end
subgraph "Worker Nodes"
N1[Node 1
CockroachDB]
N2[Node 2
CockroachDB]
N3[Node 3
CockroachDB]
N4[Node 4
CockroachDB]
N5[Node 5
CockroachDB]
end
LB[Load Balancer
Port 26257]
SW --> N1
SW --> N2
SW --> N3
SW --> N4
SW --> N5
LB --> N1
LB --> N2
LB --> N3
LB --> N4
LB --> N5
end
CLIENT[Client Application] --> LB
style N1 fill:#4CAF50
style N2 fill:#4CAF50
style N3 fill:#4CAF50
style N4 fill:#4CAF50
style N5 fill:#4CAF50
style LB fill:#2196F3
style SW fill:#FF9800
graph LR
subgraph "Range 1"
R1A[Replica A
Node 1]
R1B[Replica B
Node 2]
R1C[Replica C
Node 3]
end
subgraph "Range 2"
R2A[Replica A
Node 2]
R2B[Replica B
Node 3]
R2C[Replica C
Node 4]
end
subgraph "Range 3"
R3A[Replica A
Node 3]
R3B[Replica B
Node 4]
R3C[Replica C
Node 5]
end
R1A -.sync.-> R1B
R1B -.sync.-> R1C
R1C -.sync.-> R1A
R2A -.sync.-> R2B
R2B -.sync.-> R2C
R2C -.sync.-> R2A
R3A -.sync.-> R3B
R3B -.sync.-> R3C
R3C -.sync.-> R3A
style R1A fill:#4CAF50
style R1B fill:#4CAF50
style R1C fill:#4CAF50
style R2A fill:#2196F3
style R2B fill:#2196F3
style R2C fill:#2196F3
style R3A fill:#FF9800
style R3B fill:#FF9800
style R3C fill:#FF9800
สำหรับแต่ละ Node:
ก่อนเริ่มติดตั้ง CockroachDB เราต้องเตรียม Docker Swarm cluster ให้พร้อมก่อน
สมมติว่าเรามี 5 เครื่อง:
# บน manager1 (192.168.1.10)
docker swarm init --advertise-addr 192.168.1.10
# คำสั่งนี้จะแสดง token สำหรับ worker nodes
# ตัวอย่าง output:
# Swarm initialized: current node (xxxxx) is now a manager.
#
# To add a worker to this swarm, run the following command:
# docker swarm join --token SWMTKN-1-xxxxx 192.168.1.10:2377
# บนแต่ละ worker node (worker1-4)
docker swarm join --token SWMTKN-1-xxxxx 192.168.1.10:2377
# บน manager node
docker node ls
# ตัวอย่าง output:
# ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
# abc123 * manager1 Ready Active Leader
# def456 worker1 Ready Active
# ghi789 worker2 Ready Active
# jkl012 worker3 Ready Active
# mno345 worker4 Ready Active
CockroachDB ในโหมด secure ต้องการ certificates สำหรับการเข้ารหัสการสื่อสารและการยืนยันตัวตน
# บน manager node
mkdir -p /opt/cockroachdb/certs
mkdir -p /opt/cockroachdb/ca
cd /opt/cockroachdb
# ติดตั้ง cockroach binary สำหรับสร้าง certificates
# ดาวน์โหลด cockroach binary
wget -qO- https://binaries.cockroachdb.com/cockroach-v23.1.13.linux-amd64.tgz | tar xvz
sudo cp cockroach-v23.1.13.linux-amd64/cockroach /usr/local/bin/
sudo chmod +x /usr/local/bin/cockroach
# สร้าง CA certificate
cockroach cert create-ca \
--certs-dir=/opt/cockroachdb/certs \
--ca-key=/opt/cockroachdb/ca/ca.key \
--overwrite
# สร้างไฟล์:
# - /opt/cockroachdb/certs/ca.crt (CA certificate)
# - /opt/cockroachdb/ca/ca.key (CA private key)
# สร้าง certificate สำหรับ nodes
# ใช้ wildcard หรือระบุทุก node
cockroach cert create-node \
localhost \
127.0.0.1 \
cockroach-1 \
cockroach-2 \
cockroach-3 \
cockroach-4 \
cockroach-5 \
*.cockroachdb \
192.168.1.10 \
192.168.1.11 \
192.168.1.12 \
192.168.1.13 \
192.168.1.14 \
--certs-dir=/opt/cockroachdb/certs \
--ca-key=/opt/cockroachdb/ca/ca.key \
--overwrite
# สร้างไฟล์:
# - /opt/cockroachdb/certs/node.crt
# - /opt/cockroachdb/certs/node.key
# สร้าง certificate สำหรับ root user
cockroach cert create-client \
root \
--certs-dir=/opt/cockroachdb/certs \
--ca-key=/opt/cockroachdb/ca/ca.key \
--overwrite
# สร้างไฟล์:
# - /opt/cockroachdb/certs/client.root.crt
# - /opt/cockroachdb/certs/client.root.key
chmod 600 /opt/cockroachdb/certs/*.key
chmod 644 /opt/cockroachdb/certs/*.crt
ls -la /opt/cockroachdb/certs/
# ควรมีไฟล์:
# ca.crt - CA certificate
# node.crt - Node certificate
# node.key - Node private key
# client.root.crt - Root client certificate
# client.root.key - Root client private key
# สร้าง overlay network สำหรับ CockroachDB cluster
docker network create \
--driver overlay \
--attachable \
cockroachdb-network
docker network ls | grep cockroachdb
# Output:
# xxxxxxxxxx cockroachdb-network overlay swarm
# Label แต่ละ node เพื่อควบคุมการกระจาย containers
docker node update --label-add cockroachdb.node=1 manager1
docker node update --label-add cockroachdb.node=2 worker1
docker node update --label-add cockroachdb.node=3 worker2
docker node update --label-add cockroachdb.node=4 worker3
docker node update --label-add cockroachdb.node=5 worker4
# ตรวจสอบ labels
docker node inspect manager1 --format '{{ .Spec.Labels }}'
สร้างไฟล์ cockroachdb-stack.yml:
version: '3.8'
services:
cockroach-1:
image: cockroachdb/cockroach:v23.1.13
hostname: cockroach-1
networks:
- cockroachdb-network
volumes:
- cockroach-1-data:/cockroach/cockroach-data
- /opt/cockroachdb/certs:/cockroach/certs:ro
command: start --certs-dir=/cockroach/certs --advertise-addr=cockroach-1 --join=cockroach-1,cockroach-2,cockroach-3,cockroach-4,cockroach-5 --cache=.25 --max-sql-memory=.25
deploy:
placement:
constraints:
- node.labels.cockroachdb.node == 1
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
ports:
- target: 26257
published: 26257
mode: host
- target: 8080
published: 8080
mode: host
cockroach-2:
image: cockroachdb/cockroach:v23.1.13
hostname: cockroach-2
networks:
- cockroachdb-network
volumes:
- cockroach-2-data:/cockroach/cockroach-data
- /opt/cockroachdb/certs:/cockroach/certs:ro
command: start --certs-dir=/cockroach/certs --advertise-addr=cockroach-2 --join=cockroach-1,cockroach-2,cockroach-3,cockroach-4,cockroach-5 --cache=.25 --max-sql-memory=.25
deploy:
placement:
constraints:
- node.labels.cockroachdb.node == 2
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
ports:
- target: 26257
published: 26257
mode: host
- target: 8080
published: 8080
mode: host
cockroach-3:
image: cockroachdb/cockroach:v23.1.13
hostname: cockroach-3
networks:
- cockroachdb-network
volumes:
- cockroach-3-data:/cockroach/cockroach-data
- /opt/cockroachdb/certs:/cockroach/certs:ro
command: start --certs-dir=/cockroach/certs --advertise-addr=cockroach-3 --join=cockroach-1,cockroach-2,cockroach-3,cockroach-4,cockroach-5 --cache=.25 --max-sql-memory=.25
deploy:
placement:
constraints:
- node.labels.cockroachdb.node == 3
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
ports:
- target: 26257
published: 26257
mode: host
- target: 8080
published: 8080
mode: host
cockroach-4:
image: cockroachdb/cockroach:v23.1.13
hostname: cockroach-4
networks:
- cockroachdb-network
volumes:
- cockroach-4-data:/cockroach/cockroach-data
- /opt/cockroachdb/certs:/cockroach/certs:ro
command: start --certs-dir=/cockroach/certs --advertise-addr=cockroach-4 --join=cockroach-1,cockroach-2,cockroach-3,cockroach-4,cockroach-5 --cache=.25 --max-sql-memory=.25
deploy:
placement:
constraints:
- node.labels.cockroachdb.node == 4
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
ports:
- target: 26257
published: 26257
mode: host
- target: 8080
published: 8080
mode: host
cockroach-5:
image: cockroachdb/cockroach:v23.1.13
hostname: cockroach-5
networks:
- cockroachdb-network
volumes:
- cockroach-5-data:/cockroach/cockroach-data
- /opt/cockroachdb/certs:/cockroach/certs:ro
command: start --certs-dir=/cockroach/certs --advertise-addr=cockroach-5 --join=cockroach-1,cockroach-2,cockroach-3,cockroach-4,cockroach-5 --cache=.25 --max-sql-memory=.25
deploy:
placement:
constraints:
- node.labels.cockroachdb.node == 5
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
ports:
- target: 26257
published: 26257
mode: host
- target: 8080
published: 8080
mode: host
networks:
cockroachdb-network:
external: true
volumes:
cockroach-1-data:
cockroach-2-data:
cockroach-3-data:
cockroach-4-data:
cockroach-5-data:
Command Parameters:
--certs-dir: ระบุตำแหน่งของ certificates--advertise-addr: ที่อยู่ที่ node นี้จะโฆษณาให้ nodes อื่นรู้จัก--join: รายชื่อของ nodes ทั้งหมดใน cluster--cache: จำนวน memory ที่ใช้สำหรับ cache (25% ของ RAM)--max-sql-memory: จำนวน memory สูงสุดสำหรับ SQL queriesPort Mappings:
26257: SQL port (สำหรับ client connections)8080: HTTP port (สำหรับ Admin UI)Volumes:
# Deploy stack to Docker Swarm
docker stack deploy -c cockroachdb-stack.yml cockroachdb
# Output:
# Creating service cockroachdb_cockroach-1
# Creating service cockroachdb_cockroach-2
# Creating service cockroachdb_cockroach-3
# Creating service cockroachdb_cockroach-4
# Creating service cockroachdb_cockroach-5
# ดู services ที่สร้าง
docker stack services cockroachdb
# Output:
# ID NAME MODE REPLICAS IMAGE
# xxx1 cockroachdb_cockroach-1 replicated 1/1 cockroachdb/cockroach:v23.1.13
# xxx2 cockroachdb_cockroach-2 replicated 1/1 cockroachdb/cockroach:v23.1.13
# xxx3 cockroachdb_cockroach-3 replicated 1/1 cockroachdb/cockroach:v23.1.13
# xxx4 cockroachdb_cockroach-4 replicated 1/1 cockroachdb/cockroach:v23.1.13
# xxx5 cockroachdb_cockroach-5 replicated 1/1 cockroachdb/cockroach:v23.1.13
# ดู containers ที่ running
docker stack ps cockroachdb
# หรือดูแบบละเอียด
docker stack ps cockroachdb --no-trunc
# ดู logs ของ service ใดๆ
docker service logs cockroachdb_cockroach-1 -f
# ดู logs ของทุก services
docker service logs cockroachdb_cockroach-1 cockroachdb_cockroach-2 cockroachdb_cockroach-3 -f
หลังจาก deploy แล้ว เราต้อง initialize cluster:
# Execute init command บน node แรก
docker exec -it $(docker ps -q -f name=cockroachdb_cockroach-1) \
./cockroach init \
--certs-dir=/cockroach/certs \
--host=cockroach-1
# Output:
# Cluster successfully initialized
# ตรวจสอบสถานะ cluster
docker exec -it $(docker ps -q -f name=cockroachdb_cockroach-1) \
./cockroach node status \
--certs-dir=/cockroach/certs \
--host=cockroach-1
# Output แสดง:
# id | address | sql_address | build | started_at | updated_at | locality | is_available | is_live
# เข้าสู่ SQL shell
docker exec -it $(docker ps -q -f name=cockroachdb_cockroach-1) \
./cockroach sql \
--certs-dir=/cockroach/certs \
--host=cockroach-1
# หรือจาก host machine (ถ้าติดตั้ง cockroach binary)
cockroach sql \
--certs-dir=/opt/cockroachdb/certs \
--host=192.168.1.10:26257
# Output:
# #
# # Welcome to the CockroachDB SQL shell.
# # All statements must be terminated by a semicolon.
# # To exit, type: \q.
# #
เปิดเว็บบราวเซอร์และไปที่:
https://192.168.1.10:8080
หรือ
https://<any-node-ip>:8080
หมายเหตุ: เนื่องจากใช้ self-signed certificate จะมีคำเตือนจากบราวเซอร์ ให้ proceed ต่อได้
-- สร้าง database
CREATE DATABASE company;
-- ใช้ database
USE company;
-- สร้าง table
CREATE TABLE employees (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
first_name STRING NOT NULL,
last_name STRING NOT NULL,
email STRING UNIQUE NOT NULL,
department STRING,
salary DECIMAL(10,2),
hire_date DATE DEFAULT CURRENT_DATE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_department (department),
INDEX idx_email (email)
);
-- สร้าง table สำหรับ departments
CREATE TABLE departments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name STRING NOT NULL,
budget DECIMAL(12,2),
manager_id UUID,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- แสดงโครงสร้างของ table
SHOW CREATE TABLE employees;
-- Insert ข้อมูลพนักงาน
INSERT INTO employees (first_name, last_name, email, department, salary) VALUES
('สมชาย', 'ใจดี', 'somchai@company.com', 'Engineering', 55000.00),
('สมหญิง', 'รักงาน', 'somsing@company.com', 'Engineering', 52000.00),
('ประยุทธ', 'ทำงานหนัก', 'prayut@company.com', 'Sales', 48000.00),
('วิภา', 'ขยัน', 'wipa@company.com', 'Marketing', 50000.00),
('นพดล', 'สุขใจ', 'nopadon@company.com', 'HR', 45000.00);
-- Insert departments
INSERT INTO departments (name, budget) VALUES
('Engineering', 5000000.00),
('Sales', 3000000.00),
('Marketing', 2000000.00),
('HR', 1500000.00);
-- ตรวจสอบข้อมูล
SELECT * FROM employees;
-- Query พื้นฐาน
SELECT first_name, last_name, department, salary
FROM employees
ORDER BY salary DESC;
-- Query ด้วย JOIN
SELECT
e.first_name,
e.last_name,
e.department,
d.budget as department_budget
FROM employees e
JOIN departments d ON e.department = d.name;
-- Aggregate functions
SELECT
department,
COUNT(*) as employee_count,
AVG(salary) as avg_salary,
MAX(salary) as max_salary,
MIN(salary) as min_salary
FROM employees
GROUP BY department
ORDER BY avg_salary DESC;
-- Window functions
SELECT
first_name,
last_name,
department,
salary,
AVG(salary) OVER (PARTITION BY department) as dept_avg_salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as salary_rank
FROM employees;
-- เริ่ม transaction
BEGIN;
-- Update salary
UPDATE employees
SET salary = salary * 1.10
WHERE department = 'Engineering';
-- ตรวจสอบผลลัพธ์
SELECT first_name, last_name, salary
FROM employees
WHERE department = 'Engineering';
-- Commit หรือ Rollback
COMMIT;
-- หรือ
-- ROLLBACK;
-- Query เพื่อดูการกระจายข้อมูล
SHOW RANGES FROM TABLE employees;
-- ดู replica placements
SELECT
start_key,
end_key,
replicas,
lease_holder
FROM [SHOW RANGES FROM TABLE employees];
# Connection string format
postgresql://root@<any-node-ip>:26257/defaultdb?sslmode=verify-full&sslrootcert=<path-to-ca.crt>&sslcert=<path-to-client.root.crt>&sslkey=<path-to-client.root.key>
import psycopg2
from psycopg2 import sql
# Connection parameters
conn_params = {
'host': '192.168.1.10',
'port': 26257,
'database': 'company',
'user': 'root',
'sslmode': 'verify-full',
'sslrootcert': '/path/to/ca.crt',
'sslcert': '/path/to/client.root.crt',
'sslkey': '/path/to/client.root.key'
}
# สร้าง connection
try:
conn = psycopg2.connect(**conn_params)
conn.set_session(autocommit=True)
# สร้าง cursor
cur = conn.cursor()
# Execute query
cur.execute("SELECT first_name, last_name, department FROM employees")
# Fetch results
rows = cur.fetchall()
for row in rows:
print(f"Name: {row[0]} {row[1]}, Department: {row[2]}")
# Close cursor และ connection
cur.close()
conn.close()
except Exception as e:
print(f"Error: {e}")
const { Pool } = require('pg');
const fs = require('fs');
// สร้าง connection pool
const pool = new Pool({
host: '192.168.1.10',
port: 26257,
database: 'company',
user: 'root',
ssl: {
rejectUnauthorized: true,
ca: fs.readFileSync('/path/to/ca.crt').toString(),
cert: fs.readFileSync('/path/to/client.root.crt').toString(),
key: fs.readFileSync('/path/to/client.root.key').toString()
}
});
// Query function
async function queryEmployees() {
const client = await pool.connect();
try {
const result = await client.query(
'SELECT first_name, last_name, department FROM employees'
);
console.log('Employees:', result.rows);
} finally {
client.release();
}
}
// Execute
queryEmployees().catch(console.error);
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
func main() {
// Connection string
connStr := "postgresql://root@192.168.1.10:26257/company?" +
"sslmode=verify-full&" +
"sslrootcert=/path/to/ca.crt&" +
"sslcert=/path/to/client.root.crt&" +
"sslkey=/path/to/client.root.key"
// เปิด connection
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Test connection
err = db.Ping()
if err != nil {
log.Fatal(err)
}
// Query
rows, err := db.Query("SELECT first_name, last_name, department FROM employees")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// Iterate results
for rows.Next() {
var firstName, lastName, department string
err := rows.Scan(&firstName, &lastName, &department)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Name: %s %s, Department: %s\n", firstName, lastName, department)
}
}
-- ตรวจสอบ cluster metrics
SELECT * FROM crdb_internal.node_metrics;
-- ตรวจสอบ replication status
SHOW CLUSTER SETTING cluster.organization;
SHOW ALL CLUSTER SETTINGS;
-- ดู active queries
SELECT query_id, node_id, user_name, start, query
FROM crdb_internal.cluster_queries
ORDER BY start DESC
LIMIT 10;
-- ดู slow queries
SELECT * FROM crdb_internal.cluster_queries
WHERE now() - start > INTERVAL '5 seconds';
-- Backup แบบ full
BACKUP DATABASE company
TO 'nodelocal://1/backups/company-2024-01-01'
WITH revision_history;
-- Backup แบบ incremental
BACKUP DATABASE company
TO 'nodelocal://1/backups/company-2024-01-01'
AS OF SYSTEM TIME '-10s';
-- Restore database
RESTORE DATABASE company
FROM 'nodelocal://1/backups/company-2024-01-01';
-- Restore table
RESTORE TABLE employees
FROM 'nodelocal://1/backups/company-2024-01-01';
-- สร้าง index เพิ่มเติม
CREATE INDEX idx_hire_date ON employees(hire_date);
-- Analyze table statistics
ANALYZE employees;
-- ดู execution plan
EXPLAIN SELECT * FROM employees WHERE department = 'Engineering';
EXPLAIN ANALYZE SELECT * FROM employees WHERE department = 'Engineering';
-- ปรับแต่ง cluster settings
SET CLUSTER SETTING sql.stats.automatic_collection.enabled = true;
SET CLUSTER SETTING kv.range_split.by_load_enabled = true;
สร้าง monitoring script monitor-cluster.sh:
#!/bin/bash
# สี
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "=== CockroachDB Cluster Health Check ==="
echo ""
# ตรวจสอบ services
echo "Checking services..."
docker stack services cockroachdb
echo ""
echo "=== Node Status ==="
docker exec $(docker ps -q -f name=cockroachdb_cockroach-1) \
./cockroach node status \
--certs-dir=/cockroach/certs \
--host=cockroach-1
echo ""
echo "=== Container Health ==="
for i in {1..5}; do
container=$(docker ps -q -f name=cockroachdb_cockroach-$i)
if [ -n "$container" ]; then
status=$(docker inspect --format='{{.State.Health.Status}}' $container 2>/dev/null)
if [ "$status" == "healthy" ] || [ -z "$status" ]; then
echo -e "${GREEN}✓${NC} cockroach-$i: Running"
else
echo -e "${RED}✗${NC} cockroach-$i: $status"
fi
else
echo -e "${RED}✗${NC} cockroach-$i: Not found"
fi
done
echo ""
echo "=== Disk Usage ==="
docker exec $(docker ps -q -f name=cockroachdb_cockroach-1) \
df -h /cockroach/cockroach-data
สร้างไฟล์ haproxy.cfg:
global
maxconn 4096
log stdout format raw local0
defaults
log global
mode tcp
option tcplog
option dontlognull
retries 3
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
# Admin UI
listen admin
bind *:8080
mode http
stats enable
stats uri /
stats refresh 10s
# CockroachDB SQL
listen cockroachdb-sql
bind *:26257
mode tcp
balance roundrobin
option tcp-check
server cockroach-1 192.168.1.10:26257 check
server cockroach-2 192.168.1.11:26257 check
server cockroach-3 192.168.1.12:26257 check
server cockroach-4 192.168.1.13:26257 check
server cockroach-5 192.168.1.14:26257 check
# CockroachDB HTTP/UI
listen cockroachdb-http
bind *:8081
mode tcp
balance roundrobin
option tcp-check
server cockroach-1 192.168.1.10:8080 check
server cockroach-2 192.168.1.11:8080 check
server cockroach-3 192.168.1.12:8080 check
server cockroach-4 192.168.1.13:8080 check
server cockroach-5 192.168.1.14:8080 check
# สร้าง directory
mkdir -p /opt/haproxy
# คัดลอก config
cp haproxy.cfg /opt/haproxy/
# Deploy HAProxy
docker service create \
--name haproxy \
--publish 26257:26257 \
--publish 8081:8081 \
--publish 8080:8080 \
--mount type=bind,source=/opt/haproxy/haproxy.cfg,target=/usr/local/etc/haproxy/haproxy.cfg \
--network cockroachdb-network \
haproxy:latest
# หยุด node 1
docker service scale cockroachdb_cockroach-1=0
# รอสักครู่และตรวจสอบ
docker exec $(docker ps -q -f name=cockroachdb_cockroach-2) \
./cockroach node status \
--certs-dir=/cockroach/certs \
--host=cockroach-2
# ลอง query ข้อมูล (ควรยังทำงานได้ปกติ)
cockroach sql \
--certs-dir=/opt/cockroachdb/certs \
--host=192.168.1.11:26257 \
--execute="SELECT COUNT(*) FROM company.employees;"
# Start node 1 กลับมา
docker service scale cockroachdb_cockroach-1=1
# จำลอง network partition (บน worker1)
# Block traffic จาก worker1 ไปยัง nodes อื่น
sudo iptables -A OUTPUT -d 192.168.1.10 -j DROP
sudo iptables -A OUTPUT -d 192.168.1.12 -j DROP
# รอดู automatic rebalancing
# ตรวจสอบ cluster status
docker exec $(docker ps -q -f name=cockroachdb_cockroach-3) \
./cockroach node status \
--certs-dir=/cockroach/certs \
--host=cockroach-3
# ลบ rules เพื่อ restore network
sudo iptables -D OUTPUT -d 192.168.1.10 -j DROP
sudo iptables -D OUTPUT -d 192.168.1.12 -j DROP
อาการ:
failed to connect to node
วิธีแก้:
docker exec $(docker ps -q -f name=cockroachdb_cockroach-1) ping cockroach-2
docker exec $(docker ps -q -f name=cockroachdb_cockroach-1) \
ls -la /cockroach/certs/
docker service logs cockroachdb_cockroach-1 | tail -50
อาการ:
x509: certificate signed by unknown authority
วิธีแก้:
cd /opt/cockroachdb
cockroach cert create-node ... --overwrite
อาการ: Queries ช้า, high latency
วิธีแก้:
SELECT * FROM crdb_internal.cluster_queries
WHERE now() - start > INTERVAL '5 seconds';
EXPLAIN ANALYZE <your-slow-query>;
CREATE INDEX idx_name ON table_name(column_name);
อาการ:
insufficient disk space
วิธีแก้:
docker exec $(docker ps -q -f name=cockroachdb_cockroach-1) \
df -h /cockroach/cockroach-data
SET CLUSTER SETTING kv.range_merge.queue_enabled = true;
# 1. Backup ก่อน upgrade
cockroach sql --certs-dir=/opt/cockroachdb/certs \
--host=192.168.1.10:26257 \
--execute="BACKUP DATABASE company TO 'nodelocal://1/backups/pre-upgrade';"
# 2. Update image version ใน docker-compose file
# แก้ image: cockroachdb/cockroach:v23.1.13
# เป็น image: cockroachdb/cockroach:v23.2.0
# 3. Update stack (rolling update)
docker stack deploy -c cockroachdb-stack.yml cockroachdb
# 4. Monitor upgrade process
watch docker stack ps cockroachdb
# 5. Verify cluster health
docker exec $(docker ps -q -f name=cockroachdb_cockroach-1) \
./cockroach node status \
--certs-dir=/cockroach/certs \
--host=cockroach-1
# 6. Finalize upgrade (if needed)
cockroach sql --certs-dir=/opt/cockroachdb/certs \
--host=192.168.1.10:26257 \
--execute="SET CLUSTER SETTING version = '23.2';"
การติดตั้ง CockroachDB บน Docker Swarm ในโหมด secure ช่วยให้เราได้ระบบฐานข้อมูลที่: