Büyük bir kod tabanınız olduğunda bağımlılık zincirleri çok derinleşebilir. Basit ikili dosyalar bile genellikle on binlerce derleme hedefine bağlı olabilir. Bu ölçekte, tek bir makinede derleme işlemini makul bir süre içinde tamamlamak mümkün değildir. Hiçbir derleme sistemi, makinenin donanımına uygulanan temel fizik yasalarını aşamaz. Bunun çalışmasını sağlamanın tek yolu, sistem tarafından yapılan iş birimlerinin rastgele ve ölçeklenebilir sayıda makineye yayıldığı dağıtılmış derlemeleri destekleyen bir derleme sistemidir. Sistemin işini yeterince küçük birimlere böldüğümüzü varsayarsak (bu konuyla ilgili daha fazla bilgiyi ilerleyen bölümlerde bulabilirsiniz), bu sayede istediğimiz boyuttaki tüm derlemeleri ödemeye razı olduğumuz kadar hızlı bir şekilde tamamlayabiliriz. Bu ölçeklenebilirlik, yapay nesne tabanlı bir derleme sistemi tanımlayarak ulaşmaya çalıştığımız nihai hedefimizdir.
Uzaktan önbelleğe alma
En basit dağıtılmış derleme türü, yalnızca uzak önbelleğe alma özelliğinden yararlanan türdür. Bu tür, Şekil 1'de gösterilmiştir.
Şekil 1. Uzak önbelleğe almayı gösteren dağıtılmış bir derleme
Geliştirici iş istasyonları ve sürekli entegrasyon sistemleri de dahil olmak üzere derleme işlemi gerçekleştiren her sistem, ortak bir uzak önbellek hizmetine referans verir. Bu hizmet, Redis gibi hızlı ve yerel bir kısa süreli depolama sistemi veya Google Cloud Storage gibi bir bulut hizmeti olabilir. Bir kullanıcının doğrudan veya bağımlılık olarak bir yapıt oluşturması gerektiğinde sistem, bu yapıtın uzaktaki önbellekte mevcut olup olmadığını kontrol eder. Bu durumda, derlemek yerine yapıyı indirebilir. Aksi takdirde sistem, yapıyı kendisi oluşturur ve sonucu tekrar önbelleğe yükler. Bu sayede, çok sık değişmeyen düşük düzeydeki bağımlılıklar her kullanıcı tarafından yeniden oluşturulmak yerine bir kez oluşturulup kullanıcılar arasında paylaşılabilir. Google'da birçok yapıt sıfırdan oluşturulmak yerine önbellekten sunulur. Bu sayede derleme sistemimizi çalıştırma maliyeti büyük ölçüde düşer.
Uzak önbelleğe alma sisteminin çalışması için derleme sisteminin, derlemelerin tamamen yeniden üretilebilir olduğunu garanti etmesi gerekir. Yani, herhangi bir derleme hedefi için bu hedefe yönelik girişler kümesi belirlenebilmelidir. Böylece, aynı girişler kümesi herhangi bir makinede tam olarak aynı çıkışı üretir. Bir yapıyı indirmenin sonuçlarının, yapıyı kendiniz oluşturmanın sonuçlarıyla aynı olmasını sağlamanın tek yolu budur. Bunun için önbellekteki her yapının hem hedefi hem de girişlerinin karma değeriyle anahtarlanması gerekir. Böylece, farklı mühendisler aynı anda aynı hedefte farklı değişiklikler yapabilir ve uzak önbellek, ortaya çıkan tüm yapıları saklayıp bunları çakışma olmadan uygun şekilde sunabilir.
Elbette, uzak önbelleğin herhangi bir faydası olması için bir yapının indirilmesi, oluşturulmasından daha hızlı olmalıdır. Bu durum her zaman geçerli olmayabilir. Özellikle önbellek sunucusu, derleme işlemini yapan makineden uzaktaysa bu durum 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 oluşturulmasını gerektiren düşük düzeyli bir değişiklik yaparsanız yine de tüm derlemeyi makinenizde yerel olarak gerçekleştirmeniz gerekir. Asıl amaç, derleme işleminin herhangi sayıda çalışan arasında 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 mühendisler veya otomatik derleme sistemleridir) merkezi bir derleme yöneticisine istek gönderir. Derleme yöneticisi, istekleri bileşen işlemlerine ayırır ve bu işlemlerin yürütülmesini ölçeklenebilir bir çalışan havuzunda planlar. Her çalışan, kendisinden istenen işlemleri kullanıcı tarafından belirtilen girişlerle gerçekleştirir ve ortaya çıkan yapay nesneleri yazar. Bu yapılar, son çıktı üretilip kullanıcıya gönderilene kadar bunları gerektiren işlemlerin yürütüldüğü diğer makinelerle 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. Çalışanlar, diğer çalışanlar tarafından üretilen ara yapay nesnelere bağlı olabilir ve son çıktı, kullanıcının yerel makinesine geri gönderilmelidir. Bunu yapmak için, her çalışanın 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ği temel alabiliriz. Ana işçi, bağlı olduğu her şey tamamlanana kadar işçilerin devam etmesini engeller. Bu durumda, girişlerini önbellekten okuyabilirler. Son ürün de önbelleğe alınır ve yerel makinenin ürünü indirmesine olanak tanır. Ayrıca, çalışanların derleme yapmadan ö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 yolunun olması gerektiğini de unutmayın.
Bu işlemin çalışması için, daha önce açıklanan yapay öğe tabanlı derleme sistemlerinin tüm parçalarının bir araya gelmesi gerekir. Çalışanları insan müdahalesi olmadan başlatabilmemiz için derleme ortamları tamamen kendi kendini tanımlamalıdır. Her adım farklı bir makinede yürütülebileceğinden derleme süreçlerinin tamamen bağımsız olması gerekir. Çıkışlar tamamen deterministik olmalıdır. Böylece her çalışan, diğer çalışanlardan aldığı sonuçlara güvenebilir. Bu tür garantilerin görev tabanlı bir sistem tarafından sağlanması son derece zordur. Bu da, görev tabanlı bir sistemin üzerine güvenilir bir uzaktan yürütme sistemi oluşturmayı neredeyse imkansız hale getirir.
Google'da dağıtılmış derlemeler
Google, 2008'den beri hem uzaktan önbelleğe alma hem de uzaktan yürütme kullanan dağıtılmış bir derleme sistemi kullanmaktadır. Bu sistem Şekil 3'te gösterilmektedir.
Şekil 3. Google'ın dağıtılmış derleme sistemi
Google'ın uzak önbelleğine ObjFS adı verilir. Bu sistem, derleme çıktılarını üretim makinelerimiz genelinde dağıtılmış Bigtable'larda depolayan bir arka uç ve her geliştiricinin makinesinde çalışan objfsd adlı bir ön uç FUSE daemon'undan oluşur. FUSE daemon, mühendislerin derleme çıktılarına iş istasyonunda depolanan normal dosyalar gibi göz atmasına olanak tanır. Ancak dosya içeriği, yalnızca kullanıcı tarafından doğrudan istenen birkaç dosya için isteğe bağlı olarak indirilir. Dosya içeriklerinin isteğe bağlı olarak sunulması hem ağ hem de disk kullanımını büyük ölçüde azaltır. Ayrıca sistem, tüm derleme çıktısını geliştiricinin yerel diskinde depoladığımız zamana kıyasla iki kat daha hızlı derleme yapabilir.
Google'ın uzaktan yürütme sistemine Forge adı verilir. Blaze'deki (Bazel'in dahili eşdeğeri) Forge istemcisi olan Dağıtıcı, her işlem için istekleri Scheduler adlı veri merkezlerimizde çalışan bir işe gönderir. Planlayıcı, işlem sonuçlarının önbelleğini tutar. Bu sayede, işlem daha önce sistemin başka bir kullanıcısı tarafından oluşturulmuşsa hemen yanıt döndürebilir. Aksi takdirde, işlemi bir sıraya yerleştirir. Büyük bir Executor işleri grubu, bu kuyruktaki işlemleri sürekli olarak okur, yürütür ve sonuçları doğrudan ObjFS Bigtable'larında depolar. Bu sonuçlar, gelecekteki işlemler için yürütücülere sunulur veya objfsd aracılığıyla son kullanıcı tarafından indirilebilir.
Sonuç olarak, Google'da gerçekleştirilen tüm derlemeleri verimli bir şekilde desteklemek için ölçeklenebilen bir sistem oluşturuldu. Google'ın derlemelerinin ölçeği gerçekten çok büyük: Google, her gün milyonlarca test durumunu yürüten ve milyarlarca satır kaynak kodundan petabaytlarca derleme çıktısı üreten milyonlarca derleme çalıştırıyor. Bu tür bir sistem, mühendislerimizin karmaşık kod tabanlarını hızlı bir şekilde oluşturmasına olanak tanımakla kalmaz, aynı zamanda derlememize dayanan çok sayıda otomatik araç ve sistemi uygulamamıza da olanak tanır.