من ذاكرة أبو عمر: كيف وفرنا آلاف الدولارات بضغط البيانات بذكاء باستخدام Huffman و LZ77

قصة “فاتورة السحابة” التي كادت أن توقف المشروع

قبل عدة سنوات، كنت أعمل على نظام ضخم لجمع بيانات (Telemetry) من آلاف الأجهزة المنتشرة حول العالم. كانت هذه الأجهزة ترسل تقاريرها كل دقيقة، وهذه التقارير عبارة عن ملفات نصية (JSON) تحتوي على قراءات حساسات وحالات تشغيلية. في البداية، كان كل شيء على ما يرام. لكن مع نمو عدد الأجهزة، بدأت الكارثة تلوح في الأفق.

أتذكر ذلك اليوم جيداً، استدعاني مدير المشروع وهو يمسك رأسه بيديه، وقال لي بلهجة فيها قلق واضح: “يا أبو عمر، شوف هالفاتورة من AWS! إشي بخوّف! تكاليف التخزين (S3) ونقل البيانات (Bandwidth) صارت أعلى من رواتب نص الفريق!”.

كانت صدمة. كنا نستخدم الضغط الافتراضي `gzip` على كل شيء، واعتقدنا أننا قمنا بما يكفي. لكن الفاتورة كانت دليلاً قاطعاً على أن “الافتراضي” ليس دائماً هو “الأمثل”. هنا بدأت رحلة الغوص العميق في عالم خوارزميات الضغط، لأكتشف أن فهم “كيف” تعمل هذه الأدوات لا يقل أهمية عن استخدامها. هذه التجربة علمتني درساً لن أنساه: في عالم البرمجيات، الشيطان (والتوفير) يكمن في التفاصيل.

فهم المشكلة: لماذا الضغط ليس مجرد “كبسة زر”؟

الكثير من المطورين يتعاملون مع الضغط كصندوق أسود. نستخدم أداة مثل `gzip` أو `zip` ونفترض أنها تقوم بالمهمة على أكمل وجه. لكن دعونا نحلل المشكلة بشكل عملي:

  • تطبيقات كثيفة البيانات: أي نظام يقوم بتخزين أو نقل كميات كبيرة من البيانات بشكل مستمر (مثل سجلات الأنشطة Logs، بيانات Telemetry، النسخ الاحتياطية Backups) سيواجه حتماً تحدي التكلفة.
  • تكاليف التخزين وعرض النطاق (Bandwidth): كل بايت إضافي تقوم بتخزينه على خدمة سحابية مثل Amazon S3 أو Google Cloud Storage له تكلفة. وكل بايت تنقله عبر الشبكة يستهلك من عرض النطاق المتاح ويزيد من فاتورتك.
  • الضغط الافتراضي قد لا يكون كافياً: استخدام `gzip` بإعداداته الافتراضية هو خطوة جيدة، لكنه قد لا يكون الحل الأمثل. فهل بياناتك نصية جداً ومليئة بالتكرار؟ هل الأولوية لسرعة الضغط أم لأقصى توفير في الحجم؟ الإجابة على هذه الأسئلة هي مفتاح التحسين الحقيقي.

مفهوم الحل: سحر خوارزميات Huffman و LZ77

لفهم كيف نحسّن عملية الضغط، يجب أن نفهم الأدوات التي نستخدمها. `gzip`، الأداة الأشهر، هي في الواقع مزيج ذكي من خوارزميتين أساسيتين: LZ77 و Huffman Coding. دعونا نفكك كل واحدة منهما.

خوارزمية LZ77: ذاكرة السمكة الذهبية الذكية

تعتمد خوارزمية LZ77 (وفصائلها مثل LZ78 و LZMA) على فكرة بسيطة وعبقرية: البحث عن التكرار.

تخيل أنك تقرأ نصاً طويلاً، وتقوم الخوارزمية بالاحتفاظ بآخر جزء قرأته في “نافذة منزلقة” (Sliding Window). كلما تقدمت في قراءة النص، تبحث الخوارزمية عن تطابق بين النص الجديد الذي تقرأه وأي جزء موجود بالفعل في هذه النافذة.

  • إذا وجدت تطابقاً، بدلاً من كتابة التسلسل المكرر مرة أخرى، تقوم بتسجيل “مرجع” (pointer) بسيط يقول: “ارجع للخلف X حرفاً، وانسخ Y حرفاً من هناك”.
  • هذا المرجع يكون عادة أصغر حجماً بكثير من النص الأصلي المكرر.

