הגדרת אשכול Elasticsearch ליישומי אינטרנט
כאשר עוברים ממופע Elasticsearch יחיד לאשכול, נתקלים לעיתים קרובות בבעיות לא מובנות מאליהן: split-brain, חלוקת shard לא מאוזנת, דליפות זיכרון. הכנו מדריך שלב אחר שלב להגדרת אשכול production על 3 צמתים — מהגדרת תפקידים ועד ILM. הניסיון שלנו מראה שאשכול מוגדר כראוי מחזיר את ההשקעה תוך חודש בלבד תחת עומס.
למה אשכול של שלושה צמתים?
צומת יחיד מתאים רק לפיתוח. Production דורש אשכול לסבילות לתקלות, קנה מידה אופקי ובידוד עומסים. אשכול של 3 צמתים הוא פי 10 אמין יותר ממופע יחיד: הוא שורד אובדן של צומת אחד ללא אובדן נתונים ומטפל בשאילתות מקבילות ביעילות. עבור רוב יישומי האינטרנט, זהו האיזון האופטימלי בין עלות לביצועים.
תפקידי צמתים
ב-Elasticsearch 8.x כל צומת יכול לבצע מספר תפקידים. עבור אשכולות קטנים (3–5 צמתים) כל הצמתים בדרך כלל משלבים את כל התפקידים. עבור אשכולות של 10+ צמתים, הפרדה היא חובה.
| תפקיד | מטרה | משאבים |
|---|---|---|
| Master-eligible | ניהול מצב האשכול, בחירת master | מקסימום 3 צמתים, CPU/RAM נמוך |
| Data | אחסון shard, חיפוש, אגרגציות | דיסקים מהירים (NVMe), RAM גבוה |
| Coordinating | קבלת בקשות, איזון עומסים, הרכבת תוצאות | CPU עבור scatter-gather |
| Ingest | עיבוד מקדים של מסמכים (ניתוח, העשרה) | CPU/RAM בינוני |
צומת Master-eligible – משתתף בבחירת master, מנהל את מצב האשכול. מינימום 3 צמתים master-eligible עבור quorum.
צומת Data – מאחסן shards, מבצע חיפושים. הכי עתיר משאבים: צריך דיסקים מהירים (NVMe) והרבה RAM עבור JVM heap ו-OS file cache.
צומת Coordinating (צומת לקוח) – מקבל בקשות לקוח, מפיץ לצמתי data, אוסף תוצאות. מקל על צמתי data בשלב scatter-gather.
צומת Ingest – מעבד מסמכים דרך ingest pipelines (ניתוח, העשרה, טרנספורמציה). הגדרת תפקיד ב-elasticsearch.yml:
---
# Master-only node
node.roles: [ master ]
# Data node
node.roles: [ data, data_content, data_hot, data_warm, data_cold ]
# Coordinating only node
node.roles: []
--- תצורת Production מינימלית: 3 צמתים
כל שלושת הצמתים הם master-eligible + data. זה מספק quorum (2 מתוך 3) ואחסון נתונים. # Master-only node node.roles: [ master ] # Data node node.roles: [ data, data_content, data_hot, data_warm, data_cold ] # Coordinating only node.roles: [] עבור צומת 1:
---
cluster.name: myapp-prod
node.name: es-node-01
node.roles: [master, data, ingest]
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
discovery.seed_hosts:
- es-node-01:9300
- es-node-02:9300
- es-node-03:9300
cluster.initial_master_nodes:
- es-node-01
- es-node-02
- es-node-03
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
בצמתים 2 ו-3 רק elasticsearch.yml משתנה.
cluster.name: myapp-prod node.name: es-node-01 node.roles: [master, data, ingest] network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 discovery.seed_hosts: - es-node-01:9300 - es-node-02:9300 - es-node-03:9300 cluster.initial_master_nodes: - es-node-01 - es-node-02 - es-node-03 path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.keystore.path: elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: elastic-certificates.p12 משמש רק באתחול הראשון של האשכול. לאחר שהאשכול נוצר, יש להעיר שורה זו — אחרת הפעלה מחדש עלולה לגרום ל-split-brain.
JVM וזיכרון
ברירת המחדל של Elasticsearch היא heap של 1 GB — נמוך באופן קריטי עבור production. כלל: heap = חצי מהזיכרון הזמין, אך לא יותר מ-31 GB (מעל 32 GB ה-JVM מאבד compressed oops).
ב-node.name:
-Xms16g -Xmx16g הזיכרון הנותר הולך ל-OS file cache — Elasticsearch משתמש ב-mmap בכבדות לקריאת מקטעי Lucene. בשרת עם 64 GB RAM: 31 GB heap + 30+ GB OS cache הוא אופטימלי.
כוונון מערכת:
# /etc/sysctl.conf
vm.max_map_count=262144
vm.swappiness=1
# /etc/security/limits.conf
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536 יצירת תעודות TLS והגדרת אבטחה
# Генерация CA и сертификатов для кластера
/usr/share/elasticsearch/bin/elasticsearch-certutil ca --out /etc/elasticsearch/elastic-ca.p12
/usr/share/elasticsearch/bin/elasticsearch-certutil cert \
--ca /etc/elasticsearch/elastic-ca.p12 \
--out /etc/elasticsearch/elastic-certificates.p12
# Установка пароля elastic пользователя
/usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
HTTP TLS (לחיבורי לקוח) משתמש בתעודה נפרדת:
xpack.security.http.ssl.enabled: true xpack.security.http.ssl.keystore.path: http.p12 איך להגדיר ILM כדי לחסוך במשאבים?
עבור לוגים ונתונים זמניים, מדיניות ILM היא חובה. בלעדיה, אינדקסים גדלים ללא הגבלה וממלאים את הדיסק. דוגמה למדיניות עם ארבעה שלבים:
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_age": "7d",
"max_size": "50gb"
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"freeze": {},
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
} הגדרת אשכול שלב אחר שלב
- ניתוח: קביעת עומס, נפח נתונים, תפקידי צמתים נדרשים.
- תכנון: בחירת מספר צמתים, גודל דיסק, הגדרות JVM.
- התקנה: פריסת צמתים על שרתים או קונטיינרים, הגדרת רשת.
- הגדרת אבטחה: יצירת TLS, הגדרת סיסמאות.
- ILM ותבניות: יצירת מדיניות מחזור חיים לאינדקסים.
- בדיקות: אימות בריאות האשכול, חלוקת shard, סבילות לתקלות.
- פריסה: חיבור היישום, הפעלת ניטור דרך Kibana.
מה כלול בהקמה סוהר
- פריסת אשכול על bare metal או ענן
- הגדרת TLS ואבטחה בסיסית
- הגדרת מדיניות ILM ותבנית אינדקס
- אינטגרציה עם Kibana לניטור
- תיעוד תפעולי
- הדרכת צוות בניהול בסיסי
- שבועיים של תמיכה לאחר השקה
בדיקת בריאות האשכול
# Статус кластера (green/yellow/red)
curl -u elastic:changeme http://localhost:9200/_cluster/health?pretty
# Список узлов
curl -u elastic:changeme http://localhost:9200/_cat/nodes?v
# Неназначенные шарды и причины
curl -u elastic:changeme "http://localhost:9200/_cluster/allocation/explain?pretty"סטטוס cluster.initial_master_nodes אומר שכל ה-primary shards מוקצים אך חלק מה-replicas לא. באשכול של צומת אחד זה נורמלי. באשכול של 3 צמתים /etc/elasticsearch/jvm.options.d/heap.options מצביע על בעיה.
חיבור מהיישום
PHP (Laravel / elasticsearch-php)
use Elastic\Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()
->setHosts(['https://es-node-01:9200', 'https://es-node-02:9200', 'https://es-node-03:9200'])
->setBasicAuthentication('elastic', 'changeme')
->setCABundle('/path/to/ca.crt')
->build();הלקוח מבצע sniffing אוטומטית — מגלה את כל צמתי האשכול ומאזן בקשות. אם צומת נכשל, הוא עובר לנותרים.
Python (elasticsearch-py)
from elasticsearch import Elasticsearch
es = Elasticsearch(
['https://es-node-01:9200', 'https://es-node-02:9200'],
basic_auth=('elastic', 'changeme'),
ca_certs='/path/to/ca.crt',
retry_on_timeout=True,
max_retries=3,
) לוח זמנים ואיך להזמין
פריסת אשכול של 3 צמתים עם TLS, ILM וניטור אורכת 5 ימי עבודה. העברת נתונים קיימים ממופע יחיד מוסיפה 1–2 ימים. העלות המדויקת מחושבת באופן אישי לאחר ביקורת. אנחנו עובדים כבר למעלה מ-5 שנים והשלמנו יותר מ-50 פרויקטים של Elasticsearch. קבלו ייעוץ מהמהנדסים שלנו — נספר לכם איזו תצורה אופטימלית למשימות שלכם.







