【问题标题】:How to throttle S3 & Glacier upload/download speeds with boto?如何使用 boto 限制 S3 和 Glacier 上传/下载速度?
【发布时间】:2018-10-08 13:21:25
【问题描述】:

我正在使用 boto 将文件上传和下载到 S3 和 Glacier。

如何限制/限制上传和下载速度?

【问题讨论】:

    标签: python boto


    【解决方案1】:

    似乎没有直接可用的解决方案

    免责声明:我经常将 boto 用于 S3,并且也有使用 Amazon Glacier 的经验。我还查看了当前版本的 boto 并快速检查了源代码以了解当前知识,但是有一点机会,我可能是错的。

    • S3 和 Amazon Glacier 下载和上传方法都没有提供限制速度的选项。
    • 有 res_download_handler 的概念,它可以处理 S3 对象的下载,但这种处理程序在 boto 中唯一可用的实现是 ResumableDownloadHandler。
    • 对于 Amazon Glacier,有一个问题 Please add ability to throttle upload bandwidth used by the glacier client 已被接受,但仍处于打开状态。

    寻找可能的解决方案

    编写您自己的下载处理程序

    这可能适用于 S3 下载,因为这些方法允许设置此类处理程序。

    您必须自己编写这样的处理程序。

    对于 S3,使用带有“位阻塞”行为的 cb 参数

    上传和下载S3对象的函数提供了一个参数cb,可以定义一个函数在上传/下载一定数量的数据后重复调用。

    理论上,可以创建这样一个可调用对象,它会记录自上次调用以来的时间和数据量,并等待一段时间来限制速度。

    我没有为 Amazon Glacier 找到类似的选项。

    【讨论】:

    • 真可惜。你认为创建一个可以限制连接的代理可能是一个更简单的选择吗?
    • @jbrown 就我个人而言,我不会称之为形状(我真的很高兴,boto 提供了我需要的东西)。关于代理,我会尝试找到一个现有的解决方案,我有编写基于 Python 的代理应用程序的经验,它已经工作,但与 nginx 解决方案相比非常非常慢。
    • 代理可能需要做很多工作。我将看看修改 boto 提供的现有上传器/下载器类。还是谢谢。
    • @jbrown 我会亲自尝试回调函数。在我看来,这是最简单的开始方式。
    • 我将从这个开始。谢谢。
    【解决方案2】:

    最简单的就是使用linux下的流量整形工具,比如tc。这些工具可让您控制带宽,甚至模拟网络丢包甚至长距离通信问题。易于编写 python 脚本以通过 shell 控制端口行为。

    【讨论】:

      【解决方案3】:

      我已经为 s3 boto python 库实现了一个速率限制进度类,如下所示:它假设您的每秒速率高于速率限制,并且似乎大部分都可以正常工作。

      class ProgressPercentage(object):
          def __init__(self, rate_limit=-1):
              self._seen_so_far = 0
              self.rate_limit = rate_limit
              self.bytes_check = 0
              self._lock = threading.Lock()
              self.check_time = datetime.datetime.now()
      
          def __call__(self, bytes_amount):
              with self._lock:
                  self._seen_so_far += bytes_amount
      
                  if self.rate_limit > 0:
                      # assumes one thread
                      self.bytes_check += bytes_amount
                      elapsed_time = datetime.datetime.now() - self.check_time
                      total_seconds = elapsed_time.total_seconds()
                      if self.bytes_check > self.rate_limit:
                          if total_seconds < 1:
                              time.sleep(1.0 - total_seconds)
                          self.bytes_check = 0
                          self.check_time = datetime.datetime.now()
      
                  if sys.stderr.isatty():
                      sys.stderr.write(
                          "\r{0}".format(size_str(self._seen_so_far)))
                      sys.stderr.flush()
      

      如本例所示调用以限制每秒 100k:

      s3_client.upload_file(file_name, bucket_name, key, Callback=ProgressPercentage(100000))
      

      【讨论】:

        猜你喜欢
        • 2012-10-11
        • 1970-01-01
        • 2015-06-09
        • 1970-01-01
        • 1970-01-01
        • 2012-08-31
        • 2011-04-29
        • 2016-04-20
        • 2015-01-27
        相关资源
        最近更新 更多