跨入流式计算时代,用不着洪荒之力——在阿里云容器服务上一键部署JStorm

JStorm是阿里巴巴出品的强大的企业级流式计算引擎,跟Apache Strom相比,具有使用方便、性能高、生态丰富等优点,是搭建流式计算平台的优秀选择。更多关于JStorm的介绍,请参考官方网站http://www.jstorm.io/

但是,部署JStorm依赖于zookeeper、python、JDK等若干个组件,同时还要配置nimbus、supervisor等角色,部署过程比较长。为了简化这一过程,阿里巴巴JStorm团队和容器服务团队合作推出了Docker版的JStorm,可以实现一键部署

创建集群

首先我们需要创建一个集群用来部署JStorm。阿里云容器服务提供集成界面,可以很方便地创建出一个集群来,流程请参考这个帮助文档。需要注意的是,我们需要至少3台机器。

部署zookeeper

为了达到高可用,我们需要部署3个zookeeper节点。传统的方式部署zookeeper时,需要把所有节点的IP作为配置文件;一旦迁移,需要修改配置并重启所有节点。阿里云容器服务提供类似DNS的容器名解析服务,可以把容器名作为配置项,这样迁移时就不需要修改配置了。其编排模板如下:

zk1:
    image: 'mesoscloud/zookeeper:3.4.8-ubuntu'
    environment:
        - MYID=1
        - SERVERS=jstorm_zk1_1,jstorm_zk2_1,jstorm_zk3_1
        - constraint:aliyun.node_index==1
    restart: 'always'
zk2:
    image: 'mesoscloud/zookeeper:3.4.8-ubuntu'
    environment:
        - MYID=2
        - SERVERS=jstorm_zk1_1,jstorm_zk2_1,jstorm_zk3_1
        - constraint:aliyun.node_index==2
    restart: 'always'
zk3:
    image: 'mesoscloud/zookeeper:3.4.8-ubuntu'
    environment:
        - MYID=3
        - SERVERS=jstorm_zk1_1,jstorm_zk2_1,jstorm_zk3_1
        - constraint:aliyun.node_index==3
    restart: 'always'

其中jstorm_zk1_1、jstorm_zk2_1、jstorm_zk3_1就是容器名,其规则是<应用名>_<服务名>_<容器编号>,所以只要确定了应用名和服务名,容器名就是固定的,可以用来做配置项;而且容器名在容器网络内是可以跨主机解析的。

另外,为了使zookeeper节点分布在不同机器上,我们使用了节点约束constraint:aliyun.node_index==n,n是指集群中节点的序号,这样该容器只会部署在n号节点上。

部署JStorm

阿里巴巴JStorm团队提供了JStorm的Docker镜像https://dev.aliyun.com/detail.html?srepoId=9448,并且会定期更新最新版本。

JStorm有两个角色,Nimbus和Supervisor。从高可用角度考虑,Nimbus需要部署两个,Supervisor可以根据需要配置数量。

同样的,为了让Nimbus分布在不同的机器上,可以指定应用约束affinity:service!=nimbus,这样nimbus服务的容器只会部署在没有其他nimbus容器的机器上。

另外,supervisor依赖的nimbus地址,也是用容器名来代替的。

JStorm还提供WebUI,默认在8080端口提供服务。阿里云容器服务提供一个简单的方式将Web服务暴露到外网,只需要配置标签aliyun.routing.port_8080: 'http://nimbus'。该标签的含义是,将nimbus子域名映射到容器的8080端口。更详细的介绍请参考这篇帮助文档

其编排模板如下:

nimbus:
    image: 'registry.cn-hangzhou.aliyuncs.com/jstorm-docker/jstorm'
    environment:
        - CHARACTER=nimbus
        - ZK_ROOT=/jstorm.docker.root2
        - ZK_HOSTS=jstorm_zk1_1,jstorm_zk2_1,jstorm_zk3_1
        - CLUSTER_NAME=jstorm.docker.cluster
    labels:
        aliyun.routing.port_8080: 'http://nimbus'
        aliyun.scale: '2'
    restart: 'always'
