كانت خطوط بياناتنا هشة وتعمل بالدعاء: كيف أنقذنا Apache Airflow من جحيم ‘شغّل هذا السكريبت يدوياً’؟

يا جماعة الخير، السلام عليكم ورحمة الله.

اسمحوا لي أبدأ بقصة صارت معي قبل كم سنة، قصة بتلخص المعاناة اللي كثير من المبرمجين ومهندسي البيانات بعيشوها بصمت. كانت الساعة حوالي 2 بعد منتصف الليل، وأنا غاطس في النوم. فجأة، صوت رنين الهاتف يمزق سكون الليل. على الطرف الثاني كان صوت المدير التنفيذي، متوتر وقلق: “أبو عمر، آسف على الإزعاج، بس تقرير المبيعات اليومي ما وصل، والمستثمرون ينتظرون الأرقام في اجتماع الصباح الباكر!”.

قلبي وقع في رجلي، زي ما بحكوها. أنا كنت المسؤول عن سلسلة السكريبتات اللي بتجمع البيانات من عدة مصادر، بتنظفها، وبتحللها، وفي النهاية بتطلع التقرير اليومي. النظام كان عبارة عن مجموعة من ملفات البايثون و الـ “كرون جوبز” (cron jobs) المتناثرة على أكثر من سيرفر. أي خطأ في سكريبت واحد كان يعني انهيار السلسلة كلها زي أحجار الدومينو.

بسرعة فتحت اللابتوب، ودخلت على السيرفرات واحد واحد عن طريق SSH. بعد نصف ساعة من البحث والتحقيق، اكتشفت المشكلة: أحد السكريبتات اللي بتسحب البيانات من واجهة برمجية (API) فشل بسبب مشكلة مؤقتة في الشبكة، والسكريبت اللي بعده اشتغل على بيانات قديمة وغير مكتملة، وهكذا دواليك. الحل؟ كان لازم أعيد تشغيل كل سكريبت بالترتيب الصحيح يدوياً، وأنا بدعي ربنا إنه ما يفشل مرة ثانية.

في تلك الليلة، وأنا جالس أمام الشاشة بعيون نصف نائمة، أقسمت أن هذا الجحيم المسمى “شغّل هذا السكريبت يدوياً” يجب أن ينتهي. كانت تلك هي اللحظة التي قررنا فيها البحث عن حل حقيقي، حل ينقلنا من الفوضى إلى النظام. وكان هذا الحل هو Apache Airflow.

الفوضى المنظمة: جحيم “شغّل هذا السكريبت يدوياً”

قبل ما نحكي عن Airflow، خلينا نفصّل أكثر في طبيعة المشكلة اللي كنا عايشين فيها، واللي أنا متأكد إنه كثير منكم بعاني منها:

  • الاعتمادية الهشة (Fragile Dependencies): كان عنا سكريبت (أ) يسحب البيانات، وسكريبت (ب) ينظفها، وسكريبت (ج) يحملها على قاعدة البيانات. كنا نعتمد على توقيت الـ cron jobs. لو السكريبت (أ) تأخر أو فشل، السكريبت (ب) راح يشتغل على بيانات فارغة أو قديمة، والمصيبة تكبر.
  • انعدام الرؤية والمراقبة (No Visibility): شو القصة؟ هل السكريبت شغال؟ هل انتهى؟ هل فشل؟ ليش فشل؟ كلها أسئلة ما كان إلها جواب سهل. كنا لازم ندخل على ملفات الـ logs يدوياً على كل سيرفر لنعرف شو اللي بصير.
  • التعامل مع الأخطاء كابوس (Nightmarish Error Handling): إذا فشل سكريبت، ما كان في آلية تلقائية لإعادة المحاولة. كان لازم حدا يتدخل يدوياً. وإذا كان الفشل في منتصف الليل، الله يعينك.
  • صعوبة التوسع (Scalability Issues): كل ما أضفنا خطوة جديدة في خط البيانات، كانت التعقيدات تزيد بشكل أُسّي. إدارة عشرات الـ cron jobs الموزعة كانت أشبه بترويض الوحوش.

