Cloudflare Just Saved 100TB of Memory

BBetter Stack
Computing/SoftwareInternet Technology

Transcript

00:00:00Berapa sebenarnya biaya yang harus Anda bayar untuk satu bita?
00:00:02Nah, dengan skala Cloudflare, pemborosan satu bita per entri
00:00:04menelan biaya lebih dari 250 gigabita memori
00:00:06di seluruh armada mereka,
00:00:08dan baru-baru ini mereka berhasil memangkas memori per entri tersebut setengahnya,
00:00:11sehingga membebaskan 100 terabita memori.
00:00:13Di kondisi ekonomi seperti ini, itu jumlah uang yang sangat besar.
00:00:15Mereka sebenarnya melakukan ini dengan lima perubahan yang cukup sederhana
00:00:17pada sistem penelusuran singgah mereka,
00:00:18sekaligus membuat DNS menjadi lebih cepat pada saat bersamaan,
00:00:21jadi mari kita bahas dan lihat bagaimana mereka melakukannya.
00:00:27Sekarang, Anda mungkin pernah mendengar tentang 1.1.1.1 sebelumnya.
00:00:30Itu adalah resolver DNS publik milik Cloudflare,
00:00:32dan cara kerjanya adalah mengambil domain yang ingin Anda tuju,
00:00:34seperti betterstack.com,
00:00:35lalu mencari tahu apa IP asli dari domain tersebut.
00:00:39Nah, perangkat lunak yang melakukan tugas ini,
00:00:40namanya Big Pineapple, dan ditulis dalam bahasa Rust,
00:00:42dan seperti yang bisa Anda duga,
00:00:43ini adalah perangkat lunak yang sangat sibuk,
00:00:46menyimpan lebih dari 250 miliar entri singgah DNS pada waktu tertentu.
00:00:50Hal ini memastikan bahwa jika seseorang ingin mengunjungi betterstack.com
00:00:52dua detik setelah orang lain melakukannya,
00:00:53sistem tidak perlu menelusuri seluruh hierarki DNS lagi,
00:00:56melainkan langsung menyimpan jawabannya di memori dan menyajikannya kembali.
00:00:59Namun seperti yang saya sebutkan di intro,
00:01:01250 miliar entri singgah berarti satu bita yang terbuang per entri
00:01:04menelan biaya sekitar 250 gigabita RAM,
00:01:07dan itulah mengapa kelima perubahan ini berdampak sangat besar.
00:01:10Pertama-tama, kita membahas biaya kapasitas.
00:01:12Beginilah bentuk entri singgah pada masa lalu.
00:01:14Stempel waktu, masa berlaku, penghitung hit,
00:01:16lalu sekumpulan vektor.
00:01:17Vektor catatan jawaban,
00:01:18vektor catatan otoritas,
00:01:20vektor catatan tambahan,
00:01:21vektor galat,
00:01:22dan banyak lagi.
00:01:23Bagi Anda yang belum familiar dengan Rust,
00:01:25vektor adalah tipe data andalan untuk daftar yang dapat diperluas,
00:01:27dan vektor juga terdiri dari tiga hal di memori.
00:01:29Sebuah penunjuk, panjang, dan kapasitas.
00:01:31Ini adalah seberapa banyak ruang yang dicadangkan untuk pertumbuhan,
00:01:32sehingga sistem tidak perlu mengalokasikan ulang setiap kali Anda menambahkannya.
00:01:35Hal ini sangat berguna jika data tersebut benar-benar berkembang.
00:01:38Namun mereka mengamati entri singgah DNS asli tersebut,
00:01:40dan menyadari bahwa semuanya hanya ditulis ke dalam singgah,
00:01:42dan tidak pernah disentuh lagi.
00:01:44Data itu hanya dibaca,
00:01:45sehingga vektor-vektor ini sebenarnya tidak pernah bertambah besar.
00:01:47Artinya, ada alokasi ruang heap yang berlebihan,
00:01:49yang hanya diam terbuang sia-sia.
00:01:50Terdapat vektor dengan kapasitas untuk delapan item,
00:01:52tetapi hanya lima yang tersimpan,
00:01:53menyisakan tiga slot yang tidak terpakai,
00:01:55dan bidang kapasitas itu sendiri berukuran usize,
00:01:57yang merupakan memori delapan bita,
00:01:58di mana bagi mereka hal itu sama sekali tidak diperlukan.
00:02:00Solusi untuk masalah ini sangatlah sederhana.
00:02:02Cukup tukar vektor dengan kotak (box),
00:02:04karena ukuran kotak bersifat tetap sesuai ukuran saat pertama kali dibuat,
00:02:07sehingga tidak membutuhkan bidang kapasitas,
00:02:08dan juga hanya menyimpan apa yang ada di dalamnya secara pas.
00:02:10Sistem tidak perlu mengalokasikan kapasitas cadangan untuk masa depan.
00:02:13Mereka juga menyadari bahwa mereka dapat menerapkan penghematan yang sama persis
00:02:15pada bidang string juga,
00:02:16karena pada dasarnya string hanyalah vektor U8,
00:02:18sehingga teks tersebut dapat bertambah atau menyusut,
00:02:20tetapi jika Anda tidak membutuhkannya,
00:02:21Anda bisa menggunakan irisan string kotak (boxed string slice),
00:02:23alias string ini tidak akan berubah.
00:02:26Secara keseluruhan pada satu entri singgah,
00:02:27terdapat delapan bidang vektor dan string,
00:02:29sehingga menggantinya dengan kotak menghemat delapan bita per bidang,
00:02:31dan 64 bita per entri,
00:02:33sekaligus menghilangkan kelebihan ruang heap
00:02:35yang dicadangkan oleh vektor untuk pertumbuhan di masa depan,
00:02:36yang berarti total penghematan mencapai lebih dari 15 terabita
00:02:39ketika diskalakan ke 250 miliar entri singgah.
00:02:42Semua itu berasal dari perubahan tipe data yang sederhana.
00:02:45Namun untuk perubahan kita berikutnya,
00:02:46mereka benar-benar melihat beberapa daftar tersebut,
00:02:48dan bertanya, apakah kita benar-benar membutuhkannya?
00:02:50Respons DNS berisi tiga entri,
00:02:52jawaban, otoritas, dan tambahan,
00:02:54dan seperti yang kita lihat sebelumnya,
00:02:55ini disimpan dalam singgah apa adanya,
00:02:57yaitu tiga daftar terpisah,
00:02:58dan meskipun kita telah menghapus bidang kapasitas pada perubahan pertama,
00:03:01setiap daftar tetap terdiri dari penunjuk dan panjang,
00:03:03jadi delapan bita ditambah delapan bita dikali tiga,
00:03:05yang totalnya adalah 48 bita,
00:03:07serta tiga alokasi heap yang terpisah.
00:03:09Tetapi ketika mereka melihat bagaimana daftar-daftar ini
00:03:10sebenarnya digunakan,
00:03:12mereka menyadari bahwa data tersebut selalu dibaca bersama-sama,
00:03:13selalu ditulis bersama-sama,
00:03:14dan selalu berada dalam urutan yang persis sama.
00:03:16Jadi alih-alih menggunakan tiga daftar,
00:03:17mereka dapat memperlakukannya sebagai satu daftar dengan dua pembatas di dalamnya.
00:03:20Sehingga ketiga daftar tersebut menjadi satu daftar catatan,
00:03:22ditambah dua offset kecil yang menyatakan jawaban berakhir di sini,
00:03:25dan otoritas berakhir di sini,
00:03:26dan karena respons DNS tidak akan pernah memiliki empat miliar catatan,
00:03:29bilangan bulat tak bertanda 16-bit sudah cukup untuk offset tersebut,
00:03:33yang masing-masing hanya memakan dua bita.
00:03:34Ini berarti secara keseluruhan,
00:03:35mereka mengganti dua header 16-bita penuh dengan dua angka berukuran 2 bita,
00:03:39sehingga 28 bita dihemat per entri,
00:03:41dan ini juga memungkinkan Rust menghapus beberapa spasi ekstra di antara bidang,
00:03:44membuat struktur data menjadi lebih kecil daripada sekadar bidang yang dihapus saja.
00:03:47Mereka bahkan membawa konsep ini lebih jauh,
00:03:49dan menggabungkan beberapa bidang Boolean menjadi satu tanda biner (bit flag).
00:03:52Lanjut ke perubahan nomor tiga,
00:03:53bagaimana jika kita berhenti menyebut nama yang sama dua kali?
00:03:55Setiap catatan DNS membawa pemilik,
00:03:57yang merupakan nama domain tempat catatan tersebut berasal.
00:04:00Jadi ketika Anda meminta betterstack.com dan mendapatkan catatan Anda kembali,
00:04:03masing-masing catatan bertuliskan betterstack.com.
00:04:05Tetapi informasi itu agak berlebihan.
00:04:08Andalah yang mengajukan pertanyaan,
00:04:09sehingga sistem sudah mengetahui nama domainnya.
00:04:11Dan Cloudflare sebenarnya sudah menyimpan domain kueri tersebut sebagai kunci singgah,
00:04:14jadi mengapa mereka harus menyimpannya lagi sebagai pemilik?
00:04:17Tentu saja tidak.
00:04:17Maka Cloudflare cukup mengubah bidang ini menjadi nama kotak opsional,
00:04:20di mana jika pemiliknya cocok dengan kueri,
00:04:22Anda menyimpan nilai kosong (none),
00:04:23tetapi jika itu benar-benar berbeda,
00:04:24yang bisa terjadi pada beberapa kasus seperti CNAME Chains,
00:04:27Anda menyimpan pemiliknya seperti sebelumnya.
00:04:29Dengan melakukan ini, untuk kasus normal di mana keduanya cocok,
00:04:32mereka menghemat seluruh alokasi heap per catatan,
00:04:34sehingga penghematan ini hanyalah soal melihat data apa yang ada di singgah mereka
00:04:37dan menyadari adanya nilai-nilai yang duplikat.
00:04:39Untuk penghematan nomor empat, kita memiliki alamat IP 144 bita.
00:04:43Data catatan mereka adalah enum Rust dari catatan A, catatan AAAA, teks,
00:04:47SVCB, dan NAPTR, di mana satu tipe mencakup semuanya.
00:04:51Tetapi di sinilah letak masalah dengan enum.
00:04:52Ukurannya akan selalu sebesar varian terbesarnya.
00:04:54Setiap nilai dari tipe tersebut memakan jumlah ruang yang sama,
00:04:57terlepas apakah nilainya membutuhkannya atau tidak.
00:04:58Dalam kasus tersebut, NAPTR adalah nilai terbesar yang memakan 136 byte,
00:05:03dan ketika Anda menambahkan tag serta padding ke enum, ukurannya menjadi 144 byte.
00:05:07Jika Anda membandingkannya dengan kebutuhan record A, yaitu hanya alamat IPv4 sederhana,
00:05:12itu hanya memerlukan empat byte.
00:05:13Ini berarti setiap record A dalam tembolok tersebut berada di dalam kotak 144 byte,
00:05:17padahal hanya menggunakan empat byte,
00:05:19dan record A serta 4A merupakan sebagian besar dari lalu lintas nyata.
00:05:22Dalam bauran tolok ukur Cloudflare sendiri, 56% adalah record A dan 25% 4A, jadi sebagian besar tembolok hanyalah padding.
00:05:29Solusi untuk masalah ini adalah teknik pembungkusan (boxing) andalan kita.
00:05:32Mereka membungkus varian besar dan membiarkan A serta 4A tetap inline, karena itu kecil dan umum,
00:05:36sehingga kini teks, SVCB, dan NAPTR berada di belakang sebuah pointer,
00:05:40sehingga enum hanya perlu sebesar ukuran terbesar yang tersisa, yaitu alamat IPv6 16 byte tersebut.
00:05:45Secara total, untuk record A atau 4A, itu menghemat 120 byte untuk masing-masing record.
00:05:50Namun perubahan ini sebenarnya memiliki konsekuensi.
00:05:52Ketika Anda membungkus sebuah varian, datanya beralih dari dalam entri tembolok,
00:05:55menuju wilayah heap-nya sendiri di tempat lain yang sepenuhnya terpisah,
00:05:58dan hal itu menimbulkan dua biaya baru.
00:06:00Biaya pertama adalah alokator.
00:06:02Cloudflare menggunakan Jemalock, dan Jemalock tidak memberikan jumlah byte yang persis Anda minta,
00:06:06ia mengelompokkan alokasi ke dalam bin berukuran tetap dan membulatkannya ke ukuran terdekat.
00:06:10Jadi record teks yang meminta 32 byte akan masuk ke bin 32 byte dan tidak menyia-nyiakan apa pun,
00:06:15tetapi record MX meminta 40, dibulatkan menjadi 48 byte, dan secara diam-diam merugikan Anda sebesar 8 byte.
00:06:21Biaya kedua adalah lokalitas.
00:06:22Sebelum dibungkus, semua data record untuk sebuah entri berada dalam satu blok memori yang berdekatan,
00:06:27dan setelah dibungkus, masing-masing berada di tempat lain, dan membacanya berarti mengikuti sebuah pointer,
00:06:31dan jika pointer tersebut jatuh jauh dari sisa entri lainnya,
00:06:34CPU Anda harus mengambil baris tembolok (cache line) baru secara keseluruhan hanya untuk membacanya.
00:06:37Jadi, meskipun pembungkusan memperbaiki masalah padding, teknik ini menciptakan masalahnya sendiri,
00:06:41dan inilah saat Cloudflare berpikir, bagaimana jika kita tidak menyimpannya sebagai tipe data Rust sama sekali?
00:06:45Nah, itulah perubahan nomor lima.
00:06:46Cloudflare menjelaskan ini sebagai jalan tengah, pertahankan sisa entri tembolok sebagai bidang terstruktur normal,
00:06:50tetapi ambil data record itu sendiri dan simpan sebagai byte mentah.
00:06:54Jadi alih-alih menggunakan enum atau kotak per record, seluruh entri mendapatkan satu susunan U8 tunggal yang dibungkus,
00:07:00dengan setiap record ditulis sebagai awalan panjang 2 byte, diikuti oleh datanya.
00:07:03Langkah ini membatalkan kedua biaya yang baru saja kita bahas.
00:07:06Semua alokasi terkotak terpisah itu digabungkan menjadi satu alokasi untuk seluruh data catatan,
00:07:10sehingga tidak ada lagi pembulatan per record ke bin Jemalock,
00:07:13dan semuanya dikemas secara berdekatan lagi, sehingga Anda mendapatkan kembali lokalitas tembolok yang hilang akibat pembungkusan.
00:07:18Dan sebagai bonus tambahan, langkah ini juga membuat pencarian menjadi lebih cepat.
00:07:21Sebelumnya, pada setiap cache, Anda memiliki catatan yang terurai di dalam memori,
00:07:25dan Anda harus melakukan serialisasi ulang bidang demi bidang ke dalam format kawat DNS sebelum dapat mengirimkannya ke mana pun.
00:07:30Namun sekarang, formatnya sudah berupa format kawat DNS, sehingga sebagian besar jenis record langsung disalin dari buffer
00:07:35ke dalam pesan keluar.
00:07:37Satu-satunya yang masih memerlukan penguraian adalah record yang berisi nama domain,
00:07:40yaitu CNAME, NS, MX, dan SOA,
00:07:43dan itu hanya karena kompresi nama DNS berarti Anda harus menulis ulang nama-nama tersebut bagaimanapun caranya.
00:07:47Jadi perubahan terakhir ini memangkas memori dan menghapus banyak pekerjaan dari jalur kritis (hot path).
00:07:51Jadi begitulah, itulah 5 perubahan tingkat rendah pada tembolok,
00:07:54yang jika digabungkan mengurangi ukuran per entri dari 953 byte menjadi 420,
00:08:00jadi 56% lebih kecil, dan memori yang benar-benar dialokasikan per entri turun dari 1,1 kilobyte
00:08:05menjadi 461 byte, yang berarti pengurangan sebesar 58%.
00:08:09Selain itu, throughput penyisipan mereka juga meningkat sebesar 43%,
00:08:12dari 625.000 entri per detik menjadi 893.000,
00:08:17dan pencarian juga menjadi 19% lebih cepat, turun dari 828 nanodetik menjadi 670.
00:08:23Mereka meluncurkan perubahan ini di seluruh produksi tahun ini,
00:08:25dan memori residen P99 mereka turun dari 9,3 gigabyte menjadi 5,3,
00:08:29sehingga terjadi penghematan 43% pada lalu lintas nyata,
00:08:32yang secara keseluruhan armada kurang lebih membebaskan 100 terabyte memori,
00:08:35atau setara dengan RAM dari 130 server Gen 13 tersebut.
00:08:38Sekarang mereka berencana menggunakan ruang ekstra tersebut untuk memiliki tembolok yang lebih besar,
00:08:41sehingga mempercepat berbagai hal lebih jauh lagi.
00:08:43Saya sangat menyukai postingan blog ini karena menyoroti keputusan yang harus kita buat.
00:08:46Haruskah kita duduk bersama sebelum membangun semua ini dan merencanakan seluruh pengoptimalan,
00:08:50atau apakah itu merupakan pengoptimalan dini yang prematur?
00:08:52Dan saya bayangkan saat itu di tahun 2018 ketika hal ini dibangun,
00:08:55biaya RAM bagi Cloudflare tidak sesignifikan sekarang.
00:08:59Tulisan lengkapnya adalah artikel yang luar biasa, jadi saya akan menyertakan tautannya di bawah.
00:09:02Beri tahu saya pendapat Anda tentang hal ini di kolom komentar,
00:09:03sambil berkunjung jangan lupa berlangganan,
00:09:04dan seperti biasa, sampai jumpa di video berikutnya.
00:09:05Sampai jumpa di video berikutnya.

