Jika Anda memiliki codebase yang besar, rantai dependensi bisa menjadi sangat dalam. Bahkan biner sederhana pun sering kali dapat bergantung pada puluhan ribu target build. Di tidak mungkin menyelesaikan build dalam jumlah yang wajar waktu pada satu komputer: tidak ada sistem build yang dapat mengakali hukum fisika yang diberlakukan pada perangkat keras komputer. Satu-satunya cara agar berhasil adalah dengan sistem pembangunan yang mendukung bangunan terdistribusi di mana unit-unit pekerjaan yang dilakukan oleh sistem tersebar di seluruh wilayah yang arbitrer dan sejumlah mesin. Mengasumsikan bahwa kita telah memecah pekerjaan sistem menjadi pekerjaan yang cukup kecil unit (selengkapnya tentang hal ini akan dibahas nanti), hal ini akan memungkinkan kami menyelesaikan semua build ukuran secepat yang ingin kami bayar. Skalabilitas ini adalah hal terpenting yang telah kami kerjakan dengan menentukan sistem build berbasis artefak.
Penyimpanan cache jarak jauh
Jenis build terdistribusi paling sederhana adalah yang hanya memanfaatkan jarak jauh menyimpan cache, yang ditunjukkan pada Gambar 1.
Gambar 1. Build terdistribusi yang menampilkan caching jarak jauh
Setiap sistem yang melakukan {i>build<i}, termasuk komputer {i>workstation<i} developer dan sistem continuous integration, membagikan referensi ke cache jarak jauh yang umum layanan. Layanan ini mungkin sistem penyimpanan jangka pendek dan cepat seperti Redis atau layanan cloud seperti Google Cloud Storage. Setiap kali pengguna perlu membangun artefak, baik secara langsung maupun sebagai dependensi, sistem akan memeriksa dengan {i>cache<i} jarak jauh untuk melihat apakah artefak itu sudah ada di sana. Jika demikian, dapat mendownload artefak, bukan membangunnya. Jika tidak, sistem akan membangun artefak itu sendiri dan mengunggah hasilnya kembali ke cache. Hal ini berarti bahwa dependensi tingkat rendah yang tidak terlalu sering berubah dapat dibangun sekali dan dibagikan lintas pengguna daripada harus dibangun ulang oleh setiap pengguna. Di Google, banyak artefak disajikan dari {i>cache<i} bukan dibuat dari awal, dengan sangat mengurangi biaya menjalankan sistem build.
Agar sistem {i>caching<i} jarak jauh bekerja, sistem {i>build<i} harus menjamin bahwa build dapat direproduksi sepenuhnya. Artinya, untuk target build apa pun, tujuan itu harus memungkinkan untuk menentukan kumpulan input ke target tersebut sedemikian rupa sehingga kumpulan input yang sama akan menghasilkan {i>output<i} yang sama persis di komputer apa pun. Ini adalah satu-satunya cara untuk memastikan bahwa hasil mendownload artefak sama dengan hasilnya dalam pengembangannya sendiri. Perhatikan bahwa ini mengharuskan setiap artefak dalam cache dimasukkan pada targetnya dan hash inputnya—dengan cara ini, insinyur dapat melakukan modifikasi yang berbeda pada target yang sama dan cache jarak jauh akan menyimpan semua artefak yang dihasilkan dan menyajikan mereka dengan baik tanpa konflik.
Tentu saja, agar ada keuntungan dari cache jarak jauh, mengunduh artefak harus lebih cepat daripada membuatnya. Tidak selalu demikian, terutama jika server {i>cache<i} jauh dari komputer yang melakukan proses build. jaringan dan sistem build disesuaikan dengan cermat agar dapat membagikan build hasil pengujian tersebut.
Eksekusi jarak jauh
Cache jarak jauh bukanlah build terdistribusi yang sebenarnya. Jika {i>cache<i} hilang atau jika Anda membuat perubahan tingkat rendah yang membutuhkan semuanya untuk dibangun ulang, Anda masih perlu untuk menjalankan seluruh build secara lokal di komputer Anda. Tujuan yang sebenarnya adalah untuk mendukung eksekusi jarak jauh, di mana pekerjaan aktual melakukan build dapat disebarkan terhadap sejumlah pekerja. Gambar 2 menunjukkan sistem eksekusi jarak jauh.
Gambar 2. Sistem eksekusi jarak jauh
Alat build yang berjalan di setiap komputer pengguna (di mana pengguna adalah manusia atau sistem build otomatis) mengirimkan permintaan ke master build pusat. Build master memecah permintaan ke dalam tindakan dan jadwal komponen pelaksanaan tindakan tersebut pada kumpulan pekerja yang skalabel. Setiap pekerja melakukan tindakan yang diminta dengan input yang ditentukan oleh pengguna dan akan menulis artefak yang dihasilkan. Artefak ini dibagikan di sisi lain mesin mengeksekusi tindakan yang memerlukannya hingga {i>output<i} akhir dapat dihasilkan dan dikirim ke pengguna.
Bagian tersulit dari mengimplementasikan sistem seperti itu adalah mengelola komunikasi antara pekerja, master, dan komputer lokal pengguna. Pekerja mungkin bergantung pada artefak perantara yang dihasilkan oleh pekerja lain, dan output akhir harus dikirim kembali ke komputer lokal pengguna. Untuk melakukan ini, kita bisa membangun di atas cache terdistribusi yang dijelaskan sebelumnya dengan meminta setiap worker menulis hasilnya dan membaca dependensinya dari cache. Blok master pekerja mulai dari melanjutkan sampai semua yang mereka andalkan telah selesai, di mana ketika mereka akan dapat membaca input mereka dari {i>cache<i}. Produk akhir adalah di-cache, sehingga komputer lokal dapat mengunduhnya. Perhatikan bahwa kita juga memerlukan secara terpisah untuk mengekspor perubahan lokal pada hierarki sumber pengguna sehingga pekerja bangunan dapat menerapkan perubahan itu sebelum membangun.
Agar berfungsi, semua bagian dari sistem build berbasis artefak yang dijelaskan sebelumnya harus disatukan. Lingkungan build harus sepenuhnya menjelaskan secara mandiri agar kita dapat meningkatkan pekerja tanpa campur tangan manusia. Membuat proses itu sendiri harus sepenuhnya mandiri karena setiap langkah mungkin dieksekusi pada komputer yang berbeda. Output harus benar-benar determenistik sehingga setiap pekerja dapat memercayai hasil yang diterimanya dari pekerja lain. Seperti jaminan sangat sulit untuk disediakan oleh sistem berbasis tugas, yang mana sehingga tidak mungkin untuk membangun sistem eksekusi jarak jauh yang andal selain satu.
Build terdistribusi di Google
Sejak tahun 2008, Google telah menggunakan sistem pembangunan terdistribusi yang menggunakan caching jarak jauh dan eksekusi jarak jauh, yang diilustrasikan pada Gambar 3.
Gambar 3. Sistem build terdistribusi dari Google
Cache jarak jauh Google disebut ObjFS. Server ini terdiri dari backend yang menyimpan output build di Bigtable yang didistribusikan ke seluruh fleet produksi kami dan daemon FUSE frontend bernama objfsd yang berjalan di mesin Linux dan Windows. Daemon FUSE memungkinkan para engineer untuk menelusuri output build seolah-olah adalah file normal yang disimpan di workstation, tetapi dengan isi file diunduh sesuai permintaan hanya untuk beberapa file yang diminta langsung oleh . Menyajikan konten file sesuai permintaan sangat mengurangi jaringan dan disk dan sistem ini mampu membangun dua kali lebih cepat dibandingkan dengan saat kami semua output build pada disk lokal developer.
Sistem eksekusi jarak jauh Google disebut Forge. Klien Forge di Blaze (setara internal Bazel) yang disebut Distributor mengirimkan permintaan untuk setiap tindakan ke tugas yang berjalan di pusat data yang disebut Scheduler. Scheduler menyimpan cache tindakan hasil, memungkinkannya mengembalikan respons segera jika tindakan sudah dibuat oleh pengguna lain dari sistem. Jika tidak, tindakan tersebut ditempatkan dalam antrean. Kumpulan besar tugas Executor terus-menerus membaca tindakan dari antrean ini, mengeksekusinya, dan menyimpan hasilnya langsung di ObjFS Bigtable. Ini hasil tersedia bagi eksekutor untuk tindakan pada masa mendatang, atau akan didownload oleh pengguna akhir melalui objfsd.
Hasil akhirnya adalah sistem yang diskalakan untuk mendukung semua build secara efisien yang ditampilkan di Google. Dan skala build Google benar-benar besar: Google menjalankan jutaan build yang mengeksekusi jutaan kasus pengujian dan menghasilkan petabyte output build dari miliaran baris kode sumber setiap hari. Tidak hanya sistem seperti itu memungkinkan para insinyur kami membangun basis kode yang kompleks dengan cepat, hal itu juga memungkinkan untuk menerapkan sejumlah besar alat dan sistem otomatis yang mengandalkan buat.