VOL25: How Shopify Mitigates Deadlocks in High Concurrency Environments
أهلًا وسهلا بكم في العدد الخامس والعشرين من النشرة الأسبوعية لاقرأ-تِك 🎉
لا تنسوا أهلنا من صالح الدعاء,اللهم إنّا استودعناك اياهم، اللهم كُن عوناً لهم، اللهم انصرهم واحفظهم. 🇵🇸
أهلًا وسهلا بكم في العدد الخامس والعشرين من النشرة الأسبوعية لاقرأ-تِك 🚀
سواء كنت مهندس برمجيات مبتدئ أو محترف، فنشرتنا هدفها انها تثري المحتوى التقني العربي سعيا للتطوير من جودة المحتوى باللغة العربية, من خلال تقديم أحدث المستجدات والتطورات في عالم البرمجيات، بالإضافة إلى أفضل الممارسات والنصائح القيمة, ونشر أحدث المقالات وترشيحات الكتب ومحتوى ورقة وقلم اللي بينزلوا بشكل مستمر في موقع اقرأ-تِك.
في الإصدار ده الفهرس هيكون كالآتي:
How Shopify Mitigates Deadlocks in High Concurrency Environments
Java Collections Cheatsheet
Database Storage Systems: Database vs Data Warehouse vs Data Lake
Concurrency vs. Parallelism
Docker Series Part 2 & 3 : Docker Image , Tags, Docker File and Networks
ستجدون أيضًا في هذه النشرة:
الشراكات - Sponsorship
قناة التليجرام مجانية للجميع حتى يصلك كل مقال جديد
كيفية كتابة مقالات معنا في اقرأ-تِك: والمقالات تكون متاحة ومجانية للجميع ومحفوظة باسم الكاتب بكل تأكيد
كيفية الاشتراك في اقرأ-تِك من خلال InstaPay و VodafoneCash
How Shopify Mitigates Deadlocks in High Concurrency Environments
عشان نضمن الـ Data Integrity فالـ MySQL بيحتاج يعمل Lock على البيانات قبل ما يعمل Update على أي Record موجود ، لو فيه عمليات متعددة (Multiple Processes) بتحاول تعمل Update للبيانات في نفس الجدول في نفس الوقت، فممكن يحصل "deadlock" حسب طريقة تخزين البيانات على الـ Disk وحسب إدارة MySQL ليها.
ده ممكن يحصل حتى لو العمليات المختلفة دي بتتعامل مع Records مختلفة. فتعالوا نشوف ازاي Shopify بتشرح مشكلة الـ "deadlocks" في MySQL أثناء عمليات الـ Updates للبيانات، ونشوف إزاي الـ "composite primary keys" ممكن يكون حل للمشكلة دي بشكل فعال.
Deadlock Problem
لما MySQL بيعمل Update/Insert اللي هي (up-sert) لمجموعة من الـ Records اللي فيها بيانات جديدة وموجودة، بيحاول يضيف كل الـ Records ويعملهم Insert. فبالنسبة للسجلات اللي موجودة بالفعل، لو حصل "collision" على الـ "unique constraint" ده بيبقى معناه إن التحديث مطلوب بدل الإضافة. وعشان MySQL يقدر انه يعمل Update للسجلات دي بأمان، بيحتاج يعمل "gap lock".
لما العملية دي بتتكرر بشكل متزامن عن طريق أكتر من Process بتحاول تعمل نفس الكلام، الكلام ده بيبقى عرضة لحدوث "deadlocks".
وده طبعًا بيحصل لأن الـ "gap lock" بيستهدف الـ Record اللي بيتحدث فعليًا والـ Record اللي قبله على طول في الـ Index ، فـ MySQL بيعمل كده عشان يقدر يحدث الـ Index كمان.
لو الـ pkid
بطبيعته Sequential ، فده معناه إن البيانات هتتخزن بنفس ترتيب الـ Sequence ده. فلما يجي MySQL يحتاج يعمل "gap locks" عشان يدير العمليات المتعددة اللي بتحدث البيانات، ممكن وقتها يحصل تداخل في الـ "gap locks" اللي محتاجها العمليات المختلفة.
وعلى حسب عدد العمليات اللي شغالة في نفس الوقت وعدد الـ "unique constraint collisions" اللي بتحصل، ممكن ده طبعًا يؤدي لحدوث "deadlocks". وبناءً على تكرار الـ "deadlocks" دي، ممكن تأثر بشكل كبير على أداء التطبيق ككل.
والـ "deadlocks" ممكن تحصل حتى لو العمليات شغالة على دفعات مختلفة (Multiple Batches) من السجلات.
الصورة دي بتوضح جدول اسمه transactions
. الجدول ده بيتم تحديثه بشكل متزامن عن طريق عمليات ETL بتشتغل على كل account
بشكل مستقل. ورغم إن كل عملية بتستهدف مجموعة مختلفة من الـ Records في الجدول transaction
، إلا إن متطلبات الـ Locks بينهم ممكن تتداخل وتسبب "deadlocks".
Java Collections Cheatsheet
كلنا عارفين مدى أهمية هياكل البيانات في التطبيقات بتاعتنا ، وقد ايه معرفتنا بنوع المشكلة اللي بنحاول نحلها هو اللي بيحدد نوع هياكل البيانات اللي هنستعملها ، لإن كل واحدة بتتميز بعدة خصائص بتميزها عن الباقيين.
ولو جينا نشوف ده في الـ Java فهياكل البيانات أو الـ Collections بمعنى أصح اللي بنخزن فيها البيانات متعددة وفيه منهم كتير ، فورقة وقلم وتعالوا نتعرف على الـ Java Collections Cheatsheet ونشوف ايه هي أشهر الـ Collections اللي موجودة في الـ Java ونستعملهم امتة.
Java Collections Cheatsheet
احنا بدايتنا هتكون هل البيانات اللي محتاجين نخزنها عبارة عن مجرد قيم Values ولا محتاج اخزن البيانات على شكل Key/Value Pairs. وبناءا على اجابتنا هنا احنا هنتفرع لفرعين:
محتاجين Values
محتاجين Key/Value Pairs
لو احنا كنا عاوزين نخزن قيم فقط لا غير يعني مجرد Values ، فحد هيقول خلاص احنا ممكن نستعمل الـ ArrayList وهتكون فعالة وكويسة جدًا. ولكن صبرًا مش بنختار الـ Collections بالسرعة دي، احنا محتاجين نفهم طبيعة المشكلة اللي بنحلها الاول فخلونا نكمل.
لو احنا هنخزن مجرد Values فمحتاجين نسأل سؤال مهم هي القيم اللي هنخزنها فيها Duplicates ولا لا ؟
لو عادي نسمح بوجود قيم مقررة يعني Duplicates وقتها هنختار الـ ArrayList كـ Collection نستعمله وهيكون جميل جدًا ومناسب لطبيعة الشغل.
طب لو مافيش Duplicates ؟ يعني بمعنى أدق عاوزين القيم تبقى مميزة و Unique بدون أي تكرار ؟ حد هيرد بسرعة برضو ويقول ممكن نستعمل الـ HashSet ، هنقوله كلامك صحيح ، ولكن صبرًا احنا محتاجين نفهم طبيعة المشكلة اللي بنحلها الأول .. فخلونا نكمل.
طب لو الاجابة كانت لا وان مافيش Duplicates ؟ محتاجين دلوقتي نسأل سؤال تاني مهم الا وهو .. هي القيم الـ Unique دي اما نخزنها هل بعد كده هنبحث فيهم على حاجات معينة ؟ أو ممكن نضطر نمسح منهم حاجات معينة ؟
لو الاجابة كانت لا ..
الشراكات - Sponsorship
بفضل الله أصبح متاح حاليا دعمنا من خلال الرعاة والشراكات وفعلنا الـ Sponsorship وتقدروا تشوفوا التفاصيل كاملة من هنا والـ Analytics بتاعتنا من خلال اقرأ-تِك والنشرة الأسبوعية 🚀
لا تدع شيء يفوتك!
بفضل الله قمنا بإطلاق قناة اقرأ-تِك على التليجرام مجانًا للجميع 🚀
آملين بده اننا نفتح باب تاني لتحقيق رؤيتنا نحو إثراء المحتوى التقني باللغة العربية ، ومساعدة لكل متابعينا في انهم يوصلوا لجميع أخبار اقرأ-تِك من حيث المقالات ومحتوى ورقة وقلم والنشرة الأسبوعية وكل جديد بطريقة سريعة وسهلة
مستنينكوا تنورونا , وده رابط القناة 👇
Database Storage Systems: Database vs Data Warehouse vs Data Lake
لاشك أن البيانات أصبحت شئ مهم جدًا وقايم عليه تطبيقات وقرارات كبيرة في معظم الشركات وكمان سبب في نجاحاتهم، وعلشان هي شئ مهم فوسيلة تخزينها كمان مهمة، وده لإنها زي ما تقدر انها تسهل طريقة استخدامنا للبيانات وتساعدنا في الوصول للهدف منها برضو تقدر تصعب الموضوع جدًا وتخليه ملئ بعقبات كتير.
هنتكلم عن 3 من أشهر الأنظمة لتخزين البيانات أو ال Data Storage Systems وهما الـ Database، والـ Data Warehouse، والـ Data Lake.
طب ليه فيه أكتر من نظام لتخزين البيانات ؟ وايه هي مميزات وعيوب كل واحد منهم و ايه الهدف من استعماله ؟ وايه هي العوامل اللي تخلينا ننجح في اختيار النظام المناسب لتخزين البيانات في التطبيق بتاعنا ؟ كل ده هنعرفه سوا.
Data Storage Factors and Types
مبدئيًا الـ 3 أنظمة اللي هم الـ Database والـ Data Warehouse والـ Data Lake نقدر نستخدمهم لتخزين البيانات، ولكن أي نوع من البيانات ؟ البيانات بتتقسم لـ 3 أنواع وهم:
Structured
Semi-structured
Unstructured
وده بيوصف هل البيانات بتتبع هيكل أو Structure معين ولا لأ، يعني مثلًا لو عندي بيانات لمدرسة فهل كل الطلاب ليها نفس الخصائص (attributes) اللي بتوصفها ؟ ولا هلاقي طالب عنده معلومة السنة الدراسية وترتيبه على المدرسة وطالب تاني متخزن له السنة الدراسية بس ؟
هل البيانات بتاعتي أقدر أمثلها في جدول أو Table مكوّن من مجموعة من ال Records ولا البيانات كلها عبارة عن Files ؟
فشكل ونوع البيانات بيتحكم بشكل كبير في اختيار نظام التخزين اللي بنستخدمه، مش بس كده ده حجم البيانات كمان بيحدد ده، وهل هبقى مهتم بتاريخ البيانات ولا هبقى عايز البيانات المحدثة مؤخرًا فقط منها (most updated version).
كل دي عوامل تقدر تساعدنا في أختيار المكان اللي هنخزن فيه البيانات.
Database
ال Database واحدة من أشهر الطرق في تخزين البيانات ونقدر نستخدمها في Applications كتير. وهي عبارة عن مجموعة من ال Tables كل Table بيمثل Entity وكل Entity ليها مجموعة من ال Attributes بتتمثل في Columns لل Tableده ، والبيانات بتاعتنا بتمثل Records في كل Table وطريقة التخزين دي بيُطلَق عليها Relational Model.
لما بنيجي نعمل Design لأي Database بنحاول على قد ما نقدر نمنع أي تكرار (Duplicates) وأي اعتماديات (Dependencies) ممكن تحصل بين البيانات المتخزنة وبعضها. طريقة ال Design دي اسمها Normalization ، ودي ممكن نتكلم عنها أكتر في مقال لوحدها ، ولكن بإختصار الهدف منها أنها بتقلل التكرار والاعتمادية في البيانات، وده بيسبب أن ممكن مجموعة من البيانات اللي ليها علاقة ببعض تكون في Tables مختلفة بينهم رابطة معينة.
زي مثلًا لو هنتكلم عن بيانات ل مطعم فهيكون فيه Table بيمثل الأصناف و Table تاني بيمثل ال Category اللي كل صنف تابع ليها واللي تبان جزء من أي صنف لكن لو هتسبب تكرار كبير في ال Table هنحتاج نفصلها.
عملية ال Normalization بتسبب وجود عدد كبير من ال Tables في ال Database الواحدة وده بيخلي الحصول على معلومة مفيدة عملية صعبة بسبب كثرة عمليات ال Joins اللي هتحصل بين ال Tables وبعضها.
Concurrency vs Parallelism
الـ Concurrency والـ Parallelism اتنين من المصطلحات المهمة جدًا واللي أغلبنا حصله لبس وماقدرش انه يستوعبهم من أول مرة بشكل كويس. ولكن هم من أهم المصطلحات اللي تهمنا في الـ Software.
إيه هي الـ Concurrency؟
الـ Concurrency هي لما يكون عندك أكتر من عملية (task) شغالة في نفس الوقت، بس مش شرط كل العمليات دي تشتغل في نفس اللحظة. بمعنى تاني، الجهاز بتاعك بيتعامل مع كذا عملية في نفس الوقت بس مش شرط يشتغل عليهم كلهم في نفس الثانية.
تخيل إنك طباخ في مطبخ وعندك أكتر من طلبية، بتبدأ شوية في الطلبية الأولى، وبعدها بتسيبها مثلا لحد ما تجهز على النار وتروح للطلبية التانية وتبدأ فيها، وبعدين ترجع للأولى وهكذا. كده إنت بتتعامل مع كل الطلبات في نفس الوقت، بس مش بتخلصهم كلهم مرة واحدة.
مثال تاني على الـ Concurrency في Microsoft Word
تخيل إنك بتكتب مستند في الـ Word، وفي نفس الوقت بتعمل تدقيق إملائي (spell check) وتنفيذ بعض الصيغ (formulas) في نفس المستند.
البرنامج بيقسم وقته بين كتابة النص والتدقيق الإملائي وتنفيذ الصيغ. بمعنى إنه شوية يتأكد من الكلمات المكتوبة وشوية ينفذ الصيغ وشوية يسمح لك بالكتابة.
البرنامج هنا بيدير كل العمليات دي بشكل متزامن، بس مش شرط يكون شغال عليهم كلهم في نفس اللحظة بالظبط.
استخدامات الـ Concurrency
تصفح الويب: لما تفتح أكتر من (tab) في المتصفح وكل (tab) بيحمل صفحة مختلفة، المتصفح بيقسم وقته بين التبويبات دي.
التطبيقات اللي بتتعامل مع المدخلات الخارجية: تطبيق بيستقبل بيانات من المستخدم وفي نفس الوقت بيحدث قاعدة البيانات وبيعمل عملية حسابية، البرنامج بيعمل كل المهام دي بشكل Concurrent، بيستغل الوقت اللي بياخده في انتظار المدخلات عشان ينفذ عمليات تانية بدل ما يفضل مستني وما يعملش حاجة.
السيرفرات والتعامل مع الطلبات المتعددة: سيرفر ويب بيتعامل مع أكتر من طلب (request) من مستخدمين مختلفين، بيوزع وقت البروسيسور بين الطلبات دي عشان يقدر يرد عليهم بشكل متزامن.
Docker Series Part 2 & 3
لو بتدور على طريقة سهلة وفعّالة عشان تدير بيها التطبيقات بتاعتك، فمفيش شك إن Docker هيكون من أهم الأدوات اللي هتساعدك لتحقيق ده. Docker هو أداة قوية جدًا تقدر تعملها بيها حاويات Containers، ودي زي بيئة معزولة بتشغل فيها التطبيقات بتاعتك.
وفي السلسلة دي، هنغطي أهم المفاهيم والأدوات والـ Commands اللي ليها علاقة بـ Docker بشكل بسيط وسهل عشان تقدر تستفيد منها بسرعة وتطبّقها في شغلك.
Docker Images
الـ docker file من خلاله اقدر اعمل image خاصه بيا بدل ما استخدم ال images الموجوده علي ال docker hub واقدر ارفع ال image دي لل docker hub والناس تقدر تستخدمها كذلك.
وبيتكتب بلغة ال Yaml
ال Tag هو اني بحدد مثلا ال image ال هعملها download تكون ب version معين
الـ Docker Tags هي Reference او عنوان لل Docker Image
يمكن لأكثر من Tags ان يكون Reference لنفس ال Image
ال Tags ال Default هي ال latest
[root@mostata ~ ] docker run -d postgres:10.10
هنا بعمل tag لل image ال اسمها postgres انها تتحمل ب version معين وهو 10.10
ولو عاوز اعمل download لاخر version في طريقتين اول حاجه بكتب ال command دا
[root@mostata ~ ] docker run -d postgres:latest
ال latest هو كدا بيفهم اني محتاج اخر version من ال image دا والطريقه التانيه اني مش بكتب حاجه جمب ال image زي كدا:
docker run -d Postgres
كدا هو بيفهم انك محتاج تحمل ال image باخر version
[root@mostata ~ ] docker history pythin:latest
الامر دا هيعرضلي كل ال Layer ال بتتكون منها ال image ال اسمها python
ال docker بيعمل download مره واحده لل layer ولو احتاجها في image تاني مش بيعملها download من تاني لانها خلاص موجودة عنده
Dockerfile
بعمل من خلاله image جديدة بناءا علي تعليمات انا هكتبها
اول حاجه بكتبها داخل ال dockerfile هي
FROM ubuntu
وواخدة شكلFROM image:tag
ودي بتحددلي ال base image ال هشتغل عليها فكدا هيفهم اني عاوز استخدم ال base image ال اسمها ubuntu وال version بتاعها latestتاني حاجه وهي ال
RUN Command
بنفذ من خلالها أي command انا محتاجه واكتر وليكن:RUN apt-get update
أو مثلاRun apt-get install -y vim
كدا استخدمت اكتر من RUN لكن مش بيفضل الطريقه دي لان كل سطر يعتبر Layer وكل ما عدد ال layer بيزيد ال size بتاع ال image بتزيد فممكن اكتب كل دا ف سطر واحد وليكنRUN apt-get update && apt-git install -y vim
تالت حاجه وهي ال
CMD [“executable”,”param1”,”param2”]
والاوامر دي بتبدا تتنفذ لما ال container يكون Running ولازم يكون في CMD واحد فقط لان لو فيه اكتر من واحد Docker هيشوف اخر CMD وهو دا ال هينفذهCMD [“echo”,”Hello Dockerfile”]
ف كدا لما اعمل Run لل container دا هيطبعلي Hello Dockerfileرابع حاجه ممكن استخدها وهي
EXPOSE port
وده بيخليني افتح port معين لل user عشان يقدر يعمل access لل container عن طريق ال port دا
[root@mostata ~ ] vim Dockerfile
هعمل file واسمه Dockerfile ولازم يكون بالاسم دا
FROM alpine
CMD [“echo”, “Hello Dockerfile]”
هكتب ال code بتاعي
[root@mostata ~ ] docker build -t imagefile .
بعمل build ل image اسمها imagefile من ال Dockerfile ال عملته ولازم اديله مسار ال dockerfile وعملت هما . لاني واقف ف نفس المكان ال فيه ال Dockerfile والـ -t عشان ادي ال image اسم معين
مشاركة من أحمد عطية في مجتمع اقرأ-تِك 😂
تقدروا دلوقتي تشتركوا في اقرأ-تِك بخصم الـ 20% وتنضموا لمجتمع مهتم بالقراءة في هندسة البرمجيات بـ 50 جنيه بس 🎉
وتستمتعوا بحرية كاملة في قراءة المقالات في مواضيع مختلفة بجودة عالية زي:
Data Structure & Algorithms , System Design , Distributed Systems , Micro-Services, Clean Code, Refactoring, Databases , Web Development, DevOps وغيرهم كتير باللغة العربية!
بالاضافة لمحتوى ورقة وقلم اللي بنشرح فيه مفاهيم برمجية بطريقة سهلة وباستعمال صور توضيحية 🚀
ولو فيه مشاكل في الدفع الأونلاين فمتاح دلوقتي الاشتراك من خلال InstaPay و VodafoneCash 💪
تقدروا تتواصلوا معانا من خلال الـ WhatsApp Business أو من خلال الرسايل على مواقع التواصل الاجتماعي أو من خلال البريد الالكتروني contact@eqraatech.com 😍
رؤيتنا هي إثراء المحتوى التقني العربي وجعل التعلم من خلال القراءة أمتع، وذلك من خلال إثراء المحتوى التقني باللغة العربية وتشجيع المبرمجين على القراءة بلغتهم الأم والتفكير أيضًا بها.
لذلك اتحنا الفرصة أمام الجميع للمساهمة ومساعدتنا في نشر واثراء المحتوى التقني باللغة العربية, من خلال كتابة المقالات التقنية في مختلف مجالات هندسة البرمجيات.
وجب التنويه أنه لن يتم نشر كافة الأعمال التي تصل إلينا، وإنما سيتم الانتقاء منها ما يحقق هدفنا بإثراء المحتوى التقني العربي، ولذلك قد تُطلب بعض التعديلات من الكاتب قبل النشر.
لمعرفة المزيد بخصوص :
💬 المعايير العامة لكتابة ونشر المقالات
⚡️ كيفية الإرسال
🔥 التزامات اقرأ-تِك تجاه الكتاب
يمكنكم قراءة كافة التفاصيل من هنا 👇