הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
מאמרים בנושא פיתוח.
רשתות נוירונים בקוד פתוח... תמונת מצב
כידוע היום שוק ה־deep learning נשלט באופן כמעט בלעדי ע"י nVidia. אומנם כל תשתיות למידה החישובית הפופולריות כגן TensorFlow, PyTorch, Caffe, MXNet ואחרות משוחררות כקוד פתוח, אבל בליבו של כל אחד מהם, ללא יוצא מן הכלל, רצות ספריות cublas ו־cudnn המאפשרות לנצל את החומרה בצורה מיטבית. כולן כמובן קוד בסגור ומסוגר הרץ על בסיס CUDA. כמובן, גם הוא API פרטי וקנייני של חברת nVidia.
אקדים ואומר: אין אני טוען שהסכנה כאן כי החברה "המרושעת" תשתלט על בינה מלאכותית ותקים skynet מתחת לרגליים שלנו. לא, בסה"כ מדובר במימוש פעולות מתמטיות בסיסיות מוגדרות היטב בצורה יעילה להפליא.
אבל אני רוצה קוד פתוח?
אז יש מספר פתרונות וכיוונים:
- לאמן הכל ב־CPU בלבד.
- להשתמש בתשתית ROCm של AMD.
- להשתמש ב־OpenCL במקום ב־CUDA ואז חוץ מדרייבר של nVidia הכל יהיה פתוח (פחות או יותר)
CppCMS עובר מ-LGPLv3 ל-MIT
היום עדכנתי רישיון של CppCMS ל-MIT. הגרסה הקרובה 1.2 תשוחרר עם רישיון מעודכן
ההחלטה נובעת ממספר סיבות:
- רצון להגדיל נתח השוק של CppCMS ולהקל על כניסה של משתמשים חדשים
- להביא יותר מפתחים לפרויקט
אחרי תקופה ארוכה שוחררה בטא של CppCMS 1.1.0
אחרי תקופה ארוכה של המתנה שוחררה גרסת בטא 1.1.0 של CppCMS. גרסה זו מכילה המון שיפורים ושיוניים. ביניהם:
- תכנון מחדש של application pool לתיקון מספר בעיות מובנות שהיו קיימות בו עד כה
- API חדש של פעולות non-blocking לשיפור משמעותי בביצועי אפליקציות אסינכרוניות
- סיכון ועיבוד בזמן העלאה של התוכן (למשל עיבוד או בדיקה של קבצים תוך כדי העלאה)
- תמיכה משופרת ב-RESTful API
- מערכת לניהול plugin ושיפורים מערכת תבניות (templates) בהם.
- אפשרות ניהול session ללא עוגיות (למקרה והמשתמש ממש צריך)
- שילוב ניהול ה-session מול טכנולוגיות אחרות כולל מימוש עבור PHP, Java Servlet, ASP.Net ו-Python Django
- שיפורי ביצועים רבים
- ועוד...
התכנון הוא לבצע בדיקת בטא מהירה, לשחרר 1.2 כגרסה יציבה (גם ככה חלק ניכר מהמשתמשים כבר עובד בענף הפיתוח ב-git).
לאחר מכן אני רוצה לעבור לפיתוח בחלקים יותר קטנים ללא השהיות גדולות בין הגרסאות. בהמשך מתכנון:
- ל-1.4 תמיכה מלאה ב-HTTP/1.1, ב-HTTPS ומימוש של websockets
- ל-2.0 להעביר CppCMS ל-C++11 תוך ניקוי חלק מה-API שילקח מספריה סטנדרטית כמו
std::shared_ptr
אתם מוזמנים להתנסות בגרסת בטא האחרונה!
שילוב בין טכנולוגיות Web שונות ו-CppCMS
כשיש לך מערכת ווב גדולה ומפותחת ואתה צריך להעביר חלקים קריטיים ממנה לטכנולוגיה מהירה יותר (קרי CppCMS) אתה נתקל קודם כל בבעיה הבסיסית - איך לשתף מידע.
נתונים גולמיים זה קל - יש מסדי נתונים, יש קבצים - אין פה משהו מסובך, אבל אתה צריך גם לשתף מידע על המשתמש ועל ה-session שלו בין הטכנולוגיות ופה כל אחד ממש את מה שהוא צריך בצורה אחרת. מצד שני זה מאוד חיוני לשתף מידע קריטי כמו זיהוי משתמש בצורה מאובטחת.
לכן, יצרתי שכבת תיאמות שמאפשרת לגשת ל-Session של CppCMS מכל שפת תכנות אחרת.
בשלב ראשון עדכנתי את המחלקות הקשירות לניהול ה-Session של CppCMS שיוכלו לפעול בצורה בלתי תלויה מהמערכת. יצרתי API נקי מבוסס C בלבד כדי שלא יהיו בעיות כמו חריגות (exceptions) האופייניות ל-++C וגם כדי שאפשר היה לטעון את הפונקיות ישירות בעזרת dlopen.
אחר כך יצרתי מספר מודולים עבור שפות שונות:
- PHP עם שימוש ב-Swig
- Java/Servlet עם שימוש ב-JNA
- Python עם שימוש ב-ctypes והתממשקות עם Django (אבל לא מוגבל ל-Django)
- Asp.Net עם שימוש ב-PInvoke
כמובן זה לא מוגבל אליהם בלבד. אבל לכל שפה חדשה צריך לבנות מעטפת. שקלתי לעשות גם ל-Ruby on Rails אבל ויתרתי לבינתיים כי אין לי ניסיון עם Ruby בכלל, אז שמישהו יתרום בעת הצורך.
חייב להגיד לכל טכנולויה היו בעיות משלה... למשל ב-Python היו התנהגויות מוזרות כשניסיתי לבנות מתודות באופן דינאמי, ב-Java/JNA הכל עבר חלק להבפליא. PInvoke שיגע אותי עם חוסר רצון שלו להמיר UTF-8 ל-string ובחזרה (אגב Mono כן עושה זאת בצורה שקופה אבל לא Net. של Windows מתעקש להשתמש בקידוד ANSI). יצירת מודולים עם Swig עבדה לא רע בכלל, אבל נדרשת עוד מעטפת כדי להתאים את הכל בסופו של דבר לשפה עצמה והתנהגותה.
ואיך זה נראה
PHP:
// pool initialization
$pool=CppCMS_SessionPool::from_config('cppcms-config.js');
// per request session access
$session=$pool->session();
$session->load();
$x=0;
if($session->is_set('x')) {
$x=$session['x'];
}
$x=intval($x)+1;
$session['x']=$x;
$session->save();
...
Java/Servlet:
static SessionPool pool;
public void init() throws ServletException
{
pool = SessionPool.openFromConfig("/path/to/cppcms-config.js");
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
Session session = pool.getSession();
session.load(request);
String x="0";
if(session.isSet("x"))
x=session.get("x");
x=Integer.toString(Integer.parseInt(x)+1);
session.set("x",x);
session.save(response);
session.close();
...
}
Python/Django:
# Create global pool
pool=cppcms.SessionPool('/path/to/cppcms-config.js')
# Actual view
def home(request):
s=pool.session()
s.load(django_request=request)
v='0'
if 'x' in s:
v= s['x']
s['x']=str(int(v)+1)
response = HttpResponse()
s.save(django_response=response)
...
C#/ASP.Net:
static SessionPool pool;
static Example() {
pool = SessionPool.FromConfig("cppcms-config.js");
}
protected void Page_Load(object sender,EventArgs e)
{
using(Session s = pool.Session()) {
s.Load(Request);
string v="0";
if(s.IsSet("x"))
v=s["x"];
v = (int.Parse(v) + 1).ToString();
s["x"]=v;
s.Save(Response);
}
...
}
אפשר לראות את הקוד והדוגמאות המלאות כאן
אני עדיין תוהה עם איזו עוד פלטפורמה כדי לעשות אינטגרציה. בסופו של דבר חשובה לי הפשוטות והנוחות של העבודה.
לשרת את כל אתרי החדשות בארץ בעזרת... CppCMS
אני לא יודע אם שמתם לב, אבל בשנה האחרונה קצב הפיתוח של תשתית CppCMS ירד בצורה ניכרת. ריכזתי את מרבית המאמצים במערכת פרסום מיוחדת הבנויה על תשתית ה־CppCMS שפותח עבור לקוח.
הפרויקט נקרא ליניקום.
היום, כשליניקום כבר פעיל זמן רב ומתוחזק ע"י צוות מורחב, אני אוכל להקדיש יותר זמן לתשתית CppCMS עצמה.
מספר מילים על "ליניקום":
"ליניקום" הוא מנוע שמביא פרסומות תלויות תוכן ומותאמות למשתמש לאתרים שונים בקלות רבה. מרבית אתרי החדשות הגדולים בארץ משתמשים בשירותי ליניקום, ביניהם: ynet, הארץ, מאקו, Jerusalem Post, ואללה ועוד רבים אחרים כולל מספר אתרים גדולים בחו"ל.
להלן כמה עובדות מעניינות:
- ליניקום מבוססת על טכנולוגית CppCMS
- המערכת משרתת כ־10,000,000 פניות המותאמות למשתמש ביום - קרי כ־115 פניות בשניה.
- בשעות העמוסות הקצב מגיע לכ־160 פניות בשניה.
- השרת מייצר תעבורה יוצאת ממוצעת של כ־11 מגאביט בשניה.
- צריכת זיכרון הכוללת של המערכת (שרת וואב, בסיס נתונים, יישום, מערכת ההפעלה) הוא בסביבות 360MB
- העומס הממוצע על המעבדים הוא כ-5%
- השרת רץ על c1.medium instance בודד ב־Amazon EC2
המערכת רצה מאחורי lighttpd ומשתמשת ב־PosgreSQL לשמירה וניהול הנתונים בצורה אינטנסיבית, עם זאת, מרבית הנתונים הנדרשים בזמן אמת שמורים ומנוהלים בזיכרון.
כמעט כל פניה לשרת דורשת עיבוד נתונים על מנת לספק פרסומות מותאמות אישית, מבחינה טכנית, זה אומר שלא ניתן לעשות "מיקור חוץ" של הפניות האלה לקבצים הסטטיים וכל פניה של כל לקוח צריכה להיות מטופלת בנפרד.
מערכת הפרסום הזו, היא הדוגמה הקלאסית לשימוש בטכנולוגיית CppCMS - מערכת שצריכה להיות מהירה ואפקטיבית. מערכת שמסוגל להתמודד עם עומסים גבוהים ולעתים חריגים ללא בעיות ולספק איכות השירות גבוהה ביותר.
שימוש בנתונים השמורים בזיכרון, ניהול נתונים שלא יכולים להיות שמורים בזיכרון מטמון - זה המקום בו יכולות CppCMS באות לידי ביטוי במלואן. יכולת גדילה גבוהה עם דרישות תחזוקה מינימליות, אמינות גבוהה - האם אלה שמאפשרים לדאוג לצד העסקי בלי לחשוב על בעיות ביצועים אפשריות.