在Docker Swarm上部署Apache Storm:第2部分

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文来自 Baqend Tech Blog,描述了如何在 Docker Swarm,而不是在虚拟机上部署和调配Apache Storm集群。文章系国内 ITOM 管理平台 OneAPM 编译呈现。

【编者按】本文来自 Baqend Tech Blog,描述了如何在 Docker Swarm,而不是在虚拟机上部署和调配Apache Storm集群。文章系国内 ITOM 管理平台 OneAPM 编译呈现。

点此查看《在Docker Swarm上部署Apache Storm:第1部分》

创建Swarm集群

如果一切顺利,那么你现在已经有了三台Ubuntu服务器,每个上面都运行了一个Docker守护进程。可以通过私有网络中的zk1.cloud和manager.swarm访问Ubuntu 1,或者也可以从外部通过manager.swarm.baqend.com(至少在8080端口)访问。我们一直在这台机器上折腾,并且,从现在开始,这是我们唯一需要访问的机器。为了保证Swarm节点之间的协调通畅,我们需要配置ZooKeeper ensemble和Swarm管理器。

1.通过SSH连接Ubuntu1,接着快速检查一遍。如果Docker安装正确,运行下列代码可以显示出一个所有运行中的Docker容器的列表(只有针对Swarm的):

docker ps

2.现在我们可以按下面的方法在每台机器上启动一个ZooKeeper节点:

docker -H tcp://zk1.cloud:2375 run -d --restart=always \
      -p 2181:2181 \
      -p 2888:2888 \
      -p 3888:3888 \
      -v /var/lib/zookeeper:/var/lib/zookeeper \
      -v /var/log/zookeeper:/var/log/zookeeper  \
      --name zk1 \
      baqend/zookeeper zk1.cloud,zk2.cloud,zk3.cloud 1
docker -H tcp://zk2.cloud:2375 run -d --restart=always \
      -p 2181:2181 \
      -p 2888:2888 \
      -p 3888:3888 \
      -v /var/lib/zookeeper:/var/lib/zookeeper \
      -v /var/log/zookeeper:/var/log/zookeeper  \
      --name zk2 \
      baqend/zookeeper zk1.cloud,zk2.cloud,zk3.cloud 2
docker -H tcp://zk3.cloud:2375 run -d --restart=always \
      -p 2181:2181 \
      -p 2888:2888 \
      -p 3888:3888 \
      -v /var/lib/zookeeper:/var/lib/zookeeper \
      -v /var/log/zookeeper:/var/log/zookeeper  \
      --name zk3 \
      baqend/zookeeper zk1.cloud,zk2.cloud,zk3.cloud 3

通过明确说明-H……参数,我们可以在不同的主机上启动ZooKeeper容器。-p命令打开ZooKeeper默认需要的那些端口。两个-v命令通过将ZooKeeper使用的文件夹映射到对应的主机文件夹,可以在发生容器错误的情况仍然保持连贯性。以逗号分隔的主机名列表通知ZooKeeper这一集合中有哪些服务器。集合中的每个节点都不例外。唯一的变量就是ZooKeeper的ID(第二个参数),因为它对每个容器都是不一样的。

你可以使用以下命令行来检查ZooKeeper是否一切正常:

docker -H tcp://zk1.cloud:2375 exec -it zk1 bin/zkServer.sh status && \
docker -H tcp://zk2.cloud:2375 exec -it zk2 bin/zkServer.sh status && \
docker -H tcp://zk3.cloud:2375 exec -it zk3 bin/zkServer.sh status

如果你的集群一切正常,每个节点都会汇报它们是主节点还是从节点。

3.现在,开启Swarm管理器:

docker run -d --restart=always \
      --label role=manager \
      -p 2376:2375 \
      swarm manage zk://zk1.cloud,zk2.cloud,zk3.cloud

4.现在Swarm集群正在运行。但是我们必须把这一点告诉Docker客户端。最后你只须保证之后所有的Docker运行语句都指向Swarm管理器的容器(它会负责排程),并且不违反本地Docker守护进程。

cat << EOF | tee -a ~/.bash_profile
    # this node is the master and therefore should be able to talk to the Swarm cluster:
    export DOCKER_HOST=tcp://127.0.0.1:2376
EOF
export DOCKER_HOST=tcp://127.0.0.1:2376

上面这段会立即执行,并且保证下次我们登录机器的时候被再次执行。

健康度检查

现在一切都被启动运行了。键入docker info检查一下manager节点上的集群状态。你会看到3个运行中的worker,类似这样:

Nodes: 3
 docker1: zk1.cloud:2375
  └ Status: Healthy
  └ Containers: 3
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 2.053 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-40-generic, operatingsystem=Ubuntu 14.04.1 LTS, server=manager, storagedriver=devicemapper
  └ Error: (none)
  └ UpdatedAt: 2016-04-03T15:39:59Z
 docker2: zk2.cloud:2375
  └ Status: Healthy
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 2.053 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-40-generic, operatingsystem=Ubuntu 14.04.1 LTS, storagedriver=devicemapper
  └ Error: (none)
  └ UpdatedAt: 2016-04-03T15:39:45Z
 docker3: zk3.cloud:2375
  └ Status: Healthy
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 2.053 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-40-generic, operatingsystem=Ubuntu 14.04.1 LTS, storagedriver=devicemapper
  └ Error: (none)
  └ UpdatedAt: 2016-04-03T15:40:15Z

