

บทนำ: ทำไม Apache Druid ถึงต้องการ DevOps Culture ที่แข็งแกร่ง
ในยุคที่ข้อมูลมีปริมาณมหาศาลและเติบโตอย่างรวดเร็ว (Big Data) ระบบฐานข้อมูลแบบดั้งเดิมอย่าง MySQL หรือ PostgreSQL เริ่มแสดงข้อจำกัดในการรองรับการวิเคราะห์ข้อมูลแบบ Real-time โดยเฉพาะอย่างยิ่งในกรณีที่ต้อง query ข้อมูลจำนวนหลายล้านแถวภายในเวลาไม่กี่วินาที Apache Druid จึงถือกำเนิดขึ้นมาเพื่อแก้ปัญหานี้โดยเฉพาะ ด้วยความสามารถในการเป็นฐานข้อมูลเชิงวิเคราะห์แบบ Real-time (Real-time Analytical Database) ที่ออกแบบมาเพื่อการ OLAP (Online Analytical Processing) โดยเฉพาะ
อย่างไรก็ตาม การปรับใช้ Apache Druid ในระดับ Production ไม่ใช่เรื่องง่าย ระบบ Druid มีความซับซ้อนสูง ประกอบด้วยหลาย Component ที่ทำงานประสานกัน ไม่ว่าจะเป็น Coordinator, Broker, Historical, MiddleManager (หรือ Indexer ในรุ่นใหม่) และ Overlord การดูแลระบบให้มี Stability, Scalability และ Performance ที่ดี จึงจำเป็นต้องมี “DevOps Culture” ที่แข็งแกร่ง
บทความนี้จะพาคุณไปรู้จักกับแนวทางปฏิบัติที่ดีที่สุด (Best Practices) สำหรับการทำ DevOps บน Apache Druid ในปี 2026 ครอบคลุมตั้งแต่การออกแบบ Infrastructure การ Deploy, การ Monitoring, การทำ CI/CD, การจัดการ Schema และการ Troubleshoot ปัญหาที่พบบ่อย พร้อมตัวอย่าง Code จริงที่คุณสามารถนำไปปรับใช้ได้ทันที
1. สถาปัตยกรรมของ Apache Druid และความท้าทายด้าน DevOps
1.1 ภาพรวม Component หลัก
ก่อนที่เราจะพูดถึง DevOps เราต้องเข้าใจสถาปัตยกรรมของ Druid ก่อน โดย Druid ประกอบด้วย Service หลัก 5 ตัว ดังนี้:
- Coordinator: 负责管理 Segment metadata, ควบคุมการ Replication, การ Load Balance และการ Retention
- Overlord: รับผิดชอบการจัดคิวและการจัดการ Task ต่างๆ เช่น Ingestion task, Compaction task
- Broker: ทำหน้าที่เป็น Proxy รับ Query จาก Client แล้วกระจายไปยัง Historical และ MiddleManager
- Historical: เก็บ Segment ที่ถูก Commit แล้ว และให้บริการ Query แบบ Read-only
- MiddleManager (Indexer): รับ Task ในการ Ingest ข้อมูลใหม่ และสร้าง Segment ออกมา
ความท้าทายแรกคือการจัดสรรทรัพยากรให้เหมาะสมกับแต่ละ Service เพราะแต่ละตัวมีลักษณะการทำงานที่แตกต่างกันอย่างสิ้นเชิง
1.2 ความท้าทายหลักที่ DevOps ต้องเจอ
| ความท้าทาย | คำอธิบาย | ผลกระทบถ้าไม่จัดการ |
|---|---|---|
| การจัดการ Segment | Segment คือหน่วยพื้นฐานของข้อมูลใน Druid การจัดการ Segment ที่ไม่ดีจะทำให้ Query ช้า | Query latency สูง, ใช้พื้นที่เก็บข้อมูลมากเกินไป |
| การ Ingest ข้อมูล Real-time | การรับข้อมูลที่ไหลเข้ามาตลอดเวลาต้องการระบบที่ Stable และสามารถ Scale ได้ | Data loss, Backlog สะสม, System crash |
| การทำ Compaction | การรวม Segment เล็กๆ ให้เป็น Segment ที่ใหญ่ขึ้น เพื่อเพิ่มประสิทธิภาพ | Segment จำนวนมาก, Query ช้า, Metadata overload |
| การปรับ Tuning Parameter | Druid มี Parameter มากมายที่ต้องปรับให้เหมาะกับ Workload | Under-utilization ของทรัพยากร หรือ Out of Memory |
จากตารางข้างต้น จะเห็นว่าการทำ DevOps สำหรับ Druid ไม่ใช่แค่การ Deploy Container หรือตั้งค่า Kubernetes ให้รันได้เท่านั้น แต่ต้องเข้าใจ Behavior ของระบบในเชิงลึกด้วย
2. การออกแบบ Infrastructure และ Deployment Strategy
2.1 แนวทางการเลือกใช้ Infrastructure: Bare-metal vs Container vs Cloud
ในปี 2026 แนวโน้มการปรับใช้ Druid จะแบ่งออกเป็น 3 รูปแบบหลัก:
- Bare-metal / VM: เหมาะสำหรับองค์กรที่มีทีม DevOps ขนาดใหญ่และต้องการ Performance สูงสุด โดยเฉพาะการจัดการ I/O ของ Disk
- Container (Docker + Kubernetes): เป็นรูปแบบที่ได้รับความนิยมมากที่สุด เพราะช่วยให้การ Scale, การ Upgrade และการจัดการ Resource เป็นไปโดยอัตโนมัติ
- Managed Service (Imply, AWS, GCP): สำหรับองค์กรที่ต้องการลดภาระการดูแลระบบ แต่ยังคงความยืดหยุ่นน้อยกว่า
สำหรับองค์กรส่วนใหญ่ การใช้ Kubernetes เป็นทางเลือกที่สมดุลที่สุด เนื่องจาก Druid มี Helm Chart อย่างเป็นทางการที่ช่วยให้การ Deploy ง่ายขึ้น
2.2 การ Deploy Druid บน Kubernetes ด้วย Helm
ตัวอย่าง Code ด้านล่างนี้คือ Helm values file ที่ปรับแต่งสำหรับ Production environment ในปี 2026 โดยเน้นการแยก Resource ระหว่าง Service ต่างๆ อย่างชัดเจน:
# druid-values.yaml
global:
druid:
image:
repository: apache/druid
tag: "30.0.0"
coordinator:
replicas: 2
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "8Gi"
cpu: "4"
javaOpts: "-Xmx4g -Xms4g -XX:+UseG1GC"
broker:
replicas: 3
resources:
requests:
memory: "8Gi"
cpu: "4"
limits:
memory: "16Gi"
cpu: "8"
javaOpts: "-Xmx8g -Xms8g -XX:+UseG1GC -XX:MaxDirectMemorySize=2g"
historical:
replicas: 5
resources:
requests:
memory: "16Gi"
cpu: "4"
limits:
memory: "32Gi"
cpu: "8"
javaOpts: "-Xmx12g -Xms12g -XX:+UseG1GC -XX:MaxDirectMemorySize=4g"
persistence:
size: "500Gi"
storageClass: "ssd-fast"
middleManager:
replicas: 3
resources:
requests:
memory: "8Gi"
cpu: "4"
limits:
memory: "16Gi"
cpu: "8"
javaOpts: "-Xmx6g -Xms6g -XX:+UseG1GC"
task:
max: 5
workerCapacity: 3
overlord:
replicas: 2
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
javaOpts: "-Xmx2g -Xms2g"
zookeeper:
enabled: true
replicas: 3
postgresql:
enabled: true
postgresqlPassword: "securepassword123"
persistence:
size: "50Gi"
ข้อควรระวัง: การกำหนดค่า javaOpts ต้องสอดคล้องกับ Resource Limits ที่ตั้งไว้ใน Kubernetes มิฉะนั้นจะเกิดปัญหา OOMKilled
2.3 การทำ Auto-scaling สำหรับ MiddleManager
หนึ่งในความท้าทายที่ใหญ่ที่สุดคือการจัดการ MiddleManager (Indexer) ให้เพียงพอกับปริมาณข้อมูลที่ไหลเข้า โดยเฉพาะในช่วง Peak hour ด้วย Kubernetes เราสามารถใช้ HPA (Horizontal Pod Autoscaler) ร่วมกับ Custom Metrics จาก Druid ได้
# hpa-middlemanager.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: druid-middlemanager-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: StatefulSet
name: druid-middlemanager
minReplicas: 3
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: druid_task_pending_count
target:
type: AverageValue
averageValue: 10
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
การตั้งค่าแบบนี้จะช่วยให้ระบบปรับขนาดตัวเองโดยอัตโนมัติเมื่อมี Task รออยู่ในคิวจำนวนมาก ซึ่งเป็นสถานการณ์ที่พบบ่อยในช่วงที่มีการ Ingest ข้อมูลหนักๆ
3. การทำ CI/CD สำหรับ Druid: การจัดการ Schema และ Ingestion Spec
3.1 การ Version Control สำหรับ Ingestion Spec
ข้อผิดพลาดที่พบบ่อยที่สุดอย่างหนึ่งในการทำ DevOps สำหรับ Druid คือการที่ทีม Data Engineer แก้ไข Ingestion Spec ผ่าน Console โดยตรง โดยไม่มีการ Version Control สิ่งนี้นำไปสู่ปัญหาการเปลี่ยนแปลงที่ไม่สามารถย้อนกลับได้ (Irreversible changes)
แนวทางปฏิบัติที่ดีที่สุดคือการเก็บ Ingestion Spec ไว้ใน Git repository ในรูปแบบ YAML หรือ JSON และใช้ระบบ CI/CD ในการ Deploy ไปยัง Druid Cluster โดยอัตโนมัติ
3.2 ตัวอย่าง Pipeline การ Deploy Ingestion Spec ด้วย GitLab CI
# .gitlab-ci.yml สำหรับ Druid Ingestion Spec
image: alpine/curl:latest
stages:
- validate
- deploy
variables:
DRUID_OVERLORD_URL: "http://druid-overlord.namespace.svc.cluster.local:8081"
validate-spec:
stage: validate
script:
- |
for file in specs/*.json; do
echo "Validating $file..."
# ตรวจสอบ JSON syntax
cat $file | python3 -m json.tool > /dev/null
if [ $? -ne 0 ]; then
echo "Invalid JSON in $file"
exit 1
fi
# ตรวจสอบโครงสร้างพื้นฐานของ Ingestion Spec
has_dataSchema=$(cat $file | python3 -c "import sys,json; d=json.load(sys.stdin); print('dataSchema' in d)")
if [ "$has_dataSchema" != "True" ]; then
echo "Missing dataSchema in $file"
exit 1
fi
done
only:
- main
deploy-spec:
stage: deploy
script:
- |
for file in specs/*.json; do
echo "Deploying $file to Druid..."
curl -X POST \
-H "Content-Type: application/json" \
-d @$file \
"${DRUID_OVERLORD_URL}/druid/indexer/v1/task"
sleep 2
done
only:
- main
when: manual # ต้อง Approve ก่อน Deploy
การทำแบบนี้ช่วยให้ทุกการเปลี่ยนแปลงถูกตรวจสอบและมีประวัติที่ชัดเจน สามารถ Rollback ได้ง่ายหากเกิดปัญหา
3.3 การจัดการ Schema Evolution
Druid รองรับการเปลี่ยนแปลง Schema (Schema Evolution) แต่ต้องทำด้วยความระมัดระวัง โดยเฉพาะในส่วนของ:
- การเพิ่ม Dimension ใหม่: ทำได้โดยการเพิ่ม Column ใน Ingestion Spec โดยไม่ต้อง Re-ingest ข้อมูลเก่า
- การเปลี่ยน Data Type: ต้องสร้าง Segment ใหม่ทั้งหมด เนื่องจาก Druid ไม่รองรับการ Alter Column type
- การลบ Dimension: ควรใช้วิธี Mark as “unused” แทนการลบจริง เพื่อป้องกันข้อมูลสูญหาย
ตัวอย่างการเพิ่ม Dimension ใหม่ใน Ingestion Spec:
{
"type": "index_parallel",
"spec": {
"dataSchema": {
"dataSource": "user_events",
"timestampSpec": {
"column": "event_time",
"format": "iso"
},
"dimensionsSpec": {
"dimensions": [
"user_id",
"event_type",
"country",
{"name": "new_dimension", "type": "string"} // เพิ่ม Dimension ใหม่
]
},
"metricsSpec": [
{"type": "count", "name": "count"},
{"type": "longSum", "name": "revenue", "fieldName": "amount"}
],
"granularitySpec": {
"type": "uniform",
"segmentGranularity": "HOUR",
"queryGranularity": "MINUTE"
}
}
}
}
เมื่อเพิ่ม Dimension ใหม่แล้ว ข้อมูลเก่าที่ถูก Ingest ก่อนหน้านี้จะไม่มีค่านี้ (เป็น null) แต่ Query จะยังทำงานได้ตามปกติ
4. การ Monitoring และ Observability สำหรับ Apache Druid
4.1 Metrics ที่ต้องติดตามอย่างใกล้ชิด
Druid มี Metrics API ที่ทรงพลัง แต่ DevOps จำเป็นต้องรู้ว่า Metrics ไหนสำคัญจริงๆ ต่อความเสถียรของระบบ:
| หมวดหมู่ | Metric | ความสำคัญ | ค่า Threshold ที่ควร Alert |
|---|---|---|---|
| Ingestion | ingest/events/thrownAway | สูงมาก | > 0 (บ่งชี้ถึง Data loss) |
| Ingestion | ingest/events/unparseable | สูง | > 0.1% ของ total events |
| Query | query/time | สูง | > 90th percentile > 5 วินาที |
| Query | query/segments/count | ปานกลาง | > 1000 segments ต่อ query (บ่งชี้ถึง compaction issue) |
| System | jvm/gc/cpu | สูง | GC time > 20% ของ total CPU time |
| Coordination | coordinator/segment/overshadowed | สูง | > 0 (บ่งชี้ถึง Segment conflict) |
4.2 การตั้งค่า Prometheus และ Grafana สำหรับ Druid
Druid 30.0.0 รองรับการส่ง Metrics ไปยัง Prometheus โดยตรงผ่าน Extension druid-prometheus-emitter ตัวอย่างการเปิดใช้งาน:
# common.runtime.properties
druid.emitter=prometheus
druid.emitter.prometheus.strategy=exporter
druid.emitter.prometheus.port=9095
druid.emitter.prometheus.namespace=druid
# เปิดใช้งาน Extension
druid.extensions.loadList=["druid-prometheus-emitter", "druid-histogram"]
จากนั้นใน Prometheus config ให้เพิ่ม target สำหรับ Service แต่ละตัว:
# prometheus.yml
scrape_configs:
- job_name: 'druid-coordinator'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
regex: coordinator
action: keep
- source_labels: [__meta_kubernetes_pod_container_port_number]
regex: "9095"
action: keep
metrics_path: '/metrics'
Dashboard ที่สำคัญใน Grafana ควรประกอบด้วย:
- Ingestion Rate (events/sec) และ Backlog
- Query Latency (P50, P95, P99)
- JVM Heap Usage และ GC Pause Time
- จำนวน Segment ต่อ DataSource
- Task Queue Depth
4.3 การทำ Logging และ Alerting ที่มีประสิทธิภาพ
นอกจาก Metrics แล้ว Logging ก็เป็นส่วนสำคัญ โดยเฉพาะเมื่อเกิดเหตุการณ์ไม่คาดฝัน Druid รองรับการส่ง Log ไปยัง Elasticsearch หรือ Loki ได้ผ่าน Log4j2 configuration:
# log4j2.xml (บางส่วน)
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{ISO8601} [%t] %-5p %c{1} - %m%n"/>
</Console>
<Loki name="Loki">
<Url>http://loki-gateway:3100/loki/api/v1/push</Url>
<BatchSize>1000</BatchSize>
<BatchTimeout>5s</BatchTimeout>
<Labels>
<Label name="service">${sys:druid.service}</Label>
<Label name="host">${sys:hostname}</Label>
</Labels>
</Loki>
</Appenders>
การตั้งค่า Alert ที่สำคัญที่สุดคือ:
- Data Loss Alert: เมื่อ
ingest/events/thrownAway> 0 - Query Timeout Alert: เมื่อ Query ใช้เวลาเกิน 30 วินาที
- Disk Space Alert: เมื่อ Historical node ใช้พื้นที่เก็บข้อมูลเกิน 80%
- Task Failure Alert: เมื่อมี Ingestion task ล้มเหลวมากกว่า 5 ครั้งใน 10 นาที
5. การทำ Data Lifecycle Management และ Compaction Strategy
5.1 การตั้งค่า Retention Rule
หนึ่งในจุดแข็งของ Druid คือการจัดการ Retention ผ่าน Coordinator โดยอัตโนมัติ ตัวอย่างการตั้งค่า Retention Rule ผ่าน API:
# ตั้งค่าให้เก็บข้อมูล 30 วันสำหรับ Hot tier, 90 วันสำหรับ Cold tier
curl -X POST \
-H "Content-Type: application/json" \
-d '[
{
"type": "loadByInterval",
"interval": "2026-01-01/2026-01-31",
"tier": "hot",
"priority": 1
},
{
"type": "loadByInterval",
"interval": "2025-10-01/2026-01-01",
"tier": "cold",
"priority": 2
},
{
"type": "dropByInterval",
"interval": "2024-01-01/2025-10-01"
}
]' \
http://druid-coordinator:8081/druid/coordinator/v1/rules/user_events
การแบ่ง Tier (Hot/Cold) ช่วยให้คุณใช้ SSD สำหรับข้อมูลล่าสุดที่ถูก Query บ่อย และใช้ HDD หรือ Cloud Storage สำหรับข้อมูลเก่าที่ถูก Query นานๆ ครั้ง
5.2 Compaction Strategy ที่ดีที่สุดในปี 2026
Compaction เป็นกระบวนการที่สำคัญมากในการรักษาประสิทธิภาพของ Druid โดยเฉพาะเมื่อมี Segment ขนาดเล็กจำนวนมาก (Small Segment Problem) ซึ่งเกิดจากการ Ingest ข้อมูลแบบ Real-time ที่สร้าง Segment ใหม่ทุกๆ ชั่วโมง
แนวทางปฏิบัติที่ดีที่สุดสำหรับ Compaction:
- กำหนด Segment Size เป้าหมาย: ควรอยู่ที่ 500MB – 1GB ต่อ Segment
- ใช้ Auto Compaction: Druid 30.0.0 มี Auto Compaction ที่ฉลาดขึ้น โดยสามารถกำหนดได้ว่าเมื่อไหร่ควรทำ Compaction
- ทำ Compaction ในช่วงเวลาที่ระบบว่าง: เช่น เวลา 02.00 – 04.00 น.
- จำกัดจำนวน Task Compaction: ไม่ควรใช้ Task slot ทั้งหมดในการทำ Compaction เพราะจะแย่งทรัพยากรกับ Ingestion
ตัวอย่างการตั้งค่า Auto Compaction ผ่าน API:
{
"dataSource": "user_events",
"tuningConfig": {
"type": "index_parallel",
"maxRowsPerSegment": 5000000,
"maxRowsInMemory": 100000,
"partitionsSpec": {
"type": "hashed",
"numShards": null,
"targetRowsPerSegment": 5000000
}
},
"ioConfig": {
"type": "compact",
"inputSegmentSizeBytes": 500000000
},
"granularitySpec": {
"segmentGranularity": "HOUR",
"queryGranularity": "NONE"
}
}
การตั้งค่า targetRowsPerSegment ให้เหมาะสมจะช่วยลดจำนวน Segment ได้อย่างมาก และทำให้ Query เร็วขึ้นอย่างเห็นได้ชัด
6. การ Troubleshoot ปัญหาที่พบบ่อยใน Production
6.1 ปัญหา: Query ช้าเกินไป (High Query Latency)
สาเหตุที่เป็นไปได้และการแก้ไข:
- Segment มีขนาดเล็กเกินไป: ตรวจสอบจำนวน Segment ต่อ DataSource หากมีมากกว่า 10,000 Segment ควรทำ Compaction
- Broker มี Heap ไม่พอ: ดูจาก GC log หากมีการ Full GC บ่อย ให้เพิ่ม Xmx ให้ Broker
- Query ที่ไม่มี Filter: การ Query โดยไม่มี Time filter จะทำให้ Druid ต้องสแกนทุก Segment ควรบังคับให้ Query มี Time range เสมอ
- Data Skew: หากบาง Segment มีข้อมูลมากกว่าปกติ (Hot Spot) ให้ปรับ Partitions Spec
6.2 ปัญหา: Ingestion Task ล้มเหลวบ่อยครั้ง
สาเหตุหลักๆ:
- Memory ไม่พอ: MiddleManager ถูก OOMKilled โดย Kubernetes เนื่องจาก
maxRowsInMemoryสูงเกินไป - Schema Mismatch: ข้อมูลที่ Ingest มี Data type ไม่ตรงกับที่กำหนดใน Ingestion Spec
- Timestamp format ผิด: ตรวจสอบว่า timestamp ในข้อมูลตรงกับ format ที่ระบุใน
timestampSpec
ตัวอย่างการแก้ไขปัญหา Memory ไม่พอ:
# ลด maxRowsInMemory และเพิ่ม workerCapacity
# ใน MiddleManager runtime.properties
druid.indexer.task.maxRowsInMemory=50000 # ลดจากค่า default 1,000,000
druid.indexer.runner.javaOpts=-Xmx4g -Xms4g -XX:+UseG1GC -XX:MaxGCPauseMillis=100
druid.worker.capacity=3 # ลดจำนวน Task ต่อ MiddleManager
6.3 ปัญหา: Data Duplication หรือ Data Loss
เมื่อเกิดเหตุการณ์ที่ข้อมูลซ้ำหรือหาย ควรตรวจสอบตามขั้นตอนต่อไปนี้:
- ตรวจสอบ
ingest/events/thrownAwayและingest/events/unparseableใน Metrics - ตรวจสอบ Task log ว่ามีข้อความ “WARNING” หรือ “ERROR” ที่เกี่ยวกับการ Parse ข้อมูลหรือไม่
- ตรวจสอบ Kafka offset (ถ้าใช้ Kafka ingestion) ว่ามีการ Commit offset ที่ถูกต้องหรือไม่
- ใช้ Druid SQL Query เพื่อตรวจสอบจำนวนข้อมูลระหว่าง Source และ Druid:
-- ตรวจสอบจำนวนแถวใน Druid
SELECT COUNT(*) AS total_rows,
TIME_FLOOR(__time, 'PT1H') AS hour
FROM "user_events"
WHERE __time >= '2026-01-15'
GROUP BY 2
ORDER BY 2;
7. Best Practices และ Real-World Use Cases
7.1 Best Practices สรุปสำหรับ DevOps
- Infrastructure as Code (IaC): ใช้ Terraform หรือ Pulumi ในการจัดการ Kubernetes cluster และ Druid deployment
- GitOps: ใช้ ArgoCD หรือ Flux ในการ Sync สถานะของ Druid cluster กับ Git repository
- Canary Deployment: เมื่ออัปเกรด Druid version ควร Deploy เพียง 1-2 Pod ก่อน แล้วค่อยๆ เพิ่มจำนวน
- Backup Metadata: ตั้งค่าให้ PostgreSQL (Metadata store) มีการ Backup อัตโนมัติทุกวัน เพราะถ้า Metadata เสีย ข้อมูลทั้งหมดจะไม่สามารถ Query ได้
- Network Isolation: แยก Network Traffic ระหว่าง Druid Service กับ External Traffic โดยใช้ Service Mesh (Istio หรือ Linkerd)
7.2 Real-World Use Case: E-Commerce Platform ขนาดใหญ่
บริษัท E-Commerce แห่งหนึ่งในประเทศไทยใช้ Apache Druid สำหรับการวิเคราะห์ Real-time Analytics โดยมีข้อมูลดังนี้:
- ปริมาณข้อมูล: 1.5 ล้าน events/วินาที (peak)
- จำนวน DataSource: 25 DataSource
- ขนาดข้อมูล: 50 TB (หลัง Compaction)
- Query SLA: P99 < 3 วินาที
ความท้าทายที่พบ:
- ในช่วง促销 (Flash sale) ปริมาณข้อมูลพุ่งสูงถึง 5 ล้าน events/วินาที ทำให้ MiddleManager ทำงานไม่ทัน
- มี Segment ขนาดเล็กมากกว่า 50,000 Segment หลังจากรันมา 3 เดือน
แนวทางแก้ไข:
- ใช้ Kafka Partitioning เพื่อกระจายข้อมูลไปยัง MiddleManager หลายๆ ตัว
- ปรับ Compaction Strategy ให้ทำงานทุกๆ 6 ชั่วโมง แทนที่จะเป็น 24 ชั่วโมง
- เพิ่ม Hot Tier (SSD) สำหรับข้อมูล 7 วันล่าสุด และ Cold Tier (HDD) สำหรับข้อมูลเก่า
- ใช้ Query Caching ใน Broker Layer เพื่อลดภาระของ Historical node
ผลลัพธ์: หลังจากปรับปรุงระบบ Query latency ลดลงจาก 8 วินาที (P99) เหลือ 1.5 วินาที และลดค่าใช้จ่ายด้าน Infrastructure ลง 30%
8. การรักษาความปลอดภัย (Security) สำหรับ Druid
8.1 การตั้งค่า Authentication และ Authorization
ในปี 2026 ความปลอดภัยเป็นสิ่งที่ไม่สามารถมองข้ามได้ Druid รองรับการ Authentication ผ่านหลายวิธี:
- Basic Auth: ใช้งานง่ายแต่ไม่ปลอดภัยสำหรับ Production
- Kerberos: สำหรับองค์กรที่ใช้ Hadoop ecosystem
- OAuth 2.0 / OpenID Connect: เป็นมาตรฐานที่แนะนำสำหรับองค์กรสมัยใหม่
ตัวอย่างการเปิดใช้งาน OAuth 2.0 ผ่าน Extension druid-oauth-extensions:
# common.runtime.properties
druid.auth.authenticatorChain=["oauth"]
druid.auth.authenticator.oauth.type=oauth
druid.auth.authenticator.oauth.clientId=druid-client
druid.auth.authenticator.oauth.clientSecret=your-client-secret
druid.auth.authenticator.oauth.issuerUrl=https://your-identity-provider/.well-known/openid-configuration
druid.auth.authenticator.oauth.scopes=["openid", "profile", "email"]
druid.auth.authorizerChain=["allowAll"] # หรือใช้ RBAC authorizer
8.2 การเข้ารหัสข้อมูล (Encryption)
ข้อมูลที่ Sensitive ควรได้รับการเข้ารหัสทั้งในขณะส่ง (In-transit) และขณะจัดเก็บ (At-rest):
- In-transit: เปิดใช้งาน TLS/SSL ระหว่าง Service ทุกตัวใน Druid cluster
- At-rest: ใช้ Encryption ที่ระดับ Disk (เช่น LUKS) หรือใช้ Cloud Provider’s encryption
Summary
Apache Druid เป็นเครื่องมือที่ทรงพลังสำหรับการวิเคราะห์ข้อมูลแบบ Real-time แต่การทำให้มันทำงานได้อย่างเสถียรและมีประสิทธิภาพในระดับ Production จำเป็นต้องมี DevOps Culture ที่แข็งแกร่ง ตั้งแต่การออกแบบ Infrastructure ที่เหมาะสม การทำ CI/CD สำหรับ Schema และ Ingestion Spec การ Monitoring ที่ครอบคลุมทุกมิติ ไปจนถึงการจัดการ Data Lifecycle อย่างเป็นระบบ
ประเด็นสำคัญที่ควรจดจำจากบทความนี้:
- เข้าใจ Component และ Resource Requirement: แต่ละ Service ใน Druid มีความต้องการทรัพยากรที่แตกต่างกัน ต้องจัดสรรให้เหมาะสม
- ใช้ Infrastructure as Code และ GitOps: ทุกการเปลี่ยนแปลงควรผ่านการ Review และมี Version Control
- Monitoring คือหัวใจ: อย่ามองข้าม Metrics ที่สำคัญ เช่น Data loss, Query latency, และ Segment count
- Compaction ไม่ใช่ optional: ถ้าอยากให้ Query เร็ว ต้องทำ Compaction อย่างสม่ำเสมอ
- Security ต้องมาก่อน: เปิดใช้งาน Authentication และ Encryption ตั้งแต่เริ่มต้น
ในปี 2026 และต่อจากนี้ Apache Druid จะยังคงเป็นตัวเลือกอันดับต้นๆ สำหรับองค์กรที่ต้องการ Real-time Analytics Platform การมีทีม DevOps ที่เข้าใจทั้งในเชิงลึกของ Druid และมีแนวทางปฏิบัติที่ถูกต้อง จะเป็นกุญแจสำคัญที่ทำให้องค์กรสามารถใช้ประโยชน์จากข้อมูลได้อย่างเต็มที่ โดยไม่ต้องกังวลเรื่องความเสถียรหรือประสิทธิภาพของระบบ
สุดท้ายนี้ ขอให้ทุกท่านโชคดีในการปรับใช้ Apache Druid และอย่าลืมว่าการเรียนรู้และการปรับปรุงอย่างต่อเนื่องคือหัวใจของ DevOps Culture ที่แท้จริง