Büyük bir kod tabanınız varsa bağımlılık zincirleri çok derin olabilir. Basit ikili programlar bile çoğu zaman on binlerce derleme hedefine bağlı olabilir. Bu ölçekte, bir derlemeyi tek bir makinede makul bir sürede tamamlamak imkansızdır: Hiçbir derleme sistemi, makine donanımına uygulanan temel fizik yasalarının üstesinden gelemez. Bunun işe yarayabilmesinin tek yolu, sistem tarafından yapılan iş birimlerinin keyfi ve ölçeklenebilir sayıda makineye dağıtıldığı dağıtılmış derlemeleri destekleyen bir derleme sistemi kullanmaktır. Sistemin çalışmasını yeterince küçük birimlere ayırdığımızı varsayarsak (bu konu hakkında daha sonra daha fazla bilgi vereceğiz) bu, herhangi bir boyuttaki derlemeyi ödemeye hazır olduğumuz kadar hızlı bir şekilde tamamlamamıza olanak tanır. Bu ölçeklenebilirlik, yapı tabanlı bir derleme sistemi tanımlayarak üzerinde çalıştığımız en önemli hedeftir.
Uzaktan önbelleğe alma
En basit dağıtılmış derleme türü, yalnızca Şekil 1'de gösterilen uzak önbelleğe alma özelliğinden yararlanan türdür.
Şekil 1. Uzak önbelleğe almayı gösteren dağıtılmış derleme
Hem geliştirici iş istasyonları hem de sürekli entegrasyon sistemleri dahil olmak üzere derleme yapan her sistem, ortak bir uzak önbelleğe hizmet referansı paylaşır. Bu hizmet, Redis gibi hızlı ve yerel bir kısa süreli depolama sistemi veya Google Cloud Storage gibi bir bulut hizmeti olabilir. Kullanıcının doğrudan veya bağımlılık olarak bir yapı derlemesi gerektiğinde sistem öncelikle uzak önbelleği kontrol ederek bu yapının zaten mevcut olup olmadığını kontrol eder. Bu durumda, yapıyı derlemek yerine indirebilir. Aksi takdirde sistem, yapıyı kendisi oluşturur ve sonucu önbelleğe geri yükler. Bu, çok sık değişmeyen düşük düzey bağımlılıkların her kullanıcı tarafından yeniden oluşturulmak yerine bir kez oluşturulup kullanıcılar arasında paylaşılabileceği anlamına gelir. Google'da birçok yapı, sıfırdan derlenmek yerine önbellekten yayınlanır. Bu da derleme sistemimizin çalışma maliyetini önemli ölçüde azaltır.
Uzak önbelleğe alma sisteminin çalışması için derleme sisteminin, derlemelerin tamamen yeniden üretilebilir olmasını sağlaması gerekir. Yani, herhangi bir derleme hedefi için, söz konusu hedefe ait giriş grubunu, aynı giriş grubunun herhangi bir makinede tam olarak aynı çıktıyı oluşturacak şekilde belirlemek mümkün olmalıdır. Bir yapıyı indirmenin sonuçlarının o yapıyı kendisinin indirme sonuçlarıyla aynı olmasını sağlamanın tek yolu budur. Bunun için önbelleğe alınan her yapının hem hedefi hem de girişlerinin karması için anahtar oluşturulması gerektiğini unutmayın. Bu sayede farklı mühendisler aynı hedefte aynı anda farklı değişiklikler yapabilir ve uzak önbellek, ortaya çıkan tüm yapıları depolayarak herhangi bir çakışma olmadan uygun şekilde sunabilir.
Elbette, uzak önbellekten herhangi bir fayda elde edilebilmesi için bir yapının indirilmesinin, derlenmesinden daha hızlı olması gerekir. Özellikle önbellek sunucusu, derlemeyi yapan makineden uzaktaysa bu durum her zaman geçerli değildir. Google'ın ağ ve derleme sistemi, derleme sonuçlarını hızlı bir şekilde paylaşabilmek için dikkatlice ayarlanmıştır.
Uzaktan yürütme
Uzaktan önbelleğe alma, gerçek bir dağıtılmış derleme değildir. Önbellek kaybolursa veya her şeyin yeniden derlenmesini gerektiren düşük düzeyde bir değişiklik yaparsanız yine de derlemenin tamamını makinenizde yerel olarak yapmanız gerekir. Asıl amaç, derleme işleminin gerçek çalışmalarının herhangi bir sayıda çalışana dağıtılabileceği uzaktan yürütmeyi desteklemektir. Şekil 2'de uzaktan yürütme sistemi gösterilmektedir.
Şekil 2. Uzaktan yürütme sistemi
Her kullanıcının makinesinde çalışan derleme aracı (kullanıcıların gerçek mühendisler veya otomatik derleme sistemleri olduğu durumlarda), merkezi bir derleme yöneticisine istek gönderir. Derleme ana sistemi, istekleri bileşen işlemlerine ayırır ve bu işlemlerin ölçeklenebilir bir çalışan havuzu üzerinden yürütülmesini planlar. Her işleyici, kullanıcı tarafından belirtilen girişlerle kendisinden istenen işlemleri gerçekleştirir ve elde edilen yapıları yazar. Bu yapı taşları, nihai çıkış üretilip kullanıcıya gönderilene kadar bunları gerektiren işlemleri yürüten diğer makinelerde paylaşılır.
Böyle bir sistemi uygulamanın en zor kısmı çalışanlar, ana makine ve kullanıcının yerel makinesi arasındaki iletişimi yönetmektir. İşçiler, diğer işçiler tarafından üretilen ara yapıları kullanabilir ve nihai çıktının kullanıcının yerel makinesine geri gönderilmesi gerekir. Bunu yapmak için, her işleyicinin sonuçlarını önbelleğe yazmasını ve bağımlılıklarını önbellekten okumasını sağlayarak daha önce açıklanan dağıtılmış önbelleğin üzerine inşa edebiliriz. Ana işleyici, bağımlı oldukları her şey tamamlanana kadar işleyicilerin devam etmesini engeller. Bu durumda, girişlerini önbellekten okuyabilirler. Nihai ürün de önbelleğe alınır. Böylece yerel makine bu ürünü indirebilir. Ayrıca, çalışanların derlemeden önce bu değişiklikleri uygulayabilmesi için kullanıcının kaynak ağacındaki yerel değişiklikleri dışa aktarmanın ayrı bir yoluna da ihtiyacımız olduğunu unutmayın.
Bunun işe yaraması için daha önce açıklanan yapı tabanlı derleme sistemlerinin tüm parçalarının bir araya getirilmesi gerekir. Çalışanları insan müdahalesi olmadan oluşturabilmemiz için derleme ortamları tamamen kendi kendini açıklayıcı olmalıdır. Her adım farklı bir makinede yürütülebileceğinden derleme süreçleri tamamen bağımsız olmalıdır. Her çalışanın diğer çalışanlardan aldığı sonuçlara güvenebilmesi için çıkışların tamamen deterministik olması gerekir. Bu tür garantileri görev tabanlı bir sistem için sağlamak son derece zordur. Bu da, birine yönelik güvenilir bir uzaktan yürütme sistemi oluşturmayı neredeyse imkansız hale getirir.
Google'da dağıtılan derlemeler
Google, 2008'den beri hem uzak önbelleğe alma hem de uzak yürütme kullanan dağıtık bir derleme sistemi kullanıyor. Bu sistem Şekil 3'te gösterilmiştir.
Şekil 3. Google'ın dağıtık derleme sistemi
Google'ın uzak önbelleği ObjFS olarak adlandırılır. Bu sistem, derleme çıkışlarını üretim makineleri filomuza dağıtılan Bigtable'lerde depolayan bir arka uçtan ve her geliştiricinin makinesinde çalışan objfsd adlı bir ön uç FUSE daemon'undan oluşur. FUSE arka plan programı, mühendislerin derleme çıkışlarına sanki iş istasyonunda depolanan normal dosyalarmış gibi göz atmasına olanak tanırken, dosya içeriği yalnızca doğrudan kullanıcı tarafından istenen birkaç dosya için isteğe bağlı olarak indirilir. Dosya içeriklerini isteğe bağlı olarak sunmak hem ağ hem de disk kullanımını büyük ölçüde azaltır ve sistem, tüm derleme çıktılarını geliştiricinin yerel diskinde depoladığımız zamana kıyasla iki kat daha hızlı derleme yapabilir.
Google'ın uzaktan yürütme sisteminin adı Forge. Blaze'de (Bazel'in dahili eşdeğeri) Distribütör adı verilen bir Forge istemcisi, her işlem için Scheduler adı verilen veri merkezlerimizde çalışan bir işe her işlem için istek gönderir. Planlayıcı, işlem sonuçlarının önbelleğini tutar. Bu sayede, işlem sistemdeki başka bir kullanıcı tarafından oluşturulmuşsa hemen yanıt verebilir. Aksi takdirde işlem bir sıraya alınır. Büyük bir Executor iş havuzu, bu kuyruktaki işlemleri sürekli olarak okur, yürütür ve sonuçları doğrudan ObjFS Bigtables'da depolar. Bu sonuçlar, gelecekteki işlemler için yürütücüler tarafından kullanılabilir veya son kullanıcı tarafından objfsd aracılığıyla indirilebilir.
Sonuç olarak, Google'da yapılan tüm derlemeleri verimli bir şekilde desteklemek için ölçeklendirilebilen bir sistem elde edilir. Google'ın derlemelerinin ölçeği de gerçekten çok büyük: Google, her gün milyonlarca test durumu yürüten ve milyarlarca satır kaynak koddan petabaytlarca derleme çıktısı üreten milyonlarca derleme çalıştırır. Böyle bir sistem, mühendislerimizin karmaşık kod tabanlarını hızlı bir şekilde derlemesini sağlamakla kalmaz, aynı zamanda derlememize dayalı çok sayıda otomatik araç ve sistem uygulamamıza da olanak tanır.