限制 azure blob 上传速度的方法

Way to limit azure blob upload speed

我有一个应用程序可以将数据库备份上传到 Azure 上的 blob 容器。

我上传的文件大小约为 8GB,平均速率为 11Mbps

一切正常,但是,当 blob 被传输到容器时,它绝对会杀死该网络上的所有其他东西。

所以我的问题是,有没有办法限制上传速度到 azure?

Azure 存储本身不会提供特定的限制设置。但是:鉴于 blob 上传本质上是一系列基于 REST 的块 blob PUT 操作,您可以通过执行自己的上传实现并选择将块上传到给定 blob 的频率来进行自己的节流。

在网络接口上设置最大上传带宽可能是更好的方法。这对您的客户端应用程序是完全透明的,也是一个很好的设计目标。您在另一个 QoS 网络中的软件将在没有自定义限制的情况下运行。

这个SO question is about limiting network speed and lists some tools for this purpose. If the machine running database backups is using Windows try something like BWMeter要限制网速。

更好的策略是配置网络,使 Internet 网关(WAN/DSL 路由器)进行流量整形。这取决于产品是否足够好用。

这两种方法的长期成本应该低于在您的应用程序中实施自定义节流的替代方法。

您的问题没有具体说明您希望使用哪种编程语言(或原始 REST)来实现上传速度限制。但我找到了一种使用官方 azure 存储 .NET SDK (Microsoft.WindowsAzure.Storage) 的方法。

SDK 本身不提供明确的速度限制。然而,Upload*Async() 函数,例如 UploadFromFileAsync() 确实支持进度报告,通过采用 IProgress<StorageProgress> 实现,并定期调用其 Report() 方法。 而且似乎是同步调用的。

所以我们可以在 Report() 中设置延迟以限制上传速度。更好的是 Report 为您提供了 BytesTransferred 的信息。因此,如果您的进度处理程序跟踪持续时间。然后你可以估计当前的上传速度,并用它来精确地节流。

下面是这个想法的一个例子。请注意,这只是该想法的演示。我不到 3 分钟就把它放在一起了。速率估计和节流算法非常粗糙且未经过充分测试。

下面是您将如何使用它

await blob.UploadFromFileAsync(
    @"some_file.dat", 
    null, null, null, 
    new RateThrottleProgress(300 * 1024), // throttle at 300kb/s
    CancellationToken.None);

指数back-off节流器实现

class RateThrottleProgress : IProgress<StorageProgress>
{
    private readonly DateTime start = DateTime.Now;
    private readonly long maxbps;
    private long baseDelay, delay;

    public RateThrottleProgress(long maxbps)
    {
        this.maxbps = maxbps;
        baseDelay = 10;
        delay = baseDelay;
    }

    public void Report(StorageProgress value)
    {
        double duration = (DateTime.Now - start).TotalSeconds;
        double bps = value.BytesTransferred / duration;
        if (bps > maxbps) delay *= 2;
        else delay = Math.Max(baseDelay, delay/2);
        Console.WriteLine($"current estimated upload speed: {bps / 1024.0} KB/s. delay: {delay} ms");
        Thread.Sleep(TimeSpan.FromMilliseconds(delay));
    }
}

我还 put below code snippet as a gist 以获得更好的版本控制和协作。

油门有效:

current estimated upload speed: 287.486007463505 KB/s. delay: 10 ms
current estimated upload speed: 290.086402388889 KB/s. delay: 10 ms
current estimated upload speed: 292.685419108659 KB/s. delay: 10 ms
current estimated upload speed: 295.28201245662 KB/s. delay: 10 ms
current estimated upload speed: 297.876060423937 KB/s. delay: 10 ms
current estimated upload speed: 300.469027029562 KB/s. delay: 20 ms
current estimated upload speed: 302.927815243916 KB/s. delay: 40 ms
current estimated upload speed: 305.112558483135 KB/s. delay: 80 ms
current estimated upload speed: 306.778888691779 KB/s. delay: 160 ms
current estimated upload speed: 307.367196107083 KB/s. delay: 320 ms   <-- speed starts to drop from here...
current estimated upload speed: 305.910611140488 KB/s. delay: 640 ms
current estimated upload speed: 300.564767027164 KB/s. delay: 1280 ms
current estimated upload speed: 288.206861583389 KB/s. delay: 640 ms
current estimated upload speed: 283.672713628354 KB/s. delay: 320 ms
current estimated upload speed: 282.668039190231 KB/s. delay: 160 ms
current estimated upload speed: 283.351226090087 KB/s. delay: 80 ms
current estimated upload speed: 284.861107569046 KB/s. delay: 40 ms
current estimated upload speed: 286.781960850501 KB/s. delay: 20 ms
current estimated upload speed: 288.910675693183 KB/s. delay: 10 ms
current estimated upload speed: 291.140146046991 KB/s. delay: 10 ms
current estimated upload speed: 293.358817316007 KB/s. delay: 10 ms