Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google PubSub和自动缩放计算引擎实例(Python)_Python_Docker_Google Cloud Platform_Google Compute Engine_Google Cloud Pubsub - Fatal编程技术网

Google PubSub和自动缩放计算引擎实例(Python)

Google PubSub和自动缩放计算引擎实例(Python),python,docker,google-cloud-platform,google-compute-engine,google-cloud-pubsub,Python,Docker,Google Cloud Platform,Google Compute Engine,Google Cloud Pubsub,在我的场景中,我使用PubSub安排任务。这是多达2.000条PubSub消息,比在Google Compute Engine内的Docker容器中运行的Python脚本消耗的还要多。该脚本使用PubSub消息 每条信息的处理时间约为30秒至5分钟。因此,确认截止时间为600秒(10分钟) 因为我正在处理如此多的PubSub消息,所以我支持以以下两种方式之一使用的计算引擎: gcloud compute instance-groups managed create my-worker-group

在我的场景中,我使用PubSub安排任务。这是多达2.000条PubSub消息,比在Google Compute Engine内的Docker容器中运行的Python脚本消耗的还要多。该脚本使用PubSub消息

每条信息的处理时间约为30秒至5分钟。因此,确认截止时间为600秒(10分钟)

因为我正在处理如此多的PubSub消息,所以我支持以以下两种方式之一使用的计算引擎:

gcloud compute instance-groups managed create my-worker-group \
  --zone=europe-west3-a \
  --template=my-worker-template \
  --size=0

gcloud beta compute instance-groups managed set-autoscaling my-worker-group \
  --zone=europe-west3-a \
  --max-num-replicas=50 \
  --min-num-replicas=0 \
  --target-cpu-utilization=0.4

gcloud beta compute instance-groups managed set-autoscaling my-worker-group \
  --zone=europe-west3-a \
  --max-num-replicas=50 \
  --min-num-replicas=0 \
  --update-stackdriver-metric=pubsub.googleapis.com/subscription/num_undelivered_messages \
  --stackdriver-metric-filter="resource.type = pubsub_subscription AND resource.label.subscription_id = my-pubsub-subscription" \
  --stackdriver-metric-single-instance-assignment=10
到目前为止,一切顺利。选项一最多可扩展到8个实例,而第二个选项将启动最大数量的实例。现在我发现有些奇怪的事情发生了,这就是为什么我在这里发帖。也许你能帮我一下

消息重复:似乎每个实例中的PubSub服务(计算引擎中docker容器中的Python脚本)都会读取一批消息(~10),有点像缓冲区,并将它们提供给我的代码。看起来所有同时启动的实例都将读取所有相同的消息(2000中的前10条),并开始处理相同的内容。在我的日志中,我看到大多数消息由不同的机器处理3次。我希望PubSub知道某个订阅者是否缓冲了10条消息,以便另一个订阅者缓冲10条不同的消息,而不是相同的消息

确认截止日期:由于缓冲区的原因,进入缓冲区末尾的消息(比如消息8或9)必须在缓冲区中等待,直到前面的消息(消息1到7)被处理完毕。等待时间加上自身的处理时间之和可能会超过600秒

负载平衡:因为每台机器缓冲了如此多的消息,负载只被几个实例占用,而其他实例则完全空闲。对于使用PubSub stackdriver度量的缩放选项2,会发生这种情况

有人告诉我,我需要使用云SQL或其他方式实现手动同步服务,其中每个实例都指示它正在处理哪个消息,这样其他实例就不会启动相同的同步服务。但我觉得这不可能是真的,因为那样我就不知道PubSub是怎么回事了

更新:我找到了一位来自2015年的《企业集成模式》一书的合著者。事实上,我的观察是错误的,但观察到的副作用是真实的

谷歌云发布/订阅API实际上实现了 发布-订阅渠道和竞争消费者模式。在 云之心酒吧/酒吧是一个经典的发布-订阅频道, 它将发布给它的单个消息传递给多个 订户。这种模式的一个优点是添加订阅者 没有副作用,这是发布-订阅频道的一个原因 有时被认为比点对点更松散耦合 通道,它只向一个订户发送消息。添加 消费者对点对点渠道的竞争导致消费者之间的竞争 因此有很强的副作用

我观察到的副作用是关于每个订阅者(订阅相同订阅的订阅者,点对点==竞争消费者)中的消息缓冲和消息流控制。Python客户端库的当前版本包装了PubSub REST API(和RPC)。如果使用该包装器,则无法控制:

  • 一个VM上启动了多少个容器;如果CPU尚未充分利用,则可能会启动多个容器
  • 一次从订阅中提取多少条消息(缓冲);完全没有控制权
  • 容器内部启动了多少线程来处理拉取的消息;如果该值低于固定值,则流控制(最大消息)无效
我们观察到的副作用是:

  • 一个消费者一次提取大量消息(大约100到1000条),并将它们排入其客户机缓冲区。因此,根据自动缩放规则启动的所有其他VM不会收到任何消息,因为所有消息都在前几个VM的队列中
  • 如果消息运行到确认截止日期,则会将消息重新传递到同一个VM或任何其他VM(或docker容器)。因此,您需要在处理消息时修改确认截止日期。处理开始时,截止日期计数器开始
  • 假设消息的处理是一项长时间运行的任务(例如机器学习),您可以
    • 预先确认消息,但如果没有其他消息等待,这将导致VM被自动缩放规则关闭。该规则不关心CPU利用率是否仍然很高,处理是否尚未完成
    • 处理后确认消息。在这种情况下,您需要在处理该消息时修改该特定消息的确认截止日期。自上次修改以来,不得有一个代码块超过截止日期
  • 尚未研究的可能解决方案:

    • 使用Java客户机库,因为它可以更好地控制消息的提取和使用
    • 使用Python客户端库的底层API调用和类
    • 构建协调竞争消费者的同步存储

      • 我认为有两种主要方法可以解决这个问题

        1) 不要直接推送到工作进程,而是推送到负载平衡器

        2) 让您的工作进程拉取请求,而不是将它们推送到工作进程

        请参阅中“推拉式交付”下的“负载平衡”部分


        Python客户端库有很多配置选项:

        特别是,你想要
        gcloud compute instance-groups managed create my-worker-group \
          --zone=europe-west3-a \
          --template=my-worker-template \
          --size=0
        
        gcloud beta compute instance-groups managed set-autoscaling my-worker-group \
          --zone=europe-west3-a \
          --max-num-replicas=50 \
          --min-num-replicas=0 \
          --target-cpu-utilization=0.4
        
        gcloud beta compute instance-groups managed set-autoscaling my-worker-group \
          --zone=europe-west3-a \
          --max-num-replicas=50 \
          --min-num-replicas=0 \
          --update-stackdriver-metric=pubsub.googleapis.com/subscription/num_undelivered_messages \
          --stackdriver-metric-filter="resource.type = pubsub_subscription AND resource.label.subscription_id = my-pubsub-subscription" \
          --stackdriver-metric-single-instance-assignment=10