
אנחנו מחלקת הפיתוח הטכנולוגי של רשת קמעונאית. יום אחד, ההנהלה קבעה את המשימה להאיץ חישובים בקנה מידה גדול על ידי שימוש ב- Apache Ignite בשילוב עם MSSQL, והראתה אתר אינטרנט עם איורים יפים ודוגמאות של קוד Java. מיד אהבתי את האתר , שהתיאור שלו מבטיח ניסים: אתה לא צריך לפרוס ידנית את קוד ה-Java או Scala שלך בכל צומת ברשת ולפרוס אותו מחדש בכל פעם שהוא משתנה. ככל שהתקדמה העבודה, התברר של-Zero Deployment יש שימושים ספציפיים, שאת התכונות שלהם אני רוצה לשתף. מתחת לגזרה יש מחשבות ופרטי יישום.
1. הצהרת הבעיה
מהות הבעיה היא כדלקמן. יש ספריית נקודות מכירה של SalesPoint וספריית מוצרים של Sku (יחידת שמירה). לנקודת המכירה יש תכונה "סוג חנות" עם הערכים "קטן" ו"גדול". לכל נקודת מכירה מחובר מבחר (רשימת מוצרים של נקודת המכירה) (נטען מה-DBMS) וניתן מידע שהחל מהתאריך שצוין המוצר שצוין
לא נכלל מהמבחר או נוסף למבחר.
נדרש לארגן מטמון מחולק של נקודות מכירה ולאחסן בו מידע על מוצרים מחוברים למשך חודש מראש. תאימות עם מערכת הלחימה מחייבת את צומת הלקוח Ignite לטעון נתונים, לחשב אגרגט של הטופס (סוג חנות, קוד מוצר, יום, מספר_נקודות_מכירות) ולהעלות אותו בחזרה ל-DBMS.
2. לימוד ספרות
עדיין אין לי ניסיון, אז אני מתחיל לרקוד מהכיריים. כלומר מסקירת פרסומים.
סעיף 2016 מכיל קישור לתיעוד של פרויקט Apache Ignite ובאותו הזמן תוכחה על עמימות התיעוד הזה. קראתי אותו שוב כמה פעמים, הבהירות לא באה. אני מתייחס למדריך הרשמי אשר
מבטיח באופטימיות "אתה תתחיל במהירות!" אני מגלה את הגדרות משתני הסביבה, צופה בשני סרטוני Apache Ignite Essentials, אבל הם לא היו שימושיים במיוחד עבור המשימה הספציפית שלי. אני מפעיל בהצלחה את Ignite משורת הפקודה עם הקובץ הסטנדרטי "example-ignite.xml", ובונה את היישום הראשון באמצעות Maven. האפליקציה עובדת ומשתמשת ב- Zero Deployment, איזה יופי!
קראתי עוד, ושם הדוגמה משתמשת מיד ב-affinityKey (נוצרה קודם לכן באמצעות שאילתת SQL), ואפילו משתמשת ב-BinaryObject המסתורי:
IgniteCache<BinaryObject, BinaryObject> people
= ignite.cache("Person").withKeepBinary(); לקרוא : פורמט בינארי - משהו כמו השתקפות, גישה לשדות של אובייקט לפי שם. יכול לקרוא את הערך של שדה מבלי לבצע דה-סריאליזציה מוחלטת של האובייקט (חיסכון בזיכרון). אבל מדוע משתמשים ב-BinaryObject במקום ב-Person, מכיוון שיש פריסה אפסית? למה IgniteCache הועבר ל-IgniteCache ? זה עדיין לא ברור.
אני עורך מחדש את אפליקציית Compute כדי להתאים למקרה שלי. המפתח הראשי של ספריית נקודות המכירה ב-MSSQL מוגדר כ-[id] [int] NOT NULL, אני יוצר מטמון באנלוגיה
IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")בתצורת xml אני מציין שהמטמון מחולק למחיצות
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="spCache"/>
<property name="cacheMode" value="PARTITIONED"/>
</bean>חלוקה לפי נקודת מכירה מניחה שהמצבר הנדרש ייבנה על כל צומת אשכול עבור רשומות salesPointCache הזמינות שם, ולאחר מכן צומת הלקוח יבצע את הסיכום הסופי.
אני קורא את ההדרכה , אני עושה את זה באנלוגיה. בכל צומת אשכול אני מריץ את IgniteRunnable(), משהו כזה:
@Override
public void run() {
SalesPoint sp=salesPointCache.get(spId);
sp.calculateSalesPointCount();
..
}אני מוסיף היגיון צבירה והעלאה ומפעיל אותו על ערכת נתוני בדיקה. הכל עובד באופן מקומי על שרת הפיתוח.
אני מפעיל שני שרתי בדיקה CentOs, מציין את כתובות ה-IP ב-default-config.xml, מבצע בכל אחד מהם
./bin/ignite.sh config/default-config.xmlשני צמתי ה-Ignite פועלים ויכולים לראות זה את זה. אני מציין את הכתובות הנדרשות בתצורת ה-xml של יישום הלקוח, זה מתחיל, מוסיף צומת שלישי לטופולוגיה ומיד יש שני צמתים שוב. היומן מציג "ClassNotFoundException: model.SalesPoint" בשורה
SalesPoint sp=salesPointCache.get(spId);StackOverflow אומר שהסיבה לשגיאה היא שאין מחלקת SalesPoint מותאמת אישית בשרתי CentOs. הגענו. מה דעתך על "אינך צריך לפרוס ידנית את קוד ה-Java שלך בכל צומת" וכן הלאה? או ש"קוד ה-Java שלך" אינו קשור ל-SalesPoint?
כנראה פספסתי משהו – אני מתחילה לחפש שוב, לקרוא ושוב לחפש. לאחר זמן מה יש לי הרגשה שקראתי הכל על הנושא, אין יותר חדש. בזמן שחיפשתי, מצאתי כמה הערות מעניינות.
, אדריכל מוביל ב-GridGain Systems, ב-StackOverflow, אפריל 2016:
Model classes are not peer deployed, but you can use withKeepBinary() flag
on the cache and query BinaryObjects. This way you will avoid deserialization
on the server side and will not get ClassNotFoundException.עוד דעה מוסמכת: , מנהל ניהול מוצר, GridGain Systems.
מאמר על Habré מתייחס לשלושה מאמרים מאת דניס מגדה: , , 2016-2017. במאמר השני, דניס מציע להתחיל צומת אשכול דרך MaintenanceServiceNodeStartup.jar. אתה יכול גם להשתמש בהשקה עם תצורת xml ושורת פקודה, אבל אז אתה צריך לשים ידנית מחלקות מותאמות אישית בכל צומת אשכול פרוס:
That's it. Start (..) node using MaintenanceServiceNodeStartup file or pass
maintenance-service-node-config.xml to Apache Ignite's ignite.sh/bat scripts.
If you prefer the latter then make sure to build a jar file that will contain
all the classes from java/app/common and java/services/maintenance directories.
The jar has to be added to the classpath of every node where the service
might be deployed.אכן, זהו. הנה מתברר, למה, הפורמט הבינארי המסתורי הזה!
3.SingleJar
דניס לקח את המקום הראשון בדירוג האישי שלי, IMHO ההדרכה השימושית ביותר מכל הקיימות. בו Github מכילה דוגמה מוכנה לחלוטין להגדרת צמתים של אשכולות, שמתבצעת קומפילציה ללא כל כריעה נוספת.
אני עושה את זה באותו אופן ומקבל קובץ jar בודד שמפעיל "צומת נתונים" או "צומת לקוח" בהתאם לארגומנט שורת הפקודה. ההרכבה מתחילה ועובדת. אפס פריסה הובסה.
המעבר ממגה-בייט של נתוני בדיקה לעשרות גיגה-בייט של נתוני לחימה הראה שהפורמט הבינארי קיים מסיבה כלשהי. היה צורך לייעל את צריכת הזיכרון בצמתים, וכאן התברר כי BinaryObject היה שימושי מאוד.
4. מסקנות
התוכחה הראשונה שנתקלה בעניין העמימות של תיעוד פרויקט Apache Ignite התבררה כהוגנת; מעט השתנה מאז 2016. לא קל למתחילים להרכיב אב טיפוס מתפקד על בסיס אתר ו/או מאגר.
בהתבסס על תוצאות העבודה שנעשתה, הרושם היה כי Zero Deployment עובד, אך רק ברמת המערכת. משהו כמו זה: BinaryObject משמש כדי ללמד צמתים מרוחקים של אשכולות לעבוד עם מחלקות מותאמות אישית; אפס פריסה - מנגנון פנימי
Apache Ignite עצמו ומפיץ אובייקטי מערכת ברחבי האשכול.
אני מקווה שהניסיון שלי יהיה שימושי למשתמשי Apache Ignite חדשים.
מקור: www.habr.com
