

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 缓存构建以提高性能
<a name="build-caching"></a>

构建项目时，可以使用缓存来节省时间。缓存可以存储构建环境的可重用部分，并在多个构建中使用它们。您的构建项目可以使用两种缓存类型中的一种：Amazon S3 或本地。如果使用本地缓存，则必须选择三种缓存模式中的一种或多种：源缓存、Docker 层缓存和自定义缓存。

**注意**  
Docker 层缓存模式仅适用于 Linux 环境。如果选择此模式，则必须在特权模式下运行构建。 CodeBuild 被授予特权模式的项目授予其容器访问所有设备的权限。有关更多信息，请参阅 Docker 文档网站上的[运行时权限和 Linux 功能](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)。

**Topics**
+ [Amazon S3 缓存](caching-s3.md)
+ [本地缓存](caching-local.md)
+ [指定本地缓存](specify-caching-local.md)

# Amazon S3 缓存
<a name="caching-s3"></a>

Amazon S3 缓存将缓存存储在跨多个构建主机可用的 Amazon S3 存储桶中。对于构建成本高于下载成本的中小型构建构件，这是一个很好的选择。

要在版本中使用 Amazon S3，您可以为要缓存的文件指定路径`buildspec.yml`。 CodeBuild 将自动存储缓存并将其更新到项目中配置的 Amazon S3 位置。如果您不指定文件路径， CodeBuild 将尽最大努力缓存公共语言依赖关系以帮助您加快构建速度。您可以在构建日志中查看缓存详细信息。

此外，如果您想拥有多个版本的缓存，可以在中定义缓存密钥`buildspec.yml`。 CodeBuild 将缓存存储在此缓存密钥的上下文中，并创建一个创建后不会更新的唯一缓存副本。也可以跨项目共享缓存键。动态键、缓存版本控制和跨构建共享缓存等功能只有在指定键时才可用。

