BuildBuddy و Bazel: انتقال هوشمند بایتهای تغییریافته با CDC
خلاصهٔ کاملتر
کش ریموت Bazel یه مشکل رایج داره: حتی وقتی یه تغییر کوچیک تو سورس کد انجام میدی، خروجیهای بزرگ مثل باینریها، بستهها یا آرشیوها digest جدیدی میگیرن و کل فایل دوباره آپلود و دانلود میشه. مشکل اینجاست که اگه این فایلها اکثراً همون بایتهای قبلی باشن، این انتقال کاملاً اتلاف منابعه.
Content-Defined Chunking یا CDC یه روش تکرارپذیر برای تقسیم فایل به تکههاست — نه بر اساس offset ثابت، بلکه بر اساس محتوا. ایده اصلی اینه که یه rolling hash روی پنجرهای از بایتها اجرا میشه و هر وقت hash به یه الگوی نادر رسید، اونجا برش میخوره. چون این فرآیند کاملاً تابع محتواست، اگه چند بایت وسط فایل تغییر کنه، فقط تکههای نزدیک به اون محل عوض میشن و تکههای بعدی همچنان همون مرزها رو دارن.
برای مثال، عملیات لینک (مثل GoLink) یا بستهبندی اغلب خروجیهایی میسازن که ورودیهای ترانزیتیو زیادی دارن. یه تغییر کوچیک میتونه digest صدها باینری تست رو عوض کنه، در حالی که بیشتر محتواشون مثل قبله. CDC اینجا کمک میکنه — cache فقط تکههای جدید رو دریافت میکنه:
transitive_inputs = depset(
direct = direct_files,
transitive = [dep[MyInfo].files for dep in ctx.attr.deps],
)
ctx.actions.run(
inputs = transitive_inputs,
outputs = [bundle],
executable = bundler,
arguments = ["--output", bundle.path],
)از نظر پروتکل، دو API جدید به Remote Execution API اضافه شده: SplitBlob برای خواندن (client میپرسه این blob به چه تکههایی تقسیم میشه؟) و SpliceBlob برای نوشتن (client میگه این تکهها رو کنار هم بذار تا blob اصلی ساخته بشه). این مدل اجازه میده فقط تکههای گمشده منتقل بشن.
نتایج واقعی چشمگیره. در محیط production، CDC حدود ۸۵٪ از بایتهای نوشتهشده در فایلهای واجد شرایط رو deduplicate کرده. در یه بازه دو هفتهای، بیش از ۳۰۰ تبیبایت داده تکراری آپلود نشده. بنچمارک روی ۵۰ کامیت ریپوی BuildBuddy هم نشون داد حجم آپلود و اندازه disk cache هر دو حدود ۴۰٪ کوچیکتر شدن.
یه نکته مهم درباره محدودیتهاست: CDC برای فایلهایی بالای ۲ مگابایت اعمال میشه که حدود ۴.۲٪ از اشیاء رو شامل میشه. همچنین برای فرمتهای فشرده مثل tar.gz یا لایههای Docker کمتر مؤثره، چون یه تغییر کوچیک میتونه بخش بزرگتری از جریان بایتهای فشردهشده رو تغییر بده. بهترین نتیجه برای خروجیهای بزرگ و byte-stable مثل لینک و پکیجبندی فشردهنشده به دست میآد.
نکات کلیدی:
- CDC فایلها رو بر اساس محتوا (نه offset ثابت) به تکه تقسیم میکنه تا تغییرات محلی بمونن
- فقط تکههای تغییریافته آپلود/دانلود میشن، نه کل فایل
- دو API جدید SplitBlob و SpliceBlob این پروتکل رو استاندارد میکنن
- در production بیش از ۳۰۰ TiB داده تکراری صرفهجویی شده
- برای فعالسازی: Bazel 8.7 یا 9.1+ به همراه --experimental_remote_cache_chunking
- برای فایلهای فشرده کارایی کمتری داره