Key Takeaway

Cloudflare menghemat 100 terabita memori dan mempercepat DNS dengan lima perubahan tingkat rendah pada struktur data penelusuran singgah.

Highlights

  • Cloudflare berhasil membebaskan 100 terabita memori setelah memangkas ukuran entri singgah DNS setengahnya melalui lima perubahan sederhana.

  • Perangkat lunak penelusuran singgah DNS milik Cloudflare yang bernama Big Pineapple ditulis dalam bahasa Rust dan menyimpan lebih dari 250 miliar entri.

  • Penggantian vektor dengan kotak (box) pada delapan bidang entri singgah menghemat 64 bita per entri serta menghilangkan kelebihan ruang heap.

  • Penggabungan tiga daftar respons DNS menjadi satu daftar dengan dua pembatas offset 16-bit menghemat 28 bita per entri.

  • Penyimpanan data record sebagai byte mentah alih-alih menggunakan enum Rust meningkatkan throughput penyisipan sebesar 43% dan mempercepat pencarian sebesar 19%.

Timeline

Pengantar Penghematan Memori Sistem DNS

  • Pemborosan satu bita per entri menelan biaya lebih dari 250 gigabita memori di seluruh armada Cloudflare.
  • Lima perubahan sederhana pada sistem penelusuran singgah berhasil memangkas ukuran entri setengahnya dan membebaskan 100 terabita memori.
  • Sistem penelusuran singgah DNS publik Cloudflare bernama Big Pineapple dan ditulis dalam bahasa Rust.

