Terjemahan artikel ini disiapkan khusus untuk siswa dari kursus "Arsitek Beban Tinggi" .

Pendahuluan
Dalam arsitektur microsoftvice Netflix, mentransfer dataset dari satu ke beberapa titik akhir bisa sangat sulit. Kumpulan data ini dapat berisi apa saja dari konfigurasi layanan hingga hasil pemrosesan batch. Untuk mengoptimalkan akses, database penduduk sering diperlukan, dan perubahan harus dikirim segera setelah memperbarui data.
Satu contoh yang mencerminkan perlunya distribusi terdistribusi dari suatu dataset terlihat seperti ini: pada waktu tertentu, Netflix melakukan sejumlah besar tes A / B. Pengujian ini mencakup beberapa layanan dan perintah, dan operator pengujian harus dapat melakukan konfigurasi ulang dengan cepat. Ini juga membutuhkan kemampuan untuk mendeteksi node yang tidak bisa mendapatkan konfigurasi pengujian terbaru, dan kemampuan untuk memutar kembali ke versi yang lebih tua jika terjadi kesalahan.
Contoh lain dari kumpulan data yang perlu didistribusikan adalah urutan output dari model pembelajaran mesin: hasil kerjanya dapat digunakan oleh beberapa tim, namun tim ML tidak selalu tertarik untuk mendukung layanan akses tanpa gangguan dalam situasi kritis. Alih-alih situasi ketika masing-masing tim perlu membuat cadangan agar dapat mundur secara ringkas, perhatian khusus diberikan untuk memastikan bahwa beberapa tim dapat menggunakan hasil dari satu tim.
Tanpa dukungan di tingkat infrastruktur, setiap tim akhirnya mencoba menerapkan solusinya sendiri, tetapi ternyata dengan tim yang berbeda dengan keberhasilan yang berbeda-beda. Set data sendiri memiliki ukuran yang berbeda, dari beberapa byte hingga beberapa gigabyte. Penting untuk menciptakan kemampuan untuk memantau kinerja proses dan mendeteksi kerusakan menggunakan alat khusus sehingga operator dapat dengan cepat melakukan perubahan tanpa harus membuat solusi sendiri.
Penyebaran dataDi Netflix, kami menggunakan sistem data pub / sub internal yang disebut Gutenberg. Gutenberg memungkinkan Anda untuk mendistribusikan kumpulan data dengan versi - penerima menerima data dan menerima versi terbaru mereka saat diterbitkan. Setiap versi kumpulan data tetap tidak berubah dan berisi representasi lengkap dari data, yaitu, tidak ada ketergantungan pada versi sebelumnya. Gutenberg memungkinkan Anda untuk melihat versi data lama jika Anda perlu, misalnya, debugging, cepat memecahkan masalah data, atau melatih kembali model pembelajaran mesin. Pada artikel ini, kita akan berbicara tentang arsitektur Gutenberg tingkat tinggi.
Model data
1 topik -> banyak versiDesain tingkat atas Gutenberg adalah temanya. Penerbit menerbitkan data dalam topik, dan penerima mengekstraknya. Publikasi dalam topik ditambahkan sebagai versi terpisah. Itu ditandai dengan kebijakan penyimpanan khusus yang menentukan jumlah versi, tergantung pada kasus penggunaan. Misalnya, Anda dapat mengonfigurasi tema untuk menyimpan 10 versi atau versi 10 hari terakhir.
Setiap versi berisi metadata (kunci dan nilai) dan penunjuk data. Pointer data dapat dianggap sebagai metadata khusus yang menunjukkan di mana data yang dipublikasikan sebenarnya disimpan. Hari ini, Gutenberg mendukung pointer data langsung (jika payload ditulis dalam nilai pointer data itu sendiri) dan pointer data S3 (jika payload disimpan dalam S3). Pointer data langsung biasanya digunakan ketika data kecil (kurang dari 1 MB), dan S3 digunakan sebagai penyimpanan cadangan jika volume data besar.
1 topik -> banyak set yang diterbitkanGutenberg menyediakan kemampuan untuk mengirim publikasi ke sekelompok pengguna penerima tertentu - misalnya, satu set dapat dikelompokkan berdasarkan wilayah, aplikasi, atau cluster tertentu. Ini dapat digunakan untuk mengontrol kualitas perubahan data atau membatasi kumpulan data sehingga sebagian aplikasi dapat berlangganan. Penerbit menentukan area publikasi dari versi data tertentu dan dapat menambahkan area ke data yang diterbitkan sebelumnya. Harap perhatikan bahwa ini berarti bahwa konsep versi terbaru dari data tergantung pada area spesifik - kedua aplikasi dapat menerima versi data terbaru yang berbeda tergantung pada area publikasi yang ditentukan oleh penerbit. Layanan Gutenberg memetakan aplikasi penerima ke area penerbitan sebelum memutuskan apa yang akan dikirim sebagai versi terbaru.
Gunakan kasing
Kasus penggunaan yang paling umum untuk Gutenberg adalah mendistribusikan data dengan ukuran berbeda dari satu penerbit ke beberapa penerima. Seringkali data disimpan dalam memori penerima dan digunakan sebagai "cache bersama", di mana selalu tetap tersedia selama eksekusi kode penerima dan secara atom diganti di bawah tenda jika perlu. Banyak dari kasus penggunaan ini dapat dikelompokkan ke dalam "konfigurasi," seperti konfigurasi cache
Open Connect Appliance , ID jenis perangkat yang didukung, metadata metode pembayaran yang didukung, dan konfigurasi uji A / B. Gutenberg menyediakan abstraksi antara menerbitkan dan menerima data ini, memungkinkan penerbit untuk secara bebas beralih melalui aplikasi mereka tanpa mempengaruhi penerima hilir. Dalam beberapa kasus, penerbitan dilakukan menggunakan antarmuka pengguna yang dikelola oleh Gutenberg, dan tim tidak perlu menyentuh aplikasi penerbitan mereka sama sekali.
Penggunaan lain dari sistem Gutenberg adalah repositori data berversi. Ini berguna untuk aplikasi pembelajaran mesin di mana tim membangun dan melatih model berdasarkan data historis, melihat bagaimana mereka berubah dari waktu ke waktu, kemudian mengubah parameter tertentu dan menjalankan aplikasi lagi. Paling sering dalam perhitungan batch, Gutenberg digunakan untuk menyimpan dan mendistribusikan hasil perhitungan ini sebagai versi set data yang berbeda. Kasing penggunaan daring berlangganan topik untuk menyediakan data waktu-nyata dari set versi terbaru, sementara sistem otonom dapat menggunakan data historis dari topik yang sama, misalnya, untuk mengajarkan model pembelajaran mesin.
Penting untuk dicatat bahwa Gutenberg tidak dirancang sebagai sistem acara, ini dimaksudkan hanya untuk kontrol versi dan distribusi data. Secara khusus, publikasi yang sering tidak berarti bahwa pelanggan diminta untuk menerima setiap versi. Ketika dia meminta pembaruan, dia akan menerima versi terbaru, bahkan jika saat ini versinya saat ini jauh di belakang yang saat ini. Pub-sub atau sistem acara tradisional lebih cocok untuk pesan kecil yang dikirim berurutan. Artinya, penerima dapat membuat gagasan tentang seluruh kumpulan data dengan mengonsumsi seluruh aliran (yang dikompres) peristiwa. Namun, Gutenberg dimaksudkan untuk menerbitkan dan menggunakan representasi dataset yang lengkap dan tidak dapat diubah.
Pengembangan dan arsitektur
Gutenberg terdiri dari layanan gRPC dan API REST, serta pustaka klien Java yang menggunakan API gRPC.
Arsitektur tingkat tinggiPelanggan
Pustaka klien Gutenberg menangani tugas-tugas seperti mengelola langganan, memuat / membongkar S3, metrik
Atlas , dan parameter yang dapat dikonfigurasi menggunakan properti
Archaius . Dia berinteraksi dengan layanan Gutenberg melalui gRPC, menggunakan
Eureka untuk menemukan layanan.
Posting
Penerbit biasanya menggunakan API tingkat tinggi untuk menerbitkan string, file, dan byte array. Bergantung pada ukuran data, mereka dapat dipublikasikan sebagai penunjuk langsung ke data atau diunggah ke S3, dan kemudian diterbitkan sebagai penunjuk data S3. Klien dapat mengunggah payload ke S3 atas nama penerbit atau hanya mempublikasikan metadata payload yang sudah dalam S3.
Pointer data langsung secara otomatis direplikasi secara global. Data yang diterbitkan dalam S3, secara default, diunggah oleh penerbit di beberapa area, meskipun ini juga dapat dikustomisasi.
Manajemen Berlangganan
Pustaka klien menyediakan manajemen berlangganan penerima. Ini memungkinkan pengguna untuk membuat langganan untuk topik-topik tertentu dari mana perpustakaan mengekstraksi data (misalnya, dari S3) untuk mentransfernya ke penerima yang ditetapkan oleh pengguna. Langganan berfungsi sesuai dengan model survei - mereka meminta pembaruan baru dari layanan setiap 30 detik, mengirimkan versi yang mereka terima terakhir. Pelanggan yang berlangganan tidak akan menggunakan versi data yang lebih lama dari yang mereka miliki saat ini jika tidak diperbaiki (lihat "toleransi kesalahan" di bawah). Logika permintaan berulang kabel dan dapat dikonfigurasi. Misalnya, pengguna dapat mengonfigurasi Gutenberg untuk menggunakan versi data yang lebih lama jika proses pengunduhan rusak atau untuk memproses data versi terbaru saat startup, paling sering untuk bekerja dengan perubahan data yang tidak sesuai dengan umpan balik. Gutenberg juga menyediakan langganan pra-konfigurasi yang menyimpan data terbaru dan di bawah tenda memperbarui secara atomis ketika perubahan tiba. Ini memenuhi sebagian besar kasus penggunaan langganan di mana pelanggan hanya peduli dengan nilai saat ini pada waktu tertentu, yang memungkinkan pengguna untuk menentukan nilai default, misalnya, untuk topik yang belum pernah diposting sebelumnya (misalnya, jika tema digunakan untuk konfigurasi), atau jika ada kesalahan tergantung pada topik (untuk menghindari pemblokiran peluncuran layanan ketika ada nilai default yang valid).
API Penerima
Gutenberg juga menyediakan API klien tingkat tinggi, yang di bawah tenda memiliki API gRPC tingkat rendah dan menyediakan fungsionalitas tambahan dan transparansi pelaksanaan kueri. Salah satu contohnya adalah mengunduh data untuk tema dan versi tertentu, yang banyak digunakan oleh komponen yang terhubung ke
Netflix Hollow . Contoh lain adalah penerimaan versi terbaru dari suatu topik pada titik waktu tertentu - sebuah kasus penggunaan umum untuk debugging atau model pembelajaran mesin pengajaran.
Keberlanjutan dan "transparansi" klien
Gutenberg dirancang dengan fokus pada memungkinkan layanan penerima untuk memulai dengan sukses, daripada menjamin bahwa mereka mulai dengan data terbaru. Karena alasan ini, pustaka klien dibangun dengan logika cadangan untuk menangani status saat tidak dapat berinteraksi dengan layanan Gutenberg. Jika permintaan HTTP gagal, klien memuat cache metadata cadangan dari topik yang dipublikasikan dari S3 dan berfungsi dengannya. Cache ini berisi semua informasi untuk memutuskan apakah akan menerapkan pembaruan dan di mana mengambil data (baik dari metadata publikasi itu sendiri atau dari S3). Ini memungkinkan pelanggan untuk mengambil data (yang berpotensi ketinggalan zaman, tergantung pada keadaan cache cadangan saat ini) tanpa menggunakan layanan.
Salah satu keuntungan menyediakan perpustakaan klien adalah kemampuan untuk mendapatkan metrik yang dapat digunakan untuk melaporkan masalah infrastruktur secara umum dan kesalahan dalam aplikasi tertentu. Saat ini metrik ini digunakan oleh tim Gutenberg untuk memantau distribusi publikasi dan peringatan SLI kami jika terjadi masalah yang khas. Beberapa pelanggan juga menggunakan metrik ini untuk melaporkan kesalahan spesifik aplikasi tertentu, misalnya, kegagalan publikasi individu atau penolakan topik tertentu.
Server
Gutenberg adalah aplikasi
Governator / Tomcat yang menyediakan titik akhir gRPC dan REST. Menggunakan cluster Cassandra yang direplikasi secara global untuk menyimpan dan mendistribusikan metadata publikasi di setiap wilayah. Contoh yang memproses permintaan penerima diskalakan secara terpisah dari contoh yang memproses permintaan publikasi. Ada sekitar 1.000 kali lebih banyak permintaan untuk publikasi daripada permintaan untuk publikasi. Selain itu, ini memungkinkan Anda untuk menghapus ketergantungan dari fakta publikasi pada tanda terima, sehingga lonjakan tiba-tiba dalam publikasi tidak akan mempengaruhi penerimaan, dan sebaliknya.
Setiap instance dalam Cluster Permintaan Penerima memproses cache di-memori dari publikasi terbaru, menariknya dari Cassandra setiap beberapa detik. Ini diperlukan untuk memproses sejumlah besar permintaan penerimaan yang berasal dari klien yang ditandatangani tanpa mentransfer lalu lintas ke cluster Cassandra. Selain itu, cache dengan kelompok permintaan kecil melindungi dari lonjakan permintaan yang berpotensi memperlambat Cassandra sehingga mempengaruhi seluruh wilayah. Kami memiliki situasi ketika kesalahan tiba-tiba bertepatan dengan redistribusi cluster besar menyebabkan gangguan dalam layanan Gutenberg. Selain itu, kami menggunakan
pembatas konkurensi adaptif yang ditemukan dalam aplikasi asli untuk menekan aplikasi dengan perilaku yang salah tanpa memengaruhi orang lain.
Dalam kasus di mana data diterbitkan dalam S3 di beberapa wilayah, server memutuskan segmen mana yang akan dikirim kembali ke klien untuk diunduh, tergantung di mana klien berada. Ini juga memungkinkan layanan untuk menyediakan klien dengan segmen di wilayah "terdekat" atau memaksa klien untuk pindah ke wilayah lain jika wilayah saat ini terputus karena satu dan lain alasan.
Sebelum mengembalikan data berlangganan ke penerima, Gutenberg terlebih dahulu memeriksa data untuk konsistensi. Jika pemeriksaan gagal, dan pelanggan telah menerima beberapa data, layanan tidak mengembalikan apa pun, yang sebenarnya berarti bahwa pembaruan tidak tersedia. Jika klien pelanggan belum menerima data apa pun (biasanya ini baru dimulai), layanan akan meminta riwayat topik dan mengembalikan nilai terakhir yang melewati pemeriksaan konsistensi. Hal ini disebabkan oleh fakta bahwa kami mengamati keterlambatan episodik dalam replikasi di tingkat Cassandra, di mana pada saat pelanggan meminta data baru, metadata yang terkait dengan versi terbaru yang dipublikasikan hanya direplikasi sebagian. Ini dapat menyebabkan klien menerima data yang tidak lengkap, yang kemudian akan menyebabkan kesalahan permintaan data atau kesalahan dalam logika bisnis. Melakukan pemeriksaan konsistensi seperti itu di server melindungi penerima dari peringatan kemungkinan konsistensi yang datang dengan pilihan layanan data warehouse.
Kemampuan untuk memonitor publikasi topik dan situs yang menggunakan topik ini adalah fungsi penting untuk mengaudit dan mengumpulkan informasi penggunaan. Untuk mengumpulkan data ini, layanan memotong permintaan dari penerbit dan penerima (baik permintaan untuk memperbarui data dari pelanggan dan lainnya) dan mengindeksnya ke dalam Elasticsearch menggunakan
pipa data
Keystone . Jadi kami memiliki kesempatan untuk mendapatkan data untuk topik pemantauan yang digunakan dan tidak ada lagi. Kami menerbitkan tautan mendalam ke dasbor Kibana dari UI internal sehingga pemilik tema dapat mengelola pelanggan mereka secara mandiri.
Selain kluster yang menangani permintaan penerbit dan penerima, layanan Gutenberg meluncurkan kluster lain yang memproses permintaan berkala. Secara khusus, ia memecahkan dua masalah:
- Setiap beberapa menit, semua publikasi dan metadata terbaru dikumpulkan dan dikirim ke S3. Ini memulai dimulainya cache cadangan, yang digunakan oleh klien, seperti dijelaskan di atas.
- Pengumpul sampah menghapus versi topik yang tidak memenuhi kebijakan penyimpanannya. Itu juga menghapus data yang terkait dengannya (misalnya, objek S3) dan membantu memastikan siklus hidup data yang terdefinisi dengan baik.
Toleransi kesalahan
Jepret
Penyebaran yang gagal terjadi di dunia pengembangan aplikasi, dan kembalikan ke versi sebelumnya adalah strategi umum untuk memperbaiki masalah tersebut. Arsitektur data-driven memperumit situasi, karena perilaku ditentukan oleh data yang berubah seiring waktu.
Data yang didistribusikan oleh Gutenberg memengaruhi dan dalam banyak kasus mengontrol perilaku sistem. Ini berarti bahwa jika terjadi kesalahan, Anda perlu cara untuk memutar kembali ke versi data yang terbukti baik. Untuk meringankan situasi, Gutenberg memungkinkan untuk "menautkan" tema ke versi tertentu. Pin menggantikan versi data terbaru dan memaksa klien untuk memutakhirkan ke versi ini, yang memungkinkan Anda untuk dengan cepat memperbaiki situasi kritis, daripada mencoba mencari cara bagaimana menerbitkan versi kerja terbaru. Anda bahkan dapat menerapkan penjilidan ke area penerbitan sehingga hanya penerima dari area ini yang dapat menggunakan data. Pin juga mengesampingkan data yang diterbitkan selama pengikatan aktif, tetapi ketika pin dihapus, klien akan menerima versi terbaru, yang mungkin versi terbaru yang disematkan atau versi baru yang diterbitkan sementara yang lama disematkan.
Penyebaran berurutan
Saat menggunakan kode baru, sering disarankan untuk membuat rakitan baru dengan subset lalu lintas, menyebarkannya secara bertahap, atau dengan cara lain mengurangi risiko penyebaran, memperlambatnya. , , .
, Gutenberg, —
Spinnaker . , . , . , , , , , . , AWS- .
Gutenberg Netflix . Gutenberg , 6 . – , 1-2 , 12 .
24- , , . , 200, 7. - , , Hollow. , , , – 60, – 4.
, Gutenberg:
- : Gutenberg Java-, Node.JS Python-. , REST API Gutenberg . , Node.JS Python.
- : Gutenberg . Gutenberg.
- : , . , .
- : , Gutenberg, Gutenberg . , .
- : , , . , Elasticsearch.
- : Netflix – . , Gutenberg , .
Itu saja. .