نصيحة من أبو عمر: إذا كان نظامك يعتمد على أنك تتذكر تشغيل شيء ما يدوياً، أو على سلسلة من الـ cron jobs التي لا تتحدث مع بعضها البعض، فأنت لا تملك نظاماً، بل تملك وصفة للكارثة تنتظر الحدوث.

المنقذ Apache Airflow: شو القصة؟

ببساطة، Apache Airflow هي منصة مفتوحة المصدر تمكنك من كتابة، جدولة، ومراقبة سير العمليات (workflows) برمجياً. الكلمة المفتاح هنا هي “برمجياً”. أنت لا تقوم بسحب وإفلات الصناديق في واجهة رسومية، بل تكتب كود بايثون لوصف خط البيانات الخاص بك.

هذا يعني أن خطوط البيانات الخاصة بك تصبح جزءاً من الكود، ويمكنك تطبيق أفضل الممارسات الهندسية عليها: التحكم في الإصدارات (version control) باستخدام Git، مراجعة الكود (code reviews)، والاختبار الآلي (automated testing).

المفاهيم الأساسية في Airflow

عشان نفهم Airflow صح، لازم نعرف كم مصطلح أساسي:

  • DAG (Directed Acyclic Graph): هذا هو قلب Airflow. لا تخاف من الاسم، الموضوع بسيط. الـ DAG هو عبارة عن ملف بايثون يصف كل المهام في سير العمل الخاص بك، وكيفية اعتمادها على بعضها البعض. “Directed” تعني أن لها اتجاه (مهمة أ قبل مهمة ب)، و “Acyclic” تعني أنه لا يوجد حلقات مفرغة (مهمة أ لا يمكن أن تعتمد على نفسها بشكل مباشر أو غير مباشر).
  • Operator: هو قالب جاهز لتنفيذ مهمة معينة. بدك تشغل سكريبت بايثون؟ استخدم PythonOperator. بدك تنفذ أمر bash؟ استخدم BashOperator. بدك تتعامل مع قاعدة بيانات PostgreSQL؟ استخدم PostgresOperator. وهكذا. Airflow مليء بالـ Operators الجاهزة.
  • Task: هي نسخة من الـ Operator تمثل خطوة واحدة في الـ DAG الخاص بك.
  • Task Instance: هو تشغيل محدد لمهمة (Task) في وقت محدد.
  • Web UI: واجهة مستخدم رسومية رائعة تمنحك رؤية كاملة لكل ما يحدث. يمكنك رؤية الـ DAGs، حالة المهام (نجاح، فشل، قيد التشغيل)، إعادة تشغيل المهام الفاشلة، عرض السجلات (logs)، وأكثر من ذلك بكثير. هذه الواجهة وحدها كانت كفيلة بحل 90% من مشاكل انعدام الرؤية لدينا.

من الفوضى إلى النظام: بناء أول خط بيانات (DAG) لنا

طيب، حكينا كثير تنظير. خلينا نشوف مثال عملي بالزبط. تخيل أننا نريد بناء خط بيانات بسيط يقوم بالآتي:

  1. سحب بيانات المستخدمين من واجهة برمجية (API).
  2. معالجة هذه البيانات (مثلاً، إزالة المستخدمين غير النشطين).
  3. تخزين البيانات النظيفة في قاعدة بيانات.

في عالم ما قبل Airflow، كان هذا يعني 3 سكريبتات منفصلة، و3 cron jobs، والكثير من الدعاء. مع Airflow، كل هذا يوصف في ملف بايثون واحد.

كود بايثون بسيط: مثال عملي

هذا مثال مبسط جداً لكيفية بناء DAG لهذه العملية:


from __future__ import annotations

import json
from datetime import datetime

from airflow import DAG
from airflow.operators.python import PythonOperator

# === Python Functions for our Tasks ===

def _fetch_user_data():
    # In a real scenario, this would make an API call
    print("Fetching user data...")
    users = [
        {'name': 'Abu Omar', 'active': True},
        {'name': 'Sami', 'active': False},
        {'name': 'Layla', 'active': True}
    ]
    with open('/tmp/users.json', 'w') as f:
        json.dump(users, f)
    print("User data fetched and saved to /tmp/users.json")

