設計logo怎么收費泰安seo培訓
想要學習如何在Kubernetes上自動縮放您的Kinesis Data Streams消費者應用程序,以便節(jié)省成本并提高資源效率嗎?本文提供了一個逐步指南,教您如何實現(xiàn)這一目標。
通過利用Kubernetes對Kinesis消費者應用程序進行自動縮放,您可以從其內(nèi)置功能中受益,例如水平Pod自動縮放器(Horizontal Pod Autoscaler)。
▌什么是Amazon Kinesis和Kinesis Data Streams??
Amazon Kinesis是一個用于實時數(shù)據(jù)處理、攝取和分析的平臺。Kinesis Data Streams是一個無服務器的流式數(shù)據(jù)服務(屬于Kinesis流式數(shù)據(jù)平臺的一部分),還包括Kinesis Data Firehose、Kinesis Video Streams和Kinesis Data Analytics。
Kinesis Data Streams可以彈性地擴展,并持續(xù)適應數(shù)據(jù)攝取速率和流消費速率的變化。它可用于構(gòu)建實時數(shù)據(jù)分析應用程序、實時儀表板和實時數(shù)據(jù)管道。
讓我們首先概述一些Kinesis Data Streams的關鍵概念。
▌Kinesis Data Streams:高級架構(gòu)?
-
Kinesis數(shù)據(jù)流由一組分片組成。每個分片包含一系列數(shù)據(jù)記錄。?
-
生產(chǎn)者持續(xù)將數(shù)據(jù)推送到Kinesis Data Streams,消費者實時處理數(shù)據(jù)。?
-
分區(qū)鍵用于在流中按分片分組數(shù)據(jù)。?
-
Kinesis Data Streams將屬于流的數(shù)據(jù)記錄分隔到多個分片中。?
-
它使用與每個數(shù)據(jù)記錄關聯(lián)的分區(qū)鍵來確定給定數(shù)據(jù)記錄屬于哪個分片。?
-
消費者從Amazon Kinesis Data Streams獲取記錄,對其進行處理,并將結(jié)果存儲在Amazon DynamoDB、Amazon Redshift、Amazon S3等中。
-
這些消費者也被稱為Amazon Kinesis Data Streams應用程序。?
-
開發(fā)能夠處理KDS數(shù)據(jù)流中的數(shù)據(jù)的自定義消費者應用程序的一種方法是使用Kinesis Client Library(KCL)。
Kinesis消費者應用程序是如何實現(xiàn)水平擴展的呢??
Kinesis Client Library確保每個分片都有一個記錄處理器正在運行,并處理來自該分片的數(shù)據(jù)。KCL幫助您從Kinesis數(shù)據(jù)流中消費和處理數(shù)據(jù),通過處理與分布式計算和可擴展性相關的許多復雜任務。它連接到數(shù)據(jù)流,枚舉數(shù)據(jù)流中的分片,并使用租約來協(xié)調(diào)分片與其消費者應用程序之間的關聯(lián)。
每個分片都會實例化一個記錄處理器來管理。KCL從數(shù)據(jù)流中拉取數(shù)據(jù)記錄,將記錄推送給相應的記錄處理器,并檢查點處理過的記錄。更重要的是,當工作實例數(shù)量發(fā)生變化或數(shù)據(jù)流重新分片(分片拆分或合并)時,它會平衡分片-工作器的關聯(lián)(租約)。這意味著您可以通過添加更多實例來擴展Kinesis Data Streams應用程序,因為KCL會自動在實例之間平衡分片。
但是,當負載增加時,您仍然需要一種方法來擴展應用程序。當然,您可以手動進行操作或構(gòu)建自定義解決方案來完成此操作。
這就是Kubernetes事件驅(qū)動自動縮放(KEDA)的用武之地。KEDA是基于Kubernetes的事件驅(qū)動自動縮放組件,它可以監(jiān)視Kinesis等事件源,并根據(jù)需要處理的事件數(shù)量來調(diào)整底層的部署(和Pod)的規(guī)模。
為了觀察自動擴展的過程,您將使用一個使用Kinesis Client Library(KCL)2.x從Kinesis數(shù)據(jù)流中消費數(shù)據(jù)的Java應用程序。它將部署到Amazon EKS上的Kubernetes集群,并將使用KEDA進行自動縮放。該應用程序包括一個ShardRecordProcessor的實現(xiàn),該實現(xiàn)處理來自Kinesis流的數(shù)據(jù),并將其持久化到DynamoDB表中。我們將使用AWS CLI向Kinesis流中產(chǎn)生數(shù)據(jù),并觀察應用程序的擴展情況。
在我們深入研究之前,這里是對KEDA的快速概述。
▌什么是KEDA??
KEDA是一個構(gòu)建在原生Kubernetes原語(如Horizontal Pod Autoscaler)之上的開源CNCF項目,可以添加到任何Kubernetes集群中。以下是其關鍵組件的高級概述(您可以參考KEDA文檔進行深入了解):
-
KEDA中的keda-operator-metrics-apiserver組件充當Kubernetes度量服務器,用于公開Horizontal Pod Autoscaler的度量指標。
-
KEDA Scaler與外部系統(tǒng)(如Redis)集成,以獲取這些指標(例如列表長度),根據(jù)需要處理的事件數(shù)量來驅(qū)動Kubernetes中任何容器的自動擴展。
-
keda-operator組件的作用是激活和停用Deployment,即將其擴展到零或從零縮減。
您將看到Kinesis Stream KEDA Scaler的實際效果,它會根據(jù)AWS Kinesis Stream的分片數(shù)量進行自動擴展。
現(xiàn)在讓我們繼續(xù)進行本文的實際部分。
▌先決條件?
除了一個AWS賬戶之外,您還需要安裝AWS CLI、kubectl、Docker、Java 11和Maven。
設置一個EKS集群,創(chuàng)建一個DynamoDB表和一個Kinesis數(shù)據(jù)流?
有多種方法可以創(chuàng)建Amazon EKS集群。我喜歡使用eksctl CLI,因為它提供了很多便利。使用eksctl創(chuàng)建EKS集群可以非常簡單,就像這樣:
eksctl create cluster --name <cluster name> --region <region e.g. us-east-1>
有關詳細信息,請參閱Amazon EKS - eksctl文檔中的入門指南。
創(chuàng)建一個DynamoDB表來持久化應用程序數(shù)據(jù)。您可以使用AWS CLI使用以下命令創(chuàng)建表格:
aws dynamodb create-table \
--table-name users \
--attribute-definitions AttributeName=email,AttributeType=S \
--key-schema AttributeName=email,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
使用AWS CLI創(chuàng)建一個具有兩個分片的Kinesis流,請執(zhí)行以下命令:
aws kinesis create-stream --stream-name kinesis-keda-demo --shard-count 2
請克隆該GitHub倉庫,并切換到正確的目錄:
git clone https://github.com/abhirockzz/kinesis-keda-autoscaling
cd kinesis-keda-autoscaling
好的,讓我們開始吧!
▌在EKS上設置和配置KEDA?
在本教程中,您將使用YAML文件來部署KEDA。但是您也可以使用Helm charts。
安裝KEDA:
# update version 2.8.2 if requiredkubectl apply -f https://github.com/kedacore/keda/releases/download/v2.8.2/keda-2.8.2.yaml
驗證安裝:
# check Custom Resource Definitions
kubectl get crd# check KEDA Deployments
kubectl get deployment -n keda# check KEDA operator logs
kubectl logs -f $(kubectl get pod -l=app=keda-operator -o jsonpath='{.items[0].metadata.name}' -n keda) -n keda
▌配置IAM角色
KEDA操作員和Kinesis消費應用程序需要調(diào)用AWS API。由于兩者都將作為EKS中的部署運行,我們將使用服務賬號的IAM角色(IRSA)來提供必要的權(quán)限。
在這種情況下:
-
KEDA操作員需要能夠獲取Kinesis流的分片數(shù)量:它通過使用DescribeStreamSummary API來實現(xiàn)。?
-
應用程序(具體而言是KCL庫)需要與Kinesis和DynamoDB進行交互:它需要一系列的IAM權(quán)限來實現(xiàn)這一點。?
配置KEDA操作員的IRSA?
將AWS帳戶ID和OIDC身份提供者設置為環(huán)境變量:
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)#update the cluster name and region as required
export EKS_CLUSTER_NAME=demo-eks-cluster
export AWS_REGION=us-east-1OIDC_PROVIDER=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
創(chuàng)建一個包含角色的受信任實體的JSON文件:
read -r -d '' TRUST_RELATIONSHIP <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:aud": "sts.amazonaws.com",
"${OIDC_PROVIDER}:sub": "system:serviceaccount:keda:keda-operator"
}
}
}
]
}
EOF
echo "${TRUST_RELATIONSHIP}" > trust_keda.json
現(xiàn)在,創(chuàng)建IAM角色并附加策略(請查看policy_kinesis_keda.json文件以獲取詳細信息):???????
export ROLE_NAME=keda-operator-kinesis-roleaws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://trust_keda.json --description "IRSA for kinesis KEDA scaler on EKS"aws iam create-policy --policy-name keda-kinesis-policy --policy-document file://policy_kinesis_keda.json
aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn=arn:aws:iam::${ACCOUNT_ID}:policy/keda-kinesis-policy
關聯(lián)IAM角色和服務賬號:
kubectl annotate serviceaccount -n keda keda-operator eks.amazonaws.com/role-arn=arn:aws:iam::${ACCOUNT_ID}:role/${ROLE_NAME}# verify the annotation
kubectl describe serviceaccount/keda-operator -n keda
您需要重新啟動KEDA操作員部署以使其生效:
kubectl rollout restart deployment.apps/keda-operator -n keda# to verify, confirm that the KEDA operator has the right environment variables
kubectl describe pod -n keda $(kubectl get po -l=app=keda-operator -n keda --output=jsonpath={.items..metadata.name}) | grep "^\s*AWS_"# expected outputAWS_STS_REGIONAL_ENDPOINTS: regional
AWS_DEFAULT_REGION: us-east-1
AWS_REGION: us-east-1
AWS_ROLE_ARN: arn:aws:iam::<AWS_ACCOUNT_ID>:role/keda-operator-kinesis-role
AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
為KCL消費者應用程序配置IRSA
首先創(chuàng)建一個Kubernetes服務帳號:???????
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: kcl-consumer-app-sa
EOF
創(chuàng)建一個包含角色的受信實體的JSON文件:???????
read -r -d '' TRUST_RELATIONSHIP <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:aud": "sts.amazonaws.com",
"${OIDC_PROVIDER}:sub": "system:serviceaccount:default:kcl-consumer-app-sa"
}
}
}
]
}
EOF
echo "${TRUST_RELATIONSHIP}" > trust.json
現(xiàn)在,創(chuàng)建IAM角色并附加策略(請查看policy.json文件以獲取詳細信息):
export ROLE_NAME=kcl-consumer-app-roleaws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://trust.json --description "IRSA for KCL consumer app on EKS"aws iam create-policy --policy-name kcl-consumer-app-policy --policy-document file://policy.jsonaws iam attach-role-policy --role-name $ROLE_NAME --policy-arn=arn:aws:iam::${ACCOUNT_ID}:policy/kcl-consumer-app-policy
關聯(lián)IAM角色和服務賬號:
kubectl annotate serviceaccount -n default kcl-consumer-app-sa eks.amazonaws.com/role-arn=arn:aws:iam::${ACCOUNT_ID}:role/${ROLE_NAME}# verify the annotation
kubectl describe serviceaccount/kcl-consumer-app-sa
核心基礎架構(gòu)已準備就緒。讓我們準備并部署消費者應用程序。
▌將KCL消費者應用程序部署到EKS?
首先,您需要構(gòu)建Docker鏡像并將其推送到Amazon Elastic Container Registry(ECR)(請參閱Dockerfile獲取詳細信息)。
構(gòu)建并推送Docker鏡像到ECR
# create runnable JAR file
mvn clean compile assembly\:single# build docker image
docker build -t kcl-consumer-app .AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)# create a private ECR repo
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.comaws ecr create-repository --repository-name kcl-consumer-app --region us-east-1# tag and push the image
docker tag kcl-consumer-app:latest $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kcl-consumer-app:latest
docker push $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kcl-consumer-app:latest
部署消費者應用程序
更新consumer.yaml文件,將剛剛推送到ECR的Docker鏡像包含在內(nèi)。其他部分的清單保持不變。
apiVersion: apps/v1
kind: Deployment
metadata:name: kcl-consumer
spec:replicas: 1selector:matchLabels:app: kcl-consumertemplate:metadata:labels:app: kcl-consumerspec:serviceAccountName: kcl-consumer-app-sacontainers:- name: kcl-consumerimage: AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kcl-consumer-app:latestimagePullPolicy: Alwaysenv:- name: STREAM_NAMEvalue: kinesis-keda-demo- name: TABLE_NAMEvalue: users- name: APPLICATION_NAMEvalue: kinesis-keda-demo- name: AWS_REGIONvalue: us-east-1- name: INSTANCE_NAMEvalueFrom:fieldRef:fieldPath: metadata.name
創(chuàng)建部署(Deployment):
kubectl apply -f consumer.yaml# verify Pod transition to Running state
kubectl get pods -w
▌KEDA 中的 KCL 應用自動擴展
現(xiàn)在您已經(jīng)部署了消費者應用程序,KCL 庫應該開始運行了。它首先會在 DynamoDB 中創(chuàng)建一個“控制表”,這個表的名稱應與 KCL 應用程序的名稱相同(在本例中為 kinesis-keda-demo)。
初始的協(xié)調(diào)和表的創(chuàng)建可能需要幾分鐘時間。您可以查看消費者應用程序的日志來跟蹤進展。
kubectl logs -f $(kubectl get po -l=app=kcl-consumer --output=jsonpath={.items..metadata.name})
完成租賃分配后,請檢查表并注意 leaseOwner 屬性:???????
aws dynamodb describe-table --table-name kinesis-keda-demo
aws dynamodb scan --table-name kinesis-keda-demo
現(xiàn)在,讓我們使用 AWS CLI 向 Kinesis 流發(fā)送一些數(shù)據(jù)。???????
kubectl apply -f consumer.yaml# verify Pod transition to Running state
kubectl get pods -w
KCL 應用程序?qū)⒚織l記錄持久化到目標 DynamoDB 表中(在本例中為 users)。您可以檢查該表以驗證記錄。
aws dynamodb scan --table-name users
注意 processed_by 屬性的值?它與 KCL 消費者 Pod 的名稱相同。這將使我們更容易驗證端到端的自動擴展過程。
創(chuàng)建 Kinesis 的 KEDA Scaler?
以下是 ScaledObject 的定義。請注意,它針對的是 kcl-consumer Deployment(我們剛剛創(chuàng)建的那個),并且 shardCount 設置為 1:???????
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: aws-kinesis-stream-scaledobject
spec:
scaleTargetRef:
name: kcl-consumer
triggers:
- type: aws-kinesis-stream
metadata:
# Required
streamName: kinesis-keda-demo
# Required
awsRegion: "us-east-1"
shardCount: "1"
identityOwner: "operator"
創(chuàng)建 KEDA Kinesis Scaler:
kubectl apply -f keda-kinesis-scaler.yaml
驗證 KCL 應用程序的自動伸縮?
我們從一個 KCL 應用程序的 Pod 開始。但是,多虧了 KEDA,我們現(xiàn)在應該看到第二個 Pod 正在啟動。???????
kubectl get pods -l=app=kcl-consumer -w# check logs of the new pod
kubectl logs -f <enter Pod name>
我們的應用程序能夠根據(jù) ScaledObject 定義中的 shardCount: "1" 自動擴展到兩個 Pod。這意味著 Kinesis 流中的每個 shard 都會有一個 Pod。
在 DynamoDB 中檢查 kinesis-keda-demo 控制表:您應該看到 leaseOwner 的更新。
讓我們向 Kinesis 流發(fā)送更多的數(shù)據(jù)。
export KINESIS_STREAM=kinesis-keda-demoaws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user5@foo.com --data $(echo -n '{"name":"user5", "city":"new york"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user6@foo.com --data $(echo -n '{"name":"user6", "city":"tel aviv"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user7@foo.com --data $(echo -n '{"name":"user7", "city":"new delhi"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user8@foo.com --data $(echo -n '{"name":"user8", "city":"seattle"}' | base64)
驗證 "processed_by" 屬性的值。由于我們已經(jīng)擴展到兩個 Pod,每條記錄的值應該不同,因為每個 Pod 將處理 Kinesis 流的一部分記錄。
增加 Kinesis 流容量?
讓我們將 shard 的數(shù)量從兩個擴展到三個,并繼續(xù)監(jiān)視 KCL 應用程序的自動縮放。
aws kinesis update-shard-count --stream-name kinesis-keda-demo --target-shard-count 3 --scaling-type UNIFORM_SCALING
一旦 Kinesis 重新劃分完成,KEDA 擴展器將開始工作,將 KCL 應用程序擴展到三個 Pod。
kubectl get pods -l=app=kcl-consumer -w
就像之前一樣,確認在 DynamoDB 的 kinesis-keda-demo 控制表中,Kinesis shard 的租約已更新。檢查 leaseOwner 屬性。
繼續(xù)向 Kinesis 流發(fā)送更多數(shù)據(jù)。正如預期的那樣,Pod 將共享記錄處理,并且在 users 表中的 processed_by 屬性中會反映出來。
export KINESIS_STREAM=kinesis-keda-demoaws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user9@foo.com --data $(echo -n '{"name":"user9", "city":"new york"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user10@foo.com --data $(echo -n '{"name":"user10", "city":"tel aviv"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user11@foo.com --data $(echo -n '{"name":"user11", "city":"new delhi"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user12@foo.com --data $(echo -n '{"name":"user12", "city":"seattle"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user14@foo.com --data $(echo -n '{"name":"user14", "city":"tel aviv"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user15@foo.com --data $(echo -n '{"name":"user15", "city":"new delhi"}' | base64)
aws kinesis put-record --stream-name $KINESIS_STREAM --partition-key user16@foo.com --data $(echo -n '{"name":"user16", "city":"seattle"}' | base64)
縮小規(guī)模?
到目前為止,我們只進行了單向的擴展。當我們減少 Kinesis 流的分片容量時會發(fā)生什么?自己嘗試一下:將分片數(shù)量從三個減少到兩個,觀察 KCL 應用的情況。
一旦您驗證了端到端的解決方案,應清理資源,以避免產(chǎn)生額外的費用。
▌刪除資源?
刪除 EKS 集群、Kinesis 流和 DynamoDB 表。???????
eksctl delete cluster --name keda-kinesis-demo
aws kinesis delete-stream --stream-name kinesis-keda-demo
aws dynamodb delete-table --table-name users
▌結(jié)論
在本文中,您學習了如何使用 KEDA 自動擴展從 Kinesis 流中消費數(shù)據(jù)的 KCL 應用程序。
您可以根據(jù)應用程序的要求配置 KEDA 擴展器。例如,您可以將 shardCount 設置為 3,并為 Kinesis 流中的每三個分片設置一個 Pod。但是,如果您希望保持一對一的映射關系,可以將 shardCount 設置為 1,KCL 將負責分布式協(xié)調(diào)和租約分配,確保每個 Pod 具有一個記錄處理器的實例。這是一種有效的方法,可以根據(jù)應用程序的需求擴展 Kinesis 流處理管道,以滿足需求。
作者:Abhishek Gupta
更多技術干貨請關注公號“云原生數(shù)據(jù)庫”
squids.cn,基于公有云基礎資源,提供云上 RDS,云備份,云遷移,SQL 窗口門戶企業(yè)功能,
幫助企業(yè)快速構(gòu)建云上數(shù)據(jù)庫融合生態(tài)。