الخلاصة

  • في التقرير التقني الأصلي، يقسّم جهاز الاستقبال ملفه القديم إلى كتل ويرسل قيمتي تحقق لكل كتلة. يبحث المرسل عنها عند جميع المواضع في الملف الجديد، ثم يبعث مراجع إلى الكتل الموجودة والبايتات التي لا تطابق شيئاً.
  • يشرح موقع مشروع rsync نفسه الثمن الآخر: البحث يستهلك معالج المرسل، وتجميع الملف يستهلك قرص المستقبل، وتتحقق قيمة للملف كله من النتيجة النهائية.

أرسل المستقبل قائمة الموجودات أولاً

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

لذلك تأتي الخطوة الأولى من جهاز الاستقبال. يقسم نسخته إلى كتل متجاورة غير متداخلة، ويحسب لكل واحدة قيمة تحقق سريعة قابلة للتحريك وقيمة أقوى، ثم يرسل هذه الملخصات إلى المصدر. في وصف التصميم الأصلي، كانت القيمة الضعيفة 32 بت واستُخدم MD4 للقوية. هذه أرقام تخص التصميم التاريخي، وليست بياناً عن كل نسخة معاصرة. الفكرة أن المصدر عرف شيئاً عن القطع الموجودة لدى الطرف الآخر من دون أن يستلم ملفه القديم.

يمر المرسل على الملف الذي يريد أن يصل إلى المستقبل. إذا وجد كتلة يملكها الطرف الآخر، أرسل رقمها بدلاً من بايتاتها. وإذا لم يجد تطابقاً، أرسل البيانات الجديدة نفسها. يجمع المستقبل النتيجة من ملفه القديم وما وصله. تمر قيم التحقق وأرقام الكتل أيضاً عبر الشبكة؛ عبارة «الفروق فقط» تختصر حساب النقل ولا تصفه حرفياً. لكنها تبقى فاتورة أصغر كثيراً من إعادة ملف شبه مطابق على الوصلة البطيئة التي درسها المؤلفان.

يجب أن تنزلق نافذة البحث بايتاً واحداً

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

يشرح قسم التحقق المتحرك الحل: عند تحريك النافذة خطوة، تُحدَّث القيمة السابقة بإخراج البايت الذي غادر وإضافة البايت الذي دخل. لا تُحسب القيمة الأقوى إلا بعد ظهور تطابق مرشح في الاختبار الرخيص. ويضيف قسم البحث جدول تجزئة يصفّي المرشحين أولاً. بذلك يمكن العثور على النص نفسه حتى بعد انتقاله إلى موضع مختلف. ينشغل المعالج بالحساب كي لا تعود الوصلة الضيقة حاملةً الكتاب كله.

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

البايتات الموفَّرة صارت عملاً محلياً

يقسّم الشرح العملي للمشروع العمل بين مولّد على جهة الاستقبال، ومرسل، ومستقبل يعيد البناء. يقرر المولّد أي ملف يحتاج تحديثاً ويرسل قيم كتل النسخة الأساسية. يبحث المرسل عن المطابقات، فيستهلك المعالج. يقرأ المستقبل أجزاء قد تكون متباعدة من الملف القديم وهو يكتب ملفاً مؤقتاً جديداً، فيستهلك القرص. عند الانتهاء تُقارن قيمة تحقق للملف الكامل؛ وإذا فشلت يُرفض الملف المؤقت.

وللبروتوكول المقتصد ثمن صيانة. يصفه الموقع نفسه كتدفق مضغوط من البايتات يعتمد تفسيره على السياق وإصدار البروتوكول، مع حدود قليلة واضحة بين الرسائل. خفض هذا التصميم عبء الاتصال، لكنه صعّب التوثيق واكتشاف الأعطال والتوسعة. لم تُلغ الخوارزمية العمل؛ نقلته من المورد الشحيح في الحالة الأصلية، وهو الشبكة، إلى الحاسوبين.

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

الاختراع غيّر من يتكلم أولاً

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

يبقى التجميع والتحقق على المستقبل. إنجاز rsync لم يكن معجزة بلا تكلفة اسمها «إرسال الفروق». لقد اشترى سعة الوصلة النادرة بالحساب والوصول إلى القرص وبروتوكول أصعب. لم تعد عربة النقل تحمل المكتبة كاملة، لكن المخزنين اضطرا إلى ترتيب رفوفهما بدقة.