Skala operasi Cloudflare yang masif membuat efisiensi satu bita memori menjadi sangat krusial bagi biaya infrastruktur. Armada mereka menyimpan lebih dari 250 miliar entri singgah DNS untuk menghindari penelusuran hierarki berulang. Perubahan kecil pada struktur data menghasilkan penghematan biaya kapasitas yang sangat besar.

Penggantian Vektor dengan Kotak

  • Entri singgah DNS hanya dibaca dan tidak pernah bertambah ukurannya setelah disimpan.
  • Bidang kapasitas berukuran delapan bita pada vektor menjadi tidak diperlukan karena data bersifat statis.
  • Penggantian vektor dan string dengan kotak menghemat 64 bita per entri dan total lebih dari 15 terabita memori.

Data yang masuk ke dalam singgah hanya dibaca ulang tanpa mengalami penambahan ukuran di kemudian hari. Vektor yang dirancang untuk data yang bertumbuh menyisakan ruang heap terbuang sia-sia beserta bidang kapasitas berukuran usize. Penggunaan kotak berukuran tetap menghilangkan alokasi cadangan yang tidak terpakai secara drastis.

Penggabungan Daftar dan Penghapusan Duplikasi Nama

  • Respons DNS yang terdiri dari tiga daftar terpisah digabung menjadi satu daftar dengan dua pembatas offset 2-bita.
  • Penggabungan ini menghemat 28 bita per entri dan merampingkan spasi ekstra di antara bidang struktur data.
  • Penyimpanan nama pemilik diubah menjadi kotak opsional karena domain kueri sudah tersimpan sebagai kunci singgah.