要了解有关 buildspec 文件中的缓存语法的更多信息，请参阅 buildspec 参考中的[cache](build-spec-ref.md#build-spec.cache)。

**Topics**
+ [生成动态键](#caching-s3-dynamic)
+ [codebuild-hash-files](#caching-s3-dynamic.codebuild-hash-files)
+ [缓存版本](#caching-s3-version)
+ [项目之间的缓存共享](#caching-s3-sharing)
+ [Buildspec 示例](#caching-s3-examples)

## 生成动态键
<a name="caching-s3-dynamic"></a>

缓存键可能包含 Shell 命令和环境变量以使其具有唯一性，以便在键发生变化时自动更新缓存。例如，您可以使用 `package-lock.json` 文件的哈希值定义一个键。当该文件中的依赖项发生变化时，此哈希值（即，缓存键）也会发生变化，从而导致自动创建新缓存。

```
cache:
    key: npm-key-$(codebuild-hash-files package-lock.json)
```

CodeBuild 将评估表达式`$(codebuild-hash-files package-lock.json)`以获得最终密钥：

```
npm-key-abc123
```

您也可以使用环境变量定义缓存键，例如 `CODEBUILD_RESOLVED_SOURCE_VERSION`。这样可以确保每当源发生变化时，系统都会生成一个新的键，导致自动保存一个新缓存：

```
cache:
   key: npm-key-$CODEBUILD_RESOLVED_SOURCE_VERSION
```

CodeBuild 将计算表达式并获得最终的密钥：

```
npm-key-046e8b67481d53bdc86c3f6affdd5d1afae6d369
```

## codebuild-hash-files
<a name="caching-s3-dynamic.codebuild-hash-files"></a>

`codebuild-hash-files`是一个 CLI 工具，它使用全局模式计算 CodeBuild 源目录中一组文件的 SHA-256 哈希值：

```
codebuild-hash-files <glob-pattern-1> <glob-pattern-2> ...
```

下面是一些使用 `codebuild-hash-files` 的示例：

```
codebuild-hash-files package-lock.json
codebuild-hash-files '**/*.md'
```

## 缓存版本
<a name="caching-s3-version"></a>

缓存版本是根据所缓存目录的路径生成的一个哈希值。如果两个缓存的版本不同，则在匹配过程中它们将被视为不同的缓存。例如，以下两个缓存被认为是不同的，因为它们引用不同的路径：

```
version: 0.2

phases:
  build:
    commands:
      - pip install pandas==2.2.3 --target pip-dependencies
cache:
  key: pip-dependencies 
  paths:
    - "pip-dependencies/**/*"
```

```
version: 0.2

phases:
  build:
    commands:
      - pip install pandas==2.2.3 --target tmp/pip-dependencies
cache:
  key: pip-dependencies 
  paths:
    - "tmp/pip-dependencies/**/*"
```

## 项目之间的缓存共享
<a name="caching-s3-sharing"></a>

您可以使用 `cache` 部分下的 `cacheNamespace` API 字段在多个项目之间共享缓存。此字段用于定义缓存的范围。要共享缓存，必须执行以下操作：
+ 使用相同的 `cacheNamespace`。
+ 指定相同的缓存 `key`。
+ 定义相同的缓存路径。
+ 使用相同的 Amazon S3 存储桶和 `pathPrefix`（如果已设置）。

这样可以确保一致性并可在项目间共享缓存。

### 指定缓存命名空间（控制台）
<a name="caching-s3-sharing.console"></a>

1. 在 [https://console.aws.amazon.com/codesuite/codebuild](https://console.aws.amazon.com/codesuite/codebuild/home) /home 中打开 AWS CodeBuild 控制台。

1. 选择**创建项目**。有关更多信息，请参阅 [创建构建项目（控制台）](create-project.md#create-project-console) 和 [运行构建（控制台）](run-build-console.md)。

1. 在**构件**中，选择**其他配置**。

1. 对于**缓存类型**，选择 **Amazon S3**。

1. 对于**缓存命名空间 - 可选**，输入命名空间值。  
![\[CodeBuild 控制台中的缓存命名空间参数。\]](http://docs.aws.amazon.com/zh_cn/codebuild/latest/userguide/images/s3-cache-namespace.png)

1. 继续使用默认值，然后选择**创建构建项目**。

### 指定缓存命名空间（AWS CLI）
<a name="caching-s3-sharing.cli"></a>

您可以使用中的`--cache`参数 AWS CLI 来指定缓存命名空间。

```
--cache '{"type": "S3", "location": "your-s3-bucket", "cacheNamespace": "test-cache-namespace"}'
```

## Buildspec 示例
<a name="caching-s3-examples"></a>

以下是常用语言的若干 buildspec 示例：

**Topics**
+ [缓存 Node.js 依赖项](#caching-s3-examples.nodejs)
+ [缓存 Python 依赖项](#caching-s3-examples.python)
+ [缓存 Ruby 依赖项](#caching-s3-examples.ruby)
+ [缓存 Go 依赖项](#caching-s3-examples.go)

### 缓存 Node.js 依赖项
<a name="caching-s3-examples.nodejs"></a>

如果您的项目包含一个 `package-lock.json` 文件并使用 `npm` 来管理 Node.js 依赖项，则以下示例显示了如何设置缓存。默认情况下，`npm` 将依赖项安装到 `node_modules` 目录中。

```
version: 0.2

phases:
  build:
    commands:
      - npm install
cache:
  key: npm-$(codebuild-hash-files package-lock.json)
  paths:
    - "node_modules/**/*"
```

### 缓存 Python 依赖项
<a name="caching-s3-examples.python"></a>

如果您的项目包含一个 `requirements.txt` 文件并使用 pip 来管理 Python 依赖项，则以下示例展示了如何配置缓存。默认情况下，pip 将软件包安装到系统的 `site-packages` 目录中。

```
version: 0.2

phases:
  build:
    commands:
      - pip install -r requirements.txt
cache:
  key: python-$(codebuild-hash-files requirements.txt)
  paths:
    - "/root/.pyenv/versions/${python_version}/lib/python${python_major_version}/site-packages/**/*"
```

此外，您还可以将依赖项安装到一个特定目录中，并为此目录配置缓存。

```
version: 0.2

phases:
  build:
    commands:
      - pip install -r requirements.txt --target python-dependencies
cache:
  key: python-$(codebuild-hash-files requirements.txt)
  paths:
    - "python-dependencies/**/*"
```

### 缓存 Ruby 依赖项
<a name="caching-s3-examples.ruby"></a>

如果您的项目包含 `Gemfile.lock` 文件并使用 `Bundler` 来管理 gem 依赖项，则以下示例演示了如何有效地配置缓存。

```
version: 0.2

phases:
  build:
    commands:
      - bundle install --path vendor/bundle
cache:
  key: ruby-$(codebuild-hash-files Gemfile.lock)
  paths:
    - "vendor/bundle/**/*"
```

### 缓存 Go 依赖项
<a name="caching-s3-examples.go"></a>

如果您的项目包含 `go.sum` 文件并使用 Go 模块来管理依赖项，则以下示例演示如何配置缓存。默认情况下，将 Go 模块下载并存储在 `${GOPATH}/pkg/mod` 目录中。

```
version: 0.2

phases:
  build:
    commands:
      - go mod download
cache:
  key: go-$(codebuild-hash-files go.sum)
  paths:
    - "/go/pkg/mod/**/*"
```

# 本地缓存
<a name="caching-local"></a>

本地缓存将缓存本地存储在构建主机上，并且仅可用于该构建主机。对于大中型构建构件，这是一个很好的选择，因为构建主机上的缓存立即可用。如果您不经常构建，这不是最好的选择。这意味着构建性能不受网络传输时间的影响。

如果您选择本地缓存，则必须选择以下一个或多个缓存模式：
+ 源缓存模式用于缓存主要和辅助源的 Git 元数据。创建缓存后，后续构建仅拉取两次提交之间发生的更改。对于具有干净工作目录和源为大型 Git 存储库的项目，此模式是一个不错的选择。如果您选择此选项，并且您的项目不使用 Git 存储库（AWS CodeCommit、 GitHub、E GitHub nterprise Server 或 Bitbucket），则该选项将被忽略。
+ Docker 层缓存模式缓存现有 Docker 层。对于构建或拉取大型 Docker 映像的项目，此模式是一个不错的选择。它可以防止因从网络中拉取大型 Docker 映像而导致的性能问题。
**注意**  
您只能在 Linux 环境中使用 Docker 层缓存。
必须设置 `privileged` 标志以使您的项目具有所需的 Docker 权限。  
默认情况下，为非 VPC 构建启用 Docker 进程守护程序。如果您想使用 Docker 容器进行 VPC 构建，请参阅 Docker 文档网站上的[运行时权限和 Linux 功能](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)并启用特权模式。此外，Windows 不支持特权模式。
在使用 Docker 层缓存之前，您应考虑安全影响。
+ 自定义缓存模式用于缓存您在 buildspec 文件中指定的目录。如果您的构建方案不适合另外两种本地缓存模式之一，则此模式是一个不错的选择。如果您使用自定义缓存：
  + 只能指定目录进行缓存。不能指定单独的文件。
  + 用于引用缓存目录的符号链接。
  + 缓存目录在下载项目源代码之前链接到您的构建。如果缓存项目具有相同的名称，则它们会覆盖源项目。使用 buildspec 文件中的缓存路径指定目录。有关更多信息，请参阅 [buildspec 语法](build-spec-ref.md#build-spec-ref-syntax)。
  + 避免在源和缓存中使用相同的目录名称。本地缓存的目录可能会覆盖或删除源存储库中具有相同名称的目录。

**注意**  
`LINUX_GPU_CONTAINER` 环境类型和 `BUILD_GENERAL1_2XLARGE` 计算类型不支持本地缓存。有关更多信息，请参阅 [构建环境计算模式和类型](build-env-ref-compute-types.md)。

**注意**  
当您配置为使用 VPC 时 CodeBuild ，不支持本地缓存。有关 VPCs 与一起使用的更多信息 CodeBuild，请参阅[AWS CodeBuild 与亚马逊 Virtual Private Cloud 一起使用](vpc-support.md)。

# 指定本地缓存
<a name="specify-caching-local"></a>

您可以使用 AWS CLI、控制台、SDK 或 CloudFormation 来指定本地缓存。有关本地缓存的更多信息，请参阅[本地缓存](caching-local.md)。

**Topics**
+ [指定本地缓存 (CLI)](#caching-local-cli)
+ [指定本地缓存（控制台）](#caching-local-console)
+ [指定本地缓存 (CloudFormation)](#caching-local-cfn)

## 指定本地缓存 (CLI)
<a name="caching-local-cli"></a>

您可以使用中的`--cache`参数 AWS CLI 来指定三种本地缓存类型中的每一种类型。
+ 指定源缓存：

  ```
  --cache type=LOCAL,mode=[LOCAL_SOURCE_CACHE]
  ```
+ 指定 Docker 层缓存：

  ```
  --cache type=LOCAL,mode=[LOCAL_DOCKER_LAYER_CACHE]
  ```
+ 指定自定义缓存：

  ```
  --cache type=LOCAL,mode=[LOCAL_CUSTOM_CACHE]
  ```

有关更多信息，请参阅 [创建构建项目 (AWS CLI)](create-project.md#create-project-cli)。

## 指定本地缓存（控制台）
<a name="caching-local-console"></a>

您可以使用控制台的**构件**部分指定缓存。对于**缓存类型**，选择 **Amazon S3** 或**本地**。如果您选择**本地**，请选择三个本地缓存选项中的一个或多个。

![\[选择三个本地缓存选项中的一个或多个来指定本地缓存。\]](http://docs.aws.amazon.com/zh_cn/codebuild/latest/userguide/images/local-cache.png)


有关更多信息，请参阅 [创建构建项目（控制台）](create-project.md#create-project-console)。

## 指定本地缓存 (CloudFormation)
<a name="caching-local-cfn"></a>

如果使用 CloudFormation 指定本地缓存，则在`Cache`属性上，为`Type`，指定`LOCAL`。以下 YAML 格式的示例 CloudFormation 代码指定了所有三种本地缓存类型。您可以指定这些类型的任意组合。如果您使用 Docker 层缓存，在 `Environment` 下，您必须将 `PrivilegedMode` 设置为 `true`，将 `Type` 设置为 `LINUX_CONTAINER`。

```
CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: MyProject
      ServiceRole: <service-role>
      Artifacts:
        Type: S3
        Location: <bucket-name>
        Name: myArtifact
        EncryptionDisabled: true
        OverrideArtifactName: true
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/standard:5.0
        Certificate: <bucket/cert.zip>
        # PrivilegedMode must be true if you specify LOCAL_DOCKER_LAYER_CACHE
        PrivilegedMode: true
      Source:
        Type: GITHUB
        Location: <github-location>
        InsecureSsl: true
        GitCloneDepth: 1
        ReportBuildStatus: false
      TimeoutInMinutes: 10
      Cache:
        Type: LOCAL
        Modes: # You can specify one or more cache mode, 
          - LOCAL_CUSTOM_CACHE
          - LOCAL_DOCKER_LAYER_CACHE
          - LOCAL_SOURCE_CACHE
```

**注意**  
默认情况下，为非 VPC 构建启用 Docker 进程守护程序。如果您想使用 Docker 容器进行 VPC 构建，请参阅 Docker 文档网站上的[运行时权限和 Linux 功能](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)并启用特权模式。此外，Windows 不支持特权模式。

有关更多信息，请参阅 [创建构建项目 (CloudFormation)](create-project.md#create-project-cloud-formation)。