ארכיון עבור הקטגוריה FireStats
הערה: יש סקר בסוף.
סקירה היסטורית
בראשית היה ASCII (האמת היא שהיו קידודים לפני ASCII אבל הם לא מעניינים אותנו).
אסקי נועד בעיקר לתווים באנגלית, הערך של 'A' הוא 65, הערך של רווח הוא 32 וכן הלאה. ASCII הוא קידוד 7 ביטים, מה שאומר שהוא משתמש ב128 אפשרויות מתוך 256 האפשרויות שנכנסות בbyte.
הבעיה עם אסקי היא שהוא לא כולל תווים של שפות אחרות - קירילית ועברית למשל.
Code page
הפתרון המתבקש הוא להשתמש בערכים 128-255 כדי לייצג את האותיות החסרות.
הבעיה היא שהרבה אנשים חשבו על הפתרון הזה בו זמנית, ומטבע הדברים היו הרבה טבלאות כאלו, לפעמים אפילו כמה בתוך אותה מדינה.
לא נחמד, כי מסמך שנכתב תוך שימוש בטבלא אחת לא הוצג כמו שצריך למי שהשתמש בטבלא אחרת.
בשלב מסויים הוגדרו סטנדרטים על ידי ארגון התקינה האמריקאי (ANSI) , שנקראו Code pages, מה שעזר למנוע הווצרות של טבלאות מיותרות חדשות.
הבעיה העיקרית עם הפתרון הזה הוא שאי אפשר לערבב שפות שמשתמשות בקודים שונים.
בנוסף, הוא נותן פתרון רק לשפות בעלות פחות מ128 אותיות.
באסיה הוגדר תקן בשם DBCS - Double byte character set, שנועד לתת פתרון לשפות האסיאתיות.
התקן הזה השתמש בקידוד באורך משתנה: חלק מהתווים היו באורך בייט אחד וחלק באורך שני בייטים, ובאופן כללי היה מבלבל למדי.
UNICODE
יוניקוד הוא שם הקוד לטבלא גדולה מאוד שמתאימה מספר לכל אות ידועה (וגם כמה משפות מומצאות כמו קלינגונית), מכיוון שיש טבלא אחת לכל השפות - אין בעיה לערבב בין שפות שונות.
מיתוס נפוץ הוא שניתן לייצג כל אות ביוניקוד בעזרת מספר בין 16 סיביות (או במילים אחרות, שיש פחות מ65536 אותיות ביוניקוד).
זה לא נכון, ולמעשה יש ביוניקוד גרסא 4.0 קרוב ל240,000 סימנים, מה שאומר שצריך לפחות 3 בתים כדי למספר את כל התווים ביוניקוד.
מחרוזת ביוניקוד היא בסך הכל סדרה של מספרים, כאשר כל מספר הוא המיקום של אות מסויימת בטבלא.
מקובל לסמן תו יוניקוד בסימן כמו U+0041, כאשר U+ אומר שזה יוניקוד והמספר שאחריו הוא קוד האות בבסיס הקסדצימלי.
לא במקרה, 128 התווים הראשונים ביוניקוד הם בדיוק אותם 128 התוים הראשונים באסקי וברוב קידודי הCode page.
המחרוזת hello ביוניקוד תכתב ככה:
U+0048 U+0065 U+006C U+006C U+006F
אם נשמור את זה, נקבל:
00 48 00 65 00 6C 00 6C 00 6F
או
48 00 65 00 6C 00 6C 00 6F 00
תלוי בשיטת בה אנחנו מקודדים ספרות בזכרון המחשב (Little endian או Big endian).
כדי להבחין בין שתי השיטות ישנה תוספת של התווים FE FF בתחילת מחרוזת יוניקוד (שתראה ככה או הפוך, לפי הEndianness של המכונה).
הסימון הזה נקרא Unicode Byte Order Mark, או בקיצור BOM - והוא גורם ללא מעט צרות לדפדפנים שכתובים רע.
UTF-8
באו האמריקאים ושאלו, מה אנחנו צריכים את האפסים האלו באמצע המחרוזת? הרי המחרוזת תופסת פי שתיים, והם גם מבלבלים תוכנות שמתייחסות ל0 בתור סימון לסוף המחרוזת (מקובל בC וC++).
וככה נולד UTF-8.
UTF-8 הוא שיטה לקידוד יוניקוד בקידוד בעל אורך משתנה.

