我们最近为我们的一个用例完成了与 AWS SageMaker 和 FeatureStore 的集成。在 Cloudwatch 上,我们可以看到
p99: 50-60ms(Overhead + Model)
代表 sagemaker,p99: 15-20ms
代表特征存储。
但是我们在使用 JAVA AWS sdk 2.0 调用特征存储时观察到高延迟,有点左右。
p99: 180ms
用于 sagemaker,p99: 100ms
用于特征存储。
我们在 EKS 上运行容器化的 spring-boot 应用程序,这里我们调用 FS 和 SM。
示例代码:-
功能商店调用
private static SageMakerFeatureStoreRuntimeClient featureStoreRuntimeClient;
@PostConstruct
public void init() {
ClientOverrideConfiguration clientOverrideConfiguration = ClientOverrideConfiguration.builder()
.apiCallTimeout(Duration.of(featureStoreConfig.getApiCallAttemptTimeout(), ChronoUnit.MILLIS))
.retryPolicy(RetryPolicy.builder().numRetries(0).build())
.build();
featureStoreRuntimeClient = SageMakerFeatureStoreRuntimeClient.builder()
.overrideConfiguration(clientOverrideConfiguration)
.credentialsProvider(DefaultCredentialsProvider.create())
.region(Region.AP_SOUTHEAST_1).build();
}
贤者召唤:
private static SageMakerRuntimeClient sageMakerRuntimeClient;
@PostConstruct
public void init() {
ClientOverrideConfiguration clientOverrideConfiguration = ClientOverrideConfiguration.builder()
.apiCallTimeout(Duration.of(sageMakerConfig.getApiCallAttemptTimeout(), ChronoUnit.MILLIS))
.retryPolicy(RetryPolicy.builder().numRetries(0).build())
.build();
sageMakerRuntimeClient = SageMakerRuntimeClient.builder()
.overrideConfiguration(clientOverrideConfiguration)
.credentialsProvider(DefaultCredentialsProvider.create())
.region(Region.AP_SOUTHEAST_1)
.build();
}
将 AWS java-sdk2 用于 SageMaker 和功能存储。
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sagemakerruntime</artifactId>
<version>2.20.26</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sagemakerfeaturestoreruntime</artifactId>
<version>2.20.26</version>
</dependency>
什么可能导致如此高的延迟?
看了很多资料后,我发现延迟较高的罪魁祸首是
DefaultCredentialsProvider
。
许多 AWS 客户在使用 Java SDK 2.0 时都面临着更高延迟的问题。
根据 DefaultCredentialsProvider 上的 AWS Java SDK 文档:
在此查找凭证的 AWS 凭证提供商链 订单:
Java 系统属性 - aws.accessKeyId 和 aws.secretAccessKey
环境变量 - AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY
来自系统属性或环境变量的Web身份令牌凭据。
所有 AWS 开发工具包和 AWS CLI 共享的默认位置 (~/.aws/credentials) 中的凭证配置文件文件。
如果设置了“AWS_CONTAINER_CREDENTIALS_RELATIVE_URI”环境变量,则通过 Amazon EC2 容器服务传递凭证 并且安全管理员有权访问该变量,
通过 Amazon EC2 元数据服务传递的实例配置文件凭证
简单来说,
DefaultCredentialsProvider
在幕后做了大量工作来寻找各地的凭证。这会消耗大量时间,因此会导致更高的延迟。
根据此AWS SDK 2.0调优博客:
他们建议使用
EnvironmentVariableCredentialProvider
代替。
根据 AWS 团队的说法,
EnvironmentVariableCredentialProvider
从环境变量中加载凭证,从而减少了查找所花费的时间。
EnvironmentVariableCredentialProvider 上的 Java 文档:
EnvironmentVariableCredentialProvider 实现提供 通过查看以下凭据:AWS_ACCESS_KEY_ID(或AWS_ACCESS_KEY) 和 AWS_SECRET_KEY(或 AWS_SECRET_ACCESS_KEY)环境变量。 如果还设置了 AWS_SESSION_TOKEN 环境变量,则 将使用临时凭证。
确保您已设置这些环境变量。
更新特征存储调用:
private static SageMakerFeatureStoreRuntimeClient featureStoreRuntimeClient;
@PostConstruct
public void init() {
ClientOverrideConfiguration clientOverrideConfiguration = ClientOverrideConfiguration.builder()
.apiCallTimeout(Duration.of(featureStoreConfig.getApiCallAttemptTimeout(), ChronoUnit.MILLIS))
.retryPolicy(RetryPolicy.builder().numRetries(0).build())
.build();
featureStoreRuntimeClient = SageMakerFeatureStoreRuntimeClient.builder()
.overrideConfiguration(clientOverrideConfiguration)
.credentialsProvider(EnvironmentVariableCredentialProvider.create())
.region(Region.AP_SOUTHEAST_1).build();
}
将 SageMaker 调用更新为:
private static SageMakerRuntimeClient sageMakerRuntimeClient;
@PostConstruct
public void init() {
ClientOverrideConfiguration clientOverrideConfiguration = ClientOverrideConfiguration.builder()
.apiCallTimeout(Duration.of(sageMakerConfig.getApiCallAttemptTimeout(), ChronoUnit.MILLIS))
.retryPolicy(RetryPolicy.builder().numRetries(0).build())
.build();
sageMakerRuntimeClient = SageMakerRuntimeClient.builder()
.overrideConfiguration(clientOverrideConfiguration)
.credentialsProvider(EnvironmentVariableCredentialProvider.create())
.region(Region.AP_SOUTHEAST_1)
.build();
}
看看这是否有助于减少延迟。