Dari penerjemah: Halo, Habr! Ya, ini adalah artikel lain tentang kelebihan dan kekurangan dari monorepositori. Saya akan menulis artikel saya tentang bagaimana kami menggunakan repositori mono, bagaimana kami beralih dari maven ke bazel dan apa yang terjadi. Tapi ketika saya memikirkannya, artikel bagus dari pengembang dari Lyft keluar, yang saya putuskan untuk diterjemahkan untuk Anda. Saya berjanji untuk menerbitkan tambahan saya pada artikel, serta pengalaman dengan bazel sebagai lanjutannya.
Kami berada di tahun 2019 Baru, dan saya siap untuk diskusi lain tentang keuntungan (atau ketiadaan) dalam menyimpan semua kode sumber organisasi di “Monorepository”. Bagi Anda yang tidak terbiasa dengan pendekatan ini, idenya adalah untuk menyimpan semua kode sumber dalam satu repositori dari sistem kontrol versi. Alternatifnya, tentu saja, adalah menyimpan kode sumber di beberapa repositori independen, biasanya membaginya di sepanjang perbatasan layanan / aplikasi / perpustakaan.
Dalam posting ini, saya akan menyebut pendekatan ini "polyrepository".
Beberapa raksasa IT menggunakan repositori tunggal, termasuk Google, Facebook, Twitter, dan lainnya. Tentu saja, jika perusahaan terkemuka semacam itu menggunakan mono-repositori, maka manfaat dari pendekatan ini akan sangat besar, dan kita semua harus melakukan hal yang sama, bukan? Tidak! Seperti kata judul artikel: "Tolong jangan gunakan repositori mono!" Mengapa Karena
dalam skala besar, monorepositori akan menyelesaikan semua masalah yang sama yang dipecahkan oleh polyrepositori, tetapi pada saat yang sama memprovokasi Anda pada koherensi yang kuat dari kode Anda dan membutuhkan upaya luar biasa untuk meningkatkan skalabilitas sistem kontrol versi Anda .
Dengan demikian, dalam jangka menengah dan panjang, mono-repositori tidak memberikan keuntungan organisasi, sementara itu meninggalkan insinyur terbaik perusahaan dengan sindrom pasca-trauma (dimanifestasikan dalam bentuk air liur dan bergumam tidak jelas tentang kinerja git).
Penyimpangan singkat: apa yang saya maksud dengan "dalam skala besar"? Tidak ada jawaban tunggal untuk pertanyaan ini, tetapi karena Saya yakin Anda bertanya kepada saya tentang ini, katakanlah ini sekitar 100 pengembang yang menulis kode penuh waktu.
Keuntungan teoretis dari monorepositori dan mengapa monorepositori tidak dapat dicapai tanpa alat yang digunakan untuk polyrezitories (atau false)
Keuntungan Teoritis 1: Kolaborasi yang Lebih Mudah dan Berbagi Kode
Para pendukung mono-repositori mengklaim bahwa ketika semua kode berada dalam repositori yang sama, kemungkinan duplikasi kode kurang, dan lebih mungkin bahwa tim yang berbeda akan bekerja sama pada infrastruktur yang sama.
Inilah kebenaran pahit tentang repositori mono berukuran sedang (dan ini akan terdengar terus-menerus di bagian ini): dengan cepat menjadi tidak praktis bagi pengembang untuk menyimpan semua kode repositori di stasiun kerjanya atau mencari seluruh basis kode menggunakan utilitas seperti grep. Karenanya, setiap repositori mono yang ingin diukur harus menyediakan 2 hal:
1) sesuatu seperti sistem file virtual yang memungkinkan Anda untuk menyimpan secara lokal hanya bagian dari kode. Ini dapat dicapai dengan menggunakan sistem file berpemilik seperti
Perforce , yang mendukung mode ini secara native, menggunakan alat
G3 internal Google atau Microsoft
GVFS .
2) alat canggih sebagai layanan (sebagai layanan) untuk mengindeks / mencari / melihat kode sumber. Karena tidak ada pengembang yang akan menyimpan semua kode sumber di workstation mereka dalam keadaan yang dapat dicari, menjadi sangat penting untuk dapat melakukan pencarian seperti itu di seluruh basis kode.
Berdasarkan fakta bahwa pengembang akan memiliki akses ke hanya sebagian kecil dari kode sumber pada waktu tertentu, apakah ada setidaknya beberapa perbedaan antara mengunduh bagian dari mono-repositori atau mengunduh beberapa repositori independen?
Tidak ada perbedaan .
Dalam konteks pengindeksan / pencarian / browsing dan kode serupa, alat hipotetis seperti itu dapat dengan mudah mencari beberapa repositori dan menggabungkan hasilnya. Faktanya, inilah tepatnya cara pencarian di GitHub bekerja, serta alat pencarian dan pengindeksan yang lebih canggih seperti
Sourcegraph .
Dengan demikian, dari sudut pandang kerja kolaboratif pada kode dalam skala besar, pengembang dalam hal apa pun dipaksa untuk bekerja hanya dengan bagian dari basis kode dan menggunakan alat tingkat yang lebih tinggi. Tidak ada bedanya apakah kode disimpan dalam repositori mono atau dalam beberapa repositori independen, masalahnya diselesaikan dengan cara yang sama, dan
efektivitas bekerja bersama pada kode hanya bergantung pada budaya rekayasa, dan bukan pada cara kode sumber disimpan .
Keuntungan teoretis 2: satu perakitan / tidak ada manajemen ketergantungan
Argumen berikutnya, biasanya dikutip oleh para pendukung mono-repositori, adalah bahwa menyimpan semua kode dalam satu mono-repositori membuat Anda tidak perlu lagi mengelola dependensi, seperti semua kode dikumpulkan secara bersamaan. Ini bohong! Dalam skala besar, sama sekali tidak ada cara untuk membangun kembali semua kode sumber dan menjalankan semua tes otomatis setiap kali seseorang melakukan perubahan pada sistem kontrol versi (atau, yang lebih penting, lebih sering, pada server CI ketika permintaan cabang atau tarik baru dibuat). Untuk mengatasi masalah ini, semua repositori besar menggunakan sistem build mereka yang canggih (mis.
Bazel / Blaze dari Google atau
Buck dari Facebook), yang dirancang untuk memantau perubahan dan blok ketergantungan mereka dan membangun grafik dependensi dari kode sumber. Grafik ini memungkinkan Anda untuk mengatur penyimpanan dan hasil caching yang efisien, sehingga hanya perubahan dan ketergantungannya yang perlu disatukan kembali dan diuji.
Apalagi sejak itu kode yang terkumpul pada akhirnya harus dikerahkan, dan, seperti yang Anda tahu, semua perangkat lunak tidak dapat digunakan sekaligus, penting bahwa semua artefak perakitan dikendalikan, sehingga artefak diulang kembali sesuai keperluan. Pada dasarnya, ini berarti bahwa bahkan di dunia repositori tunggal, beberapa versi kode dapat ada pada saat yang sama di alam, dan harus dipantau dan dikoordinasikan dengan hati-hati.
Para pendukung mono-repositori juga akan berpendapat bahwa meskipun dengan mempertimbangkan kebutuhan untuk melacak majelis / dependensi, ini masih memberikan keuntungan yang tidak dapat disangkal, karena satu komit menggambarkan keadaan lengkap seluruh dunia. Saya akan mengatakan bahwa keuntungan ini agak kontroversial, mengingat bahwa grafik ketergantungan sudah ada, dan sepertinya tugas yang cukup sepele untuk memasukkan pengidentifikasi komit untuk setiap repositori independen sebagai bagian dari grafik ini, dan pada kenyataannya Bazel dapat dengan mudah bekerja dengan beberapa repositori independen serta satu mono-repositori, mengabstraksi level yang mendasarinya dari pengembang. Selain itu, mudah untuk mengimplementasikan alat refactoring otomatis yang secara otomatis memperbarui versi pustaka dependen di beberapa repositori independen sekaligus, meratakan perbedaan antara monorepositori dan polyrepositori di bagian ini (lebih lanjut tentang ini nanti).
Hasil akhirnya adalah bahwa kenyataan perakitan / penyebaran dalam skala besar sebagian besar sama untuk mono-repositori dan poli-repositori.
Tidak ada perbedaan untuk alat, seharusnya tidak untuk pengembang yang menulis kode .
Keuntungan teoritis 3: kode refactoring adalah komit atom sederhana
Akhirnya, kebajikan terakhir yang disebutkan oleh pendukung mono-repositori adalah fakta bahwa satu repositori membuat kode refactoring lebih mudah karena kemudahan pencarian, dan gagasan bahwa komit tunggal dapat menjangkau seluruh repositori. Ini tidak benar karena beberapa alasan:
1) seperti yang dijelaskan di atas, dalam skala besar, pengembang tidak akan dapat mengedit atau mencari seluruh basis kode pada mesin lokalnya. Dengan demikian, gagasan bahwa siapa pun dapat dengan mudah mengkloning seluruh repositori mereka ke diri mereka sendiri dan hanya melakukan grep / ganti tidak begitu mudah untuk dipraktikkan.
2) bahkan jika kita mengasumsikan bahwa dengan bantuan sistem file virtual yang kompleks seorang pengembang dapat mengkloning dan mengedit seluruh basis kode, lalu seberapa sering hal ini akan terjadi? Saya tidak berbicara tentang memperbaiki bug dalam implementasi pustaka bersama, karena situasi ini ditangani sama dalam kasus repositori tunggal dan dalam kasus multi-repositori (dengan asumsi sistem build / deployment yang sama, seperti dijelaskan di atas). Saya sedang berbicara tentang mengubah API perpustakaan, yang akan diikuti oleh banyak kesalahan kompilasi di tempat-tempat di mana perpustakaan ini dipanggil. Dalam basis kode yang sangat besar,
hampir tidak mungkin untuk melakukan perubahan pada API dasar, yang akan dipratinjau oleh semua tim yang terlibat sebelum konflik gabungan memaksa Anda untuk memulai proses lagi . Pengembang memiliki 2 kemungkinan nyata: dia bisa menyerah dan mencari solusi untuk masalah dengan API (dalam praktiknya, ini terjadi lebih sering daripada yang kita semua inginkan), atau dia dapat membelokkan API yang ada, menulis API baru dan kemudian memulai dan memperbarui semua panggilan ke API lama dengan susah payah di seluruh basis kode. Bagaimanapun,
ini benar-benar proses yang sama dengan polyrepositori .
3) dalam dunia yang berorientasi layanan, aplikasi terdiri dari banyak komponen yang digabungkan secara longgar yang saling berinteraksi menggunakan beberapa jenis API yang dijelaskan dengan baik. Organisasi yang lebih besar cepat atau lambat akan beralih ke menggunakan IDL (bahasa deskripsi antarmuka), seperti Thrift atau Protobuf, yang memungkinkan Anda membuat API jenis-aman dan membuat perubahan yang kompatibel ke belakang. Seperti dijelaskan di bagian sebelumnya tentang perakitan / penyebaran,
kode tidak dapat digunakan secara bersamaan . Ini dapat digunakan selama periode waktu: jam, hari, atau bahkan bulan. Oleh karena itu, pengembang harus memikirkan kompatibilitas ke belakang dari perubahan mereka. Ini adalah realitas pengembangan perangkat lunak modern, yang ingin diabaikan banyak orang, tetapi tidak bisa. Oleh karena itu, ketika datang ke layanan (sebagai lawan dari pustaka API), pengembang harus menggunakan salah satu dari dua pendekatan yang dijelaskan di atas (jangan mengubah API atau melalui siklus penghentian) dan
ini benar-benar sama untuk monorepositori dan polyrepository .
Berbicara tentang refactoring basis kode besar, banyak organisasi besar sedang mengembangkan alat refactoring otomatis mereka sendiri, seperti
fastmod , baru-baru ini dirilis oleh Facebook. Seperti biasa, alat ini dapat dengan mudah bekerja dengan satu repositori atau beberapa yang independen. Lyft memiliki alat yang disebut "refactorator" yang melakukan hal itu. Ini bekerja seperti fastmod, tetapi mengotomatiskan perubahan di beberapa repositori kami, termasuk membuat permintaan tarikan, melacak status ulasan, dll.
Kekurangan Unik dari Monorepositori
Pada bagian sebelumnya, saya mencantumkan semua keuntungan teoretis yang disediakan monorepositori, dan mencatat bahwa untuk memanfaatkannya, perlu untuk membuat alat yang sangat rumit yang tidak akan berbeda dari yang untuk polipositori. Pada bagian ini, saya akan menyebutkan 2 kelemahan unik dari mono-repositori.
Kelemahan 1: Konektivitas yang Kuat dan Perangkat Lunak Sumber Terbuka
Secara organisasi, monorepositori memprovokasi pembuatan perangkat lunak yang sangat erat dan rapuh. Ini memberi pengembang perasaan bahwa mereka dapat dengan mudah memperbaiki kesalahan dalam abstraksi, meskipun dalam kenyataannya mereka tidak bisa karena proses perakitan / penyebaran yang tidak stabil dan faktor manusia / organisasi / budaya yang muncul ketika mencoba untuk membuat perubahan segera di seluruh basis kode.
Struktur kode dalam polrepositori mewakili batas yang jelas dan transparan antara tim / proyek / abstraksi / pemilik kode dan memaksa pengembang untuk mempertimbangkan antarmuka interaksi dengan cermat. Ini adalah keuntungan yang halus, tetapi sangat penting: ini membuat pengembang berpikir lebih luas dan dalam jangka panjang. Selain itu, penggunaan multi-repositori tidak berarti pengembang tidak dapat melampaui batas repositori. Apakah ini terjadi atau tidak, itu hanya tergantung pada budaya pembangunan, dan bukan pada apakah monorepositori atau polyrepositori digunakan.
Ikatan yang kuat juga memiliki konsekuensi serius terkait pembukaan kode sumbernya. Jika sebuah perusahaan ingin membuat atau menggunakan perangkat lunak open source, penggunaan multi-repositori adalah suatu keharusan. Distorsi yang terjadi ketika perusahaan mencoba untuk meletakkan proyeknya di open source dari mono-repositori (impor / ekspor kode sumber, pelacak bug publik / pribadi, lapisan tambahan untuk abstrak perbedaan dalam perpustakaan standar, dll.) Tidak mengarah pada kolaborasi yang produktif dan membangun komunitas serta menciptakan overhead yang signifikan.
Cacat 2: skalabilitas sistem kontrol versi
Melakukan penskalaan sistem kontrol versi untuk ratusan pengembang, ratusan juta baris kode, dan sejumlah besar komit adalah tugas yang monumental. Mono-repositori Twitter, dibuat 5 tahun yang lalu (berdasarkan git), adalah salah satu proyek paling tidak berharga yang pernah saya tonton dalam karier saya. Menjalankan perintah sederhana seperti
git status
memerlukan waktu
beberapa menit . Jika salinan lokal repositori terlalu lama, pembaruan dapat memakan waktu
berjam -
jam (pada saat itu bahkan merupakan praktik untuk mengirim hard drive dengan salinan repositori ke karyawan jarak jauh dengan versi kode terbaru). Saya ingat ini bukan untuk mengejek pengembang Twitter, tetapi untuk menggambarkan betapa rumitnya masalah ini. Saya dapat mengatakan bahwa 5 tahun kemudian, kinerja mono-repositori Twitter masih jauh dari yang ingin dilihat oleh para pengembang tim Tilling, dan ini bukan karena mereka berusaha keras.
Tentu saja, selama 5 tahun terakhir, beberapa pengembangan telah terjadi di daerah ini. Microsoft
Git VFS , yang digunakan untuk mengembangkan Windows, telah menyebabkan munculnya sistem file virtual nyata untuk git, yang saya jelaskan di atas sebagai prasyarat untuk penskalaan sistem kontrol versi (dan dengan pembelian Microsoft Github tampaknya tingkat penskalaan ini akan menemukan aplikasi dalam fitur yang GiHub tawarkan kepada klien korporatnya). Dan tentu saja, Google dan Facebook terus menginvestasikan sumber daya besar dalam sistem internal mereka sehingga mereka terus berfungsi, meskipun hampir tidak ada yang tersedia untuk umum.
Jadi mengapa Anda harus secara umum menyelesaikan masalah ini dengan meningkatkan sistem kontrol versi, jika, seperti yang dijelaskan di bagian sebelumnya, toolkit harus persis sama dengan multirepositori? Tidak ada alasan yang masuk akal untuk ini.
Kesimpulan
Seperti yang sering terjadi dalam pengembangan perangkat lunak, kami melihat perusahaan perangkat lunak yang paling sukses sebagai contoh dan mencoba untuk meminjam praktik terbaik mereka tanpa memahami apa sebenarnya yang menyebabkan perusahaan-perusahaan ini sukses. Monorepositori, menurut pendapat saya, adalah contoh khas dari kasus seperti itu. Google, Facebook, dan Twitter telah menginvestasikan sejumlah besar sumber daya dalam sistem penyimpanan kode mereka hanya untuk menghasilkan solusi yang pada dasarnya
sama dengan yang diperlukan untuk multi-repositori, tetapi memicu hubungan yang kuat dan membutuhkan investasi besar dalam penskalaan kontrol versi .
Bahkan, dalam skala besar, bagaimana perusahaan bekerja dengan bekerja bersama dengan kode, kolaborasi, ikatan yang kuat, dll.
secara langsung tergantung pada budaya dan kepemimpinan teknik, dan tidak ada hubungannya dengan apakah monorepositori atau polipositori digunakan . Kedua solusi terlihat sama untuk pengembang. Jadi mengapa menggunakan monorepositori?
Tolong jangan!