השבוע ביצעתי הטמעה של Auto Suggestion Search (ובעברית שבורה: "חיפוש מוצע אוטומטית") עבור אחד מלקוחותיי בחו"ל, ללקוח יש אתר עם מספר גדול של מאמרים והוא מעוניין לשפר את חווית המשתמש בחיפוש באתר.
השתמשתי בסקריפט מוכן: "A fancy Apple.com-style search suggestion", ערכתי את הסקריפט והתאמתי את השאילתות למסד הנתונים של הלקוח והטמעתי את הקוד החדש בתוך העיצוב הקיים.
לאחר מכן עלתה סוגיה נוספת שדורשת פתרון, ללקוח יש עשרות אלפי מבקרים באתר ביום, הטמעת התוסף תיצור עוד עשרות אלפי בקשות ל-MySQL ביום, ללא התוסף מספר הפניות ל-MySQL נמוך מאוד בגלל שימוש ב-Nginx ו-Varnish ל-Cache.
הפתרון הפשוט יהיה ליצור מנגנון Cache ב-Nginx לשאילתות ה-Auto Suggest, אבל הבעיה שמילה כמו: "architecture" תדרוש 10 קבצי Cache שונים (קובץ 1 ל-3 אותיות הראשונות ו-9 נוספים עבור כל אות נוספת) ובמהרה ה-Cache של Nginx יכיל מיליון קבצי Cache וזה יאט את המערכת בצורה דרסטית.
כדי לא להציף את Nginx, זנחתי את השימוש ב-Cache של Nginx ובמקום התקנתי את Memcached וערכתי את הסקריפט שיבצע את הפעולה הבא:
QueryString: architecture$
Pull $QueryString "architecture" from memcached.
If (!$QueryString)….
Pull from MySQL, Update Memcached
כל שאילתה תעבור קודם כל דרך Memcached, במידה והנתונים לא נמצאים ב-Memcached, תתבצע פנייה ל-MySQL, משיכת הנתונים והכנסת הנתונים ל-Memcached.
הפתרון עובד מעולה, בשעות הראשונות הורגש עומס קליל ולאחר מכן העומס ירד.
2 הערות:
1. בסקריפט המקורי השאילתות מתבצעות באמצעות בקשת POST,
בגלל שבקשת POST איטית יותר מ-GET (משום שב-POST, הדפדפן מתחבר לשרת, שולח נתונים ואז ממתין לקבלת תשובה, בעוד שב-GET הדפדפן מתחבר ושולח נתונים באותו הזמן), ערכתי את הסקריפט ושאילתות מתבצעות באמצעות בקשת GET.
2. Memcached הוא סופר מהיר משום שהמידע מאוחסן על זכרון ה-RAM, במידה ו-Memcached קורס/או שהשרת מופעל מחדש, כל ה-Cache שב-Memcached נמחק.
אהבתי אחי רעיון יפה 🙂