在Docker容器中进行并行代码执行

5
我有一个脚本,通过URL列表抓取数据。 这个脚本在docker容器中执行。 我想要运行多个实例,比如20个。 为此,我想使用 docker-compose scale worker=20 并将INDEX传递给每个实例,以便脚本知道应该抓取哪些URL。
ID, URL
0 https://example.org/sdga2
1 https://example.org/fsdh34
2 https://example.org/fs4h35
3 https://example.org/f1h36
4 https://example.org/fs4h37
...

如果有3个实例,第一个脚本实例应该处理ID等于0、3、6、9的url,即ID = INDEX + INSTANCES_NUM * k。

我不知道如何将INDEX传递给在Docker容器中运行的脚本。 当然,我可以在docker-compose.yml中使用不同的环境变量复制服务并设置不同的INDEX。但如果实例数超过10甚至50,这将是一个非常糟糕的解决方案)

有人知道如何做到这一点吗?


1
请包含您的Compose文件。 - BMitch
2个回答

5

使用docker-compose我认为目前不支持此功能。但是,在群集模式下,可以使用类似的编排文件,并且可以使用服务模板{{.Task.Slot}}作为环境变量传递。例如:

version: '3'
services:
  test:
    image: busybox
    command: /bin/sh -c "echo My task number is $$task_id && tail -f /dev/null"
    environment:
      task_id: "{{.Task.Slot}}"
    deploy:
      replicas: 5

与其使用docker-compose up,我使用docker stack deploy -c docker-compose.yml test进行部署。我的本地swarm集群只是通过docker swarm init创建的单一节点。

然后,我会逐个查看这些正在运行的容器:

$ docker ps --filter label=com.docker.swarm.service.name=test_test
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
ccd0dbebbcbe        busybox:latest      "/bin/sh -c 'echo My…"   About a minute ago   Up About a minute                       test_test.3.i3jg6qrg09wjmntq1q17690q4
bfaa22fa3342        busybox:latest      "/bin/sh -c 'echo My…"   About a minute ago   Up About a minute                       test_test.5.iur5kg6o3hn5wpmudmbx3gvy1
a372c0ce39a2        busybox:latest      "/bin/sh -c 'echo My…"   About a minute ago   Up About a minute                       test_test.4.rzmhyjnjk00qfs0ljpfyyjz73
0b47d19224f6        busybox:latest      "/bin/sh -c 'echo My…"   About a minute ago   Up About a minute                       test_test.1.tm97lz6dqmhl80dam6bsuvc8j
c968cb5dbb5f        busybox:latest      "/bin/sh -c 'echo My…"   About a minute ago   Up About a minute                       test_test.2.757e8evknx745120ih5lmhk34

$ docker ps --filter label=com.docker.swarm.service.name=test_test -q | xargs -n 1 docker logs
My task number is 3
My task number is 5
My task number is 4
My task number is 1
My task number is 2

-1
为什么不使用数据库?MySQL或Redis。
每个容器都可以从数据库中获取URL,并将获取的URL标记为已完成,始终从每个容器中获取未完成的URL。这样可以扩展。

看看BMitch的解决方案。 - Daler
我倾向于使用专门的作业队列,例如RabbitMQ,但是同样的想法。 - David Maze
根据代码本身,有很多关于“为什么不”的答案。这是一个相对通用的要求,可以反映到许多不同的问题上。这个建议的主要问题是失败的作业会造成很大的混乱。当你不确定任务是否真的死亡或者只是忙碌时,必须处理启动新任务的情况。另一方面,Docker/Swarm/Kubernetes等工具都知道作业何时完全消失(进程已死),并且可以平稳地处理重新启动逻辑,而不会出现同时运行两个作业的风险。 - Philip Couling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接