我可以测量TableBatchOperation的大小吗?

时间:2015-11-09 15:01:52

标签: azure-storage azure-table-storage

TableBatchOperation的.Net SDK文档说明了

  

批处理操作最多可包含100个单独的表操作,并要求每个操作实体必须具有相同的分区键。具有检索操作的批处理不能包含任何其他操作。请注意,批处理操作的总有效负载限制为4MB。

很容易确保我不会向批处理中添加超过100个单独的表操作:在最坏的情况下,我可以检查Count属性。但有没有办法检查有效负载大小,而不是手动序列化操作(此时我已经失去了使用SDK的大部分好处)?

2 个答案:

答案 0 :(得分:3)

添加实体时,您可以跟踪名称和数据的大小。假设您使用的是一个默认值为Json的新库,添加的其他字符应该相对较小(与数据相比,如果您接近4MB)并且可以估算。这不是一条完美的路线,但它会让你接近。

如果你实际上接近100个实体限制或4MB限制经常序列化你将失去很多性能,除了任何便利性丢失。您可以通过估算大小或序列化来尝试跟踪,而不是按原样发送批处理请求,如果您得到413指示请求正文太大,请抓住错误,将批处理分成2,并且继续。

答案 1 :(得分:1)

我遵循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;
        }