Analisis penggunaan daftar menunjukkan bahwa jawaban, otoritas, dan catatan tambahan selalu dibaca serta ditulis secara bersamaan dalam urutan yang sama. Penggunaan dua offset kecil menggantikan header 16-bita penuh tanpa memerlukan empat miliar catatan. Selain itu, penyimpanan nama pemilik yang sama persis dengan kueri awal dihilangkan untuk menghemat alokasi heap.

Optimalisasi Record IP dan Format Data Mentah

  • Pembungkusan record besar dalam enum Rust mencegah pemborosan ruang padding untuk record A dan AAAA yang berukuran kecil.
  • Penyimpanan record sebagai susunan U8 byte mentah menghilangkan pembulatan bin Jemalock dan mengembalikan lokalitas tembolok.
  • Pencarian menjadi 19 persen lebih cepat karena sebagian besar record langsung disalin dari format kawat DNS tanpa penguraian ulang.

Enum Rust berukuran sebesar varian terbesarnya, membuat record A yang hanya berukuran empat byte tersimpan dalam kotak 144 byte. Meskipun pembungkusan record besar mengatasi padding, teknik ini memunculkan masalah alokasi Jemalock dan lokalitas CPU. Solusi akhir berupa penyimpanan data sebagai byte mentah menyatukan alokasi dan mempercepat proses pengiriman pesan.

Community Posts

No posts yet. Be the first to write about this video!

Write about this video