def _process_user_data():
    print("Processing user data...")
    with open('/tmp/users.json', 'r') as f:
        users = json.load(f)
    
    active_users = [user for user in users if user['active']]
    
    with open('/tmp/active_users.json', 'w') as f:
        json.dump(active_users, f)
    print("Active users processed and saved to /tmp/active_users.json")

def _store_user_data():
    # In a real scenario, this would connect to a database
    print("Storing data...")
    with open('/tmp/active_users.json', 'r') as f:
        active_users = json.load(f)
    
    print("--- Stored Users ---")
    for user in active_users:
        print(f"Stored: {user['name']}")
    print("Data stored successfully.")


# === DAG Definition ===

with DAG(
    dag_id='our_first_data_pipeline',
    start_date=datetime(2023, 1, 1),
    schedule_interval='@daily', # Run once a day
    catchup=False,
    tags=['tutorial'],
) as dag:
    
    fetch_data = PythonOperator(
        task_id='fetch_user_data',
        python_callable=_fetch_user_data,
    )

    process_data = PythonOperator(
        task_id='process_user_data',
        python_callable=_process_user_data,
    )

    store_data = PythonOperator(
        task_id='store_user_data',
        python_callable=_store_user_data,
    )

    # === Defining Dependencies ===
    # This is the magic part!
    fetch_data >> process_data >> store_data

لاحظ جمال وبساطة الجزء الأخير: fetch_data >> process_data >> store_data. بهذه الأسطر البسيطة، أخبرنا Airflow بالترتيب الدقيق الذي يجب أن تنفذ به المهام. إذا فشلت مهمة fetch_data، فإن process_data لن تبدأ أبداً. Airflow سيدير كل هذا التعقيد بالنيابة عنك.

نصائح من خبرتي (إشي من الآخر)

بعد سنوات من العمل مع Airflow، تعلمت بعض الدروس بالطريقة الصعبة. إليكم بعض النصائح العملية لتجنب أخطائي:

  1. اجعل مهامك قابلة للتكرار بأمان (Idempotent): هذه أهم نصيحة. يجب أن تكون المهمة مصممة بحيث لو قمت بتشغيلها 10 مرات بنفس المدخلات، فإن النتيجة النهائية تكون نفسها كما لو قمت بتشغيلها مرة واحدة. هذا يسمح لك بإعادة تشغيل المهام الفاشلة بثقة دون القلق من تكرار البيانات أو إفسادها.
  2. خلّي كل مهمة تعمل إشي واحد وبس (Atomic Tasks): لا تضع كل المنطق في مهمة واحدة ضخمة. قسّم عملك إلى مهام صغيرة ومركزة. هذا يجعل تصحيح الأخطاء (debugging) أسهل بكثير، ويسمح بإعادة استخدام المهام في DAGs أخرى.
  3. لا تكتب كلمات المرور في الكود يا حبيب! (Use Connections & Variables): Airflow يوفر واجهة لإدارة الاتصالات (مثل تفاصيل قاعدة البيانات) والمتغيرات بشكل آمن ومشفر. استخدمها دائماً ولا تقم أبداً بكتابة معلومات حساسة مباشرة في كود الـ DAG.
  4. استخدم الـ Versioning مع Git: بما أن الـ DAGs هي كود، عاملها ككود. ضعها في مستودع Git. هذا يمنحك تاريخاً كاملاً للتغييرات، القدرة على العودة لإصدار قديم، والعمل ضمن فريق بشكل منظم.
  5. راقب وضع التنبيهات (Monitoring & Alerting): Airflow رائع في إظهار الأخطاء، لكنك لن تجلس أمام الشاشة 24/7. قم بإعداد تنبيهات عبر البريد الإلكتروني أو Slack أو أي أداة أخرى لإعلامك فوراً عند فشل أي مهمة مهمة.

الخلاصة: من الدعاء إلى الأتمتة بثقة

التحول إلى Apache Airflow لم يكن مجرد تغيير تقني، بل كان تغييراً في ثقافة العمل. انتقلنا من حالة القلق الدائم والتدخلات اليدوية الطارئة، إلى نظام يمكننا الوثوق به. أصبح لدينا رؤية واضحة، وقدرة على تتبع الأخطاء بسهولة، والأهم من ذلك كله، استعدنا ليالي نومنا الهادئة.