هذه الطريقة فعالة بشكل مذهل مع البيانات التي تحتوي على الكثير من التكرار، مثل ملفات السجلات (logs) التي تكرر نفس الرسائل، أو كود HTML الذي يكرر نفس الوسوم، أو حتى المستندات النصية.

نصيحة من أبو عمر: خوارزميات عائلة LZ هي صديقك المفضل عند التعامل مع البيانات النصية والملفات ذات الأنماط المتكررة. كلما زاد حجم “النافذة المنزلقة”، زادت فرصة إيجاد تكرارات بعيدة، مما يحسن نسبة الضغط، لكنه يزيد من استهلاك الذاكرة ووقت الضغط.

خوارزمية Huffman Coding: فن الترميز متغير الطول

بعد أن تقوم LZ77 بعملها وتستبدل التسلسلات المكررة بمراجع، يأتي دور Huffman Coding ليضيف طبقة أخرى من الضغط.

الفكرة هنا مختلفة تماماً. بدلاً من البحث عن تسلسلات مكررة، تقوم الخوارزمية بتحليل تردد كل حرف (أو رمز) في البيانات المتبقية.

  • الأحرف/الرموز الأكثر تكراراً (مثل حرف ‘e’ أو المسافة في اللغة الإنجليزية) تحصل على كود ثنائي قصير جداً (مثلاً: 01).
  • الأحرف/الرموز النادرة (مثل حرف ‘z’ أو ‘q’) تحصل على كود ثنائي أطول (مثلاً: 1110101).

في أنظمة الترميز التقليدية مثل ASCII، كل حرف يأخذ 8 بتات ثابتة. لكن مع Huffman، متوسط عدد البتات لكل حرف يقل بشكل كبير، مما يؤدي إلى تقليص الحجم النهائي للملف.

إذن، `gzip` تستخدم LZ77 أولاً لإزالة التكرارات الكبيرة، ثم تطبق Huffman Coding على الناتج لضغط ما تبقى بأفضل شكل ممكن.

مثال عملي: ضغط سجلات الأنشطة (Logs)

دعنا نرجع لسيناريو “فاتورة السحابة” ونطبق ما تعلمناه. لدينا نظام يجمع سجلات الأنشطة من السيرفرات ويرسلها إلى مستودع بيانات مركزي (Data Lake).

الخطوات العملية للتجربة والقياس

لنفترض أن لدينا ملف سجلات بحجم 100 ميجابايت اسمه `app.log`.

1. القياس بدون ضغط

حجم الملف: 100 ميجابايت. إذا أردنا نقله عبر شبكة سرعتها 100 Mbps، فسيستغرق الأمر نظرياً حوالي 8 ثوانٍ ((100 MB * 8) / 100 Mbps). هذه هي النقطة المرجعية.

2. تجربة الضغط باستخدام `gzip` بمستويات مختلفة

`gzip` يقبل مستويات ضغط من `-1` (الأسرع، أقل ضغط) إلى `-9` (الأبطأ، أعلى ضغط). المستوى الافتراضي هو `-6`.

سنستخدم الأمر `time` لقياس زمن التنفيذ.


# تجربة المستوى 1 (الأسرع)
time gzip -c -1 app.log > app.log.gz1

# تجربة المستوى 9 (الأبطأ والأقوى)
time gzip -c -9 app.log > app.log.gz9

3. تجربة خوارزمية حديثة مثل `zstd`

Zstandard (`zstd`) هي خوارزمية ضغط حديثة طورتها فيسبوك، وتشتهر بسرعتها المذهلة مع الحفاظ على نسبة ضغط ممتازة. هي أيضاً مبنية على فصيلة LZ.


# تجربة المستوى 1 مع zstd
time zstd -1 app.log -o app.log.zst1

# تجربة المستوى 19 مع zstd (مستوى ضغط عالٍ)
time zstd -19 app.log -o app.log.zst19

4. قياس ومقارنة الأداء

بعد تنفيذ الأوامر السابقة، سنحصل على نتائج شبيهة بالجدول التالي (الأرقام تقديرية للتوضيح):

