הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
צוואר בקבוק של מערכת תוכן הוא בסיס נתונים, האומנם?
עודכן 02/11/2007.
לאחר סדרת הפוסטים בנושא ביצועים (כתיבה ב-++C, וורדפרס, מדידות) הכנתי חומר שמסכם את נושא הביצועים ומביא סדרת מדידות שמכינות בסיס קצת יותר מוצק לכל הנאמר וממחישות שלא כל מה שמקובל לחשוב עליו כבעיית הביצועים היא באמת בעיה. בנוסף, כנראה גם אני נפלתי לאותה המלכודת כשהתייחסתי לבסיסי נתונים בצורה לא לגמרי נכונה.
מה הדעה המקובלת בתחום פיתוח האתרים?
אני אביא לכאן את הציטוט של מאיר, אדם שלמעשה מחזיק את האתר WhatsUp למעלה.
מניסיון, במערכות כאלה הקוד הוא לא משמעותי ולא צוואר הבקבוק, אלא בסיסי הנתונים (מערכות ניהול תוכן, מעבר לטרוויאליות, מבצעות עשרות ומאות שאילתות עבור כל עמוד). קשה לי להאמין שתראה הבדל (ואולי אפילו תראה שינוי לרעה).
מסתבר שזה לא לגמרי נכון. כפי שציינתי בפוסטים הקודמים, הכנתי תשתית Web שמאפשרת עבודה מול Berkeley DB ובחנתי במקביל עבודה מול MySQL עם API מבוסס על C++/C. לצורך מטרה זו השתמשתי בבסיס נתונים אמיתי של הבלוג שלי.
המשימה הייתה לכתוב רכיב פשוט שימשוך פוסטים 10 אחרונים ויציג את התקצירים שלהם. השרת ששימוש אותי בניסויים היה lighttpd והתשתית FastCGI. הכנתי ארבע תוכנות שעשות זאת עבורי:
- תכנה שכתובה ב-php שמשתמשת ב-MySQL עם האצה ע"י php5-xcache.
- תכנה שכתובה ב-C שמשתמשת ב-MySQL.
- תכנה שכתובה ב-++C שמשתמשת ב-Berkeley DB.
- תכנה שכתובה ב-C ולוקחת דפי מוכנים לחלוטין מזכרון על מנת לבדוק מגבלה עליונה של הארכיטקטורה.
במהלך ניסויים ביצעתי משיכות של עמוד ראשי וכתבה בודדת בעזרת פקודה ab -c 5 -n 1000 URL ממחשב מקומי. זאת, על מנת לנטרל השפעת רכיבי תקשורת (וגם בגלל העדר מחשב נוסף שיכול לבצע עבורי את המשימה). החומרה שהרצתי עליה את המדידות היא AthlonXP 64 3000, 1G RAM. מערכת הפעלה Debian Etch 64bit.
התוצאות היו מפתיעות:
מערכת | עמוד ראשי | כתבה בודדת |
---|---|---|
PHP | 810 | 880 |
C, MySQL | 2020 | 2290 |
C++, Berkeley DB | 2040 | 2950 |
C, memory | 3100 | 3150 |
כפי שניתן לראות, יש הבדל בין שיטת העבודה הסטנדרטית בטכנולוגיית LAMP לבין הכנת הקוד ב-C++/C. לתוצאות האלו יש שתי בעיות:
- השוואת Berkeley DB מול MySQL:
- בעמוד הראשי בוצעה שאילתה אחת מורכבת יחסית, שמשכה את כל הנתונים במכה, לעומת זאת בעבודה עם Berkeley DB, בגלל האופי שלי היו עשרות פניות לבסיס הנתונים.
- באותה מידה, ביצירת דף בודד היו 3 פניות ל-MySQL ומצד שני, היו גם 3 פניות בלבד ל-Berkeley DB. במילים אחרות, כמעט ואין כאן התחשבות בעומס יתר שנוצר משליחת שאילת SQL מעל רכיבי התקשורת השונים.
- יצירת עמודים עצמם היא מאוד פשוטה וכוללת מספר מועט של פניות לבסיס נתונים כך שלא יכולה לייצג מערכת תוכן מורכבת אמיתית.
על מנת לשלול את הטענה השניה, החלטתי לעשות בדיקות מול מערכת תוכן אמיתית.
יש להבין מהו העומס האמיתי שנוצר על בסיס הנתונים ומהו העומס האמיתי שמערכת התוכן מייצרת? לצורך זה לקחתי שתי מערכות נפוצות:
- וורדפרס הידוע באיטיות שלו
- אחת מערכות פורומים הפופולריות ביותר -- phpBB2.
הפעלתי לוגים של MySQL ולקחתי בדיוק את כל שאילתות SQL שמערכת התוכן מבצעת. הרצתי אותן על יבש 1000 פעמים ובדקתי ע"י
time mysql -u username --password=pwd db_name <sql-requests_x_1000.sql >/dev/null
וחישבתי כמה שאילתות אופייניות (הדרושות ליצירת עמוד שלם) בשניה MySQL יודע לעשות. כמו כן, מדדתי: כמה דפים בשניה מערכת התוכן עצמה יודעת לייצר.
התוצאות מפריכות את כל הדעות המקובלות שבסיסי הנתונים הם אלה שמאיטים את המערכת:
מערכת | עמודים בשניה | שאילתות לעמוד | MySQL בלבד -- שאילתות לשניה לעמוד | סה"כ שאילתות לשניה |
---|---|---|---|---|
וורדפרס | 8.2 | 23 | 180 | 4,140 |
phpBB2 | 45 | 13 | 950 | 12,300 |
מסקנות:
- בסיסי נתונים אכן עושים את העבודה בצורה הטובה ביותר.
- קוד הסקריפטים מהווה צוואר בקבוק משמעותי ביצירת העמודים.
- אין להאמין לדעות מקובלות -- בדוק עובדות בעצמך
- יתרון של Berkeley DB בסופו של דבר, יכול להיות לא כל כך משמעותי על MySQL אם מייצרים את השאילתות בצורה חכמה.
כפי שניתן להבין מהתוצאות האלו, כל שפות הסקריפטים המקובלות בכתיבת האתרים בטכנולוגיית LAMP (קרי php/perl/python/ruby) לא מתאימות לכתיבת האתרים בעלי עומסים גבוהים במיוחד. בהנחה שאין הבדל משמעותי בין מהירות השפות האלו, שזו הנחה סבירה ביותר, מאחר והן מבוססות על אותן רעיונות של שערוך הקוד.
מצורף:
קוד של כל התוכנות ששימשו לבדיקת המערכת.
עדכון 1:
בעקבות ההערה של צפריר, חזרתי על ניסוי של מדידת ביצועי php באותה קונפיגורציה -- lighttpd עם FastCGI במקום apache2 עם mod-php5. מאחר ולא היו הבדל ביצועים ביניהם, לא חזרתי על אותם ניסוים עם מערכות תוכן אמיתיות phpBB2/וורדפרס.
עדכון 2:
מאיר, עזר לי ושיפר את הסקריפט שהשתמשתי בו, בנוסף להכל, התקנתי מאיץ php ששיפור ביצועים עוד קצת -- xcache. הטבלה עודכנת. כרגע ההבדל בביצועים הוא כבר לא בסדרי גודל אלא פי 3 בלבד, מה שאומר שיש להשקיע ביישום שמבצע את רוב העבודה שאחת המערכות התוכן עושה ולהשוות.
תגובות
או אולי הבעיה היא בקוד PHP לא אופטימלי שכתבת.
מה ייקח פחות זמן תוכניתן (עבור מערכת מספיק מורכבת) - אופטימיזציה לקוד בשפה דינאמית או טיפול במחרוזות ב־C?
ואגב: משתנה אחד נשאר: apache לעומת lighttpd/fastcgi .
לדוגמה: מה קורה אם אתה מריץ את כל הדברים הללו ב־fastcgi של אפאצ'י?
הקוד מצורף, אתה מוזמן להסתכל. אבל עד כמה שאני רואה, הוא לא עד כדי כך גרוע. בנוסף, אני גם עשיתי השוואות של הזמן הדרוש לביצוע קריאות SQL וזמן יצירת דף שלא אני כתבתי, אלא כתבו אנשים שמכירים php קצת יותר טוב ממני.
מצטער, אני לא מקבל את זה: א. ב-++C הטיפול במחרוזות הרבה יותר קל (אם אתה לא רוצה לחשוב). ב. כמה זמן תכניתן יקח לממש לערכת מבוזרת עם DB Replication ועם שימוש ב-memcached כולל השילוב שלו בתוכנה? יותר מטיפול מחרוזות ב-C. ג. אני לא מתייחס לזמן תכניתן אני מתייחס לארכיטקטורה שמתאימה לסביבה עמוסה או לא.
בניגוד מה שמייחסים -- lighttpd הוא לא הרבה יותר מהיר בתנאים שציינתי, יש לו חתימת זכרון יותר נמוכה, הוא יודע להתמודד טוב יותר עם עומסים בעלי concurrency גבוה כאשר צד הלקוח לא מסוגל להוריד תכן במהירות. כל אלו לא היו קריטיים בסביבת ניסוי
בנוסף, אני מצפה ש-mod-php לא אמור להיות הרבה יותר גרוע ב-fastcgi (אם לא יותר טוב).
ההבדל המשמעותי עדיין נשאר -- בכל פעם מריצים את הסקריפט מהתחלה.
בכל מקרה, אני לא אמור לקבל הבדלים בסדרי גודל.
נ.ב.
הגדרתי lighttpd+php5 וכצפוי קיבלתי בדיוק אותם זמני הריצה. כך שזה ממש לא משנה.
שיפרתי לך קצת את הקוד של הPHP: http://rafb.net/p/M72Cal64.html
איך אתה בודק כמה שאלתיות הקוד שלך מריץ בשנייה ואיך אפשר לקבל את כל השאלתיות שנעשו על המסד מהטרמינל?
תודה רבה, אני אבוק אותו בערב.
התייחסתי לזה אבל אסביר שוב: - ניתן להפעיל log של MySQL שבו הוא רושם את השאילתות (ב-/etc/mysql/my.ini) או משהו כזה. בונים דף, מסתכלים בלוג. חשוב! לא להריץ בדיקת ביצועים עם הלוג מופעל - הוא performance killer.
אני לוקח את כל השאלתות ורושם אותם קובץ r.sql ולאחר מכן בונה קובץ עם 1000 שאילתות כאלה ע"י שכפול: for x in {1..1000} ; do cat r.sql >>all.sql ; done ומריץ עם שורת פקודות שנתתי בפוסט עצמו time mysql <all.sql >/dev/null
מכאן ניתן לראות את הזמן הדרוש לביצוע שאילתה בודדת.
http://blog.ulf-wendel.de/?p=164
תנסה גם עם PHP ו mysqlnd - זהו דרייבר חדש של mysql ל PHP שלא מבוסס על ספריית ה C שמסופקת אלא מתממשק ישירות לתוך מנוע PHP. זה אמור להוות שינוי משמעותי בביצועים. מסתבר שבדרייבר הישן היתה באמת כפילות נוראית. כלומר - הנתונים קודם נשמרו בדרייבר ולאחר מכן שוכפלו ל PHP .
כמו כן - האם הקונפיגורציה שלך כוללת APC ? http://www.php.net/manual/en/ref.apc.php זה אמור לחסוך את תהליך הקימפול מחדש כל פעם.
כמו כן - יש חבילת שיפור ביצועים לשרת שחברת זנד מציעה. זה אמנם מוצר סגור אבל ניתן להוריד ולנסות רק לצורך ההשוואה.
אני מתכוון לבדוק אחד מ"מאיצי php" בזמן הקרוב. בנוסף, קיבלתי גם ממאיר נקודה חשובה לשיפור קוד ה-php.
למרות שאני מניח שאתה קורה לינמגזיון, אבל מכיוון שלא הגבת: http://linmagazine.co.il/hacking/01/11/2007/klone-2-released
נכון נדב,
וודאי שראיתי את הכתבה. אבל תשים לב, ל-Klone יש מטרות שונות לחלוטין. הוא לא נבנה בשביל לספק סביבה בעלת ביצועים יוצאים מן הכלל. מדובר כאן בפרוייקט שמכוון לתחום Embedded שבהם שימוש בשפות תסריטים הוא "overkill".
למשל, מדוע אני לא מצפה מ-klone להיות מהיר יותר ממשהו שכתוב ב-php (אפילו שזה יכול להיות). מכיוון שהוא בעצמו מהווה שרת אינטרנט וודאי לא יספק את אותם הביצועים כמו lighttpd או אפילו apache2. גם עבודה מול CGI היא מאוד לא יעילה -- על כל שאילתה נכנסת עולה process חדש, וזה מאוד יקר (בגלל זה פיתחו FastCGI שמאפשר לשרת לעבוד מול presitent process).
במילים אחרות, הפרויקט מאוד מעניין אבל הוא לא מתאים למה שאני מחפש -- מערכת תוכן שיודע לעמוד בעומסים גדולים במיוחד, כי זה פשוט לא היעד שלו.
היי ארתיום, אני מנסה לבדוק את הסקריפט שלך עם ROADSEND קומפילר רק בשביל המספרים אך אין לי את בסיס הנתונים שהשתמשת בו וגם אין לי כח להתקין וורדפרס בשביל זה אז אם תואיל בטובך לשים איפושהו את קובץ הSQL שהשתמשת בו לבדיקה (טבלאות + רשומות) אני ישמח לדווח לכם איך ROADSEND מתפקד. אם אין לכם עניין בתוצאות הללו כי אחרי הכל זה קוד PHP שמקומפל לC אז תכסוך לי זמן יקר ותרשום פה שזה לא מעניין.
תודה.
אני מתכוון לבדוק את RoadSend בזמן הקרוב, על מערכת אמיתית כמו WP או phpBB.
לגבי בסיס הנתונים:
מכיוון שמדובר ב-DB אמיתי שמכיל מידע חסוי (למשל כתובות דוא"ל של המבקרים) וגם מידע פרטי אני לא מתכוון לפרסם אותו.
הוסף תגובה:
חובה לאפשר JavaScript כדי להגיב.