SDK 现在是我们几个系统的瓶颈,dotnet 生态系统越来越快,越来越充实这个问题。
我们正在编写一些客户端的自定义实现,因为 SDK 的性能对于我们的某些工作负载来说是不可接受的,这大大增加了使用 AWS 服务的成本。
我建议将性能测试包含在您的开发管道中。
以下是 S3 客户端的示例跟踪,作为 SDK 中存在的问题的示例:
您可以看到发送此 get 请求所花费的 CPU 时间的 20% 位于:
public static bool IsAmazonS3Endpoint(Uri uri)
{
Match match = !(uri == (Uri) null) ? new Regex("^(.+\\.)?s3[.-]([a-z0-9-]+)\\.").Match(uri.Host) : throw new ArgumentNullException(nameof (uri));
return (uri.Host.EndsWith("amazonaws.com", StringComparison.OrdinalIgnoreCase) || uri.Host.EndsWith("amazonaws.com.cn", StringComparison.OrdinalIgnoreCase)) && match.Success;
}
每个请求都运行此代码。
考虑到这一点,有几件事可以尝试:
AmazonS3Uri
中创建Regex
作为常量字段RegexOptions.Compilex
或Regex.CompileToAssembly
(最佳实践)MethodImplOptions.AggressiveInlining
装饰IsAmazonS3Endpoint
#$再往上看AmazonS3KmsHandler.EvaluateIfSigV4Required
,看起来我们解析了request
两次? 我们首先检查AmazonS3Uri.IsAmazonS3Endpoint(request)
然后调用new AmazonS3Uri(request)
重复正则表达式匹配。
我们也许可以返工AmazonS3KmsHandler.EvaluateIfSigV4Required
以减少重复匹配?
public class AmazonS3KmsHandler
{
// try and reduce duplicate input checking
internal static void EvaluateIfSigV4Required(IRequest request)
{
// Skip this for S3-compatible storage provider endpoints
if (request.OriginalRequest is S3.Model.GetObjectRequest &&
AmazonS3Uri.TryParseAmazonS3Uri(request.Endpoint, out var amazonS3Uri)) &&
amazonS3Uri.Region != RegionEndpoint.USEast1)
{
request.UseSigV4 = true;
}
}
}
不过,看看AmazonS3Uri.TryParseAmazonS3Uri
,这最终也会运行两次正则表达式检查; 但这感觉像是解决这个问题的更好地方。
我们遇到了类似的问题,并发现使用预签名的 url 可以缓解很多问题,以防万一有助于@Rodrigo-Andrade
问候,
印地
AWSSDK.S3 3.5.1.9
中提供了性能改进
最有用的评论
AWSSDK.S3 3.5.1.9
中提供了性能改进