Bu sayfada, kalıcı çalışanların nasıl kullanılacağı, avantajlar, gereksinimler ve çalışanların korumalı alanı nasıl etkilediği açıklanmaktadır.
Kalıcı çalışan, Bazel sunucusu tarafından uzun süredir devam eden bir işlemdir. Gerçek aracın (genellikle derleyici) etrafında bir sarmalayıcı işlevi görür veya aracın kendisidir. Kalıcı çalışanlardan yararlanmak için aracın bir dizi derleme yapmayı desteklemesi ve sarmalayıcının, aracın API'si ile aşağıda açıklanan istek/yanıt biçimi arasında çeviri yapması gerekir. Aynı çalışan, aynı derleme içinde --persistent_worker
işaretiyle ve bu işaret olmadan çağrılabilir ve aracın uygun bir şekilde başlatılıp konuşulmasından ve çıkışta çalışanların kapatılmasından sorumludur. Her çalışan örneğine <outputBase>/bazel-workers
altında ayrı bir çalışma dizini atanır (ancak hesaba çok amaçlı atanmaz).
Kalıcı çalışanların kullanılması, başlangıç ek yükünü azaltan, daha fazla JIT derlemesine olanak tanıyan ve örneğin, işlem yürütme sırasında soyut söz dizimi ağaçlarının önbelleğe alınmasını sağlayan bir yürütme stratejisidir. Bu strateji, uzun süreli bir sürece birden fazla istek göndererek bu iyileştirmelerden yararlanır.
Kalıcı çalışanlar Java, Scala, Kotlin ve daha birçok dilde uygulanır.
NodeJS çalışma zamanı kullanan programlar, çalışan protokolünü uygulamak için @bazel/worker yardımcı kitaplığını kullanabilir.
Kalıcı çalışanları kullanma
Bazel 0.27 ve sonraki sürümler, derlemeleri yürütürken varsayılan olarak kalıcı çalışanları kullanır ancak uzaktan yürütme önceliklidir. Bazel, kalıcı çalışanları desteklemeyen işlemlerde her işlem için bir araç örneği başlatmaya geri dönüyor. Geçerli araç hatıraları için worker
stratejisini ayarlayarak derlemenizi açık bir şekilde kalıcı çalışanlar kullanacak şekilde ayarlayabilirsiniz. En iyi uygulama olarak bu örnek, worker
stratejisine yedek olarak local
öğesini belirtmeyi içerir:
bazel build //my:target --strategy=Javac=worker,local
Yerel strateji yerine çalışan stratejisini kullanmak, uygulamaya bağlı olarak derleme hızını önemli ölçüde artırabilir. Java'da derlemeler 2 ila 4 kat daha hızlı olabilir ve bazen ek derleme için daha fazla işlem yapılabilir. Bazel'ı derlemek çalışanlara göre yaklaşık 2,5 kat daha hızlı. Daha fazla bilgi için "Çalışan sayısını seçme" bölümüne bakın.
Yerel derleme ortamınızla eşleşen bir uzaktan derleme ortamınız da varsa uzaktan yürütme ve bir çalışan yürütme için yarışan deneysel dinamik stratejisini kullanabilirsiniz. Dinamik stratejiyi etkinleştirmek için --experimental_spawn_programr işaretini işaretleyin. Bu strateji, çalışanları otomatik olarak etkinleştirir. Bu nedenle worker
stratejisini belirtmenize gerek yoktur, ancak yedek olarak local
veya sandboxed
özelliğini kullanmaya devam edebilirsiniz.
Çalışan sayısını seçme
Hatıra başına varsayılan çalışan örneği sayısı 4'tür ancak worker_max_instances
işaretiyle ayarlanabilir. Mevcut CPU'lardan iyi şekilde yararlanmak ile JIT derleme ve önbellek isabetleri miktarı arasında bir denge vardır. Daha fazla çalışanla, daha fazla sayıda hedef Oluşturmanız gereken az sayıda hedef varsa tek bir çalışan, derleme hızı ve kaynak kullanımı arasında en iyi dengeyi sunabilir (örneğin, 8586 numaralı soruna bakın).
worker_max_instances
işareti, ipucu ve işaret grubu başına maksimum çalışan örneği sayısını (aşağı bakın) gösterir. Bu nedenle, varsayılan değeri korursanız karma sistemde çok fazla bellek kullanabilirsiniz. Artımlı derlemeler için birden fazla çalışan örneğinin avantajı daha da azdır.
Bu grafikte, 64 GB RAM'i olan 6 çekirdekli hiper iş parçacığı Intel Xeon 3,5 GHz Linux iş istasyonunda Bazel (hedef //src:bazel
) için çizimden derleme süreleri gösterilmektedir. Her çalışan yapılandırması için beş temiz derleme çalıştırılır ve son dörtünün ortalaması alınır.
1. Şekil. Temiz derlemelerin performans iyileştirmeleri grafiği.
Bu yapılandırmada, iki çalışan en hızlı derlemeyi verir, ancak bir çalışana kıyasla yalnızca %14'lük iyileşme görülür. Daha az bellek kullanmak istiyorsanız tek bir çalışan iyi bir seçenektir.
Artımlı derleme genellikle daha da faydalıdır. Temiz derlemeler nispeten nadir görülse de derlemeler arasında tek bir dosyanın değiştirilmesi, özellikle teste dayalı geliştirmede özellikle yaygındır. Yukarıdaki örnekte, ek derleme süresini gölgelendiren Java dışı bazı paketleme işlemleri de vardır.
Yalnızca Java kaynaklarını yeniden derlemek için (//src/main/java/com/google/devtools/build/lib/bazel:BazelServer_deploy.jar
) AbstractContainerizingSandboxedSpawn.java
2. Şekil. Artımlı derlemelerin performans iyileştirmeleri grafiği.
Hızlanma, yapılan değişikliğe bağlıdır. Yaygın olarak kullanılan bir sabit değer değiştirildiğinde, yukarıdaki durumda 6 faktörlü hızlanma ölçülür.
Kalıcı çalışanları değiştirme
Çalışanlara başlangıç işaretleri belirtmek için --worker_extra_flag
flag'ini, anahtarın içinde bulunduğu anahtarla belirtebilirsiniz. Örneğin, --worker_extra_flag=javac=--debug
iletilmesi, yalnızca Javac için hata ayıklamayı etkinleştirir.
Bu flag'in her kullanımı için yalnızca bir çalışan bayrağı ayarlanabilir ve yalnızca bir ipucu için ayarlanabilir.
Çalışanlar yalnızca her anı için ayrı olarak oluşturulmaz, aynı zamanda başlangıç işaretlerindeki varyasyonlar için de oluşturulur. Her bir hatırlatıcı ve başlatma işareti kombinasyonu WorkerKey
olarak birleştirilir ve her WorkerKey
için en fazla worker_max_instances
çalışan oluşturulabilir. İşlem yapılandırmasının kurulum işaretlerini nasıl belirtebileceğini görmek için sonraki bölüme bakın.
--high_priority_workers
flag'ini, normal öncelikli annelikler yerine çalıştırılacak bir ipucu belirtmek için kullanabilirsiniz. Bu yaklaşım, her zaman kritik yolda olan işlemlere öncelik verebilir. İstekleri yürüten iki veya daha fazla yüksek öncelikli çalışan varsa diğer tüm çalışanların çalışması engellenir. Bu bayrak birden çok kez kullanılabilir.
--worker_sandboxing
işaretinin iletilmesi, her çalışan isteğinin tüm girişleri için ayrı bir korumalı alan dizini kullanmasına neden olur. Korumalı alan ayarlamak, özellikle macOS'te biraz daha zaman alır ancak daha iyi bir doğruluk garantisi verir.
--worker_quit_after_build
işareti esas olarak hata ayıklama ve profil oluşturma için yararlıdır. Bu flag, tüm çalışanları derleme tamamlandıktan sonra kapanmaya zorlar. Çalışanların yaptıklarıyla ilgili daha fazla sonuç almak için --worker_verbose
aracını da iletebilirsiniz. Bu işaretleme, WorkRequest
içindeki verbosity
alanına yansıtılır. Böylece çalışan uygulamaları daha ayrıntılı olur.
Çalışanlar, günlüklerini <outputBase>/bazel-workers
dizininde saklar (örneğin, /tmp/_bazel_larsrc/191013354bebe14fdddae77f2679c3ef/bazel-workers/worker-1-Javac.log
).
Dosya adı, çalışan kimliğini ve ipucunu içerir. Hatırlama başına birden fazla WorkerKey
olabileceği için belirli bir ipucu için en fazla worker_max_instances
günlük dosyası görebilirsiniz.
Android derlemeleri için Android Derlemesi Performans sayfasında ayrıntılara bakın.
Kalıcı çalışanları uygulama
Bir çalışanın nasıl oluşturulacağını öğrenmek için kalıcı çalışanlar oluşturma sayfasına bakın.
Bu örnekte, JSON kullanan bir çalışan için Starlark yapılandırması gösterilmektedir:
args_file = ctx.actions.declare_file(ctx.label.name + "_args_file")
ctx.actions.write(
output = args_file,
content = "\n".join(["-g", "-source", "1.5"] + ctx.files.srcs),
)
ctx.actions.run(
mnemonic = "SomeCompiler",
executable = "bin/some_compiler_wrapper",
inputs = inputs,
outputs = outputs,
arguments = [ "-max_mem=4G", "@%s" % args_file.path],
execution_requirements = {
"supports-workers" : "1", "requires-worker-protocol" : "json" }
)
Bu tanımda, bu işlemin ilk kullanımı /bin/some_compiler -max_mem=4G --persistent_worker
komut satırını yürüterek başlar. Foo.java
derlemek için istek şöyle görünür:
arguments: [ "-g", "-source", "1.5", "Foo.java" ]
inputs: [
{path: "symlinkfarm/input1" digest: "d49a..." },
{path: "symlinkfarm/input2", digest: "093d..."},
]
Çalışan, stdin
alanında yeni satırla ayrılmış JSON biçiminde alır (requires-worker-protocol
JSON olarak ayarlandığından). Daha sonra çalışan bu işlemi gerçekleştirir ve STCout'ta Bazel'e JSON biçimli bir WorkResponse
gönderir. Daha sonra Bazel bu yanıtı ayrıştırıp manuel olarak bir WorkResponse
protokolüne dönüştürür. JSON yerine ikili kodlamalı protobuf kullanarak ilişkili çalışanla iletişim kurmak için requires-worker-protocol
şu şekilde ayarlanır: proto
:
execution_requirements = {
"supports-workers" : "1" ,
"requires-worker-protocol" : "proto"
}
Yürütme koşullarına requires-worker-protocol
öğesini dahil etmezseniz Bazel, çalışan iletişimini varsayılan olarak protobuf kullanacak şekilde ayarlar.
Bazel WorkerKey
öğesini ipucu ve paylaşılan flag'lerden türetir. Bu nedenle, bu yapılandırma max_mem
parametresinin değiştirilmesine izin verirse kullanılan her değer için ayrı bir çalışan oluşturulur. Çok fazla varyasyon kullanılırsa aşırı bellek tüketimine neden olabilir.
Her çalışan şu anda tek seferde yalnızca bir isteği işleyebilir. Deneysel Multiplex çalışanlar özelliği, temel araç çok iş parçalıysa ve sarmalayıcı bunu anlayacak şekilde ayarlanmışsa birden fazla ileti dizisinin kullanılmasına olanak tanır.
Bu GitHub deposunda, Java'da ve Python'da yazılmış örnek çalışan sarmalayıcılarını görebilirsiniz. JavaScript veya TypeScript üzerinde çalışıyorsanız @bazel/worker paketi ve nodejs çalışan örneği faydalı olabilir.
Çalışanlar, korumalı alanı nasıl etkiler?
Varsayılan olarak, worker
stratejisi kullanıldığında işlem, local
stratejisine benzer bir korumalı alanda çalıştırılmaz. --worker_sandboxing
işaretini, tüm çalışanları korumalı alanlar içinde çalıştıracak şekilde ayarlayabilirsiniz. Böylece aracın her yürütme işleminin, olması gereken giriş dosyalarını görmesini sağlayabilirsiniz. Araç, önbellekler aracılığıyla dahili olarak istekler arasındaki bilgileri sızdırabilir. dynamic
stratejisinin kullanılması için çalışanların korumalı alana alınması gerekir.
Derleyici önbelleklerinin çalışanlarla doğru şekilde kullanılmasına izin vermek için her giriş dosyasıyla birlikte bir özet iletilir. Bu nedenle, derleyici veya sarmalayıcı, dosyayı okumak zorunda kalmadan girişin hâlâ geçerli olup olmadığını kontrol edebilir.
İstenmeyen önbelleğe alma işlemlerine karşı koruma sağlamak için giriş özetleri kullanıldığında bile, korumalı alana sahip çalışanlar saf korumalı alana kıyasla daha az katı korumalı alan sağlar, çünkü araç önceki isteklerden etkilenen diğer dahili durumları koruyabilir.
Multiplex çalışanları, yalnızca çalışan uygulaması destekliyorsa korumalı alana alınabilir ve korumalı alan --experimental_worker_multiplex_sandboxing
işaretiyle ayrı olarak etkinleştirilmelidir. Tasarım dokümanından daha fazla bilgi edinebilirsiniz).
Daha fazla bilgi
Kalıcı çalışanlar hakkında daha fazla bilgi için aşağıdaki konulara bakın:
- Kalıcı kalıcı çalışanlar blog yayını
- Haskell uygulama açıklaması {: .external}
- Mike Morearty tarafından hazırlanan blog yayını {: .external}
- Bazel ile Ön Uç Geliştirme: Angular/TypeScript ve Kalıcı Çalışanlar Asana {: .external}
- Altın stratejileri açıklanıyor {: .external}
- Pazarel-Tartışma posta listesinde bilgilendirici iş stratejisi tartışması {: .external}