כשקוראים UTF-8, מסתכלים על התו הראשון ולפי הביטים הראשונים אפשר לדעת בדיוק על כמה בתים האות הבאה יושבת.
UTF-8 הפך לסטנדרט המקובל ביותר לקידוד מחרוזות יוניקוד.
PHP ויוניקוד
PHP התמיכה של PHP 4 ו5 ביוניקוד חלקית ביותר.
מחרוזות בPHP הן בעצם סדרה של בייטים ולא יותר ולמרות שתמיד אפשר להשתמש במחרוזת PHP כדי לשמור מחרוזות בקידודים שונים - רק במקרה שהPHP קומפל עם תמיכה בmb_string יהיו לנו פונקציות מיוחדות לטיפול במחרוזות מרובות בתים.
פתרון נוסף הוא להשתמש בספריה iconv, שמוסיפה לPHP יכולות המרה של קידודים, אבל היא לא מגיעה כברירת מחדל עם PHP ומי שרוצה תוכנה שתוכל לרוץ בקלות בכל מחשב ימנע ממנה.
בPHP 6 שמתבשל לאיטו צפויה תמיכה ביוניקוד, UTF-8 וכל זה, אבל זה עדיין לא שוחרר, ואם לשפוט לפי הקצב שלוקח לשוק לאמץ את PHP5 - אז PHP6 לא יהיה רלוונטי בשנים הקרובות למי שרוצה לשחרר תוכנה שתרוץ בכל מחשב.
מכיוון שהפונקציות הסטנדרטיות בPHP תומכות בעצם רק בקידוד שבו כל אות תופסת בייט אחד, הן יכולות ליצור בעיות מעניינות.
אם תקבלו מחרוזת שמקודדת בUTF-8, נניח "שלום", ותציגו אותה בדפדפן האורך שלה יהיה 4 אותיות. אם תשתמשו בפונקצית הPHP לחישוב אורך של מחרוזות, תקבלו שהאורך שלה הוא 8 תווים, כי כל אות מקודדת בשני בתים.
אם תנסו את אותו דבר על המחרוזת המעורבת "שלום SHALOM", תקבלו שהאורך הוא 8 + 1 + 6 = 15.
לעומת זאת, אם תשתמשו בmb_strlen תקבלו את האורך הנכון.
בעיה נוספת היא בעיה של חיתוך מחרוזות UTF-8.
אם נשתמש בפונקציה wordwrap לחיתוך מחרוזות UTF8, היא עלולה לחתוך אות בין שני הבתים שלה, ובעצם להעלים אותה. לא נעים.
הפתרון שלי היה לכתוב גרסא של wordwrap שעובדת על מחרוזות UTF-8.
אפשר להבין למה מפתחי PHP מתבלבלים כשהם מתעסקים עם מחרוזות בUTF-8.
המרות וקיבועים
למרות שרוב אתרי האינטרנט בימינו השכילו לעבור לUTF-8 לקידוד של מחרוזות, עדיין יש אתרים מסויימים שמשתמשים בקידודים מבוססי Code page. למשל - מנוע החיפוש של Walla מקודד לפעמים את מילות החיפוש בכתובת בקידוד עברית 1255 (עברית חלונות), ולפעמים בקידוד UTF-8. מאוד נחמד מצידם של המפתחים לפחות להעביר את הקידוד כחלק מהכתובת (e=hew לעברית 1255 וe=utf לutf8).
לא חסרות דוגמאות אחרות, בעיקר במנועי חיפוש מקומיים (yandex.ru, mail.ru שמשתמשים בקידוד קירילי 1251) ועוד.
מכיון שאני רוצה שמילות החיפוש יוצגו כמו שצריך בFireStats, צריך להמיר את הקידודים האלו לUTF-8.
הבעיה היא שכאמור - אין תמיכה מובטחת בiconv שמאפשר המרות כאלו, ולכן נאלצתי לכתוב בעצמי ספריית המרות קטנה מקידודי codepage כלשהם לקידוד UTF8. הספריה מסתמכת על טבלאות המרה שאפשר להשיג באתר הראשי של יוניקוד.
הרעיון של הספריה הוא להמיר באמצעות הטבלא את המחרוזת ליוניקוד, ואז לקודד אותה לUTF8.
וזו האגדה על אסקי יוניקוד וUTF-8.
 Loading …
 Loading …
