首页 > 解决方案 > 尝试将数据处理分布在集群中,然后将其聚合到主服务器中

问题描述

现在我有一个运行 50 个线程来处理数据的 Python 应用程序。它需要一个 xlsx 文件并将处理一个值列表,并将输出一个简单的 csv。

我对自己说,既然这是一个简单的 50 个线程的 Python 应用程序,我该如何创建一个集群来分配更多的数据处理?例如:让每个 Worker 节点处理 master 给它的子集。这听起来很简单,只需将主应用程序对生成的数据集进行切片,然后通过负载平衡将其推送给工作人员。

我如何获得结果?我想获取所有结果(在这种情况下为 out.csv)并将它们返回给主并合并它们以创建 1 master_out.csv

起初我在想一个 Docker swarm,但我知道没有人使用它们,除了一个简单的 docker 容器之外的所有东西都被卸载到了 K8。

现在,我有一个简单的文件结构:

app/
  __init__.py (everything is in this file)
  dataset.xlxs
  out.csv

我正在考虑创建一个 docker 映像,这样我就可以将这个应用程序移动到映像中,更新/升级,如果它还没有安装 python3,然后运行这个应用程序。

我开始深入处理,并意识到可能有一些内置的方法来处理这个问题。创建一个烧瓶应用程序来处理摄取,然后在 master 上创建一个烧瓶应用程序以在完成时接受文件等。但是 master 需要知道所有工作人员等。

所以集群会打开,准备好后会运行所有东西,然后在最后去皮重。由于他们希望集群可能是分布式的,因此我不确定这将如何工作,因为处理具有 IP 地址限制。似乎这在本地集群上不起作用,因为用于引用的机器会在足够多的请求后撞到 cloudflare(或类似)墙,所以我试图想一个 UNIQUE IP 解决方案。

我对架构有一个想法,但我不确定是否应该为此创建一个 dockerfile,然后找出 kube 可以为我处理所有这些的方式。虽然我认为在 kube 配置文件中我们可以放置远程 aws 实例登录凭据,这样它就会启动所有远程服务器。

虽然我一直在用 Swarms 做一些事情,但似乎 kube 才是真正完成工作的地方,因为 swarms 似乎更适合其他事情。

我试图从 kube(或 swarm)的角度思考如何处理这个问题。

鉴于这些信息,这个概念让我想起了更少的负载平衡,因为数据聚合,更像是 Kubeflow,您可以在其中专门为 ML 创建一个 CLOUD,但不是 ML,而是任何分布式处理。

标签: dockerkubernetesdocker-composedocker-swarmkubeflow

解决方案


这个问题中有趣的问题与 Docker 无关;让我们暂时把它放在一边。

您期望您将拥有一堆计算机,它们都在处理这个大数据集的一部分。您已经对问题进行了结构化,以便您可以处理小块输入并产生小块输出。您需要设计的主要问题是:

  1. 如果需要,您将输入保存在哪里,以便任务可以读取它?
  2. 您如何将工作单元传递给工人?如果工人失败了怎么办?
  3. 你如何传达输出?你把它们存放在哪里?它们是否需要与输入的顺序相同?

这里一个有用的工具是工作队列;RabbitMQ是一种流行的开源实现。您可以将其作为单独的服务器运行,工作人员可以连接到它并从队列中读取和写入消息。只要每个人都可以联系到 RabbitMQ 服务器,那么系统中的各个工作人员或其他进程实际上不需要相互了解。

对于某些规模的问题,一种直接的方法是说原始输入和最终输出是单个系统上的单个文件。您将其分解为足够小以适合消息有效负载的部分,并且响应也适合消息有效负载。运行一个进程来读取输入并填充工作队列;运行一些工人,并运行一个进程来读回输出。

Input handler      +------+ --> worker --> +------+
dataset.xlsx  ---> +------+ --> worker --> +------+ --> Output handler
                   +------+ --> worker --> +------+     out.csv
                   +  ... +      ...       + ...  +

如果您使用 Python 作为实现语言,还可以考虑将Celery作为管理它的框架。

要运行它,您需要运行三个单独的进程。

export RABBITMQ_HOST=localhost RABBITMQ_PORT=5672
./input_handler.py dataset.xlsx
./output_handler.py out.csv
./worker.py

您可以运行多个工人;RabbitMQ 将负责确保任务在工作人员之间分配,并且如果工作人员失败则重试任务。没有特别要求所有这些都在同一主机上运行,​​只要它们都可以到达 RabbitMQ 代理即可。

如果您无法在消息中保留输入或输出,则需要某种所有节点都可以访问的共享存储。如果您在云环境中,像 Amazon 的 S3 这样的对象存储服务是一种流行的选择。然后,在输入和输出消息中,您会将相关文件的路径而不是数据放在 S3 中。

Docker 或 Kubernetes 将如何适应这幅画?需要注意的是,这两种技术都没有提供像工作队列这样的东西,并且共享文件系统可能参差不齐。尽管如此,我在上面提到了三个不同的过程,你可以将它们打包成三个 Docker 镜像,然后你可以将它们部署在 Kubernetes 中。我说你不必只运行一个 worker,Kubernetes Deployment 可以让你运行 5、10 或 50 个相同的 worker 副本,并且 RabbitMQ 将负责确保它们都有工作要做。


推荐阅读