Uzaktan Önbelleğe Alma

Sorun bildir Kaynağı göster

Bu sayfada uzaktan önbelleğe alma, önbelleği barındıracak bir sunucu ayarlama ve uzak önbelleği kullanarak derleme çalıştırma konuları ele alınmaktadır.

Uzak önbellek, geliştiricilerden oluşan bir ekip ve/veya sürekli entegrasyon (CI) sistemi tarafından derleme çıkışlarını paylaşmak için kullanılır. Derlemeniz yeniden oluşturulabiliyorsa bir makineden elde edilen sonuçlar başka bir makinede güvenli bir şekilde yeniden kullanılabilir. Bu da derlemeleri önemli ölçüde hızlandırabilir.

Genel bakış

Bazel, bir yapıyı işlemler olarak adlandırılan ayrı adımlara böler. Her eylemin girişleri, çıkış adları, komut satırı ve ortam değişkenleri vardır. Gerekli girişler ve beklenen çıkışlar, her işlem için açıkça belirtilir.

Bir sunucuyu, derleme çıkışları (bu işlem çıkışları) için uzak önbellek olacak şekilde ayarlayabilirsiniz. Bu çıkışlar, çıkış dosyası adları ve içeriklerinin karmalarından oluşan bir liste içerir. Uzak önbellek sayesinde, her yeni çıktıyı yerel olarak oluşturmak yerine başka bir kullanıcının derlemesindeki derleme çıkışlarını yeniden kullanabilirsiniz.

Uzaktan önbelleğe almayı kullanmak için:

  • Önbelleğin arka ucu olarak sunucu ayarlama
  • Bazel derlemesini uzak önbelleği kullanacak şekilde yapılandırma
  • Bazel 0.10.0 veya sonraki bir sürümünü kullanma

Uzak önbellek iki tür veri depolar:

  • İşlem karmalarının işlem sonucu meta verilerine eşlenmesinin bir haritası olan işlem önbelleği.
  • İçerikle uyumlu bir çıkış dosyası deposu (CAS).

Uzak önbelleğin ek olarak her işlem için stdout ve stderr dosyalarını depoladığını unutmayın. Dolayısıyla Bazel'in stdout/stderr dosyasının incelenmesi, önbellek isabetlerini tahmin etmek için iyi bir sinyal değildir.

Bir derleme uzaktan önbelleğe almayı nasıl kullanır?

Bir sunucu uzak önbellek olarak ayarlandıktan sonra, önbelleği birden çok şekilde kullanırsınız:

  • Uzak önbelleğe okuma ve yazma
  • Belirli hedefler dışında uzak önbelleğe okuma ve/veya yazma
  • Yalnızca uzak önbellekten okur
  • Uzak önbelleği hiç kullanma

Uzak önbellekte okuma ve yazma yapabilen bir Bazel derlemesi çalıştırdığınızda, derleme aşağıdaki adımları izler:

  1. Bazel, oluşturulması gereken hedeflerin grafiğini oluşturur ve daha sonra, gerekli işlemlerin bir listesini oluşturur. Bu işlemlerin her biri, girdileri ve çıkış dosya adlarını tanımlar.
  2. Bazel, yerel makinenizi mevcut derleme çıktıları için kontrol eder ve bulduklarını yeniden kullanır.
  3. Bazel, mevcut derleme çıktıları için önbelleği kontrol eder. Çıkış bulunursa Bazel çıktıyı alır. Bu bir önbellek isabetidir.
  4. Çıkışların bulunmadığı gerekli işlemler için Bazel, işlemleri yerel olarak yürütür ve gerekli derleme çıktılarını oluşturur.
  5. Yeni derleme çıkışları uzak önbelleğe yüklenir.

Önbelleğin arka ucu olarak sunucu ayarlama

Önbelleğin arka ucu olarak işlev görecek bir sunucu ayarlamanız gerekir. HTTP/1.1 sunucusu, Bazel verilerini opak baytlar olarak işleyebilir ve çok sayıda mevcut sunucu, uzaktan önbelleğe alma arka ucu olarak kullanılabilir. Bazel'in HTTP Önbelleğe Alma Protokolü, uzaktan önbelleğe almayı destekler.