קריאה נוספת
Joel on software במאמר מצויין על יוניקוד
מצגת על השרדות עם UTF-8
שאלות נפוצות על יוניקוד וUTF-8 בלינוקס ויוניקס
19 תגובות »
במסגרת מקצה אופטימיזציות לFireStats מימשתי מנגנון נוסף לקליטת כניסות.
המנגנון הרגיל בו כולם משתמשים היום בודק שהכניסה לא צריכה להיות מסוננת (כניסה של רובוט ידוע או IP מסונן למשל), ומכניס את הנתונים בצורה מנורמלת.
נירמול בסיס נתונים נועד למנוע כפילויות, מה שעוזר במניעת אנומליות ובחיסכון במקום. בFireStats הנרמול מתבטא בכך שכל כתובת נשמרת פעם אחת בטבלאת הURLים, כל UserAgent בטבלאת הUserAgents וכדומה. כאשר מכניסים את הנתון העיקרי של כל הכניסה, משתמשים במזהה של כל נתון מנורמל.
המשמעות של זה בזמן הכנסת הנתונים היא כזו:
הגיעה כניסה עם כתובת מסויימת, מפנה מסויים ודפדפן (UserAgent) מסויים. לכל אחד מהנתונים האלו מבצעים פחות או יותר את סדרת הפעולות הבאה:
הכנס לטבלא הרלוונטית עם INSERT IGNORE, מה שמונע שגיאה במקרה שהנתון כבר נמצא שם (הטבלאות מוגדרות לא לקבל רשומות כפולות).
בדוק מה המזהה של הנתון שהכנסנו (אם הוא נכנס, אז זה יהיה מזהה חדש, אם לא זה יהיה המזהה שנבחר בפעם הראשונה שהכנסנו את הנתון לטבלא).
לבסוף, הכנס שורה לטבלאת הכניסות תוך שימוש במזהים שמצאנו בצעדים הקודמים.
זה קצת יותר מורכב מזה כי גם צריך לזהות ולסנן כניסות מסויימות כאמור.
כל התהליך הוא איטי למדי.
יצרתי קובץ CSV עם 100,000 כניסות (מfirestats.cc) והשתמשתי בו למדידת הביצועים:
בשיטה של הכנסה מנורמלת של כל כניסה, הקצב מתחיל די לא רע עם 80 כניסות לשניה, אבל ככל שבסיס הנתונים מתמלא הוא יורד עד שמתייצב על 7-8 כניסות לשניה.
למרות שקצב כזה בהחלט מספיק לכל בלוג מצוי, הוא ממש לא מספק לאתרים רציניים יותר או לבלוגיות עתירות בלוגים.
כשהוספתי תמיכה בWPMU בFireStats 1.4, חזיתי (חודשים לפני שביצעתי את המדידות) שקצב הכניסות יכול להיות בעיה בבלוגיות והוספתי שיטה חדשה לקליטת נתונים.
במקום לקלוט את הנתונים בצורה מנורמלת, הנתונים נקלטים לטבלאת כניסות ממתינות בצורה לא מנורמלת עם INSERT DELAYED. המשמעות של הDELAYED היא שבסיס הנתונים מכניס את הנתונים בזמנו הפנוי, ולא מחזיק את הקורא עד שהנתון הוכנס ממש.
עדיין צריך לנרמל את הנתונים, ולכל כתבתי סקריפט PHP פשוט שעובר על הכניסות הלא מנורמלות בטבלא אחת אחת, ולכל אחת קורא לפונקציה הרגילה שקולטת נתונים ומנרמלת אותם, ולבסוף מוחק את הכניסה מטבלאת הכניסות הממתינות. (מנהל המערכת אחראי לדאוג שהסריפט ירוץ בפרקי זמן סבירים, למשל באמצעות cron).
אני שומע אתכם צועקים: כן, אבל זה יהיה איטי לפחות כמו קודם, אם לא יותר!
זה נכון, אבל לפחות זה מאפשר לתזמן את העיבוד של הכניסות לזמנים פחות עמוסים כמו הלילה.
חיסרון נוסף הוא שהמשתמשים כבר לא מקבלים את הנתונים בזמן אמת, אלא נתונים שנכונים נכון לזמן העיבוד האחרון של הכניסות בטבלאת הממתינים.
אחרי שמדדתי את הזמן שדרוש כדי להכניס 100,000 כניסות בשיטה הרגילה, כמובן שמדדתי את הזמן שדרוש בשיטה המעוכבת, שנועדה לשפר ביצועים.
מסתבר שבשיטה המעוכבת, FireStats קולט בסביבות ה1000 כניסות לשניה, אבל המילכוד הוא שהנתונים עדיין דורשים עיבוד כדי שיהיו שימושיים, והעיבוד יקר בדיוק כמו הטיפול הרגיל.
הצעד הבא הוא כמובן לשפר את הביצועים של העיבוד הנ"ל.
כבר מהרגע הראשון שכתבתי אותו, היה לי ברור שדרושה פה אופטימיזציה רצינית, והיה לי גם ברור שהיא תהיה מסובכת.
האופטימיזציה מתבססת על התובנה הבאה:
בתוך קבוצת כניסות שנקלטו בפרק זמן מסויים, יהיו חזרות רבות מאוד של כתובות, מפנים ודפדפנים.
מה אם במקום לטפל בהם אחד אחד, נטפל בהם בקבוצות? נניח 1000 כניסות בכל קבוצה?
במקום 1000 כתובות ו1000 מפנים, יהיו לנו משהו כמו 300 כתובות (שכוללים מפנים).
במקום משהו כמו 1000 דפדפנים יהיו לנו משהו כמו 50 או 100 דפדפנים.
עכשיו נצטרך להכניס את כל מה שחדש לבסיס הנתונים, לחלץ את המזהים שלהם, ולבסוף להכניס את הכניסות עצמן תוך שאנחנו משתמשים במזהים מקודם, רק שהפעם נכניס 1000 כניסות במכה במקום כניסה אחת.
המשמעות של זה היא בעצם לממש את הפונקציה שמכניסה כניסה בודדת - אבל לרוחב, כך שתהיה ברוחב של k כניסות (קבוע כלשהו).
המימוש של זה מורכב, ולמעשה לקח יותר מפי עשר שורות קוד מהמימוש התמים הקודם, אבל הביצועים סוכר:
מעיבוד של 8 כניסות בשניה, עליתי לעיבוד של 600 כניסות לשניה.
שיפור של פי 75!
עכשיו נשאר רק לבדוק נכונות.
אם אני לוקח חבילת כניסות נתונה, ומכניס אותה השיטה המיידית אך האיטית, או מכניס אותה בשיטה המעוכבת אך המהירה התוצאה בבסיס הנתונים צריכה להיות זהה.
לא דומה, זהה.
בהתחלה השתמשתי בmysqldump (תוכנית שמגיעה עם mysql כדי לגבות את בסיס הנתונים) כדי לשמור שני קבצים, מתוך כוונה להשוות אותם.
מסתבר שזה לא היה רעיון כל כך מוצלח, כי היא הפיקה שורות ארוכות מאוד מאוד, שגרמו לרוב תוכנות ההשוואה שניסיתי להתבלבל או פשוט להיות לא שימושיות.
הצלחתי לדעת שיש בעיות, אבל לא הצלחתי לזהות אותן.
אחרי חיפוש קצר מצאתי את phpsqldiff, תוכנת קוד פתוח שמאפשרת השוואה של טבלאות.
phpmysqldiff מסוגלת לומר בדיוק מה נוסף, מה ירד ומה השתנה בין שתי טבלאות, ובעזרתה מצאתי בדיוק מה שגוי ומשם הדרך לפתרון היא די קצרה.
אני שוקל ברצינות להפוך את שיטת קליטת הכניסות הזו לשיטה היחידה, אבל בשביל שזה יקרה היא תצטרך להיות יותר ידידותית למשתמש הפשוט:
למשל אם תהליך העיבוד יתבצע אוטומטית פעם ב10 דקות, ואולי אפילו בכל פעם שמנהל האתר בודק את הסטטיסטיקות.
מימוש כזה יגרום לעסק להיות שקוף, תוך הורדה משמעותית מהעומס על השרת.
זה עדיין לא הסוף של מקצה שיפור הביצועים: אני עדיין צריך לשפר את הביצועים של השאילתות, אבל זה בהחלט צעד חשוב בכיוון.
11 תגובות »
נכתב על ידי עמרי בנושא FireStats, אינטרנט
IPV6 היא הגרסא הבאה של פרוטוקול האינטרנט, שכבר מתבשלת כמה שנים טובות.
השינוי המרכזי ביותר, והמוטיבציה הגדולה של השינוי נובעת מהבעיה המחריפה והולכת של חוסר בכתובות IP פנויות. בIPV4 - הגרסא הנוכחית, כל כתובת תופסת 4 בתים שהם 32 ביט, מה שאומר שיש 2 בחזקת 32 כתובות אפשריות שזה קצת יותר מארבע מיליארד כתובות אפשריות.
התקן של IPV4 נקבע ב1981, ארבע מיליארד כתובות נראו אז כמו הגזמה פראית, ואף אחד לא דימיין שבתוך כמה עשרות שנים יהיה צורך ביותר כתובות.
השוק התמודד עם המגבלה במספר כתובות הIP במספר צורות:
כתובות IP דינאמיות
כשהאינטרנט הפך לפופולרי, אנשים התחילו להתחבר בחיוג מהבית, מכיוון שהחיוב היה לפי דקה, לא היה הגיון בהקצאת כתובת IP לכל משתמש, שממילא היה מחובר רק לפרקי זמן קצרים. לכן ספקי שרות האינטרנט בחרו בגישה הנכונה של הקצאה דינמית של כתובת IP פנויה ברגע החיבור.
במהלך השנים טכנולוגית החיבור השתנתה, והיום רוב המשתמשים מחוברים לפרקי זמן ארוכים הרבה יותר, וחלק גדול מהם מחוברים בצורה קבועה. ההגיון במתן כתובת IP דינמית יורד משמעותית במצב כזה, אבל ספקי האינטרנט מעדיפים לא לשנות את המצב כי זה מאפשר להם לגבות יותר כסף ממשתמשים שרוצים כתובת קבועה (הנבלות).
NAT
מכיוון שאין מספיק כתובות IP לתת לכל מחשב או לכל מכשיר נייד (כן, לסלולרי שלכם יש כתובת IP), קמו חכמים וחשבו:
מה אם נגדיר טווח כתובות מיוחד (או כמה טווחים) שישמש לרשתות פנימיות בלבד, ולא יהיה חוקי באינטרנט הגדול?
זה יאפשר לנו לבחור כתובות IP למחשבים ברשת הפנימית שלנו בלי תלות במספר הכתובות האמיתיות שלנו (שעולות לא מעט).
הבעיה עם זה היא שאם הכתובות לא חוקיות באינטרנט, איך מחשב כזה יכול לתקשר עם מחשבים מחוץ לרשת הפנימית שלו (בה הכתובות חוקיות)?
ברגע שנתב שם בחוץ יראה חבילת מידע עם הכתובת שלו ככתובת יעד, הוא לא ידע לאן לנתב אותה ויזרוק אותה לסל המיחזור של החבילות.
הפתרון הוא NAT, או Network address translation. הרעיון די פשוט: נשים מחשב (או נתב) אחד עם כתובת IP אמיתית, וננתב את כל חבילות המידע שנשלחות החוצה מהרשת שלנו דרכו. המחשב הזה ישנה את פרטי החבילה כך שכתובת הIP ממנה היא נשלחה תהיה שלו, יזכור את פורט המקור של החבילה, וישלח אותה.
ברגע שמגיעה חבילה שממוענת אל אותו מחשב NAT, הוא יבדוק את החבילה, יסיק לפי מה שהוא זוכר לאיזה מחשב ברשת הפנימית החבילה ממוענת, יתקן את הכתובת והפורט לפרמטרים הנכונים ויעביר את החבילה.
גישה זו מאפשרת לרשת עם עשרות או מאות מחשבים להתחבר לאינטרנט עם כתובת IP אמיתית אחת בלבד.

