VOL45: How Canva Built Scalable and Reliable Content Usage Counting Service
أهلًا وسهلا بكم في العدد الخامس والأربعين من النشرة الأسبوعية لاقرأ-تِك 🚀
لا تنسوا أهلنا من صالح الدعاء,اللهم إنّا استودعناك اياهم، اللهم كُن عوناً لهم، اللهم انصرهم واحفظهم. 🇵🇸
أهلًا وسهلا بكم في العدد الخامس والأربعين من النشرة الأسبوعية لاقرأ-تِك 🚀
سواء كنت مهندس برمجيات مبتدئ أو محترف، فنشرتنا هدفها انها تثري المحتوى التقني العربي سعيا للتطوير من جودة المحتوى باللغة العربية، من خلال تقديم أحدث المستجدات والتطورات في عالم البرمجيات، بالإضافة إلى أفضل الممارسات والنصائح القيمة، ونشر أحدث المقالات وترشيحات الكتب ومحتوى ورقة وقلم اللي بينزلوا بشكل مستمر في موقع اقرأ-تِك.
في الإصدار ده الفهرس هيكون كالآتي:
How Canva Built Scalable and Reliable Content Usage Counting Service
Introduction to Apache Spark: The Fast and Scalable Data Processing Engine
ACID Properties in DBMS
Concurrency Building Blocks (Threads)
Scrum master vs. Product Owner in Scrum
How Canva Built Scalable and Reliable Content Usage Counting Service
مهمة Canva ورؤيتهم إنهم يمكنوا أي شخص في العالم من تصميم أي حاجة ونشرها في أي مكان. وجزء مهم من تحقيق الهدف ده هو برنامج Canva Creators.
من ساعة إطلاق البرنامج من 3 سنين تقريبًا، واستخدام المحتوى اللي بيقدموه الـ creators تضاعف في خلال 18 شهر. وحاليًا هم بيحسبوا ويدفعوا بناءً على مليارات الاستخدامات للمحتوى ده كل شهر للـ creators.
وطبعًا البيانات دي مش بتشمل templates بس، لكنها كمان بتضم الصور، والفيديوهات، وغيرهم من المحتوى اللي بيتم استعماله.
فبناء وصيانة خدمة لتتبع البيانات دي علشان الدفع يكون مظبوط وموثوق للـ creators كان فيه تحديات كتير زي:
الدقة (Accuracy): عدد الاستخدامات لازم يكون مظبوط 100% لأن الدخل المالي وثقة الـ creators معتمدين عليه.
القابلية للتوسع (Scalability): تخزين ومعالجة البيانات اللي بيتم استخدامها بشكل مهول وكبير جدًا بالإضافة لإنها في تزايد مستمر.
سهولة التشغيل (Operability): مع زيادة حجم بيانات الاستخدام، بيزيد التعقيد في الصيانة، والتعامل مع المشاكل اللي ممن تحصل، وأيضًا استرجاع البيانات في حالة أي مشاكل حصلت.
رحلة التطوير والبداية مع MySQL
في الأول كانوا بيستعملوا MySQL لأنهم كانوا متعودين عليه. وبالتالي بنوا الأجزاء الكبيرة من الـ Architecture بشكل منفصل باستخدام Worker Services، وكان عندهم طبقات متعددة من النتائج الوسيطة أو الـ Intermediary Output.
فبكل بساطة كان عندهم Raw Usage من الـ Events اللي بتحصل وفيه Worker Service بيقوم بعمل الـ Deduplication على الـ raw usage events وبعدين يحطهم في قاعدة بيانات مستقلة للـ deduplicated usage events وفيه عندنا Aggregation Workers هم اللي بيقرأوا من قاعدة البيانات دي ويبدأوا يعملوا الحسابات وزيادة الـ usage counters ويعملوا update في الـ Aggregated Usages ودي برضو قاعدة بيانات منفصة.
بس للأسف ظهر عندهم 3 مشاكل:
1- قابلية التوسع في معالجة البيانات (Processing Scalability)
كل record عشان يحصله processing أو معالجة كان بيتطلب round-trip رايح جاي من الـ Database، وده كان غير عملي مع زيادة الحجم الضخم للـ events.
2- التعامل مع الـ Incidents
أي مشكلة كانت بتحصل كانت معقدة وبتاخد وقت كبير للتعامل معاها. وده لإن المهندسين كانوا مضطرين يبصوا في الـ Database ويشوفوا المشكلة فين ويصلحوا الـ data اللي فيها مشكلة. وقدروا إنهم يعملوا categorization لأنواع المشاكل اللي بتحصل وكانت كالآتي:
مشكلة الـ Overcounting: الزيادة بتحصل لما الـ (Event Source) يضيف نوع جديد من الـ event المفروض إنه ما يتمش حسابه، والـ (Consumers) مايعرفوش ده. النتيجة إنه النوع الجديد ده بيتحسب بالغلط في مراحل الـ Deduplication والـ Aggregation.
وطبعًا عشان يعالجوا النوع ده من المشاكل:
أول حاجة بيحددوا الـ events اللي اتحسبت بالغلط ويقفوا الـ Pipeline بتاع الـ Deduplication والـ Aggregation.
بعد كده بيحسبوا عدد الـ events اللي اتعالجت بالغلط ويشيلوها من جدول الـ Deduplication ويصححوا البيانات في جدول الـ Aggregation.
العملية دي بتاخد وقت ومجهود كبير من فريق المهندسين.
مشكلة الـ Undercounting: أحيانًا بيتم إضافة نوع جديد من الـ events اللي المفروض يتحسب في عملية الدفع، ولكن الـ (Event Source) فشل بطريقة ما إنه يـ integrate مع الـ (Usage Services)، وبالتالي الـ events دي ما بتتجمعش.
بيحددو ا الفترة الزمنية اللي فيها البيانات المفقودة (Missing Data Window).
بعد كده بيبجيبوا البيانات دي من (Backup Data Source)، ودي أكتر خطوة بتاخد وقت ومجهود.
بعد ما يتم جمع البيانات من الـ Backup، بيرجعوها للـ Service مرة تانية المسئولة ويبدأوا يعيدوا معالجتها.
طبعًا لو حجم البيانات كبير، العملية دي ممكن تاخد أيام، وده ممكن يأخر الدفع بسبب مشاكل الأداء اللي اتكلمنا عنها قبل كده.
مشكلة الـ Misclassification: الخطأ ده بيحصل أثناء مرحلة الـ Deduplication، لما event معين (Usage Event) المفروض يتصنف على إنه نوع "A" ويتم تصنيفه بالغلط على إنه نوع "B". المشكلة هنا إنهم بيدفعوا أسعار مختلفة على حسب النوع.
أول حاجة بيحددوا سبب المشكلة، وغالبًا ده بيكون Bug في الكود.
بيصلحوا الـ Bug وطبعًا يوقفوا الـ Pipeline.
بعد كده بيصححوا البيانات في جدول الـ Deduplication وجداول المراحل اللي بعد كده عن طريق إعادة حساب البيانات مرة تانية.
العملية دي مرهقة جدًا وبتاخد أيام، وبتحتاج أكتر من مهندس علشان يتأكدوا من صحة البيانات بعد التصليح.
مشكلة الـ Processing Delay: دي مشكلة Performance بسبب إن المعالجة كانت بتعتمد على عملية Sequential بتتم من خلال الـ (Single-threaded Sequential Scan) ومع عدد كبير من الـ round-trips بين الـ Service وقاعدة البيانات.
3- استهلاك التخزين
مساحة التخزين في MySQL RDS كانت بتتستهلك بسرعة جدًا، والمشكلة إن MySQL مش بتعمل Horizontal Scaling من خلال الـ Partitioning بشكل تلقائي على سبيل المثال. فكان الحل مضاعفة حجم الـ RDS Instance كل 8-10 شهور.
قسموا قواعد البيانات (Database Split) علشان يوزعوا الحمل.
عملوا أدوات زي الـ (Sweepers) بتنضف البيانات القديمة من فترة للتانية.
بس مع زيادة عدد الـ events بشكل كبير، كان واضح إن الحل ده مش هيكمل على المدى الطويل.
Migration to DynamoDB
مبدئيًا عشان يحلوا مشكلة الـ Scalability اللي كانت ظاهرة بشكل مستمر ، أول حاجة عملوها هي إنهم نقلوا الـ Raw Usage Events اللي كانت في مرحلة الـ Collection لـ DynamoDB وده ساعد في تقليل الضغط على مساحة التخزين اللي كانت بتتزايد بشكل مستمر.
Introduction to Apache Spark: The Fast and Scalable Data Processing Engine
هنتكلم النهارده عن Apache Spark وهو يعتبر Joker في مجال تحليل ومعالجة البيانات الضخمة (Big Data).
مع كم البيانات المهول حول الانترنت وزيادته بسرعة بنحتاج نعالج البيانات دي ونحللها عشان نستفاد بيها وهنا بيجي دور Spark اللي بيقدر يحقق لنا دا بسرعة وفعالية.
تم تطوير Spark ليكون أسرع وأبسط من الأنظمة التقليدية زي Hadoop MapReduce لأنه بيعتمد علي الـ In-Memory Processing بدلاً من ال Disk Reads/Writes.
المميزات
أداء عالي وسريع: عشان نتخيل السرعة فـ Spark أسرع 100 مرة في تحليل كمية معينة من البيانات من Hadoop MapReduce. وده بيخليه الخيار الأمثل لأغلب الشركات الكبيرة في تحليل بياناتها زي Amazon , Intel وغيرها..
التكامل مع لغات برمجة متعددة بـ Unified Interface: بيوفر واجهة موحدة [أوامر وFunctions واحدة] للعمل بلغات مثل Java، Python، Scala، وR ودا بيسهل تعلمه.
مكونات متنوعة لاستخدامات متنوعة: يدعم Spark عدة مكونات مثل:
Spark SQL: لتحليل البيانات باستخدام SQL.
Spark Streaming: لمعالجة تدفقات البيانات مباشرة Real time analysis .
MLlib: مكتبة تعلم الآلة المدمجة.
GraphX: لتحليل الرسوم البيانية (Graphs).
تكامل مع Hadoop: يمكن استخدام Spark مع نظام الملفات الموزع Hadoop (HDFS) ومع موارد أخرى مثل S3.
إدارة الأخطاء: يحتوي على آليات للتعامل مع الأخطاء أثناء معالجة البيانات.
قابلية التوسع Scalability : يمكن تشغيله على مجموعة صغيرة من الـ Servers أو على آلاف.
الاستخدامات
تحليل البيانات الكبيرة Big Data Analysis
تعلم الآلة: يقدر يبني نماذج تعلم الآلة وتحليل البيانات باستخدام مكتبة MLlib.
معالجة تدفقات البيانات: معالجة بيانات Real-Time مثل Server Logs, Sensors Reads.
ETL (Extract, Transform, Load): يستخدم أيضًا لمعالجة وفلترة البيانات قبل تخزينها في قواعد البيانات أو Data Warehouses.
ACID Properties in DBMS
من المفاهيم الاساسية والشهيرة في الـ Relational Databases هي الـ ACID فورقة وقلم وتعالوا نعرف هي إيه وليه مهم إن قاعدة البيانات تكون بتحققها.
ال ACID ببساطة عبارة عن اختصار ل 4 قواعد لازم تحققهم قاعدة البيانات و العمليات اللي بتتم عليها بغض النظر عن أي Software or Hardware Failure أو حتى Power Failure.
و ال 4 قواعد دي هي الضمان إن ال Database دي والبيانات اللي فيها صحيحة وموثوق فيها و دا عامل أساسي في مجال البرمجيات ككل "صحة البيانات".
ال 4 قواعد هما:
Atomicity
Consistency
Isolation (Safe Concurrent Transactions Execution)
Durability(Committed Transactions Must Be Durable)
Atomicity
القاعدة دي بتقول ان ال Transaction الواحد واللي بيعني "عملية مفيدة كاملة من وجهة نظر النظام" يا اما يتنفذ كله يا ما يتنفذش خالص, فمثال على ال Transaction لو شغال علي برنامج لبنك هيكون عملية نقل الأموال من حساب للتاني العملية دي كلها مع بعض البرنامج هينفذها على 3 خطوات:
اتاكد ان الحساب فيه 100 جنيه
خصم 100 جنيه من الحساب
احط 100 جنيه في حساب الطرف الثاني
فهنا القاعدة بتقول ان لازم ننفذ كل الخطوات دي مع بعض كعملية واحدة، ولكن في حالة فشل أي خطوة في النص فلازم يحصل تراجع عن كل الخطوات اللي تم تنفيذها مسبقًا - بمعنى اصح Rollback - لأنها هتحط قاعدة البيانات في حالة غير مفهومة وغير صحيحة لو ما تراجعناش عن كل الخطوات اللي اتنفذت قبلها.
خصم يصل إلى 40% على جميع خطط الاشتراك السنوية لفترة محدودة، تقدروا دلوقتي تشتركوا في اقرأ-تِك وتستمتعوا بكافة المقالات في كل ما يخص هندسة البرمجيات باللغة العربية والمحتوى المميز من ورقة وقلم ومدونات فطين اللي بيتميزوا بتصاميم ذات جودة عالية وكل ده بحرية كاملة وكمان مفاجآت اقرأ-تِك الجاية 🚀
وبرضو متاح الاشتراك من خلال InstaPay و VodafoneCash 🎁
بفضل الله أصبح متاح حاليا دعمنا من خلال الرعاة والشراكات وفعلنا الـ Sponsorship واحنا بنرحب بجميع الشراكات مع المؤسسات والشركات وأصحاب الأعمال لبناء مجتمع عربي يشجع على القراءة والتعلم ومشاركة التجارب والخبرات العملية في هندسة البرمجيات.
دورك كشريك أو راعي هيكون محوري في دعم المحتوى وتوسيع نطاق تأثيره. فانضم لرحلتنا وكن جزءًا من صناعة مستقبل التكنولوجيا في المنطقة 🚀
تقدروا تشوفوا التفاصيل كاملة من هنا والـ Analytics بتاعتنا من خلال اقرأ-تِك والنشرة الأسبوعية 👇
Concurrency Building Blocks (Threads)
مشاركة الـ memory بين الـ processes وبعضها ممكنة في معظم الـ OSs، بس محتاجة مجهود إضافي مننا كمطورين للتعامل معاها. وعشان كده فيه abstraction تاني بيسمح لينا بمشاركة الـ memory بشكل فعال أكتر: وهو الـ threads.
في النهاية، البرنامج بتاعنا هو مجرد مجموعة من الأوامر اللي لازم تتنفذ واحدة ورا التانية بالترتيب. وعشان ده يحصل، الـ OS بيستخدم مفهوم الـ thread. من الناحية التقنية، الـ thread بتتعرف على إنها سيل مستقل من التعليمات اللي الـ OS ممكن يجدول تنفيذها.
فاكرين لما قولنا إن الـ process هو برنامج شغال بالإضافة لشوية موارد معمولها Allocation ليه؟
لو قسمنا البرنامج لمكونات منفصلة، الـ process بتكون هي الـ container للموارد دي زي (address space، ملفات، اتصالات، إلخ)، والـ thread هي الجزء الديناميكي— مجموعة من التعليمات بتتنفذ جوة الـ container.
الـ threads اتولدت من فكرة إن أسهل طريقة لمشاركة البيانات بين الـ processes اللي بتتفاعل مع بعض، هي إنهم يشاركوا الـ (address space). وعشان كده، الـ threads اللي في نفس الـ process، نقدر نعتبرهم زي الـ processes اللي ممكن تشارك الموارد بسهولة مع بعض ومع الـ parent process بتاعتهم، وكذلك الـ address space، والملفات، والاتصالات، والبيانات المشتركة، وهكذا.
الـ threads كمان بتحافظ على الحالة بتاعتها عشان تسمح بالتنفيذ الآمن والمستقل للتعليمات بتاعتها. كل thread مش واخدة بالها من الـ threads التانية إلا لو كانت بتتداخل معاهم عن قصد.
فالـ OS بيدير الـ threads وممكن يوزعهم على الـ CPUs المتاحة. وعشان كده، تطوير برنامج multithreaded ممكن يكون طريقة سهلة لتشغيل كذا task في نفس الوقت بالنسبة لكتير من الناس.
مثال واقعي لتوضيح الفرق بين الـ Process والـ Thread
عشان نوضح الفرق بين الـ processes والـ threads، خلينا نشوف مثال بسيط. تخيل إننا عندنا شركة مقاولات، واحنا بنوظف 3 فرق بناء عشان يشتغلوا على 3 مشاريع مختلفة في نفس الوقت.
فهنعتبر كل فرقة بناء هي (process) مخصصة لمشروع واحد (مهمة) ليها الأدوات بتاعتها، وخطة المشروع، والموارد كذلك. ده حال الـ multi processes.
ولكن من ناحية تانية، عشان نقدر وفر فلوس، احنا ممكن نوظف فرقة بناء واحدة بس لكل الـ 3 مشاريع مع بعض، ونخليهم يستخدموا نفس الأدوات ونفس الموارد، بس هيكون فيه قايمة من التعليمات منفصلة على حسب كل مشروع، وده شبيه أكتر بالـ threads.
فهنقدر نلاقي أن سهل جدًا يتم التواصل والـ communication بين الـ threads وبعضهم وده لانهم تقريبًا بيتشاركوا كل حاجة داخل الـ process الواحدة ، فالفريق الواحد يقدر يستعمل نفس الادوار والموارد اللي موجودة ، بدلًا ما يبقى عندنا الكلام ده 3 مرات والتواصل مع الفرق وبعضها اكيد هيكون أصعب ومكلف.
مميزات الـ Threads
الـ threads ليها بعض المميزات والعيوب زيها زي أي حاجة فتعالوا نشوف مع بعض مميزات وعيوب الـ threads.
Scrum master vs. Product Owner in Scrum
في عالم تطوير البرمجيات والمنتجات، يعد سكرم من أكثر المناهج الفعّالة التي تساهم في تحسين العمل الجماعي وضمان تحقيق الأهداف بكفاءة عالية. ولكن، لتحقيق النجاح الفعلي باستخدام هذا الإطار، من الضروري أن نفهم الفرق بين الأدوار المختلفة التي يشملها، خاصة دور Owner Product وMaster Scrum.
سنتناول في هذا المقال الفروق الرئيسية بين هذين الدورين ونوضح كيف يمكن لكل منهما أن يسهم في نجاح الفريق والمشروع.
دور الـ Product Owner
يعد مالك المنتج من الأدوار الرئيسية في سكرم، حيث يقع على عاتقه تحديد أولويات العمل وضمان تحقيق القيمة القصوى للمستخدم النهائي. إليك أبرز مهام مالك المنتج:
تحديد الأولويات: المسؤولية الرئيسية لمالك المنتج هي تحديد المهام الأكثر أهمية وتحقيق أقصى استفادة منها. يعتمد مالك المنتج على تقييم احتياجات العملاء وتحديد الأولويات وفقا لها. ً
معرفة احتياجات العملاء: يجب أن يكون مالك المنتج على دراية تامة باحتياجات العملاء وتوقعاتهم، وتحديد كيفية تلبيتها من خلال المهام
والميزات المقررة.
التواصل مع فريق التطوير: يعد التواصل المستمر مع فريق التطوير من مهام مالك المنتج الرئيسية. حيث يقوم بتوضيح متطلبات العميل ويساعد الفريق على فهم الرؤية الأساسية للمشروع.
إعداد قائمة المهام (Backlog): يحتفظ مالك المنتج بقائمة المهام التي تمثل جميع الأفكار والمهام المستقبلية لتحسين المنتج. يقوم بترتيب هذه المهام وفقا لأولويات، لضمان تحقيق الأهداف في الوقت المحدد. ً
تخطيط السبرينت (Planning Sprint): في بداية كل سبرينت، يختار مالك المنتج المهام الأكثر أهمية ويشارك الفريق في تحديد كيفية تنفيذ هذه المهام خلال فترة السبرينت.
دور الـ Scrum Master
على الرغم من أهمية دور مالك المنتج، لا يمكننا تجاهل أهمية Master Scrum في تطبيق منهجية سكرم. يشرف Scrum Master على سير العمل ويضمن تطبيق مبادئ سكرم بشكل صحيح. إليك مهام Master Scrum:
الإصدار الأول - ورقة وقلم 🚀
في الإصدار ده جمعنا أكتر من 50 موضوع في مختلف مجالات هندسة البرمجيات بأكتر من 170 صفحة + تصاميم بجودة عالية وكل ده بالعربي وبشكل مميز ومتقسم لفصول سهل تنتقلوا من فصل وموضع للتاني بدون مشاكل 💎
تقدروا تشوفوا النسخة كاملة من هنا كـ E-Book ، وحاولنا نخليها بسعر رمزي يناسب الجميع 👇
ولو عندكوا أي مشكلة في الدفع ، تقدروا تتواصلوا معانا وهنكون مبسوطين باننا نوفر بدايل زي InstaPay و VodafoneCash 🎁
ولو عاوزين تعاينوا جودة الـ E-Book قبل ما تشتروه ، تقدروا تحملوا النسخة المجانية واللي بتضم حوالي 30 موضوع فيما لايزيد عن 100 صفحة من هنا 😉
رؤيتنا هي إثراء المحتوى التقني العربي وجعل التعلم من خلال القراءة أمتع، وذلك من خلال إثراء المحتوى التقني باللغة العربية وتشجيع المبرمجين على القراءة بلغتهم الأم والتفكير أيضًا بها.
لذلك اتحنا الفرصة أمام الجميع للمساهمة ومساعدتنا في نشر واثراء المحتوى التقني باللغة العربية, من خلال كتابة المقالات التقنية في مختلف مجالات هندسة البرمجيات.
وجب التنويه أنه لن يتم نشر كافة الأعمال التي تصل إلينا، وإنما سيتم الانتقاء منها ما يحقق هدفنا بإثراء المحتوى التقني العربي، ولذلك قد تُطلب بعض التعديلات من الكاتب قبل النشر.
لمعرفة المزيد بخصوص :
💬 المعايير العامة لكتابة ونشر المقالات
⚡️ كيفية الإرسال
🔥 التزامات اقرأ-تِك تجاه الكتاب
يمكنكم قراءة كافة التفاصيل من هنا 👇