Önbelleğe alınan çıkışları depolayacak arka uç sunucusunu seçmek, ayarlamak ve sürdürmek sizin sorumluluğunuzdadır. Sunucu seçerken şunları göz önünde bulundurun:

  • Ağ iletişimi hızı. Örneğin, ekibiniz aynı ofisteyse kendi yerel sunucunuzu çalıştırmak isteyebilirsiniz.
  • Güvenlik. Uzak önbellek, ikili programlarınızı içerecek ve bu nedenle güvenli olmalıdır.
  • Yönetim kolaylığı. Örneğin, Google Cloud Storage, tümüyle yönetilen bir hizmettir.

Uzak bir önbellek için kullanılabilecek birçok arka uç vardır. Bazı seçenekler şunlardır:

nginx

nginx açık kaynak bir web sunucusudur. [WebDAV modülü] ile Bazel için uzak bir önbellek olarak kullanılabilir. Debian ve Ubuntu'da nginx-extras paketini yükleyebilirsiniz. macOS'te nginx, Homebrew aracılığıyla kullanılabilir:

brew tap denji/nginx
brew install nginx-full --with-webdav

Aşağıda nginx için örnek bir yapılandırma verilmiştir. /path/to/cache/dir dosyasını, nginx'in yazma ve okuma izninin olduğu geçerli bir dizinle değiştirmeniz gerektiğini unutmayın. Daha büyük çıkış dosyalarınız varsa client_max_body_size seçeneğini daha büyük bir değerle değiştirmeniz gerekebilir. Sunucu, kimlik doğrulama gibi başka yapılandırmalar gerektirir.

nginx.conf içindeki server bölümü için örnek yapılandırma:

location /cache/ {
  # The path to the directory where nginx should store the cache contents.
  root /path/to/cache/dir;
  # Allow PUT
  dav_methods PUT;
  # Allow nginx to create the /ac and /cas subdirectories.
  create_full_put_path on;
  # The maximum size of a single file.
  client_max_body_size 1G;
  allow all;
}

bazel-uzaktan-uzaktan

bazel-remote, altyapınızda kullanabileceğiniz açık kaynaklı bir uzaktan derleme önbelleğidir. 2018'in başlarından beri çeşitli şirketlerde başarıyla kullanılmaktadır. Bazel projesinin Bazel-remote için teknik destek sağlamadığını unutmayın.

Bu önbellek, içerikleri diskte depolar ve üst depolama alanı sınırını uygulamak ve kullanılmayan yapıları temizlemek için atık toplama işlemi sağlar. Önbellek bir [docker görüntüsü] olarak ve kodu GitHub'da bulunmaktadır. Hem REST hem de gRPC uzak önbellek API'leri desteklenir.

Nasıl kullanacağınızla ilgili talimatlar için GitHub sayfasına bakın.

Google Cloud Storage

[Google Cloud Storage], Bazel'in uzaktan önbelleğe alma protokolüyle uyumlu bir HTTP API sağlayan, tümüyle yönetilen bir nesne deposudur. Faturalandırmanın etkin olduğu bir Google Cloud hesabınızın olması gerekir.

Cloud Storage'ı önbellek olarak kullanmak için:

  1. Storage paketi oluşturun. Ağ bant genişliği, uzak önbellek için önemli olduğundan size en yakın paket konumunu seçtiğinizden emin olun.

  2. Cloud Storage'da kimlik doğrulaması yapmak üzere Bazel için bir hizmet hesabı oluşturun. Hizmet hesabı oluşturma başlıklı makaleyi inceleyin.

  3. Gizli bir JSON anahtarı oluşturun ve kimlik doğrulaması için bunu Bazel'e iletin. Anahtara sahip herkes GCS paketinize rastgele veriler okuyup yazabilir. Bu nedenle anahtarı güvenli bir şekilde saklayın.

  4. Aşağıdaki işaretleri Bazel komutunuza ekleyerek Cloud Storage'a bağlanın:

    • İşareti kullanarak aşağıdaki URL'yi Bazel'a iletin: --remote_cache=https://storage.googleapis.com/bucket-name burada bucket-name depolama paketinizin adıdır.
    • Uygulama Kimlik Doğrulaması'nı kullanmak için --google_credentials=/path/to/your/secret-key.json veya --google_default_credentials işaretini kullanarak kimlik doğrulama anahtarını geçirin.
  5. Cloud Storage'ı eski dosyaları otomatik olarak silecek şekilde yapılandırabilirsiniz. Bunu yapmak için Nesne Yaşam Döngülerini Yönetme bölümüne bakın.