supervisor:
    image: 'registry.cn-hangzhou.aliyuncs.com/jstorm-docker/jstorm'
    environment:
        - CHARACTER=supervisor
        - NIMBUS_HOSTS=jstorm_nimbus_1
        - ZK_ROOT=/jstorm.docker.root2
        - ZK_HOSTS=jstorm_zk1_1,jstorm_zk2_1,jstorm_zk3_1
        - CLUSTER_NAME=jstorm.docker.cluster
    labels:
        aliyun.routing.port_8080: 'http://supervisor'
        aliyun.scale: '3'
    restart: 'always'
    links:
        - nimbus

一键部署

我们可以把zookeeper和JStorm放在一个编排文件里,实现一键部署。

在这个编排文件中,我们使用了COMPOSE_PROJECT_NAME这个环境变量。COMPOSE_PROJECT_NAME是默认设置的环境变量,其值为当前应用的名称。

zk1:
    image: 'mesoscloud/zookeeper:3.4.8-ubuntu'
    environment:
        - MYID=1
        - SERVERS=${COMPOSE_PROJECT_NAME}_zk1_1,${COMPOSE_PROJECT_NAME}_zk2_1,${COMPOSE_PROJECT_NAME}_zk3_1
        - constraint:aliyun.node_index==1
    restart: 'always'
zk2:
    image: 'mesoscloud/zookeeper:3.4.8-ubuntu'
    environment:
        - MYID=2
        - SERVERS=${COMPOSE_PROJECT_NAME}_zk1_1,${COMPOSE_PROJECT_NAME}_zk2_1,${COMPOSE_PROJECT_NAME}_zk3_1
        - constraint:aliyun.node_index==2
    restart: 'always'
zk3:
    image: 'mesoscloud/zookeeper:3.4.8-ubuntu'
    environment:
        - MYID=3
        - SERVERS=${COMPOSE_PROJECT_NAME}_zk1_1,${COMPOSE_PROJECT_NAME}_zk2_1,${COMPOSE_PROJECT_NAME}_zk3_1
        - constraint:aliyun.node_index==3
    restart: 'always'
nimbus:
    image: 'registry.cn-hangzhou.aliyuncs.com/jstorm-docker/jstorm'
    environment:
        - CHARACTER=nimbus
        - ZK_ROOT=/jstorm.docker.root2
        - ZK_HOSTS=${COMPOSE_PROJECT_NAME}_zk1_1,${COMPOSE_PROJECT_NAME}_zk2_1,${COMPOSE_PROJECT_NAME}_zk3_1
        - CLUSTER_NAME=jstorm.docker.cluster
    labels:
        aliyun.routing.port_8080: 'http://nimbus'
        aliyun.scale: '2'
    restart: 'always'
    links:
        - zk1
        - zk2
        - zk3
supervisor:
    image: 'registry.cn-hangzhou.aliyuncs.com/jstorm-docker/jstorm'
    environment:
        - CHARACTER=supervisor
        - NIMBUS_HOSTS=jstorm_nimbus_1
        - ZK_ROOT=/jstorm.docker.root2
        - ZK_HOSTS=${COMPOSE_PROJECT_NAME}_zk1_1,${COMPOSE_PROJECT_NAME}_zk2_1,${COMPOSE_PROJECT_NAME}_zk3_1
        - CLUSTER_NAME=jstorm.docker.cluster
    labels:
        aliyun.routing.port_8080: 'http://supervisor'
        aliyun.scale: '3'
    restart: 'always'
    links:
        - nimbus

为了保证zookeeper在JStorm之前部署,我们使用了link功能。link除了让容器之间网络互通,还告诉调度器服务之间的依赖关系,调度器会保证被依赖的服务先启动。

生产部署

通过上面的编排文件,我们从容地实现了一键部署JStorm,但在生产上应用,还需要注意一些细节。

  • zookeeper默认把持久化数据保存在/tmp/zookeeper中,生产部署时需要把该数据卷映射到指定的主机目录上
  • JStorm的WebUI开放到了公网,生产部署时需要使用内网域名或使用内网SLB
  • 我们把zookeeper和JStorm部署在了相同的机器上;生产部署时最好隔离开

资料

上一篇:.Net 实现游戏修改器


下一篇:视频站点的搭建