מסדי נתונים לסדרות זמן: TimescaleDB, InfluxDB ולמה Postgres נחנק במטריקות

מאת צוות מדיה דיל · 25.06.2026 · טכנולוגיה · 5 דק׳

Hypertables ו-chunks לפי זמן, tags ו-fields ב-InfluxDB, Continuous Aggregates, Retention Policies ו-Downsampling, כתיבות בקצב גבוה של מטריקות.

מערכת שאוספת מטריקות מכל שרת ומכל מכשיר IoT כל כמה שניות מייצרת קצב כתיבה שמסד נתונים רגיל לא בנוי בשבילו: מיליוני INSERT-ים בדקה, כמעט תמיד עם timestamp עולה, וכמעט אף פעם לא UPDATE. Postgres רגיל נחנק בעומס כזה כי כל INSERT דורש עדכון אינדקסים, בדיקת constraints וכתיבה ל-WAL בנפרד, וטבלה שגדלה כל הזמן הופכת בהדרגה גם את השאילתות איטיות יותר. מסדי time-series כמו TimescaleDB ו-InfluxDB נבנו סביב ההנחה שכתיבה היא אירוע חד-פעמי לפי זמן, לא רשומה שמתעדכנת. ההנחה הזו משנה כמעט כל החלטת עיצוב במנוע — מבנה האינדקסים, אסטרטגיית הדחיסה וגם צורת השאילתות שהשפה תומכת בהן כברירת מחדל.

Hypertables: partitioning אוטומטי לפי זמן

TimescaleDB, כתוסף ל-Postgres, מציג hypertable שנראה כלפי חוץ כטבלה רגילה אבל מחולק מאחורי הקלעים ל-chunks לפי טווחי זמן (ולפעמים גם לפי מפתח נוסף כמו device_id) — הרחבה אוטומטית של אותו עיקרון partitioning שמתוחזק ידנית ב-Postgres רגיל. כתיבה חדשה תמיד פוגעת ב-chunk האחרון והכי "חם", שקטן מספיק כדי שהאינדקסים שלו יישבו כולם בזיכרון, ושאילתה שמסננת לפי טווח תאריכים מדלגת אוטומטית על chunks שלמים שלא רלוונטיים. גודל ה-chunk עצמו מתכוונן, לרוב סביב שבוע או יום בהתאם לקצב הכתיבה, כך שכל chunk בודד נשאר קטן מספיק לביצועים טובים אבל לא כה קטן שהמערכת מבזבזת זמן בניהול אלפי chunks זעירים.

InfluxDB ומודל הנתונים הייעודי

InfluxDB לוקח גישה שונה: הוא לא Postgres מורחב אלא מסד נתונים שנכתב מהיסוד למטריקות, עם מודל נתונים של measurement, tags (מאונדקסים, לסינון) ו-fields (הערכים המספריים עצמם, לא מאונדקסים), ומנוע אחסון עמודתי-דחוס שמותאם לטורי זמן. שפת השאילתות שלו (Flux או InfluxQL) חושבת במונחי חלונות זמן כברירת מחדל — "ממוצע לכל 5 דקות" הוא ביטוי טבעי, לא GROUP BY מסורבל. tags מאונדקסים תמיד, כך שסינון וקיבוץ לפי מקור המדד (שרת מסוים, אזור גיאוגרפי, גרסת אפליקציה) מהיר בכל היקף, בעוד ש-fields נועדו לערכים המספריים עצמם שמצטברים ולא לסינון.

Continuous Aggregates ו-Downsampling

שאילתת "מגמה של שנה אחרונה" על נתונים גולמיים ברזולוציה של שנייה היא בזבוז — אף אחד לא צריך לראות מיליוני נקודות בגרף. Continuous aggregates (ב-TimescaleDB) או continuous queries (ב-InfluxDB) מחשבים מראש אגרגציות ברזולוציות גסות יותר — ממוצע לדקה, לשעה, ליום — ומעדכנים אותן ברקע תוך כדי שנתונים חדשים נכנסים, בדומה לעיקרון של materialized views אבל מותאם במיוחד לחלונות זמן מתגלגלים.

Retention Policies וניהול נפח

נתוני מטריקות גולמיים ברזולוציה גבוהה לא שווים לשמור לנצח — retention policy מגדירה אוטומטית מתי chunk ישן נמחק או מועבר לאחסון זול יותר, בעוד שהאגרגציות המחושבות מראש (שנפחן קטן בהרבה) יכולות להישמר לשנים. תבנית נפוצה היא לשמור נתונים גולמיים ל-30 יום, ממוצעי שעה לשנה, וממוצעי יום לצמיתות — כך שגודל האחסון נשאר יציב גם כשהמערכת אוספת נתונים ברציפות. בלי retention policy מוגדר, טבלת מטריקות פשוט גדלה לנצח, וגם אם הכתיבות עצמן מהירות, גיבוי, replication ותחזוקה שגרתית כמו vacuum הופכים איטיים ויקרים יותר ככל שהנפח ההיסטורי מצטבר.

מתי לא צריך מסד time-series ייעודי

אם קצב הכתיבה נמוך (עשרות עד מאות רשומות בשנייה) ואין צורך באגרגציות מתגלגלות מורכבות, Postgres רגיל עם partitioning ואינדקס על timestamp מספיק בהחלט, וחוסך את העלות התפעולית של מערכת נוספת. מסד time-series ייעודי משתלם כשקצב הכתיבה נמדד באלפים ומעלה בשנייה, או כשצריך retention ו-downsampling אוטומטיים כתכונת ליבה ולא כלוגיקה מותאמת אישית בקוד האפליקציה.

אוספים מטריקות בקצב שהמסד הקיים כבר לא עומד בו? נשמח לעזור לכם בוואטסאפ.

תגיות: Time Series Database · TimescaleDB · InfluxDB · Hypertables · Downsampling · Retention Policy

← חזרה לבלוג · צור קשר