Kararlı Çalışanlar

Sorun bildirme Kaynağı görüntüleme Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bu sayfada, kalıcı çalışanların nasıl kullanılacağı, kazanımları, gereksinimleri nasıl etkilediğiyle ilgili daha fazla bilgi edinin.

Kalıcı çalışan, Bazel sunucusu tarafından başlatılan uzun süreli bir işlemdir. gerçek aracın (genellikle bir derleyici) etrafında bir sarmalayıcı işlevi görür veya aracın kendisidir. Aracın kalıcı çalışanlardan yararlanabilmesi için bir derleme dizisini teşvik ediyor ve sarmalayıcının arasında bir bağlantı oluşturun. Aynı işçi, aynı derlemede --persistent_worker işaretiyle ve işaretsiz olarak çağrılabilir. İşçi, aracı uygun şekilde başlatmaktan ve araçla konuşmaktan, ayrıca çıkışta işçileri kapatmaktan sorumludur. Her çalışan örneği atanır altında ayrı bir çalışma dizinine (ana dizin olmadan) <outputBase>/bazel-workers

Kalıcı çalışanlar kullanmak, başlangıç masraflarını azaltan, daha fazla JIT derlemesine olanak tanıyan ve örneğin işlem yürütmedeki soyut söz dizimi ağaçlarının önbelleğe alınmasını sağlayan bir yürütme stratejisidir. Bu strateji bu iyileştirmeleri uzun süreli bir bahsedeceğim.

Kalıcı çalışanlar Java, Scala, Kotlin ve daha birçok dil için uygulanır.

NodeJS çalışma zamanı kullanan programlar, işleyici 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 çalıştırırken varsayılan olarak kalıcı çalışanları kullanır ancak uzaktan yürütme önceliklidir. Kalıcı çalışanları desteklemeyen işlemler için Bazel, her işlem için bir araç örneği başlatır. Bu kapsamdaki kullanıcıları worker ayarlayarak derlemenizi kalıcı çalışanları kullanacak şekilde ayarlayın geçerli aracın stratejisini anımsatıcılar. En iyi uygulama olarak, bu örnekte local öğesinin bir worker stratejisinden yararlanın:

bazel build //my:target --strategy=Javac=worker,local

Yerel strateji yerine işçi stratejisinin kullanılması, uygulamaya bağlı olarak derleme hızını önemli ölçüde artırabilir. Java için derlemeler 2-4 kat daha hızlı olabilir. Artımlı derlemede bu süre bazen daha da uzayabilir. Bazel derleniyor: yaklaşık 2,5 kat daha hızlıdır. Daha fazla bilgi için "Çalışanların sayısını seçme" bölümüne bakın.

Yerel derlemenizle eşleşen bir uzak derleme ortamınız da varsa isterseniz, deneysel ortamı kullanmak için dinamik strateji, Böylece hem uzaktan yürütme hem de işçi yürütme. Dinamik gezinmeyi etkinleştirmek için strateji, proje yönetimi --experimental_spawn_scheduler tıklayın. Bu strateji, işçileri otomatik olarak etkinleştirir. Bu nedenle, worker stratejisini belirtmeniz gerekmez. Ancak yedek olarak local veya sandboxed'yi kullanmaya devam edebilirsiniz.

Çalışan sayısını seçme

