在.NET SDK文檔中說,我可以測量TableBatchOperation的大小嗎?
批處理操作可以包含多達100個單獨的表操作,與各經營單位必須具有相同的分區鍵的要求。具有檢索操作的批處理不能包含任何其他操作。請注意,批量操作的總有效負載限制爲4MB。
這很容易,以確保我不添加超過100個單獨的表操作的批次:在最壞的情況下,我可以檢查Count
屬性。但是除了手動序列化操作之外,是否有任何方法來檢查有效負載大小(在這一點上,我已經失去了使用SDK的大部分好處)?
在.NET SDK文檔中說,我可以測量TableBatchOperation的大小嗎?
批處理操作可以包含多達100個單獨的表操作,與各經營單位必須具有相同的分區鍵的要求。具有檢索操作的批處理不能包含任何其他操作。請注意,批量操作的總有效負載限制爲4MB。
這很容易,以確保我不添加超過100個單獨的表操作的批次:在最壞的情況下,我可以檢查Count
屬性。但是除了手動序列化操作之外,是否有任何方法來檢查有效負載大小(在這一點上,我已經失去了使用SDK的大部分好處)?
在添加實體時,您可以跟蹤名稱的大小和數據。假設您使用的是默認爲Json的較新庫,則添加的附加字符應該相對較小(與數據相比,如果您接近4MB)並且可以估算。這不是一條完美的路線,但它會讓你接近。
當你走時序列化,特別是如果你實際上接近100個實體的限制或4MB的限制經常會失去你很多的性能,除了丟失的任何便利。您可能最好是按照原樣發送批處理請求,並且如果您得到的413指示請求體太大,最好趕上錯誤,將批處理分成兩部分,然後繼續。
我遵循Emily Gerner的建議,使用樂觀插入和錯誤處理,但使用StorageException.RequestInformation.EgressBytes
來估計符合極限的操作數。除非操作規模變化很大,否則這應該更有效率。每次都有一個案例可以不提高len
,但是這裏有一個每次都會變得樂觀的實現。
int off = 0;
while (off < ops.Count)
{
// Batch size.
int len = Math.Min(100, ops.Count - off);
while (true)
{
var batch = new TableBatchOperation();
for (int i = 0; i < len; i++) batch.Add(ops[off + i]);
try
{
_Tbl.ExecuteBatch(batch);
break;
}
catch (Microsoft.WindowsAzure.Storage.StorageException se)
{
var we = se.InnerException as WebException;
var resp = we != null ? (we.Response as HttpWebResponse) : null;
if (resp != null && resp.StatusCode == HttpStatusCode.RequestEntityTooLarge)
{
// Assume roughly equal sizes, and base updated length on the size of the previous request.
// We assume that no individual operation is too big!
len = len * 4000000/(int)se.RequestInformation.EgressBytes;
}
else throw;
}
}
off += len;
}