

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Amazon EC2 Spot 執行個體
<a name="working-with-ec2-spot-instances"></a>

FSx for Lustre 可與 EC2 Spot 執行個體搭配使用，以大幅降低 Amazon EC2 成本。Spot 執行個體是未使用的 EC2 執行個體，其使用價格低於隨需定價。當 Spot 價格超過您的最高價格、Spot 執行個體的需求增加或 Spot 執行個體的供應減少時，Amazon EC2 可以中斷您的 Spot 執行個體。

當 Amazon EC2 中斷 Spot 執行個體時，會提供 Spot 執行個體中斷通知，在 Amazon EC2 中斷執行個體前，向該執行個體發出兩分鐘的警告。如需詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的[Spot 執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html)。

為了確保 Amazon FSx 檔案系統不受 EC2 Spot 執行個體中斷的影響，我們建議在終止或休眠 EC2 Spot 執行個體之前卸載 Amazon FSx 檔案系統。如需詳細資訊，請參閱[卸載檔案系統](unmounting-fs.md)。

## 處理 Amazon EC2 Spot 執行個體中斷
<a name="handling-ec2-spot-interruptions-in-fsx"></a>

 FSx for Lustre 是一種分散式檔案系統，其中伺服器和用戶端執行個體會合作以提供效能良好且可靠的檔案系統。它們會在用戶端和伺服器執行個體之間維持分散式和一致狀態。FSx for Lustre 伺服器會在用戶端主動執行 I/O 和快取檔案系統資料時，將暫時存取許可委派給用戶端。當伺服器要求他們撤銷臨時存取許可時，用戶端應該會在短時間內回覆 。為了保護檔案系統免於用戶端運作錯誤，伺服器可以移出幾分鐘後未回應的Lustre用戶端。若要避免不回應的用戶端必須等待幾分鐘才能回覆伺服器請求，請務必徹底卸載Lustre用戶端，尤其是在終止 EC2 Spot 執行個體之前。清除卸載是透過使用不含 `-f`或 的 `umount`命令來啟動`-l`。

 如果Lustre用戶端在未完全卸載檔案系統的情況下關閉，使用該檔案系統的其他用戶端可能會遇到暫時增加的延遲、懸置操作或 I/O 錯誤。

 EC2 Spot 會提前 2 分鐘傳送終止通知，然後再關閉執行個體。建議您在終止 EC2 Spot 執行個體之前，先自動執行徹底卸載Lustre用戶端的程序。

**Example – 用來徹底卸載終止 EC2 Spot 執行個體的指令碼**  
此範例指令碼會執行下列動作，以徹底卸載終止的 EC2 Spot 執行個體：  
+ 適用於 Spot 的 手錶終止通知。
+ 當它收到終止通知時：
  + 停止正在存取檔案系統的應用程式。
  + 在執行個體終止之前卸載檔案系統。
您可以視需要調整指令碼，尤其是用於正常關閉應用程式。如需處理 Spot 執行個體中斷的最佳實務的詳細資訊，請參閱[處理 EC2 Spot 執行個體中斷的最佳實務](https://aws.amazon.com/blogs//compute/best-practices-for-handling-ec2-spot-instance-interruptions/)。  
Lustre 用戶端卸載檔案系統可能需要一些時間。如果您在相同的 Amazon EC2 Spot 執行個體上掛載許多檔案系統，在兩分鐘 Spot 終止通知時段內卸載所有檔案系統可能需要太長的時間。如果您需要在一個主機上掛載大量檔案系統，建議您使用隨需執行個體，以避免因 Amazon EC2 Spot 執行個體中斷而導致無法清理卸載的問題。

```
#!/bin/bash

# TODO: Specify below the FSx mount point you are using
*FSXPATH=/fsx*

cd /

TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
if [ "$?" -ne 0 ]; then
    echo "Error running 'curl' command" >&2
    exit 1
fi

# Periodically check for termination
while sleep 5
do

    HTTP_CODE=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s -w %{http_code} -o /dev/null http://169.254.169.254/latest/meta-data/spot/instance-action)

    if [[ "$HTTP_CODE" -eq 401 ]] ; then
        # Refreshing Authentication Token
        TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 30")
        continue
    elif [[ "$HTTP_CODE" -ne 200 ]] ; then
        # If the return code is not 200, the instance is not going to be interrupted
        continue
    fi

    echo "Instance is getting terminated. Clean and unmount '$FSXPATH' ..."
    curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/spot/instance-action
    echo

    # Gracefully stop applications accessing the filesystem
    #
    # TODO*: Replace with the proper command to stop your application if possible*

    # Kill every process still accessing Lustre filesystem
    echo "Kill every process still accessing Lustre filesystem..."
    fuser -kMm -TERM "${FSXPATH}"; sleep 2
    fuser -kMm -KILL "${FSXPATH}"; sleep 2

    # Unmount FSx For Lustre filesystem
    if ! umount -c "${FSXPATH}"; then
        echo "Error unmounting '$FSXPATH'. Processes accessing it:" >&2
        lsof "${FSXPATH}"

        echo "Retrying..."
        continue
    fi

    # Start a graceful shutdown of the host
    shutdown now

done
```