Diğer sunucular

Önbelleğin arka ucu olarak PUT ve GET'i destekleyen herhangi bir HTTP/1.1 sunucusu kurabilirsiniz. Kullanıcılar Hazelcast, Apache httpd ve AWS S3 gibi arka uçları önbelleğe almanın başarılı olduğunu bildirdi.

Kimlik doğrulama

0.11.0 sürümünden itibaren HTTP Temel Kimlik Doğrulaması için Bazel'a destek eklendi. Bir kullanıcı adını ve şifreyi Bazel'e, uzak önbellek URL'si üzerinden iletebilirsiniz. Söz dizimi https://username:password@hostname.com:port/path şeklindedir. HTTP Temel Kimlik Doğrulaması'nın kullanıcı adını ve şifreyi ağ üzerinden şifrelenmemiş metin halinde ilettiğini ve bu nedenle her zaman HTTPS ile kullanılması çok önemli olduğunu unutmayın.

HTTP önbelleğe alma protokolü

Bazel, HTTP/1.1 aracılığıyla uzaktan önbelleğe almayı destekler. Protokol kavram olarak basittir: İkili veriler (BLOB), PUT istekleri aracılığıyla yüklenir ve GET istekleri aracılığıyla indirilir. İşlem sonucu meta verileri /ac/ yolunun altında, çıkış dosyaları ise /cas/ yolunun altında depolanır.

Örneğin, http://localhost:8080/cache altında çalışan bir uzak önbelleği ele alalım. SHA256 karmasına (01ba4719...) sahip bir işlemin işlem sonucu meta verilerini indirme isteği aşağıdaki gibi görünür:

GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive

CAS'ye SHA256 karması 15e2b0d3... içeren bir çıkış dosyası yüklemek için Bazel isteği aşağıdaki gibi görünür:

PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive

0x310x320x330x340x350x360x370x380x39

Uzak önbelleği kullanarak Bazel'ı çalıştırma

Bir sunucu uzak önbellek olarak ayarlandıktan sonra, uzak önbelleği kullanmak için Bazel komutunuza işaretler eklemeniz gerekir. Yapılandırmaların listesini ve işaretlerini aşağıda bulabilirsiniz.

Ayrıca, seçtiğiniz sunucuya özgü kimlik doğrulamayı yapılandırmanız da gerekebilir.

Bu işaretleri bir .bazelrc dosyasına eklemek isteyebilirsiniz, böylece Bazel'i her çalıştırdığınızda bunları belirtmeniz gerekmez. Projenize ve ekip dinamiklerine bağlı olarak bir .bazelrc dosyasına işaret ekleyebilirsiniz:

  • Yerel makinenizde
  • Projenizin çalışma alanında, ekibinizle paylaşılır
  • CI sisteminde

Uzak önbellekten okuma ve uzak önbelleğe yazma

Uzak önbelleğe kimin yazma yetkisi olduğuna dikkat edin. Uzak önbelleğe yalnızca CI sisteminizin yazabilmesini isteyebilirsiniz.

Uzak önbelleğe okuma yapmak ve uzak önbelleğe yazmak için aşağıdaki işareti kullanın:

build --remote_cache=http://your.host:port

HTTP dışında şu protokoller de desteklenir: HTTPS, grpc, grpcs.

Yalnızca uzaktan önbellekten okumak için yukarıdaki işarete ek olarak aşağıdaki işareti de kullanın:

build --remote_upload_local_results=false

Belirli hedefleri uzak önbellekten hariç tutma

Belirli hedeflerin uzak önbelleği kullanmamasını sağlamak için hedefi no-remote-cache ile etiketleyin. Örneğin:

java_library(
    name = "target",
    tags = ["no-remote-cache"],
)

Uzak önbellekten içerik sil

Uzak önbellekten içerik silmek, sunucu yönetiminin bir parçasıdır. Uzak önbellekteki içeriğin nasıl silineceği, önbellek olarak ayarladığınız sunucuya bağlıdır. Çıkışları silerken önbelleğin tamamını veya eski çıkışları silin.

