我们有一些函数几乎会不断地从 blob 存储中读取各种文件,而其他进程会在幕后的其他触发器上更新它们。
我们目前正在使用相当于 put blob 的 C# 版本,它声明它将覆盖现有的 blob:
Put Blob 操作创建新的块、页面或追加 blob,或更新现有块 blob 的内容。 Put Blob 操作将覆盖同名现有 Blob 的所有内容。
更新现有块 blob 时,您会覆盖该 blob 上的任何现有元数据。现有 Blob 的内容将被新 Blob 的内容覆盖。
这正是我们想要的,但是它到底是如何实现的呢?如果它删除现有的 blob,然后创建一个空的“文件”,然后上传新内容,则此处存在并发问题,其中另一个进程将尝试读取现有的 blob,然后看到它丢失,或者看到空/部分上传文件。
我希望任何其他进程都能够读取旧版本,直到新版本准备就绪,然后切换到查看新版本 - 其间停机时间为零。
我考虑过使用租约,但这些工作方式我需要在每次读取时获取租约,而该租约会完全阻止其他读取和写入,因此性能会很糟糕。
我可以使用任何其他机制来获得此功能吗?或者我是否误解了 put blob 在幕后所做的事情?
我可以使用任何其他机制来获得此功能吗?或者我是否误解了 put blob 在幕后所做的事情?
根据此MS-Document,
Put Blob
操作不会删除现有的blob然后创建一个空文件。要实现这些过程,可以读取旧版本的 blob,直到新版本完全上传为止,您可以使用
blob versioning
或 snapshots
的概念。
如果要维护同一 Blob 的多个版本,可以使用 Blob 版本控制。要启用 Blob 版本控制,需要将存储帐户的
IsVersioningEnabled
属性设置为 true
您可以使用以下命令来启用 blob 版本控制。
命令与输出:
venkatesan [ ~ ]$ az storage account blob-service-properties update --resource-group xxxx --account-name xxxx --enable-versioning true
{
"automaticSnapshotPolicyEnabled": null,
"changeFeed": null,
"containerDeleteRetentionPolicy": {
"allowPermanentDelete": null,
"days": null,
"enabled": false
},
"cors": {
"corsRules": [
{
"allowedHeaders": [
"*"
],
"allowedMethods": [
"DELETE",
"GET",
"HEAD",
"MERGE",
"POST",
"OPTIONS",
"PUT",
"PATCH"
],
"allowedOrigins": [
"*"
],
"exposedHeaders": [
"*"
],
"maxAgeInSeconds": xxx
},
{
"allowedHeaders": [
"*"
],
"allowedMethods": [
"GET",
"OPTIONS"
],
"allowedOrigins": [
"xxx"
],
"exposedHeaders": [
"*"
],
"maxAgeInSeconds": 200
}
]
},
"defaultServiceVersion": null,
"deleteRetentionPolicy": {
"allowPermanentDelete": false,
"days": null,
"enabled": false
},
"id": "/subscriptions/xxxxx/resourceGroups/xxxx/providers/Microsoft.Storage/storageAccounts/xx/blobServices/default",
"isVersioningEnabled": true,
"lastAccessTimeTrackingPolicy": {
"blobType": null,
"enable": true,
"name": null,
"trackingGranularityInDays": null
},
"name": "default",
"resourceGroup": "xxxxx",
"restorePolicy": null,
"sku": null,
"type": "Microsoft.Storage/storageAccounts/blobServices"
}
参考: