Udostępnij za pośrednictwem


Buforowanie potoku

Usługi Azure DevOps

Buforowanie potoku może pomóc w skróceniu czasu kompilacji przez ponowne użycie pobranych zależności z poprzednich uruchomień, unikając konieczności ponownego tworzenia lub ponownego pobierania tych samych plików. Jest to szczególnie przydatne w scenariuszach, w których te same zależności są pobierane wielokrotnie na początku każdego przebiegu. Jest to często czasochłonny proces obejmujący setki lub tysiące wywołań sieciowych.

Buforowanie jest najskuteczniejsze, gdy czas wymagany do przywrócenia i zapisania pamięci podręcznej jest krótszy niż czas potrzebny na ponowne wygenerowanie plików. Jednak w niektórych przypadkach buforowanie może nie zapewnić korzyści w zakresie wydajności, a nawet może negatywnie wpłynąć na czas kompilacji. Ważne jest, aby ocenić konkretny scenariusz, aby określić, czy buforowanie jest właściwym podejściem.

Notatka

Buforowanie potoków nie jest obsługiwane w przypadku klasycznych potoków wydania.

Kiedy używać artefaktów potoku, a kiedy buforowania potoku

Buforowanie potoku i artefakty potoku wykonują podobne funkcje, ale są przeznaczone dla różnych scenariuszy i nie powinny być używane zamiennie.

  • Użyj artefaktów potoku: gdy musisz wziąć określone pliki utworzone przez jedno zadanie i udostępnić je innym zadaniom (a te inne zadania prawdopodobnie zakończą się niepowodzeniem bez nich).

  • Użyj buforowania potoku: jeśli chcesz skrócić czas kompilacji, ponownie używając plików z poprzednich przebiegów (a brak tych plików nie wpłynie na możliwość uruchomienia zadania).

Notatka

Buforowanie potoku i artefakty potoku są dostępne bezpłatnie dla wszystkich warstw (bezpłatnych i płatnych). Aby uzyskać więcej informacji, zobacz zużycie przechowywania artefaktów i.

Wymagania dotyczące własnego agenta

Następujące pliki wykonywalne muszą znajdować się w folderze wymienionym w zmiennej PATH środowiskowej. Należy pamiętać, że te wymagania dotyczą tylko agentów hostowanych samodzielnie, ponieważ hostowani agenci są wstępnie zainstalowani z niezbędnym oprogramowaniem.

Archiwizowanie oprogramowania/platformy Windows Linuxa Mac
Smoła GNU Wymagane Wymagane Nie
Smoła BSD Nie Nie Wymagane
7-Zamek błyskawiczny Zalecane Nie Nie

Zadanie pamięci podręcznej: Jak to działa

Buforowanie jest dodawane do potoku przez dodanie zadania Pamięć podręczna do steps sekcji zadania.

Podczas wykonywania potoku, gdy napotkany zostanie krok pamięci podręcznej, zadanie próbuje przywrócić pamięć podręczną na podstawie podanych danych wejściowych. Jeśli pamięć podręczna nie zostanie znaleziona, krok zostanie ukończony i zostanie wykonany następny krok w zadaniu.

Po pomyślnym uruchomieniu wszystkich kroków w zadaniu specjalny krok "Po zadaniu: pamięć podręczna" jest automatycznie dodawany i wyzwalany dla każdego kroku "przywracania pamięci podręcznej" , który nie został pominięty. Ten krok jest odpowiedzialny za zapisywanie pamięci podręcznej.

Notatka

Pamięci podręczne są niezmienne. Po utworzeniu pamięci podręcznej nie można modyfikować jej zawartości.

Konfiguracja zadania pamięci podręcznej

Zadanie Cache ma dwa wymagane argumenty: path i key:

  1. path: Ścieżka do folderu, który chcesz buforować. Może to być ścieżka bezwzględna lub względna. Ścieżki względne są rozwiązywane względem $(System.DefaultWorkingDirectory).

    Napiwek

    Za pomocą wstępnie zdefiniowanych zmiennych można przechowywać ścieżkę do folderu, który ma być buforowany. Symbole wieloznaczne nie są jednak obsługiwane.

  2. klucz: Określa identyfikator pamięci podręcznej, którą chcesz przywrócić lub zapisać. Klucz składa się z kombinacji wartości ciągów, ścieżek plików lub wzorców plików, przy czym każdy segment jest oddzielony | znakiem.

    • ciągi:
      Stała wartość (taka jak nazwa pamięci podręcznej lub nazwa narzędzia) lub pobrana ze zmiennej środowiskowej (takiej jak bieżący system operacyjny lub nazwa zadania).

    • ścieżki plików:
      Ścieżka do określonego pliku, którego zawartość zostanie zaszyfrowana. Plik musi istnieć w momencie uruchomienia zadania. Każdy segment, który przypomina ścieżkę do pliku, jest traktowany jako taki, więc należy zachować ostrożność, zwłaszcza w przypadku korzystania z segmentów zawierających ., ponieważ może to prowadzić do błędów typu "plik nie istnieje".

      Napiwek

      Aby uniknąć traktowania segmentu ciągu przypominającego ścieżkę jak ścieżka pliku, opakuj go podwójnymi cudzysłowami, na przykład: "my.key" | $(Agent.OS) | key.file

    • wzorce plików :
      Rozdzielona przecinkami lista wzorców symboli wieloznacznych w stylu globu, które muszą pasować do co najmniej jednego pliku. Przykłady:

      • **/yarn.lock: wszystkie pliki yarn.lock w katalogu sources.
      • */asset.json, !bin/**: wszystkie plikiasset.json znajdujące się w katalogu w katalogu sources, z wyjątkiem tych w katalogu bin .

Zawartość dowolnego pliku identyfikowanego przez ścieżkę pliku lub wzorzec pliku jest haszowana w celu wygenerowania dynamicznego klucza pamięci podręcznej. Jest to przydatne, gdy projekt zawiera pliki, które jednoznacznie identyfikują, co jest buforowane. Na przykład pliki takie jak package-lock.json, yarn.lock, Gemfile.lock, lub Pipfile.lock są często przywoływane w kluczu pamięci podręcznej, ponieważ reprezentują unikalny zestaw zależności. Względne ścieżki lub wzorce plików są rozpoznawane względem $(System.DefaultWorkingDirectory).

  • Przykład:

W poniższym przykładzie pokazano, jak buforować pakiety usługi Yarn:

variables:
  YARN_CACHE_FOLDER: $(Pipeline.Workspace)/s/.yarn

steps:
- task: Cache@2
  inputs:
    key: '"yarn" | "$(Agent.OS)" | yarn.lock'
    restoreKeys: |
       "yarn" | "$(Agent.OS)"
       "yarn"
    path: $(YARN_CACHE_FOLDER)
  displayName: Cache Yarn packages

- script: yarn --frozen-lockfile

W tym przykładzie klucz pamięci podręcznej składa się z trzech części: ciągu statycznego ("przędzy"), systemu operacyjnego, na którym jest uruchomione zadanie (ponieważ pamięć podręczna jest unikatowa dla każdego systemu operacyjnego) i skrótu yarn.lock pliku (który jednoznacznie identyfikuje zależności).

Przy pierwszym uruchomieniu po dodaniu zadania krok pamięci podręcznej zgłosi "chybienie pamięci podręcznej", ponieważ pamięć podręczna identyfikowana przez ten klucz nie istnieje. Po wykonaniu ostatniego kroku pamięć podręczna z plików w $(Pipeline.Workspace)/s/.yarn zostanie utworzona i załadowana. Przy następnym uruchomieniu etap pamięci podręcznej zgłosi "trafienie pamięci podręcznej", a zawartość pamięci podręcznej zostanie załadowana i przywrócona.

W przypadku korzystania z checkout: selfprogramu repozytorium jest wyewidencjonowane w $(Pipeline.Workspace)/s, a .yarn folder prawdopodobnie będzie znajdował się w samym repozytorium.

Notatka

Pipeline.Workspace to ścieżka lokalna agenta uruchamiającego potok, w którym są tworzone wszystkie katalogi. Ta zmienna ma taką samą wartość jak Agent.BuildDirectory. Jeśli nie używasz checkout: selfprogramu , upewnij się, że zmienna została zaktualizowana YARN_CACHE_FOLDER tak, aby wskazywała lokalizację .yarn w repozytorium.

Używanie kluczy przywracania

restoreKeys Umożliwia wykonywanie zapytań dotyczących wielu dokładnych kluczy lub prefiksów kluczy. Jest on używany jako rozwiązanie awaryjne, gdy określone key działanie nie daje trafienia. Klucz przywracania wyszukuje klucz według prefiksu i zwraca ostatnio utworzony wpis pamięci podręcznej. Jest to przydatne, gdy potok nie może znaleźć dokładnego dopasowania, ale nadal chce użyć częściowego trafienia w pamięci podręcznej.

Aby określić wiele kluczy przywracania, wymień je w osobnych wierszach. Kolejność, w jakiej wypróbowywane są klucze przywracania, jest od góry do dołu.

  • Przykład:

Oto przykład użycia kluczy przywracania do buforowania pakietów Yarn:

variables:
  YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn

steps:
- task: Cache@2
  inputs:
    key: '"yarn" | "$(Agent.OS)" | yarn.lock'
    restoreKeys: |
       yarn | "$(Agent.OS)"
       yarn
    path: $(YARN_CACHE_FOLDER)
  displayName: Cache Yarn packages

- script: yarn --frozen-lockfile

W tym przykładzie zadanie pamięci podręcznej najpierw próbuje przywrócić określony klucz. Jeśli klucz nie istnieje w pamięci podręcznej, próbuje użyć pierwszego klucza przywracania: yarn | $(Agent.OS). Spowoduje to wyszukanie wszystkich kluczy pamięci podręcznej, które dokładnie pasują do tego prefiksu lub zaczynają się od niego.

Dopasowanie prefiksu może wystąpić, jeśli skrót pliku uległ zmianie yarn.lock . Jeśli na przykład pamięć podręczna zawiera klucz yarn | $(Agent.OS) | old-yarn.lock (gdzie old-yarn.lock ma inny skrót niż bieżący yarn.lock), ten klucz przywracania spowoduje częściowe trafienie w pamięć podręczną.

Jeśli pierwszy klucz przywracania nie da dopasowania, następny klucz przywracania (yarn) Spowoduje to wyszukanie dowolnego klucza pamięci podręcznej, który zaczyna się od yarn. W przypadku dopasowań prefiksów proces przywracania zwraca ostatnio utworzony wpis pamięci podręcznej.

Notatka

Potok może zawierać wiele zadań buforowania i nie ma limitu miejsca do buforowania. Zadania i zadania w ramach tego samego potoku mogą uzyskiwać dostęp do tej samej pamięci podręcznej i współużytkować ją.

Użyj warunku przywracania

W niektórych scenariuszach może być konieczne warunkowe wykonanie kroków w zależności od tego, czy pamięć podręczna została pomyślnie przywrócona. Na przykład możesz pominąć krok, który instaluje zależności, jeśli pamięć podręczna została przywrócona. Można to osiągnąć za pomocą argumentu cacheHitVar .

Ustawienie tych danych wejściowych na nazwę zmiennej środowiskowej powoduje, że zmienna jest ustawiana na true wtedy, gdy nastąpi trafienie pamięci podręcznej, inexact jeśli klucz przywracania daje częściowe trafienie pamięci podręcznej i false jeśli nie zostanie znaleziona żadna pamięć podręczna. Następnie można odwołać się do tej zmiennej w warunku kroku lub w skrypcie.

Oto przykład, w którym install-deps.sh krok jest pomijany po przywróceniu pamięci podręcznej:

steps:
- task: Cache@2
  inputs:
    key: mykey | mylockfile
    restoreKeys: mykey
    path: $(Pipeline.Workspace)/mycache
    cacheHitVar: CACHE_RESTORED

- script: install-deps.sh
  condition: ne(variables.CACHE_RESTORED, 'true')

- script: build.sh

Izolacja i zabezpieczenia pamięci podręcznej

Aby zapewnić izolację między pamięciami podręcznymi z różnych potoków i różnych gałęzi, każda pamięć podręczna jest przechowywana w kontenerze logicznym nazywanym zakresem. Zakresy działają jako granica zabezpieczeń, która gwarantuje:

  • Zadania z jednego potoku nie mogą uzyskiwać dostępu do pamięci podręcznych z innego potoku.

  • Zadania kompilujące żądania ściągnięcia mogą odczytywać pamięci podręczne z gałęzi docelowej (dla tego samego potoku), ale nie mogą zapisywać (tworzyć) pamięci podręcznych w zakresie gałęzi docelowej.

Gdy w trakcie procesu natrafimy na etap pamięci podręcznej, pamięć podręczna zidentyfikowana przez klucz jest żądana z serwera. Następnie serwer szuka pamięci podręcznej z tym kluczem z zakresów widocznych dla zadania i zwraca pamięć podręczną (jeśli jest dostępna). W przypadku zapisywania pamięci podręcznej (pod koniec zadania) pamięć podręczna jest zapisywana do zakresu reprezentującego ciąg i gałąź.

Przebiegi ciągłej integracji (CI), ręczne i zaplanowane

Zakres Czytaj Pisać
Gałąź źródłowa Tak Tak
gałąź main Tak Nie
gałąź master Tak Nie

Wykonania pull requestów

Zakres Czytaj Pisać
Gałąź źródłowa Tak Nie
Gałąź docelowa Tak Nie
Gałąź pośrednia (na przykład refs/pull/1/merge) Tak Tak
gałąź main Tak Nie
gałąź master Tak Nie

Uruchomienia forków pull requestów

Gałąź Czytaj Pisać
Gałąź docelowa Tak Nie
Gałąź pośrednia (na przykład refs/pull/1/merge) Tak Tak
gałąź main Tak Nie
gałąź master Tak Nie

Napiwek

Ponieważ pamięci podręczne są już ograniczone do projektu, potoku i gałęzi, nie ma potrzeby dołączania żadnych identyfikatorów projektu, potoku lub gałęzi w kluczu pamięci podręcznej.

Przykłady

W przypadku projektów Ruby korzystających z Bundler, zastąp BUNDLE_PATH zmienną środowiskową, aby ustawić ścieżkę , w której Bundler szuka klejnotów.

Przykład:

variables:
  BUNDLE_PATH: $(Pipeline.Workspace)/.bundle

steps:
- task: Cache@2
  displayName: Bundler caching
  inputs:
    key: 'gems | "$(Agent.OS)" | Gemfile.lock'
    path: $(BUNDLE_PATH)
    restoreKeys: | 
      gems | "$(Agent.OS)"
      gems   

Znane problemy i opinie

Jeśli masz problemy z konfiguracją buforowania w potoku, sprawdź listę otwartych problemów w microsoft/azure-pipelines-tasks repozytorium. Jeśli nie widzisz swojego problemu na liście, utwórz nowy i podaj niezbędne informacje o swoim scenariuszu.

Pytania i odpowiedzi

Czy mogę wyczyścić pamięć podręczną?

Odp.: Czyszczenie pamięci podręcznej nie jest obsługiwane. Można jednak uniknąć trafień w istniejących pamięciach podręcznych, dodając literał ciągu (taki jak version2) do klucza pamięci podręcznej. Na przykład zmień następujący klucz pamięci podręcznej z tego:

key: 'yarn | "$(Agent.OS)" | yarn.lock'

Do tego:

key: 'version2 | yarn | "$(Agent.OS)" | yarn.lock'

.: Kiedy pamięć podręczna wygaśnie?

Pamięci podręczne wygasają po siedmiu dniach braku aktywności.

Kiedy pamięć podręczna zostanie przekazywana?

Odp.: Pamięć podręczna jest tworzona na podstawie określonego path i przekazywana po ostatnim kroku zadania. Aby uzyskać więcej informacji, zobacz przykład .

.: Czy istnieje limit rozmiaru pamięci podręcznej?

Odp.: Nie ma wymuszonego limitu rozmiaru poszczególnych pamięci podręcznych ani całkowitego rozmiaru pamięci podręcznej w organizacji.