Önbelleğe alınan çıkışlar, bir ad ve karma grubu olarak depolanır. İçeriği silerken hangi çıktının belirli bir derlemeye ait olduğunu ayırt etmek mümkün değildir.

Aşağıdakileri yapmak için önbellekteki içeriği silmek isteyebilirsiniz:

  • Önbellek zehirlendikten sonra temiz bir önbellek oluşturma
  • Eski çıkışları silerek kullanılan depolama alanı miktarını azaltın

Unix yuvaları

Uzak HTTP önbelleği, unix alan yuvaları üzerinden bağlanmayı destekler. Davranış, curl'in --unix-socket işaretine benzer. Unix alan yuvasını yapılandırmak için aşağıdakileri kullanın:

   build --remote_cache=http://your.host:port
   build --remote_proxy=unix:/path/to/socket

Bu özellik Windows'da desteklenmez.

Disk önbelleği

Bazel, dosya sistemindeki bir dizini uzak önbellek olarak kullanabilir. Bu özellik, dalları değiştirirken ve/veya aynı projenin birden fazla çalışma alanında (ör. birden fazla ödeme) çalışırken derleme yapıları paylaşmak için yararlıdır. Bazel, dizini çöp kutusuna atmadığından bu dizin için düzenli aralıklarla temizlik yapılmasını isteyebilirsiniz. Disk önbelleğini aşağıdaki şekilde etkinleştirin:

build --disk_cache=path/to/build/cache

~ takma adını kullanarak --disk_cache işaretine kullanıcıya özel bir yol aktarabilirsiniz (Bazel, geçerli kullanıcının ana dizinini değiştirir). Bu, projenin işaretli .bazelrc dosyası aracılığıyla projenin tüm geliştiricileri için disk önbelleğini etkinleştirirken kullanışlıdır.

Bilinen sorunlar

Derleme sırasında dosya değişikliği girme

Derleme sırasında bir giriş dosyası değiştirildiğinde Bazel, uzak önbelleğe geçersiz sonuçlar yükleyebilir. --experimental_guard_against_concurrent_changes işaretiyle değişiklik algılamayı etkinleştirebilirsiniz. Bilinen bir sorun bulunmamaktadır ve gelecekteki bir sürümde varsayılan olarak etkinleştirilecektir. Güncellemeler için [sayı #3360] sayfasına bakın. Genel olarak, oluşturma sırasında kaynak dosyaları değiştirmekten kaçının.

Ortam değişkenlerinin bir işleme sızması

Bir işlem tanımında ortam değişkenleri bulunur. Bu, uzak önbellek isabetlerinin makineler arasında paylaşılması açısından bir sorun olabilir. Örneğin, farklı $PATH değişkenlerine sahip ortamlar önbellek isabetlerini paylaşmaz. Yalnızca --action_env aracılığıyla açıkça beyaz listeye eklenen ortam değişkenleri işlem tanımına dahil edilir. Bazel'in Debian/Ubuntu paketi, /etc/bazel.bazelrc hizmetini yüklemek için $PATH dahil olmak üzere ortam değişkenlerini içeren bir beyaz listeyle birlikte kullanılır. Beklenenden daha az önbellek isabeti alıyorsanız ortamınızda eski bir /etc/bazel.bazelrc dosyası olmadığından emin olun.

Bazel, çalışma alanının dışındaki araçları izlemiyor

Bazel şu anda araçları çalışma alanı dışındakileri izlemiyor. Örneğin, bir işlem /usr/bin/ kaynağından bir derleyici kullanıyorsa bu sorun olabilir. Daha sonra, farklı derleyiciler yüklemiş iki kullanıcı, çıktılar farklı olsa da aynı işlem karmasına sahip olduğu için önbellek isabetlerini yanlış bir şekilde paylaşır. Güncellemeler için 4558 numaralı soruna bakın.

Derlemeler docker container'larının içinde çalıştırılırken artımlı bellek içi durum kaybedilir Bazel, tek bir docker container'ında çalışırken bile sunucu/istemci mimarisi kullanır. Sunucu tarafında Bazel, bellek içi durumunu korur ve bu sayede derlemeleri hızlandırır. CI gibi docker container'larının içinde derlemeler çalıştırılırken, bellek içi durum kaybolur ve Bazel'ın uzak önbelleği kullanmadan önce bunu yeniden oluşturması gerekir.