async Queued

blue25

New member
async Queued

היי,
יש לי מערכת שאמורה לבצע המון קריאות ל db למטרת תיעוד, אני לא רוצה להעמיס על המערכת ולפגוע בביצועים.
חשבתי על הפתרון הבא ואני אשמח שתחוו את דעתכם בנושא.
המערכת תבצע הכנסה ל MSMQ לוקאלי (אני יודע שיש מוצרים טובים יותר כגון rabbitmq, אבל הסיבה של שימוש ב MSMQ היא שאין לנו אופציה להתקין בייצור מוצרי open source), במקביל יהיה windows service ששולף ומעדכן את ה db.

מה דעתכם ? האם יצא לכם לממש עבודה מול MSMQ עם ארכיטקטורה שונה ?
 

HackPoint

New member
ארכיטקטורה זה עיניין של הכרת מערכת לעומק ולהבין את הדרישה

אחרת כל דיון אחר הוא יהיה פילוסופי לחולוטין.
&nbsp
יצא לי המון להתעסק עם תורים. אם יש לך שאלה ספציפית אתה מוזמן לשאול.
 
לא נתת מספיק פרטים כדי להשיב מעבר לרמה הפואטית

אז ברמה הפואטית:
1. תעשה את הדבר הכי פשוט שמממש את הפונקציונליות המבוקשת (רמז: לא יהיה שם לא תור ולא web service).
2. פרופיילינג.
3. אם יש בעיות ביצועים, רכז מאמץ ראשית בלשנות את ה-db, את ה locking policy או Isolation level איך שלא קוראים לזה בימינו.

לא פותרים בעיות שאין.
 

nocgod

New member
אני עובד עם rmq באמצעות masstransit

אני חושב שהפיתרון הכי טוב בשבילך היה לעשות פעולות log אסינכרוניות
תבדוק אם לlog4net יש appender שיודע לכתוב לDB ותבדוק אם את פעולות log אפשר לבצע בצורה אסינכרונית, אם לא תעטוף אותה ככה שיהיה אפשר :)
נראה יש לך פה overhead ענק וcomplexity מיותר למערכת שאמורה להיות שקופה יחסית
 

blue25

New member
אני לא בעד לפתוח thread-ים שלא לצורך

אתה ממליץ שעבור כל כתיבה ל db לפתוח thread ? אני לא ממש אוהב את הרעיון מאחר ש switch context הוא נחשב יקר.
אני אסביר קצת יותר לעומק מה הצורך, עבור כל משתמש שגולש למערכת אני צריך לאסוף "המון" נתונים במהלך הגלישה, אני לא ארד לעומק העניין למה ומדוע אבל יש צורך לבצע בממוצע 10 פניות ל db לצורך ביצוע insert פשוט.
פנייה לבסיס נתונים היא מבחינתי פעולה "יקרה" מאחר ויש צורך לפתוח connection וכ"ו ואני מעוניין שביצועי המערכת לא יפגעו כתוצאה מכך (נניח וה db כרגע עמוס ופעולת insert תיקח כ 100ms אזי 10 פניות במצטבר ייקחו לי כשנייה).

אני מעוניין למקבל את הפעולה (ולא ע"י שימוש מסיבי ב thread-ים), לדעתי שימוש ב MSMQ הוא פעולה מהירה, מה דעתכם ?
השאלה היותר רלוונטית היא האם שימוש ב windows server אשר יבצע את השליפה הוא פתרון נכון ?
 

nocgod

New member
אני ממליץ שתקרא על tpl וספציפית על Task

בקיצור: תוך שימוש ב TPL אתה מקבל threadpool ממוחזר, ככה שאתה בתחלס לא פותח שום thread חדש, אתה ממחזר קיימים.
כמובן שאתה חייב לדאוג שגם הגישה ל DB תהיה אסינכרונית (אם אני לא טועה יש executeAsync או משהו כזה)
שימוש ב rmq/msmq/zmq מוסיף המון סיבוכיות לתוכנה שלך, סיבוכיות שאתה תעדיף לא לעשות על thread מבצע ראשי כדי לא לחסוף flow
של הלוגיקה בכל מקרה.

אם אתה להוט על להשתמש ב MSMQ לך על זה, שום דבר רע בלהכיר עבודה עם service bus
אני לא הייתי עושה את זה, למען האמת לפני כמה חודשים כתבתי facade משלי ללוגינג של תזמונים ו hits על כל מיני שירותים ודברים
אז עשיתי monitor שאותחל ברשימת writters כל אחד כותב למקום אחר (קובץ, DB ו statsd)
 
עדיין לא מספיק ברור...

קודם כל לשאלה האחרונה שלך: כן, ליצור Windows Service שיבצע את השליפה מהתור הרלוונטי של MSMQ ויבצע את ההכנסה ל DB - זה הכיוון לפתרון. אם אתה רוצה ללכת "עד הסוף" עם הטרנזקציות, אז אתה יכול לעשות שם two-phase-commit, אבל זה נשמע לי כבר מדי לצרכים שלך.
&nbsp
ואני שואל אותך משהו אחר: אתה מבצע הרבה write-ים ל db שלך. מתי צריך לבצע את ה read-ים? כמה זמן המערכת יכולה "לספוג" בכתיבה מאוחרת ל db?
 

blue25

New member
כמה זמן המערכת יכולה "לספוג" בכתיבה מאוחרת ל db

הנתונים שאני צריך לשמור לא קריטיים לעבודה השוטפת, כלומר זהו סוג של תיעוד לשלבים מאוחרים יותר של המערכת לביצוע אופטימיזציות וכ"ו.
כלומר הנחת העבודה היא שאין בעיה שהנתונים יישמרו בצורה אסינכרונית עם delay של שעות...
הסיבה שאני בעד לעבוד עם MSMQ (או בכלל שימוש בתור) היא, מהירות של שמירה, גמישות של מעבר משמירה ל DB לשמירה למיקום אחר (ללא צורך של העלאת גרסה של האפליקציה, כמובן דורש גרסה של ה service)...

אני רואה שהאנשים פה לא ממש בעד וככל הנראה היו בוחרים לעבוד עם thread, לדעתי (האישית בלבד) זה פתרון טוב לאפליקציות "קטנות"/"בינוניות" אבל במידה ואתה מפתח מערכת לארגון גדול ואתה רוצה לספק פתרון גמיש לשינויים עתידיים שימוש ב MSMQ נותן את זה בקלות יחסית.

שורה תחתונה, קיבלתי מספר דעות (כנראה אני אמשיך בדעה המקורית שלי :) ) ובעצתך אני אעבוד עם windows service שיבצע את השליפה...
 
ברשותך עצה קטנה

1. סבבה, לך על message queue כלשהו.
2. יכול להיות שתרצה להשתמש בארכיטקטורה הבאה:
האפליקציה כותבת לתור לוקאלי (שנמצא על אותו שרת)
יש service לוקאלי שמעביר מהתור הלוקאלי לתור שאמור להכניס ל db.
יש service אחד (ויחיד) שקורא מהתור "שלו" ובאמת מכניס ל db.
&nbsp
יש לי נסיון מצויין עם ה pattern הזה. יכול להיות שזה overkill בשביל התרחיש שלך, אבל שווה לדעת בכל מקרה.
 
פתרון נוסף: רפליקציה

בצע רפליקציה של ה DB לשרת אחר, ועליו תריץ את כל הדוחות/תיעוד/ שאילתות DW, וכן הלאה. כך לא תפגע בביצועים של ה DB המקורי.
&nbsp
 
למעלה