| الطريقة | الحجم الناتج | نسبة الضغط | زمن الضغط |
| :— | :—: | :—: | :—: |
| بدون ضغط | 100 MB | 0% | 0 ثانية |
| `gzip -1` | 15 MB | 85% | 1.5 ثانية |
| `gzip -9` | 10 MB | 90% | 8 ثوانٍ |
| `zstd -1` | 14 MB | 86% | 0.5 ثانية |
| `zstd -19`| 9 MB | 91% | 25 ثانية |

تحليل النتائج:

  • نسبة تقليل الحجم (Compression Ratio): نرى أن كل الخيارات قدمت توفيراً هائلاً يتجاوز 85%. الانتقال من `gzip -1` إلى `gzip -9` وفر 5 ميجابايت إضافية، لكنه استغرق وقتاً أطول بكثير.
  • زمن النقل عبر الشبكة:
    • نقل الملف الأصلي (100 MB): ~8 ثوانٍ.
    • نقل ملف `gzip -9` (10 MB): ~0.8 ثانية.
  • التكلفة الإجمالية للعملية (The Trade-off):
    • باستخدام `gzip -9`: زمن الضغط (8 ثوانٍ) + زمن النقل (0.8 ثانية) = 8.8 ثوانٍ.
    • بدون ضغط: زمن الضغط (0) + زمن النقل (8 ثوانٍ) = 8 ثوانٍ.

لحظة! هل هذا يعني أن الضغط جعل العملية أبطأ؟ نعم، في هذا السيناريو المحدد ذي الشبكة السريعة جداً. لكن ماذا لو كانت الشبكة أبطأ (مثلاً 10 Mbps)؟

  • زمن النقل بدون ضغط (100 MB على 10 Mbps): ~80 ثانية.
  • زمن النقل مع `gzip -9` (10 MB على 10 Mbps): ~8 ثوانٍ.
  • التكلفة الإجمالية مع `gzip -9`: زمن الضغط (8 ثوانٍ) + زمن النقل (8 ثوانٍ) = 16 ثانية.

هنا يتضح الفرق الهائل! وفرنا أكثر من دقيقة كاملة (80 ثانية مقابل 16 ثانية). وهذا هو جوهر الموضوع: الزمن الإضافي الذي تستغرقه في الضغط يصبح مقبولاً تماماً، بل ومربحاً، عندما يكون التوفير في زمن النقل أو تكلفة التخزين أكبر بكثير.

نصيحة من أبو عمر: لا تقع في فخ “الأعلى هو الأفضل”. في قصتنا الواقعية، وجدنا أن `gzip -6` (الافتراضي) كان يحقق التوازن المثالي بين سرعة الضغط على سيرفراتنا المحدودة الموارد وحجم الملف النهائي. لم نكن بحاجة للوصول إلى `-9` الذي كان يستهلك الكثير من الـ CPU. قم دائماً بالقياس في بيئة تشبه بيئة الإنتاج الحقيقية.

الخلاصة: كن أنت الخبير، لا مجرد مستخدم 🤓

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

الدرس المستفاد ليس مجرد استخدام `gzip` أو `zstd`، بل هو فهم المبادئ التي تقف خلفها:

  1. افهم طبيعة بياناتك: هل هي نصية؟ ثنائية؟ هل تتكرر كثيراً؟
  2. حدد أولوياتك: هل السرعة أهم أم الحجم؟ (CPU vs. Bandwidth/Storage).
  3. جرّب وقِس: لا تفترض. قم بإجراء تجارب حقيقية على عينة من بياناتك.
  4. اختر الأداة والمستوى المناسبين: قد يكون `gzip -6` مثالياً لمشروع، و`zstd -3` مثالياً لمشروع آخر.

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

أبو عمر

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

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

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

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

آخر المدونات

أتمتة العمليات

قهوتك الصباحية مع ملخص الإنجازات: كيف تبني داشبورد يومي يصلك على الموبايل باستخدام n8n والذكاء الاصطناعي

كف عن تشتيت نفسك كل صباح بين Jira وGitHub والإيميلات. تعلم معي، أبو عمر، كيف تبني ورك فلو أتمتة يرسل لك ملخصاً ذكياً ومنسقاً بإنجازات...

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