Anımsatıcı başına varsayılan çalışan örneği sayısı 4'tür, ancak ayarlanabilir şununla: worker_max_instances tıklayın. Mevcut CPU'lardan iyi bir şekilde yararlanmak ile elde ettiğiniz JIT derlemesi ve önbellek isabeti oranıdır. Daha fazla çalışanla, hedefler, JIT uygulanmamış kod çalıştırmanın ve baştan başlatmanın başlangıç maliyetlerini öder. önbellek. Oluşturulacak az sayıda hedefiniz varsa tek bir çalışan size en iyi dengeyi bulmaya çalışın (örneğin, 8586 numaralı sorunu inceleyin. worker_max_instances işareti, her bir anımsatıcı ve işaret grubu için maksimum işleyici örneği sayısını belirler (aşağıya bakın). Bu nedenle, karma bir sistemde varsayılan değeri kullanırsanız çok fazla bellek kullanabilirsiniz. Artımlı derlemeler için daha az avantaj sunar.

Bu grafikte, 64 GB RAM'e sahip 6 çekirdekli hiper iş parçacıklı Intel Xeon 3,5 GHz Linux iş istasyonunda Bazel'in (hedef //src:bazel) sıfırdan derleme süreleri gösterilmektedir. Her çalışan yapılandırması için beş tane temiz derleme çalıştırılıyor ve ortalaması alınır.

Temiz derlemelerde performans iyileştirmelerini gösteren grafik

Şekil 1. Temiz derlemelerin performans iyileştirmelerini gösteren grafik.

Bu yapılandırmada iki çalışan en hızlı derlemeyi sağlar ancak bir çalışana kıyasla yalnızca %14 oranında iyileşme sağlar. Bir çalışan dahil olmak üzere daha az bellek kullanır.

Artımlı derleme genellikle daha da fazla avantaj sağlar. Temiz derlemeler nispeten nadirdir ancak tek bir dosyanın derlemeler arasında değiştirilmesi, teste dayalı geliştirmede pek çok yöntem mevcut. Yukarıdaki örnekte, artımlı derleme süresini gölgeleyebilecek bazı Java dışı paketleme işlemleri de vardır.

AbstractContainerizingSandboxedSpawn.java dosyasında dahili bir dize sabitinin değiştirilmesinden sonra yalnızca Java kaynaklarını yeniden derlemek (//src/main/java/com/google/devtools/build/lib/bazel:BazelServer_deploy.jar), 3 kat hızlanma sağlar (bir ısıtma derlemesi atlanarak ortalama 20 artımlı derleme):

Artımlı derlemelerdeki performans iyileştirmelerinin grafiği

Şekil 2. Artımlı derlemelerin performans iyileştirmelerinin grafiği.

Hızlanma, yapılan değişikliğe bağlıdır. Yukarıdaki durumda, yaygın olarak kullanılan bir sabit değiştiğinde 6 kat hızlanma ölçülür.

Kalıcı çalışanları değiştirme

Çalışanlara başlangıç işaretlerini belirtmek için --worker_extra_flag işaretini iletebilirsiniz. Örneğin, --worker_extra_flag=javac=--debug parametresini iletmek yalnızca Javac için hata ayıklamayı etkinleştirir. Bu işaretin kullanımı başına ve yalnızca bir anımsatıcı için yalnızca bir çalışan işareti ayarlanabilir. Çalışanlar yalnızca her bir hatırlatıcı için ayrı ayrı değil, aynı zamanda başlangıç işaretlerindeki varyasyonlar için de ayrı ayrı oluşturulur. Anımsatıcı ve başlatmanın her kombinasyonu bayraklar bir WorkerKey olarak birleştirilir ve her WorkerKey için worker_max_instances çalışan oluşturulabilir. işlem yapılandırması, kurulum bayraklarını da belirtebilir.

Normal öncelikli anımsatıcılara tercih edilerek çalıştırılması gereken bir anımsatıcı belirtmek için --high_priority_workers işaretini kullanabilirsiniz. Bu sayede her zaman kritik önemde olan işlemlere öncelik verebilirsiniz yol'a dokunun. İ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 işaret birden çok kez kullanılabilir.

Başarılı --worker_sandboxing flag, her çalışan isteğinin tüm istekleri için ayrı bir korumalı alan dizini kullanmasını sağlar. giriş değerleridir. Korumalı alanın oluşturulması biraz zaman alır. özellikle macOS'te çalışır, ancak daha iyi doğruluk garantisi verir.

İlgili içeriği oluşturmak için kullanılan --worker_quit_after_build flag, özellikle hata ayıklama ve profil çıkarma için faydalıdır. Bu işaret, bir derleme tamamlandığında tüm iş parçacıklarını çıkmaya zorlar. Ayrıca, çalışanların ne yaptığıyla ilgili daha fazla sonuç almak için --worker_verbose parametresini de iletebilirsiniz. Bu işaret, WorkRequest içinde verbosity alanı, çalışan uygulamalarının da kullanılmasına izin verir anlatabilmişimdir.

Çalışanlar günlüklerini <outputBase>/bazel-workers dizininde (ör. /tmp/_bazel_larsrc/191013354bebe14fdddae77f2679c3ef/bazel-workers/worker-1-Javac.log) depolar. Dosya adı, çalışan kimliğini ve anımsatıcıyı içerir. Her anımsatıcı için birden fazla WorkerKey olabilir. Bu nedenle, belirli bir anımsatıcı için worker_max_instances'ten fazla günlük dosyası görebilirsiniz.

Android derlemeleri için Android Derleme Performansı sayfasında ayrıntıları inceleyin.

Kalıcı çalışanları hayata geçirme

Çalışan oluşturma hakkında daha fazla bilgi için kalıcı çalışan oluşturma sayfasına bakın.

Bu örnekte, JSON kullanan bir işleyici 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ıma göre, bu eylemin ilk kullanımı komut satırından /bin/some_compiler -max_mem=4G --persistent_worker. İstek işlevi şu şekilde görünür: Foo.java

NOT: Protokol arabellek spesifikasyonunda "yılan büyük/küçük harf" kullanılmasına rağmen (request_id), JSON protokolünde "deve büyük/küçük harf" kullanılır. (requestId). Bu belgede, JSON örneklerinde büyük harf, alan hakkında konuşurken yılan durumu veya protokolden bağımsız olarak.

{
  "arguments": [ "-g", "-source", "1.5", "Foo.java" ]
  "inputs": [
    { "path": "symlinkfarm/input1", "digest": "d49a..." },
    { "path": "symlinkfarm/input2", "digest": "093d..." },
  ],
}

Çalışan, bunu stdin üzerinde yeni satırlarla ayrılmış JSON biçiminde (çünkü requires-worker-protocol, JSON değerine ayarlanır). İşleyici daha sonra işlemi gerçekleştirir ve stdout'sinde Bazel'e JSON biçiminde bir WorkResponse gönderir. Bazel, ardından bu yanıtı ayrıştırıp manuel olarak bir WorkResponse protosuna dönüştürür. JSON yerine ikili kodlu protobuf kullanarak ilişkili işleyiciyle iletişim kurmak için requires-worker-protocol, aşağıdaki gibi proto olarak ayarlanır:

  execution_requirements = {
    "supports-workers" : "1" ,
    "requires-worker-protocol" : "proto"
  }

Yürütme şartlarına requires-worker-protocol dahil etmezseniz Bazel, çalışan iletişimini varsayılan olarak protobuf kullanacak şekilde ayarlar.

Bazel, WorkerKey değerini kısaltmadan ve paylaşılan işaretlerden türetmektedir. Bu nedenle, bu yapılandırma max_mem parametresinin değiştirilmesine izin veriyorsa kullanılan her değer için ayrı bir işleyici oluşturulur. Çok fazla varyasyon kullanılırsa bu durum aşırı bellek tüketimine yol açabilir.

Her işleyici şu anda yalnızca tek bir isteği işleyebilir. Deneysel Multiplex çalışanları özelliği, birden fazla çalışan iş parçacıkları; temel araç çok iş parçacıklıysa ve sarmalayıcı anlayamıyorum.

İçinde bu GitHub deposunu Python'un yanı sıra Java'da da yazılmış örnek çalışan sarmalayıcılar görebilirsiniz. Şu durumda: JavaScript veya TypeScript'te çalışıyorsanız @bazel/worker paketi ve nodejs çalışanı örneği yardımcı olabilir.

Çalışanlar korumalı alanı nasıl etkiler?

Varsayılan olarak worker stratejisinin kullanılması, local stratejisine benzer şekilde işlemi bir korumalı alanda çalıştırmaz. --worker_sandboxing işaretini, tüm işleyicileri korumalı alan içinde çalıştıracak şekilde ayarlayarak aracın her çalıştırmasında yalnızca olması gereken giriş dosyalarının gösterilmesini sağlayabilirsiniz. Araç yine de istekler arasında dahili olarak bilgi sızdırabilir (örneğin, önbellek. dynamic stratejisi kullanılıyor çalışanların korumalı alana alınmasını gerektirir.

Derleyici önbelleklerinin işleyicilerle doğru şekilde kullanılmasına izin vermek için her giriş dosyasıyla birlikte bir özet gönderilir. Böylece derleyici veya sarmalayıcı, dosyayı okumak zorunda kalmadan girişin hâlâ geçerli olup olmadığını kontrol edebilir.

İstenmeyen önbelleğe almayı önlemek için giriş özetleri kullanılırken bile korumalı alana alınır çalışanlar saf korumalı alana göre daha az katı bir korumalı alan sunar, çünkü araç önceki isteklerden etkilenen diğer dahili durumları koruma

Multiplex çalışanları, yalnızca çalışan uygulaması destekliyorsa korumalı alana alınabilir. Bu korumalı alan, --experimental_worker_multiplex_sandboxing işareti. Daha fazla bilgi için tasarım dokümanındaki ayrıntıları inceleyin.

Daha fazla bilgi

Kalıcı çalışanlar hakkında daha fazla bilgi için bkz: