![1.png](https://dev-media.amazoncloud.cn/96ec127f249e43039024f78a9be109a0_1.png "1.png")
本文将展示如何使用 Apache SkyWalking 监控 [Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail)。
By **张跃骎**
# 背景
[Apache SkyWalking](https://skywalking.apache.org/?trk=cndc-detail) 是一个开源应用性能管理系统,帮助用户收集和聚合日志、追踪、指标和事件,并在 UI 上显示。从 OAP 9.4.0 开始,SkyWalking 新增了 [Amazon Firehose receiver](https://skywalking.apache.org/docs/main/next/en/setup/backend/aws-firehose-receiver/?trk=cndc-detail),用来接收,计算 CloudWatch metrics 的数据。本文将以 DynamoDB 为例,展示如何使用 SkyWalking 接收并计算 CloudWatch metrics 数据,以监控 Amazon Web Services。
# 什么是 Amazon CloudWatch 与 Amazon Kinesis Data Firehose ?
[Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) 是一个指标存储库, 此工具可从亚马逊云科技中 ( 如 DynamoDB ) 收集原始数据,近实时处理为可读取的指标。同时,我们也可以使用指标流持续地将 CloudWatch 指标流式传输到所选的目标位置,实现近实时传送和低延迟。Skywalking 利用此特性,创建指标流并将其导向 [Amazon Kinesis](https://aws.amazon.com/cn/kinesis/?trk=cndc-detail) Data Firehose 传输流,并由后者进一步传输处理。
[Amazon Kinesis Data Firehose](https://aws.amazon.com/cn/kinesis/data-firehose/?trk=cndc-detail) 是一项提取、转换、加载服务,可以将流式处理数据以可靠方式捕获、转换和提供到数据湖、数据存储和分析服务中。Skywalking 利用此特性,将指标流最终导向 aws-firehose-receiver,交由 OAP 计算并最终展示指标。
整体过程流程图如下:
![2.png](https://dev-media.amazoncloud.cn/acd6138f96034b80a21ff410c47a3c61_2.png "2.png")
**注意**
- 由于 Kinesis Data Firehose 规定,HTTP 端点的 URL 必须使用 HTTPS 协议,且必须使用443端口。同时,此 URL 必须由 Gateway 代理并转发到真正的 aws-firehose-receiver。
- TLS 证书必须由 CA 签发的,自签证书不会被 Kinesis Data Firehose 信任。
# 设置 DynamoDB 监控
接下来以 DynamoDB 为例说明使用 OAP 收集 CloudWatch metrics 前,亚马逊云科技中必要的设置:
1. 进入 [Kinesis 控制台](https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fkinesis%2Fhome%3FhashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_eu-north-1_82fda079b9fbe868&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fkinesis&forceMobileApp=0&code_challenge=QPsRtleGHIp04GuvKuFkTFAri84EfJvaXT0Dz45GvJU&code_challenge_method=SHA-256?trk=cndc-detail),创建数据流, `Source` 选择 `Direct PUT`, `Destination` 选择 `HTTP Endpoint`. 并且设置 `HTTP Endpoint URL` 为 `Gateway 对应 URL`。 其余配置选项可由需要自行配置。
![3.png](https://dev-media.amazoncloud.cn/daf0b9193dc4467dbe0e69ac77d21af4_3.png "3.png")
2. 进入 [CloudWatch 控制台](https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fcloudwatch%2Fhome%3Fstate%3DhashArgs%2523%26isauthcode%3Dtrue&client_id=arn%3Aaws%3Aiam%3A%3A015428540659%3Auser%2Fcloudwatch&forceMobileApp=0&code_challenge=uNHeXBxH15FZ1CBpMKnh-E4LuE3dwJMtLSP1Wgv2bjE&code_challenge_method=SHA-256?trk=cndc-detail),在左侧控制面板中选择 `Metrics-Stream`,点击 Create metric stream。其中,`namespace` 选择 `Amazon/DynamoDB`。同时,根据需要,也可以增加其他命名空间。 `Kinesis Data Firehose` 选择在第一步中创建好的数据流。最后,设置输出格式为 opentelemetry0.7。其余配置选项可由需要自行配置。
![4.png](https://dev-media.amazoncloud.cn/4138041abce94a66840d852e4631e74e_4.png "4.png")
至此,DynamoDB 监控配置的亚马逊云科技方面设置完成。
# Skywalking OAP 指标处理分析
Skywalking 利用 aws-firehose-receiver 接收并解码由 Gateway 转发来的亚马逊云科技指标流,交由 [Opentelemetry-receiver](https://github.com/apache/skywalking/tree/master/oap-server/server-receiver-plugin/otel-receiver-plugin?trk=cndc-detail) 进行处理,转化为 Skywalking metrics。并由 [Meter Analysis Language (MAL)](https://skywalking.apache.org/docs/main/next/en/concepts-and-designs/mal/?trk=cndc-detail) 进行指标的分析与聚合,最终呈现在 UI 上。
其中 MAL 部分以及 UI 部分,Skywalking 支持用户自由定制,从而更多样性的展示指标数据。详情请参考 [MAL doc](https://skywalking.apache.org/docs/main/next/en/concepts-and-designs/mal/?trk=cndc-detail) 以及 [UI doc](https://skywalking.apache.org/docs/main/next/en/ui/readme/?trk=cndc-detail)。
![5.png](https://dev-media.amazoncloud.cn/31b516030a38434e86ef0b2470714596_5.png "5.png")
# 典型指标分析
## 作用域
Skywalking 中,有作用域 (scope) 的概念。通过作用域, 我们可以对指标进行更合理的分类与聚合。在对 DynamoDB 的监控中,使用到了其中两种作用域———Service 和 Endpoint。
Service 表示一组工作负荷,这些工作负荷为传入请求提供相同的行为。常用作服务的集群级别作用域,在亚马逊云科技中,用户的账户更接近集群的概念。所以 Skywalking 将 Amazon account id 作为 key,将亚马逊云科技账户映射为 Service 类型。
同理,Endpoint 表示一种逻辑概念,常用于服务中用于传入请求的路径,例如 HTTP URI 路径或 gRPC 服务类+方法签名,也可以表示数据库中的表结构。所以 SkyWalking 将 DynamoDB 表映射为 Endpoint 类型。
## 指标
| 指标名称 | 含义 |
| ---| --- |
| AccountMaxReads / AccountMaxWrites | 账户可以使用的最大 读取/写入 容量单位数。|
| AccountMaxTableLevelReads / AccountMaxTableLevelWrites | 账户的表或全局二级索引可以使用的最大 读取/写入 容量单位数。 |
| AccountProvisionedReadCapacityUtilization / AccountProvisionedWriteCapacityUtilization | 账户使用的预置 读取/写入 容量单位百分比。 |
| MaxProvisionedTableReadCapacityUtilization / MaxProvisionedTableWriteCapacityUtilization | 账户的最高预调配 读取/写入 表或全局二级索引使用的预调配读取容量单位百分比。 |
以上为一些常用的账户指标(Serivce 作用域)。它们是 DynamoDB 中的各种配置信息,SkyWalking 通过对这些指标的监控,可以完整的展示出数据库配置的变动情况。
| 指标名称 | 含义 |
| --- | --- |
| ConsumedReadCapacityUnits / ConsumedWriteCapacityUnits | 指定时间段内占用的 读取/写入 容量单位数 |
| ReturnedItemCount | `Query`、`Scan` 或 `ExecuteStatement`(可选择)操作在指定时段内返回的项目数。 |
| SuccessfulRequestLatency | 指定时间段内对于 DynamoDB 或 [Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail) Streams 的成功请求的延迟。 |
| TimeToLiveDeletedItemCount | 指定时间段内按存活时间 (TTL) 删除的项目数。 |
以上为一些常用的表指标 (Endpoint 作用域),它们也会被聚合到账户指标中。这些指标一般用于分析数据库的性能,用户可以通过它们判断出数据库配置的合理程度。例如,用户可以通过 ConsumedReadCapicityUnits / ConsumedReadCapicityUnits,跟踪预置吞吐量的使用,从而判断表或账户的预制吞吐量的合理性。关于预置吞吐量,请参见[读/写容量模式](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html?trk=cndc-detail)。
| 指标名称 | 含义 |
| --- | --- |
| UserErrors | 在指定时间段内生成 HTTP 400 状态代码的对 DynamoDB 或 [Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail) Streams 的请求。HTTP 400 通常表示客户端错误,如参数组合无效,尝试更新不存在的表或请求签名错误。 |
| SystemErrors | 在指定的时间段内生成 HTTP 500 状态代码的对 DynamoDB 或 [Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail) Streams 的请求。HTTP 500 通常指示内部服务错误。|
| ThrottledRequests | 超出资源(如表或索引)预置吞吐量限制的 DynamoDB 请求。 |
| TransactionConflict | 由于同一项目的并发请求之间的事务性冲突而被拒绝的项目级请求。 |
以上为一些常用的错误指标,其中 UserErrors 为用户级别指标,其余为表级别指标。用户可以在这些指标上设置告警,如果警告出现,那么可能说明数据库的使用出现了一些问题,需要用户自行查看验证。
## 注意
Skywalking 对于 DynamoDB 的指标选取直接来源于 CloudWatch metrics, 您也可以通过 [CloudWatch metrics doc](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/metrics-dimensions.html?trk=cndc-detail) 来获取指标详细信息。
# Demo
在本节中,我们将演示如何利用 terraform 创建一个 DynamoDB 表,以及可以产生指标流的其他亚马逊云科技服务,并部署 Skywalking 完成指标收集。
首先,您需要一个正在运行的网关实例,例如 [NGINX](https://www.nginx.com/?trk=cndc-detail),它负责接收亚马逊云科技传来的指标流并且转发到 aws-firehose-receiver。注意,网关需要配置证书以便接受 HTTPS 协议的请求。
下面是一个 NGINX 的示例配置。配置不要求完全一致,只要能将收到的 HTTPS 请求发送到 `oap 所在 host:12801/aws/firehose/metrics` 即可。
```js
server {
listen 443 ssl;
ssl_certificate /crt/test.pem;
ssl_certificate_key /crt/test.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location /aws/firehose/metrics {
proxy_pass http://test.xyz:12801/aws/firehose/metrics;
}
}
```
## 部署 Skywalking
Skywalking 的部署方式有很多种,您可以直接从 [release 页面](https://github.com/apache/skywalking/releases/tag/v9.4.0?trk=cndc-detail)中直接获取。
当然,如果您更习惯于 Kubernetes,您也可以从 [Skywalking-kubernetes](https://github.com/apache/skywalking-kubernetes?trk=cndc-detail) 找到相应部署方式。
请注意,无论使用哪种部署方式,请确保 OAP 和 UI 的版本为9.4.0以上,并且需要开放12801端口。
下面是一个使用 helm 指令部署的示例:
```js
export SKYWALKING_RELEASE_VERSION=4.3.0
export SKYWALKING_RELEASE_NAME=skywalking
export SKYWALKING_RELEASE_NAMESPACE=default
helm install "\${SKYWALKING_RELEASE_NAME}" \\
oci://registry-1.docker.io/apache/skywalking-helm \\
--version "\${SKYWALKING_RELEASE_VERSION}" \\
-n "\${SKYWALKING_RELEASE_NAMESPACE}" \\
--set oap.image.tag=9.4.0 \\
--set oap.storageType=elasticsearch \\
--set ui.image.tag=9.4.0 \\
--set oap.ports.firehose=12801
```
## 开启对应亚马逊云科技服务
terraform 配置文件如下(实例修改于[Terraform Registry - kinesis_firehose_delivery_stream](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kinesis_firehose_delivery_stream?trk=cndc-detail)):
**terraform 配置文件**
```js
provider "aws" {
region = "ap-northeast-1"
access_key = "在这里填入您的access_key"
secret_key = "在这里填入您的secret_key"
}
resource "aws_dynamodb_table" "basic-dynamodb-table" {
name = "GameScores"
billing_mode = "PROVISIONED"
read_capacity = 20
write_capacity = 20
hash_key = "UserId"
range_key = "GameTitle"
attribute {
name = "UserId"
type = "S"
}
attribute {
name = "GameTitle"
type = "S"
}
attribute {
name = "TopScore"
type = "N"
}
ttl {
attribute_name = "TimeToExist"
enabled = true
}
global_secondary_index {
name = "GameTitleIndex"
hash_key = "GameTitle"
range_key = "TopScore"
write_capacity = 10
read_capacity = 10
projection_type = "INCLUDE"
non_key_attributes = ["UserId"]
}
tags = {
Name = "dynamodb-table-1"
Environment = "production"
}
}
resource "aws_cloudwatch_metric_stream" "main" {
name = "my-metric-stream"
role_arn = aws_iam_role.metric_stream_to_firehose.arn
firehose_arn = aws_kinesis_firehose_delivery_stream.http_stream.arn
output_format = "opentelemetry0.7"
include_filter {
namespace = "AWS/DynamoDB"
}
}
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-metric-streams-trustpolicy.html
data "aws_iam_policy_document" "streams_assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["streams.metrics.cloudwatch.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role" "metric_stream_to_firehose" {
name = "metric_stream_to_firehose_role"
assume_role_policy = data.aws_iam_policy_document.streams_assume_role.json
}
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-metric-streams-trustpolicy.html
data "aws_iam_policy_document" "metric_stream_to_firehose" {
statement {
effect = "Allow"
actions = [
"firehose:PutRecord",
"firehose:PutRecordBatch",
]
resources = [aws_kinesis_firehose_delivery_stream.http_stream.arn]
}
}
resource "aws_iam_role_policy" "metric_stream_to_firehose" {
name = "default"
role = aws_iam_role.metric_stream_to_firehose.id
policy = data.aws_iam_policy_document.metric_stream_to_firehose.json
}
resource "aws_s3_bucket" "bucket" {
bucket = "metric-stream-test-bucket"
}
resource "aws_s3_bucket_acl" "bucket_acl" {
bucket = aws_s3_bucket.bucket.id
acl = "private"
}
data "aws_iam_policy_document" "firehose_assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["firehose.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role" "firehose_to_s3" {
assume_role_policy = data.aws_iam_policy_document.firehose_assume_role.json
}
data "aws_iam_policy_document" "firehose_to_s3" {
statement {
effect = "Allow"
actions = [
"s3:AbortMultipartUpload",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:PutObject",
]
resources = [
aws_s3_bucket.bucket.arn,
"\${aws_s3_bucket.bucket.arn}/*",
]
}
}
resource "aws_iam_role_policy" "firehose_to_s3" {
name = "default"
role = aws_iam_role.firehose_to_s3.id
policy = data.aws_iam_policy_document.firehose_to_s3.json
}
resource "aws_kinesis_firehose_delivery_stream" "http_stream" {
name = "metric-stream-test-stream"
destination = "http_endpoint"
http_endpoint_configuration {
name = "test_http_endpoint"
url = "这里填入Gateway的url"
role_arn = aws_iam_role.firehose_to_s3.arn
}
s3_configuration {
role_arn = aws_iam_role.firehose_to_s3.arn
bucket_arn = aws_s3_bucket.bucket.arn
}
}
```
使用步骤:
1.获取亚马逊云科技账户的 access_key 以及 secret_key。( 关于如何获取,请参考:[create-access-key](https://aws.amazon.com/cn/premiumsupport/knowledge-center/create-access-key/?trk=cndc-detail) )
2.将上一步中获取的 access_key 与 secret_key 填入对应位置,并将您的网关对应 url 填入 `aws_kinesis_firehose_delivery_stream` 配置的对应位置中。
3.复制以上内容并保存到 main.tf 文件中。
4.在对应路径下执行以下代码。
```js
terraform init
terraform apply
```
至此,需要的亚马逊云科技服务已全部建立成功,您可以检查您的控制台,查看服务是否成功创建。
## 完成!
如果以上步骤全部成功,请耐心等待约五分钟。之后您可以访问 Skywalking UI,查看指标变动情况。
目前,Skywalking 默认收集的指标展示如下:
**账户指标**:
![6.png](https://dev-media.amazoncloud.cn/692b68a054d143d4a67c39a7caa98dfc_6.png "6.png")
**表指标**:
![7.png](https://dev-media.amazoncloud.cn/f67b1dc6ff6f48d485b469d1f5dd1bbf_7.png "7.png")
### 现已支持的服务
目前 SkyWalking 官方支持 EKS,S3,DynamoDB 监控。 用户也参考 [OpenTelemetry receiver](https://skywalking.apache.org/docs/main/next/en/setup/backend/opentelemetry-receiver/?trk=cndc-detail) 配置 OTEL rules 来收集,计算亚马逊云科技其他服务的 CloudWatch metrics,并且通过[自定义 dashboard](https://skywalking.apache.org/docs/main/next/en/ui/readme/?trk=cndc-detail) 展示。
### 相关的资料
- [Monitoring S3 metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cloudwatch-monitoring.html?trk=cndc-detail)
- [Monitoring DynamoDB metrics with Amazon CloudWatch](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/monitoring-cloudwatch.html?trk=cndc-detail)
- [Supported metrics in Amazon Firehose receiver of OAP](https://skywalking.apache.org/docs/main/next/en/setup/backend/aws-firehose-receiver/?trk=cndc-detail)
- [Configuration Vocabulary | Apache SkyWalking](https://skywalking.apache.org/docs/main/next/en/setup/backend/configuration-vocabulary/?trk=cndc-detail)
文章审核:亚马逊云科技 Container Hero **吴晟**