c# - Azure Blob 存储读取时间非常慢
问题描述
我将 JSON 数据保存为 Azure Blob 存储 - 标准层中的块 Blob。文件大小为 14.5MB,它包含大约 25,000 个 OLHC 数据对象,我从位于同一区域的 Azure 函数访问 blob。该代码只是读取 blob 进行反序列化,但需要 20-40 秒。有什么我错过的吗?
public static async Task<Stream> GetBlob(string ConnectionString, string ContainerName, string Path)
{
BlobClient blobClient = new BlobClient(ConnectionString, ContainerName, Path);
MemoryStream ms = new MemoryStream();
try
{
await blobClient.DownloadToAsync(ms);
ms.Seek(0, SeekOrigin.Begin);
return ms;
} catch (Exception ex)
{
ms.Dispose();
throw;
}
}
我请求函数中的 blob
log.LogInformation($"Begin Downloading Blob ");
using (Stream blob = await Core.Azure.Blob.GetBlob(blobString, "containerName", fileName))
{
log.LogInformation($"End Downloading Blob ");
log.LogInformation($"Begin Reading Blob ");
using (StreamReader reader = new StreamReader(blob))
{
string json = await reader.ReadToEndAsync();
log.LogInformation($"Begin Deserialize Blob ");
sticks = JsonConvert.DeserializeObject<List<MyModel>>(json);
log.LogInformation($"End Deserialize Blob ");
}
}
log.LogInformation($"{symbol} End Get Blob ");
检查 Blob 是否存在函数
public static async Task<bool> CheckExists(string ConnectionString, string ContainerName, string Path)
{
BlobClient blobClient = new BlobClient(ConnectionString, ContainerName, Path);
return await blobClient.ExistsAsync();
}
这是计时最多 47 秒的结果
我切换到流阅读器和 JSON 阅读器,它下降到 10-30 秒.. 但仍然是很长的时间
我在这里添加了时间
2021-01-09 23:53:26.656 开始下载 Blob
2021-01-09 23:53:30.163 结束下载 Blob
2021-01-09 23:53:30.163 开始读取 Blob
2021-01-09 23:53:37.040 开始反序列化 Blob
2021-01-09 23:53:49.737 结束反序列化 Blob
另一个运行
OHLCData.Json 14.44 MB(28,000 行)
2021-01-10 12:40:49.970 开始检查 Blob 是否存在
2021-01-10 12:40:58.962 结束检查 Blob 是否存在
2021-01-10 12:40:58.962 开始下载 Blob
2021-01-10 12:41: 08.181 结束下载 Blob
2021-01-10 12:41:08.187 开始读取 Blob
2021-01-10 12:41:25.713 开始反序列化 Blob
2021-01-10 12:41:33.817 结束反序列化 Blob
2021-01-10 12: 41:33.817 结束获取 Blob
解决方案
您正在将整个 blob 下载到内存流中(不必要的额外内存终止),转换为字符串然后反序列化它。我宁愿直接从 blob 流中直接使用下面的流支持Newtonsoft.Json
来优化速度和内存使用。
BlobClient blobClient = new BlobClient(ConnectionString, ContainerName, Path);
using (var stream = await blobClient.OpenReadAsync())
using (var sr = new StreamReader(stream))
using (var jr = new JsonTextReader(sr))
{
result = JsonSerializer.CreateDefault().Deserialize<T>(jr);
}
您也可以使用System.Text.Json
API 进行类似操作。
JsonSerializerOptions Options = new JsonSerializerOptions();
using (var stream = await blobClient.OpenReadAsync())
{
result = await JsonSerializer.DeserializeAsync<T>(stream , Options);
}
推荐阅读
- android - 构建失败的 Google io 2018 (iosched)
- docker - 证书在 Docker Nginx 官方镜像中不起作用
- java - 将动态值传递给 Java 注释
- xamarin - 如何持久化 Serilog.Sinks.Xamarin 日志
- codeigniter - 不存在 URI。默认控制器集。Codeigniter 3.1.9 和 PHP 7.0
- python - 无法在 Python 中使用 MySQLdb 连接到 MySQL,可以从命令行连接
- hive - 运行配置单元查询时失败 - 映射运算符初始化失败 - OOM
- html - IIS - 目录时删除尾部斜杠
- javascript - 从“@angular/forms”导入 {FormControl,FormGroup};
- python - 迭代列表中的字符串元素并将该字符串的一部分附加到一个空列表中