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.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video