最重要的是每个节点的Status: Healthy那一行。如果你发现出现了其它的状态,例如Status: Pending,或者有的节点没有显示出来,那么即使其它地方还没有报错,也应该用以下命令试着重启管理容器,

docker restart $(docker ps -a --no-trunc --filter "label=role=manager"

然后再检查一次(这个操作可能会引发一个错误信息;无视它)。

配置Storm集群

现在Swarm已经运行起来了,你将要创建一个覆盖网络来跨越所有的Swarm节点,为单独的Storm组建运转多个容器。尽管Supervisor节点(即Storm workers)散布于Swarm集群中的所有节点,Nimbus和UI会在manager节点上,每台服务器上一个。

1.先创建覆盖网络stormnet:

docker network create --driver overlay stormnet

然后通过Docker来检查stormnet是否存在:

docker network ls

2.现在一个一个地启动Storm组件。每个Storm相关的容器会有一个cluster=storm标记,这样你在后面杀死整个Storm集群时,不会错杀其它容器。

首先,启动UI

docker run \
    -d \    
    --label cluster=storm \    
    --label role=ui \    
    -e constraint:server==manager \    
    -e STORM_ZOOKEEPER_SERVERS=zk1.cloud,zk2.cloud,zk3.cloud \    
    --net stormnet \    
    --restart=always \    
    --name ui \    
    -p 8080:8080 \    
    baqend/storm ui \
      -c nimbus.host=nimbus

接下来是Nimbus:

docker run \
    -d \    
    --label cluster=storm \    
    --label role=nimbus \    
    -e constraint:server==manager \    
    -e STORM_ZOOKEEPER_SERVERS=zk1.cloud,zk2.cloud,zk3.cloud \    
    --net stormnet \    
    --restart=always \    
    --name nimbus \    
    -p 6627:6627 \    
    baqend/storm nimbus \
      -c nimbus.host=nimbus

为了确保这些在manager节点上运行,我们加入一个限制条件:constraint:server==manager。

3.你现在可以访问Storm UI了,就好像它是在manager节点上运行一样:假如你的manager节点有个公开IP并且其端口8080开放,你就可以用链接http://manager.swarm.baqend.com:8080通过浏览器来访问Storm集群。但是目前还没有运行任何supervisor节点。

4.运行以下语句三次,来启动三个supervisor:

docker run \
    -d \    
    --label cluster=storm \    
    --label role=supervisor \    
    -e affinity:role!=supervisor \    
    -e STORM_ZOOKEEPER_SERVERS=zk1.cloud,zk2.cloud,zk3.cloud \    
    --net stormnet \    
    --restart=always \    
    baqend/storm supervisor \
     -c nimbus.host=nimbus \     
     -c supervisor.slots.ports=[6700,6701,6702,6703]

因为我们无所谓具体启动哪里的supervisor节点,这里我们不用加入任何限制条件或容器名。但是,为了防止同一台机器上的有两个supervisor被启动,我们用了一个affinity标记:affinity:role!=supervisor。如果你要用更多的supervior容器,就得添加更多的Swarm worker节点(Ubuntu 4、Ubuntu 5等等)。

5.看一眼Storm UI,确保有三个Supervisor在运行。

(远程)拓扑部署

可以通过与manager主机在同一网络中的任意一台装有Docker守护进程的服务器来部署拓扑网络。在下面的代码中,假设你目前使用的目录中,拓扑fatjar是一个名为topology.jar的文件。

docker -H tcp://127.0.0.1:2375 run \
   -it \   
   --rm \   
   -v $(readlink -m topology.jar):/topology.jar \   
   baqend/storm \
     -c nimbus.host=manager.swarm \     
     jar /topology.jar \
       main.class \
       topologyArgument1 \
       topologyArgument2

注意:这个命令会生出一个Docker容器,部署拓扑,接着删除容器。我们用-H tcp://127.0.0.1:2375参数来确保容器是在你当前使用的机器上启动的。如果让Docker Swarm自己来编排,部署就可能会失败,因为在生成容器的主机上可能找不到必要的拓扑文件。

另外,readlink -m topology.jar会为topology.jar生成一个绝对路径,因为并不支持相对路径。但是你也可以直接提供一个绝对路径。

终止一个拓扑

可以通过与Storm web UI交互从而终止一个拓扑,或者也可以通过下面的方式,假设正在运行的拓扑叫做runningTopology:

docker run \
   -it \   
   --rm \   
   baqend/storm \
     -c nimbus.host=manager.swarm \     
     kill runningTopology

此处并不需要主机参数-H …,因为上述命令是独立的,并不依赖任何文件。

关掉Storm集群

由于每个与Storm相关的容器都有一个cluster=storm标签,你可以用下述语句终止所有的容器:

docker rm -f $(docker ps -a --no-trunc --filter "label=cluster=storm"

不要忘记安全性!

我们在此教程中示范了如何在Docker上用多节点的ZooKeeper集为了高可用性和容错性运行一个分布式Storm集群。为了不让这个教程过分复杂,我们跳过了针对TLS配置Docker Swarm的部分。如果你打算把Docker Swarm用于关键的业务应用中,你必须在这个方面多下些功夫。

Baqend是怎样使用Apache Storm的?

我们利用Storm的能力来提供低延迟的流查询和查询缓存:

连续查询

如果你的APP允许连续查询,Apache Storm能接受你的连续查询和所有你的写入操作,并且将它们相比对:每当写一个对象时,所有注册的连续查询都与之比对。既然Storm一直在跟踪所有查询的结果,它就能发现新的主机或者新的匹配或不匹配的情况,并且在变更刚发生的时候通知你。

查询缓存

对于查询缓存来说,我们用这些通知来主动让缓存失效:Baqend Cloud用一段合理长度的TTL来缓存一个查询结果,一旦发生变更就自动让缓存的查询结果无效。得益于Storm,我们的匹配网络延迟仅为几毫秒,相较以往,数据的获取速度显著提高。

Baqend Cloud将很快发布这两大功能,近期,我们也会在Baqend Tech博客发表更多有关架构的细则和标杆性测试结果。敬请期待!

结束语

本教程是为1.10.3版本的Docker和1.1.3的Swarm所做,并在OpenStack和AWS上测试。本教程及我们的Storm和ZooKeeper Docker镜像文件都在Chicken Dance License v0.2的保护下有效。

你可以在GitHub上复制我们的项目,如有任何改进,也欢迎发起pull请求!

本文转自 OneAPM 官方博客

原文地址:http://highscalability.com/blog/2016/4/25/the-joy-of-deploying-apache-storm-on-docker-swarm.html

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
1月前
|
人工智能 API 数据安全/隐私保护
使用 Docker 一键免费部署 63.8k 的私人 ChatGPT 网页应用
NextChat 是一个可以在 GitHub 上一键免费部署的私人 ChatGPT 网页应用,支持 GPT3、GPT4 和 Gemini Pro 模型。该项目在 GitHub 上获得了 63.8k 的 star 数。部署简单,只需拉取 Docker 镜像并运行容器,设置 API Key 后即可使用。此外,NextChat 还提供了预设角色的面具功能,方便用户快速创建对话。
140 22
使用 Docker 一键免费部署 63.8k 的私人 ChatGPT 网页应用
|
16天前
|
Java 应用服务中间件 Docker
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
22 2
|
22天前
|
Java Linux Docker
什么是 Docker?如何将 Spring Boot 应用程序部署到 Docker?
什么是 Docker?如何将 Spring Boot 应用程序部署到 Docker?
39 3
|
29天前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
|
1月前
|
运维 开发者 Docker
Docker Compose:简化容器化应用的部署与管理
Docker Compose:简化容器化应用的部署与管理
|
1月前
|
Docker 微服务 容器
使用Docker Compose实现微服务架构的快速部署
使用Docker Compose实现微服务架构的快速部署
56 1
|
26天前
|
持续交付 开发者 Docker
掌握Docker容器化技术,加速软件开发与部署
掌握Docker容器化技术,加速软件开发与部署
45 0
|
4天前
|
存储 人工智能 大数据
The Past, Present and Future of Apache Flink
本文整理自阿里云开源大数据负责人王峰(莫问)在 Flink Forward Asia 2024 上海站主论坛开场的分享,今年正值 Flink 开源项目诞生的第 10 周年,借此时机,王峰回顾了 Flink 在过去 10 年的发展历程以及 Flink社区当前最新的技术成果,最后展望下一个十年 Flink 路向何方。
244 33
The Past, Present and Future of Apache Flink
|
2月前
|
SQL Java API
Apache Flink 2.0-preview released
Apache Flink 社区正积极筹备 Flink 2.0 的发布,这是自 Flink 1.0 发布以来的首个重大更新。Flink 2.0 将引入多项激动人心的功能和改进,包括存算分离状态管理、物化表、批作业自适应执行等,同时也包含了一些不兼容的变更。目前提供的预览版旨在让用户提前尝试新功能并收集反馈,但不建议在生产环境中使用。
798 13
Apache Flink 2.0-preview released
|
2月前
|
存储 缓存 算法
分布式锁服务深度解析:以Apache Flink的Checkpointing机制为例
【10月更文挑战第7天】在分布式系统中,多个进程或节点可能需要同时访问和操作共享资源。为了确保数据的一致性和系统的稳定性,我们需要一种机制来协调这些进程或节点的访问,避免并发冲突和竞态条件。分布式锁服务正是为此而生的一种解决方案。它通过在网络环境中实现锁机制,确保同一时间只有一个进程或节点能够访问和操作共享资源。
88 3