إذا كنت لا تزال تعيش في جحيم “شغّل هذا السكريبت يدوياً”، فأتمنى أن تكون هذه المقالة قد أعطتك الدافع والخطوات الأولى نحو التغيير. قد يبدو الأمر صعباً في البداية، لكن الاستثمار في تعلم وتطبيق أداة مثل Airflow سيوفر عليك وقتاً وجهداً لا يقدران بثمن على المدى الطويل.

توقف عن الاعتماد على الدعاء لتشغيل خطوط بياناتك، وابدأ في بناء أنظمة مؤتمتة وموثوقة. وقتك وراحة بالك أغلى بكثير. بالتوفيق يا جماعة! 🚀

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

برمجة وقواعد بيانات

تحديثات قاعدة البيانات بدون توقف: كيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من جحيم التوقفات المجدولة؟

هل سئمت من إيقاف الخدمة مع كل تحديث لهيكلة قاعدة البيانات؟ أشارككم قصة حقيقية وكيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من ليالي النشر الطويلة والمُجهدة،...

4 يونيو، 2026 قراءة المزيد
الشبكات والـ APIs

كانت إعادة المحاولة كارثة: كيف أنقذتنا مفاتيح عدم تكرار العمليات (Idempotency Keys) من جحيم الفواتير المزدوجة؟

أشارككم قصة حقيقية من الخنادق البرمجية، يوم كاد خطأ بسيط في إعادة محاولة طلبات الدفع أن يكلفنا سمعتنا وأموال عملائنا. اكتشفوا معنا كيف كانت مفاتيح...

4 يونيو، 2026 قراءة المزيد
الحوسبة السحابية

من التوقف التام إلى النجاة: كيف أنقذتنا استراتيجية “الضوء المرشد” (Pilot Light) يوم انقطعت السحابة؟

أتذكر ذلك اليوم جيدًا، فنجان القهوة الصباحي، وصوت تنبيهات المراقبة يصرخ كأنه يوم القيامة. كانت منطقة سحابية كاملة قد توقفت عن العمل، لكن بفضل استراتيجية...

4 يونيو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

كانت مهمتي البرمجية للاختبار مجرد كود: كيف أنقذني توثيق القرارات من جحيم الصمت بعد المقابلة؟

أشارككم قصة حقيقية من بداياتي، وكيف تعلمت بالطريقة الصعبة أن المهمة البرمجية ليست مجرد كتابة كود، بل هي فرصة لإظهار طريقة تفكيرك. اكتشف كيف يمكن...

4 يونيو، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

من الانتظار لأيام إلى الدفع في ثوانٍ: كيف أنقذتنا شبكات الدفع الفوري من جحيم التحويلات البنكية؟

أسرد لكم من واقع تجربتي كـ "أبو عمر"، كيف عانينا من بطء وتكلفة التحويلات البنكية الدولية، وكيف جاءت شبكات الدفع الفوري ومعيار ISO 20022 لتكون...

4 يونيو، 2026 قراءة المزيد
البنية التحتية وإدارة السيرفرات

كان كل خادم لدينا ‘ندفة ثلج’ فريدة: كيف أنقذنا ‘الكود كبنية تحتية’ (IaC) من جحيم الانجراف اليدوي؟

في هذه المقالة، أشارككم قصة حقيقية من قلب المعركة التقنية مع "خوادم ندفات الثلج" الفوضوية. سنغوص في مفهوم "الكود كبنية تحتية" (IaC) وكيف أن أدوات...

4 يونيو، 2026 قراءة المزيد
اختبارات الاداء والجودة

كانت تغطية الاختبارات 100% لكن الأخطاء تتسرب: كيف أنقذنا “الاختبار الطفري” من جحيم الثقة الزائفة؟

كنا نظن أن تغطية الاختبار بنسبة 100% هي درعنا الواقي، لكن الأخطاء كانت تتسلل إلى الإنتاج كاللصوص في ليل بهيم. اكتشف كيف أنقذنا "الاختبار الطفري"...

4 يونيو، 2026 قراءة المزيد
البودكاست