کلادفلیر با بهینهسازی کش DNS صد ترابایت رم آزاد کرد
خلاصهٔ کاملتر
تو بلاگ کلادفلیر اومده که Big Pineapple، همون پلتفرمی که پشت 1.1.1.1 و Gateway DNS و DNS Firewall کار میکنه، هر لحظه بیشتر از ۲۵۰ میلیارد ورودی کش DNS نگه میداره. تو این مقیاس، هدر رفتن فقط یه بایت روی هر ورودی یعنی بیشتر از ۲۵۰ گیگابایت رم روی کل ناوگان. تیم با پنج تغییر پشتسرهم توی نحوهی چیده شدن همین ورودیها تو حافظه، مصرف هر ورودی رو بالای ۵۰٪ کم کرد.
اولین تغییر سراغ Vec رفت. Vec سه چیز نگه میداره: اشارهگر به داده، طول فعلی و ظرفیت. ولی پاسخ DNS بعد از نشستن تو کش دیگه تغییر نمیکنه، پس فیلد ظرفیت بیخودی ۸ بایت میگیره و فضای اضافهای هم که Vec رو هیپ رزرو کرده هدره. با Box و Box این فیلد حذف شد و چون هر ورودی ۸ فیلد از این جنس داشت، ۶۴ بایت روی هر ورودی صرفهجویی شد؛ رو ۲۵۰ میلیارد ورودی میشه بالای ۱۵ ترابایت. بعدش سه لیست جدای answer و authority و additional شد یه لیست با آفست u16 و ۲۸ بایت دیگه کم شد.
تغییر سوم سراغ فیلد owner رکوردها رفت، یعنی همون دامنهای که رکورد بهش تعلق داره. تو بیشتر پاسخها این owner دقیقاً همون دامنهی پرسیدهشدهست، پس ذخیرهش تکراریه. حالا این فیلد Optionه: وقتی None باشه، موقع ساختن پاسخ از روی کلید کش بازسازی میشه و هیچ تخصیص هیپی لازم نداره. فقط جایی مثل رکوردهای پشت یه CNAME که owner با کوئری فرق داره، اسم کامل ذخیره میشه.
چهارمی جالبترینه. enum تو Rust همیشه به اندازهی بزرگترین واریانتشه و بزرگترین نوع رکورد یعنی NAPTR تنهایی ۱۳۶ بایت میگیره، پس کل enum با تگ و padding میرسه به ۱۴۴ بایت. این در حالیه که یه رکورد A فقط ۴ بایت داده داره و A و AAAA بالای ۸۰٪ ترافیک هستن. راهحل این بود که واریانتهای بزرگ Box بشن و برن رو هیپ:
pub enum RecordData {
// Small and common variants are stored inline
A(Ipv4Addr),
Aaaa(Ipv6Addr),
// Large variants are stored on the heap
Txt(Box<Txt>),
Naptr(Box<Naptr>),
}این کار برای هر A و AAAA ۱۲۰ بایت آزاد کرد، ولی دو تا هزینه داشت: هر Box یه تخصیص جداست و jemalloc اندازهها رو به بین بالاتر گرد میکنه (مثلاً MX که ۴۰ بایت میخواد، ۴۸ بایت میگیره)، ضمن اینکه داده تو هیپ پخش میشه و locality خراب میشه. تغییر پنجم هر دو رو برداشت: دادهی همهی رکوردها تو یه Box پشتسرهم میشینه، هر کدوم با یه پیشوند طول ۲ بایتی. حالا A، AAAA، TXT و رکوردهای DNSSEC مستقیم کپی میشن و فقط رکوردهای اسمدار مثل CNAME پارس میشن تا فشردهسازی اسم اعمال بشه.
نکات کلیدی:
- مصرف حافظهی هر ورودی از ۹۵۳ بایت به ۴۲۰ بایت رسید، یعنی ۵۶٪ کمتر
- توان درج کش از ۶۲۵ هزار به ۸۹۳ هزار ورودی در ثانیه رفت و تأخیر جستوجو از ۸۲۸ به ۶۷۰ نانوثانیه اومد پایین
- تو پروداکشن حافظهی هر اینستنس تو p99 از ۹.۳ به ۵.۳ گیگابایت افتاد و روی کل ناوگان حدود ۱۰۰ ترابایت آزاد شد
- رولاوت از ۱۸ مه ۲۰۲۶ شروع شد و ۶ ژوئیهی ۲۰۲۶ روی همهی سرویسها کامل شد
- حافظهی آزادشده قراره صرف بالا بردن ظرفیت کش بشه تا نرخ hit بره بالا و کوئری کمتری به بالادست بخوره




