בעיה: קטלוג עם מאפיינים שרירותיים "שובר" את המודל הרלציוני
הקמנו MongoDB לחנות אלקטרונית: לכל קטגוריה יש סט מאפיינים ייחודי (אלכסון, מספר ליבות, גודל זיכרון). ב-PostgreSQL היינו צריכים לבנות EAV או שדות JSON — שאילתות מורכבות וירידה בביצועים עם 500 מוצרים. MongoDB פתר זאת ללא כאב: הסכמה אינה קבועה, ומסמכי BSON מתאימים למבנה המוצר בצורה מושלמת. הלקוח שלנו — חנות עם 5000 מוצרים ב-20 קטגוריות — קיבל זמני תגובה לשאילתות מתחת ל-10 אלפיות השנייה ללא אופטימיזציה מיוחדת. נספר לכם כיצד להקים מסד נתונים כזה באופן מלא.
בעיות שאנו פותרים
- שאילתות N+1 בעבודה עם מסמכים — טעות אופיינית כאשר במקום מערכים מקוננים, מסמכים קשורים נשלפים בשאילתות נפרדות. פתרון: שימוש ב-
$lookupבאגרגציה או אחסון תת-מערכים מקוננים. - כתיבה איטית ללא שכפול — כאשר צומת בודד נופל, נתונים אובדים לדקות. Replica Set של שלושה שרתים נותן RPO=0 ומעבר אוטומטי במקרה תקלה.
- אינדקסים אינם מכסים שאילתות — ללא אינדקסים חלקיים ומורכבים, אגרגציות לפי סטטוס ותאריך לוקחות שניות במקום אלפיות השנייה. עם אינדקסים מוגדרים כראוי, ביצועי השאילתות משתפרים פי 10–100.
כיצד הקמנו MongoDB: מקרה Replica Set
לאותה חנות אלקטרונית, פרסנו קלאסטר על שלושה שרתים (MongoDB 7.0, Ubuntu 22.04). הגדרנו Replica Set עם שני צמתים רגילים וצומת נסתר אחד לגיבויים. מחרוזת החיבור של היישום: mongodb://myapp:password@mongo1:27017,mongo2:27017/myapp?replicaSet=rs0&readPreference=secondaryPreferred. התוצאה — סובלנות לתקלות ואיזון קריאה לצמתים משניים. עומס של 10,000 בקשות בשנייה נתמך ללא עיכובים.
התקנה והגדרה
# Установка MongoDB 7.0
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" > /etc/apt/sources.list.d/mongodb-org-7.0.list
apt update && apt install -y mongodb-org
systemctl enable mongod && systemctl start mongod
# /etc/mongod.conf (основные настройки)
net:
port: 27017
bindIp: 127.0.0.1
# для продакшена замените на внутренний IP
security:
authorization: enabled
storage:
dbPath: /var/lib/mongodb
wiredTiger:
engineConfig:
cacheSizeGB: 2
# 50% RAM
replication:
replSetName: "rs0"
operationProfiling:
slowOpThresholdMs: 100
mode: slowOp
אינדקסים לשאילתות אופייניות
// Создаём индексы сразу при проектировании схемы
// Уникальный индекс по email
db.users.createIndex({ email: 1 }, { unique: true, background: true })
// Составной для сортировки заказов пользователя
db.orders.createIndex({ userId: 1, createdAt: -1 })
// Частичный — только активные сессии
db.sessions.createIndex(
{ userId: 1, expiresAt: 1 },
{ partialFilterExpression: { revokedAt: { $exists: false } } }
)
// TTL-индекс — автоудаление логов через 30 дней
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 })
// Текстовый поиск с русским языком
db.articles.createIndex({ title: "text", body: "text" }, { default_language: "russian" })
// Wildcard для каталога с произвольными атрибутами
db.products.createIndex({ "attributes.$**": 1 }) אגרגציה: הכנסות לפי קטגוריה
db.orders.aggregate([
{ $match: { createdAt: { $gte: ISODate("2024-01-01"), $lt: ISODate("2024-04-01") }, status: "paid" } },
{ $unwind: "$items" },
{ $lookup: { from: "products", localField: "items.productId", foreignField: "_id", as: "product" } },
{ $unwind: "$product" },
{ $group: { _id: "$product.category", revenue: { $sum: { $multiply: ["$items.price", "$items.quantity"] } }, orders: { $addToSet: "$_id" } } },
{ $project: { category: "$_id", revenue: { $round: ["$revenue", 2] }, orderCount: { $size: "$orders" } } },
{ $sort: { revenue: -1 } }
]) כיצד לבחור טופולוגיית MongoDB לפרויקט שלכם?
| טופולוגיה | עומס | נפח נתונים | סובלנות לתקלות | מורכבות ניהול |
|---|---|---|---|---|
| צומת בודד | עד 10,000 פעולות/שנייה | עד 100 GB | לא | נמוכה |
| Replica Set | עד 50,000 פעולות/שנייה | עד 10 TB | מעבר אוטומטי במקרה תקלה | בינונית |
| קלאסטר מפוצל (Sharded) | >50,000 פעולות/שנייה | >10 TB | גבוהה (קנה מידה אופקי) | גבוהה |
מדוע Replica Set הוא חובה לסביבת ייצור?
Replica Set הוא התצורה המינימלית לסביבת ייצור. צומת בודד אינו מספק סובלנות לתקלות: אם השרת נופל, הנתונים אינם זמינים עד לשחזור. Replica Set של שלושה צמתים מבטיח מעבר אוטומטי לצומת משני תוך שניות. RPO (נקודת שחזור) מתקרב לאפס. עבור רוב היישומים זהו האיזון האופטימלי בין אמינות לעלות. צרו קשר — נבצע ביקורת על הסכמה הנוכחית שלכם ונציע טופולוגיה אופטימלית.
תהליך
| שלב | מה אנו עושים | משך |
|---|---|---|
| ניתוח | לימוד עומס, סכמות, שאילתות אופייניות. קביעת צורך בפיצול (sharding). | יום אחד |
| עיצוב | בחירת טופולוגיה (Replica Set, פיצול), תצורת שרת, אינדקסים. | יום אחד |
| יישום | פריסת שרתים, הגדרת שכפול, יצירת אינדקסים, כתיבת מיגרציות. | 1–3 ימים |
| בדיקות | בדיקות עומס, בדיקת מעבר תקלה, ניטור. | יום אחד |
| השקה | מעבר לייצור, תיעוד, הדרכת צוות. | יום אחד |
מה כלול
- תצורת שרת ורשת (אימות, TLS)
- הקמת Replica Set או קלאסטר מפוצל
- יצירת אינדקסים לעומס (חלקיים, TTL, טקסט)
- אופטימיזציה של שאילתות אגרגציה
- אינטגרציה עם Mongoose/Node.js (סכמות, hooks, virtuals)
- הקמת ניטור (MongoDB Atlas, Prometheus + Grafana)
- גיבוי (mongodump + אוטומציה)
- תיעוד והוראות לצוות
טעויות אופייניות בהקמת MongoDB
- חוסר אינדקסים למיון —
# Установка MongoDB 7.0 curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" > /etc/apt/sources.list.d/mongodb-org-7.0.list apt update && apt install -y mongodb-org systemctl enable mongod && systemctl start mongod # /etc/mongod.conf (основные настройки) net: port: 27017 bindIp: 127.0.0.1 # для продакшена замените на внутренний IP security: authorization: enabled storage: dbPath: /var/lib/mongodb wiredTiger: engineConfig: cacheSizeGB: 2 # 50% RAM replication: replSetName: "rs0" operationProfiling: slowOpThresholdMs: 100 mode: slowOpללא אינדקס מוביל לסריקת אוסף (קריסת ביצועים). - התעלמות מגודל מטמון WiredTiger — ברירת מחדל 50% זיכרון RAM, עבור ערכות עבודה גדולות יש להגדיל ל-70%.
- אינדקס גלובלי
// Создаём индексы сразу при проектировании схемы // Уникальный индекс по email db.users.createIndex({ email: 1 }, { unique: true, background: true }) // Составной для сортировки заказов пользователя db.orders.createIndex({ userId: 1, createdAt: -1 }) // Частичный — только активные сессии db.sessions.createIndex( { userId: 1, expiresAt: 1 }, { partialFilterExpression: { revokedAt: { $exists: false } } } ) // TTL-индекс — автоудаление логов через 30 дней db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 }) // Текстовый поиск с русским языком db.articles.createIndex({ title: "text", body: "text" }, { default_language: "russian" }) // Wildcard для каталога с произвольными атрибутами db.products.createIndex({ "attributes.$**": 1 })על אימייל — חוסם רישום של אותו אימייל בסטטוסים שונים. השתמשו באינדקסים חלקיים. - כתיבה ל-Replica Set ללא
db.orders.aggregate([ { $match: { createdAt: { $gte: ISODate("2024-01-01"), $lt: ISODate("2024-04-01") }, status: "paid" } }, { $unwind: "$items" }, { $lookup: { from: "products", localField: "items.productId", foreignField: "_id", as: "product" } }, { $unwind: "$product" }, { $group: { _id: "$product.category", revenue: { $sum: { $multiply: ["$items.price", "$items.quantity"] } }, orders: { $addToSet: "$_id" } } }, { $project: { category: "$_id", revenue: { $round: ["$revenue", 2] }, orderCount: { $size: "$orders" } } }, { $sort: { revenue: -1 } } ])— במהלך גלגול לאחור של הצומת הראשי נתונים עלולים ללכת לאיבוד.
לוח זמנים ועלות
הקמה בסיסית של Replica Set עם אינדקסים וניטור — בין 2 ל-5 ימים. העלות מחושבת באופן אישי לפי מורכבות הסכמה ומספר הצמתים. צרו קשר להערכת פרויקט — נכין הצעה מסחרית תוך יום עסקים אחד. הזמינו הקמת MongoDB ממומחים מוסמכים עם 10 שנות ניסיון.
מדוע להזמין הקמה מאיתנו?
אנחנו מומחי MongoDB מוסמכים (מעל 10 שנות ניסיון בניהול NoSQL). הקמנו יותר מ-50 קלאסטרים לפרויקטים עם עומסים של עד 100,000 בקשות בשנייה. אנו מספקים אחריות על כל העבודות — בין 3 ל-12 חודשים לפי SLA. קבלו ייעוץ עכשיו — נעריך את הארכיטקטורה הנוכחית שלכם.