שני הפתרונות האלו (ועוד כמה פחות משמעותיים) הורידו את דחיפות הפיתרון האמיתי, שהוא מעבר לIPV6.
IPV6
השינוי המרכזי בIPV6 הוא הרחבת טווח הכתובות האפשריות. במקום 4 בתים לכתובת IPV4, יש לא פחות מ16 בתים בכתובת IPV6.
קצת מתמטיקה:
4 בתים הם 32 סיביות. 2 בחזקת 32 זה 4,294,967,296,
4 מיליארד כתובות בIPV4.
16 בתים הם 128 סיביות, 2 בחזקת 128 זה:
340,282,366,920,938,463,463,374,607,431,770,000,000
340 מיליארד מיליארד מיליארד מיליארד כתובות בIPV6.
אז תחום הכתובות של IPV6 יספיק להרבה הרבה זמן.
שיפורים נוספים בIPV6
IPV4 לא תוכנן להיות מאובטח בשום רמה, ובשלב מסויים הוגדר תקן IPSec, אבל גם אחרי שהוא הוגדר הוא היה אופציונלי ולא מחויב.
בIPV6 לעומת זאת, האבטחה מוגדרת כחובה, והיא בנויה בצורה יותר טובה.
למשל, בIPV4 - נתמכת הצפנה של תוכן ההודעות בלבד (payload), ובIPV6 נתמכת הצפנה של התוכן והכותרת (header).
שיפורים נוספים הם תמיכה מובנית בתעדוף תעבורה מסויימת (QOS), הגדרה אוטומטית (Auto-configuration), חבילות נתונים גדולות לשיפור ביצועים ברשתות שמעבירות הרבה מאוד מידע (JumboGrams, חבילות נתונים בIPV4 מוגבלות לגודל של 65535 בתים, בIPV6 לעומת זאת החבילות יכולות להגיע לגודל 4 ג'יגה לחבילה)
למרות כל השיפורים הפרישה של IPV6 עדיין דלה ונקודתית.
וצפויים לפחות עוד כמה שנים טובות לפנישהתקן יצבור תאוצה (ויש מי שטוען שהוא לעולם לא יצבור תאוצה).
ייצוג טקסטואלי של כתובות IPV6
אנשים רגילים לכך שכתובת IP הן מהצורה המקובל של a.b.c.d, כאשר כל מספר הוא בן 0 ל255.
בIPV6 התמונה משתנה, במקום 4 קבוצות בין 0 ל255, פתאום יש לנו 8 קבוצות של 0 עד 65535, שמיוצגות בבסיס 16, ומופרדות על ידי נקודותיים.
למשך:
2001:0db8:0000:0000:0000:0000:1428:57ab
יהיה לא נעים להקריא את זה בטלפון.
כדי לעזור קצת, הוגדר הקיצור הבא:
סדרת אפסים אחת בכתובת יכולה להתכווץ לצמד נקודותיים, ואפשר גם להתעלם מאפסים שפותחים קבוצה - מה שאומר שאת הכתובת הזו אפשר לכתוב גם כך:
2001:db8::1428:57ab
קצת יותר טוב.
FireStats וIPV6.
עד גרסא 1.4, פיירסטטס מאכסן כתובות IP בתוך מחרוזת תווים, ולכן תומך גם בIPV4 וגם בIPV6.
אחד הפיצ'רים המבוקשים ביותר הוא היכולת להתעלם מטווח של כתובות IP.
עד 1.4, ניתן להוסיף כתובות מסויימות לרשימת ההתעלמות, אבל זה לא מספיק כשרוצים להתעלם מטווח שלם, למשל כדי לסנן את הספאם של מייקרוסופט.
כדי לתמוך בסינון לפי טווח כתובות, הכי טוב לשמור את כתובת הIP כמספר ולא כמחרוזת - כי אז אפשר לבדוק אם המספר נמצא בטווח בקלות.
אבל באיזה כתובות IP לתמוך?
אומנם 99% מהמשתמשים עובדים עם IPV4 בלבד, אבל אם אני אסתמך על זה, זה בעצם אומר שאני מבטל את התמיכה בIPV6, צולעת ככל שתהיה.
לא ממש רציתי לעשות את זה, ולכן החלטתי לתמוך בIPV6 גם אחרי המעבר משמירת כתובות טקסטאלית לשמירה מספרית.
אבל איך שומרים כתובת IPV6 בMySQL כמספר? הטיפוס המספרי הגדול ביותר בMySQL הוא BIGINT, שרוחבו 8 בתים, וסיכמנו כבר שכתובת IPV6 היא ברוחב 16 בתים.
הפתרון הוא להשתמש בשתי עמודות של BIGINT, אחת לחצי הימני של כתבות הIP והשניה לחצי השמאלי.
קצת מכוער, אבל זה המצב.
בעיה נוספת שצריכה התייחסות מיוחדת היא בעיית ההצגה והקליטה של כתובות IP.
כשמגיעה כתובת IP טקסטואלית למערכת, צריך להבין מאיזה גרסא היא, ולתרגם אותה לייצוג מספרי.
כשרוצים להציג כתובת IP מספרית, צריך לעשות את הפעולה ההפוכה ולהציג אותה בצורה הידידותית ביותר (IPV4 אם הכתובת המקורית היא בIPV4, אחרת IPV6).
מכיוון שהתמיכה בIPV6 בPHP די צולעת - קיימות פונקציות, אבל רק מגרסאות חדשות של PHP וגם אז הן לא נתמכות בכל מערכות ההפעלה - כתבתי את פונקציות ההמרה והזיהוי בעצמי.
אפשר לראות בתמונה טווח IPV6 ליד כתובת IPV4 בודדת:

קריאה נוספת:
IPv6: The Promise, The Problems, The Protocol
ווקיפדיה
8 תגובות »
נכתב על ידי עמרי בנושא FireStats, אינטרנט
האם גוגל יוצרים SiteMap לאתרים מיוזמתם?
בלי שעשיתי שום דבר, פתאום חיפוש של FireStats מראה תוצאה משופרת עם לינקים פנימה למה שחשוב.
6 תגובות »
נכתב על ידי עמרי בנושא FireStats, וורדפרס
והרי כותרות הסופ"ש:
יום שישי
שוחררה תוכנת ההתקנה FireStats Installer, שמאפשרת התקנה מהירה של FireStats.
FireStats Installer מוריד את הגרסא האחרונה של FireStats, פורש אותה ומוודא שכל הקבצים תקינים - כל זה על השרת בצורה מהירה ואמינה.
יום שבת בבוקר
שוחררה גרסא 1.0.0 של Plugin Commander
Plugin Commander הוא תוסף לWordPress MU שמאפשר הפעלה אוטומטית של תוספים לבלוגים חדשים וכן כיבוי והדלקה של תוספים עבור כל הבלוגים.
בגרסא החדשה נוספה תכונה נוספת שחסרה בWordPress MU, והיא היכולת לשלוט על רשימת התוספים שמשתמשים יכולים להדליק ולכבות.
שבת בערב
שוחררה FireStats 1.4.3-RC1, גרסא זו היא מועמדת לשחרור רשמי של FireStats 1.4 (מה חדש?), וכוללת כמה תיקוני באגים.
עם הגרסא הזו, FireStats 1.4 נחשב כבר מספיק יציב, ופתחתי את הברז של ההתראה על גרסא חדשה, מה שאומר שצפוי גשם של מורידים בימים הקרובים, לא לשכוח מטריות.
אין תגובות »
מזה מספר חודשים אני רואה בפיירסטטס של firestats.cc זרימה הולכת וגוברת הפניות חיפוש ממנוע החיפוש של מיקרוסופט:

מסתבר שההפניות, שמכילות UserAgent מזוייף ודף מפנה מזוייף (עם מילות חיפוש שלא באמת מובילות אלי), יוצאות - תאמינו או לא - משרתי מייקרוסופט.
יש שני טווחי כתובות IP שמהן יוצאות הבקשות:
65.55.165.*
131.107.151.*
מסתבר שאני לא היחיד שזה הרגיז אותו. תגובת מייקרוסופט על פי הודעה בפורום שקישרתי אליו:
Second, we want to explain what this is all about. The traffic you are seeing is part of a quality check we run on selected pages. While we work on
addressing your conerns, we would request that you do not actively block the IP addreses used by this quality check; blocking these IP addresses could prevent your site from being included in the Live Search index.
אז מייקרוסופט מודים שזה הם (כאילו הם יכלו להסתתר באמת), וטוענים - תחזיקו - שהם עושים לדפים נבחרים בדיקת איכות!
ואו, הרבה תודה מייקרוסופט, עכשיו שבדקתם את איכות הדפים שלי (תודה תודה!), אתם מוכנים (תודה!) להפסיק לזבל לי את הסטטיסטיקות בצואה דיגיטלית?
(הממ, צואה דיגיטלית = דואה?)
מה שיפה זה שהם טוענים שאם תחסמו את כתובות הIP האלו, אתם עלולים לא להיות מאונדקסים על ידי הזחלנים של מנוע החיפוש של מייקרוסופט.
אכן טרגדיה, הרי אני מקבל כל כך הרבה הפניות משם שפשוט חבל לחסום אותו, כהוכחה - ראו את התמונה המצורפת למעלה, כמעט כל ההפניות מLive!
אגב, ניתן לזהות בקלות שאלו הפניות מאותה חווה גם על פי הדף המפנה, שמכיל תמיד את המילה LIVOP, למשל:
http://search.live.com/results.aspx?q=custom&mrt=en-us&FORM=LIVSOP
נראה שהתעלמות מטווח של כתובות IP יהיה אחד הפיצ'רים של הגרסא הבאה של פיירסטטס.
מייקרוספט, אני באמת מציע לכם לתפוס את הגאון שיזם את המהלך הזה ולקדם אותו, אסור לו לגעת במחשבים!
7 תגובות »
נכתב על ידי עמרי בנושא FireStats, וורדפרס
שחררתי בטא ראשונה של FireStats 1.4.
בין השינויים:
- זמני עליה משופרים של המסך הראשי.
- תמיכה בריבוי משתמשים (כולל אימות והגדרות אישיות)
- תמיכה בכותרות פוסטים של וורדפרס (אם יש כותרת זמינה היא תוצג במקום הURL)
- שיפור משמעותי של תצוגת המפנים האחרונים
- ווידג'ט וורדפרס חדש של פוסטים פופולריים
- תמיכה בWPMU
- שיפור משמעותי בביצועים של הוידג'טים.
אפשר לראות את רשימת השינויים המשמעותיים (כולל תמונות!) פה.
כמו שהשם מרמז, זו גרסאת בטא. Buyer beware.
11 תגובות »
נכתב על ידי עמרי בנושא FireStats, וורדפרס
רשמו לפניכם, ב25 לאוקטובר במכללת אפקה יתקיים וורדקאמפ ישראל 2007.
הכנס מתאפשר בעיקר תודות לעבודה הקשה של טל גלילי, שהביא את זה על עצמו (מגיע לך!).
לורל מLorelle on WordPress תהיה שם כמרצה אורחת (!), ועוד הרבה אנשים מעניינים.
גם אני אהיה שם, ואקשקש קצת על FireStats (אלא אם אני אשתפן ברגע האחרון).
בקיצור, הרשמו לפני שיגמר המקום, יהיה אחלה.

2 תגובות »
אחד החידושים בוורדפרס 2.3 הוא היכולת של המערכת לבדוק קיום של גרסא חדשה, של עצמה ופוטנציאלית גם של הפלאגינים שמותקנים.
הבעיה עם הפיצ'ר המתבקש הזה הוא שוורדפרס שולחת בלי צורך אמיתי את הURL של הבלוג שלכם אל ספינת האם.
אין סיבה אמיתית לשלוח את המידע, ואין אפשרות לכבות את זה בלי לשנות את הקוד או להתקין פלאגינים שנכתבו במיוחד בשביל לנטרל את הפונקציונליות הזו.
כשנודע על הפיצ'ר הריגולי החדש, קמה מהומה קטנה ברשימה של wp-hackers, ואני בתוכה, וביקשנו הסברים לצורך לשלוח נתונים שמאפשרים לזהות את בעל הבלוג.
מאט נפנף את המודאגים ("תעשו פורק", "תתקינו פלאגינים", "זה לא מזיק", "אולי יום אחד נצטרך את זה") ולא ממש נתן הסברים מספקים.
הזהרתי שזה יתפוצץ, וכך היה.
אני אישית מתכוון לנטרל את הפעולה הזו פשוט על ידי שינוי הקוד כך שישלח URL אחר אל ספינת האם, אולי את זה של הבלוג של מאט, כי הרי זה לא מזיק.
חוץ מעניין הפרטיות, יש פה גם סוגית אבטחה:
מה קורה אם מישהו עויין ישים את הידיים שלו על רשימת כל הבלוגים של וורדפרס, כשליד כל בלוג יש גם את הגרסא, כדי להקל על מציאת קורבנות?
כמפתח תוכנה בעצמי אני מודע היטב לצורך לדעת כמה שיותר מידע על ההתקנות של התוכנה שלי, ואפילו הוספתי לFireStats אפשרות לשלוח לי מידע.
ההבדל הוא שהמידע נשלח אלי רק בעקבות הסכמה מפורשת של המשתמש, ושהמידע שנשלח אלי הוא אנונימי.
למעשה, הצעתי ברשימת התפוצה של wp-hackers לעשות את אותו דבר (ואפילו לתרום קוד אם צריך) עוד לפני שהתפוצץ כל העניין, והרבה אנשים הביעו עניין ברעיון.
אף אחד, כולל מטורפי הפרטיות הגדולים ביותר לא התנגד להוסיף את האפשרות הזו כל עוד היא בגדר אפשרות, והיא מופעלת רק בעקבות אישור מפורש של המשתמש.
מאט העדיף להתעלם, ולהשאיר את המימוש הפולשני ששולח בשקט מידע בלי אפשרות מובנית לבטל את הפעולה.
אני חושב שהגלים מההתנהלות הזו רק מתחילים.
2 תגובות »
נכתב על ידי עמרי בנושא FireStats
כשהתחלתי לפתח את פיירסטטס הייתי חסר נסיון מעשי בפיתוח של בסיסי נתונים, הייתי אומנם אחרי קורס של מבוא לבסיסי נתונים בפתוחה, שנתן לי את הרקע התאורטי, אבל לא היה לי את הרקע המעשי.
לאור זה, אני חושב שזה יפה שהצלחתי לתכנן בסיס נתונים בצורה מספיק חכמה כדי שהוא יוכל להתפתח ולהשתנות (כמעט מדי גרסא גדולה 1.x -> 1.y).
למרות זאת, לפעמים אני מפקפק בהחלטות תכנון שעשיתי אז וחושב שאולי הייתי עושה אחרת עכשיו.
למזלי, האפשרות לשנות את בסיס הנתונים מגרסא לגרסא קיימת ועובדת בפועל.
פיירסטאטס התבססה בהתחלה על Counteirze, שהיה בעל מבנה פשוט מאוד בבסיס הנתונים: טבלא אחת.
יש כמה בעיות עם התכנון הזה:
*הוא בזבזני מאוד במקום כי כל כתובת מפנה את מחרוזת דפדפן (UserAgent) תופיעה שוב ושוב ושוב.
* קשה להרחיב אותו לתמוך בנתונים נוספים בלי להחריף את בעיית המקום.
אחת ההחלטות הראשונות שעשיתי היתה לעבור למבנה מנורמל, שבו על כתובת מפנה ומחרוזת דפדפן נשמרות פעם אחת בטבלאות נפרדות, וטבלאת הכניסות מכילה מזהה יחודי של כל אחד מהשדות האלו בעמודה הרלוונטית.
טבלאת הכתובות נראית היום כ:

טבלאת ההמפנים נראית היום כך:

אפשר לראות שיש דמיון:
url וreferer הם בעצם שדה הכתובת.
md5 הוא שדה של גיבוב md5 של הכתובת
אבל גם הבדלים:
בטבלאת המפנים יש עוד כמה שדות שקשורים לתמיכה במילות חיפוש (שנכנסה בגרסא האחרונה).
במסגרת רצון להוסיף תמיכה בווידג'ט של פוסטים פופולריים הוספתי טבלאת METADATA לטבלאת הURLים.
הmetadata יכול להכיל פרטים כמו כותרת של הפוסט, אם יש, וסוג הכתובת (post, לינק להורדה בהמשך ועוד).
נשאלת השאלה, למה רק לכתובת מגיעה טבלאת metadata. אותה כתובת פוסט תופיע גם כמפנה ואז פתאום צריך לתחזק פעמיים את הmetadata שלה, או לחילופין לגשת לאותו metadata, רק עם מזהה שונה (כי הרי בטבלת המפנים יש מזהים שונים מבטבלאת הכתובות).
שאלה נוספת היא, למה רק למפנים חיצוניים יש מילות חיפוש, מה אם משתמש מחפש משהוא בבלוג? זה הרי מאוד דומה מהבחינה הזו וגם פה יש מילות חיפוש.
אז מפתה לחשוב בכיוון של איחוד של טבלאת המפנים וטבלאת הכתובות, כדי לפשט את המבנה וכדי לישר קו מבחינת היכולות שיש למערכת בטיפול בכתובת פנימית מול טיפול במפנה חיצוני.
שינוי כזה הוא שינוי רציני מאוד במבנה, והוא יהיה שדרוג מורכב במיוחד, במיוחד לאור העובדה שהחל מגרסא 1.3 יש גם טבלאות ארכיון שמכילות נתונים היסטוריים, וצריך לאחד גם אותם.
בקיצור, יהיה שמח.
מה דעתכם?
4 תגובות »
|