QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

数据中心的 Yarn on Docker 集群方案

  • 2017-03-21
  • 本文字数:4126 字

    阅读完需:约 14 分钟

当前数据中心存在的问题

数据中心中的应用一般独立部署,为了保证环境隔离与方便管理,保证应用最大资源 数据中心中普遍存在如下问题:

  1. 主机资源利用率低
  2. 部署和扩展复杂
  3. 资源隔离无法动态调整
  4. 无法快速响应业务

方案选型

Yarn on Docker 有哪些特点?

彻底隔离队列

  • 为了合理利用 Hadoop yarn 的资源,队列间会互相抢占计算资源,造成重要任务阻塞
  • 根据部门申请的机器数量划分 Yarn 集群方便财务管理
  • 更细粒度的资源分配

统一的资源分配

  • 每个 NodeManager 和容器都可以限定 CPU、内存资源

  • Yarn 资源划分精确到 CPU 核数和内存大小

弹性伸缩性服务

  • 每个容器中运行一个 NodeManager,增减 yarn 资源只需增减容器个数

  • 可以指定每个 NodeManager 拥有的计算资源多少,按需申请资源

Docker 集群管理系统:Kubernetes or Swarm?

关于容器集群管理系统的选型,用 Kubernetes 还是 Swarm?我们结合自己的经验和业务需求,对比如下:

特性

Kubernetes

Swarm

功能

功能强大

功能单一,基本够用

扩展

难以扩展,灵活性低

丰富的插件机制,兼容 docker api

文档

文档少,当时用的版本较低

docker 官方文档支持,丰富易读

使用

结构复杂,部署麻烦

简单易用

基于以上四点,我们最终选择了 Swarm,它基本满足我们的需求,掌握和开发时常较短。

解决方案的优势

选用 Yarn on Docker 的好处有以下两点:

Swarm 统一集群资源调度

  • 统一资源
  • 增加 Docker 虚拟化层,降低运维成本

增加 Hadoop 集群资源利用率

  • For datacenter:避免了静态资源隔离
  • For cluster:加强集群内部资源隔离

系统架构

比如数据中心中运行的 Hadoop 集群,我们将 HDFS 依然运行在物理机上,即 DataNode 依然部署在实体机器上,将 Yarn 计算层运行在 Docker 容器中,整个系统使用二层资源调度,Spark、Flinek、MapReduce 等应用运行在 Yarn 上。

Swarm 调度最底层的主机硬件资源,CPU 和内存封装为 Docker 容器,容器中运行 NodeManager,提供给 Yarn 集群,一个 Swarm 集群中可以运行多个 Yarn 集群,形成圈地式的 Yarn 计算集群。

具体流程

  1. swarm node 向 swarm master 注册主机资源并加入到 swarm cluster 中
  2. swarm master 向 cluster 申请资源请求启动容器
  3. swarm 根据调度策略选择在某个 node 上启动 docker container
  4. swarm node 的 docker deamon 根据容器启动参数启动相应资源大小的 NodeManager
  5. NodeManager 自动向 YARN 的 ResourceManager 注册资源一个 NodeManager 资源添加完成。

Swarm 为数据中心做容器即主机资源调度,每个 swarm node 的节点结构如图:

一个 Swarm node 就是一台物理机,每台主机上可以起多个同类型的 docker container,每个 container 的资源都有限制包括 CPU、内存 NodeManager 容器只需要考虑本身进程占用的资源和需要给主机预留资源。假如主机是 24 核 64G,我们可以分给一个容器 5 核 12G,NodeManager 占用 4 核 10G 的资源提供给 Yarn。

技术详解

(一) 镜像制作与发布

镜像制作和发布流程如下图:

用户从客户端提交代码到 Gitlab 中,需要包含 Dockerfile 文件,通过集成了 docker 插件的 Jenkins 的自动编译发布机制,自动 build 镜像后 push 到 docker 镜像仓库中,同一个项目每提交一次代码都会重新 build 一次镜像,生成不同的 tag 来标识镜像,Swarm 集群使用该镜像仓库就可以直接拉取镜像。

Dockerfile 的编写技巧

Dockerfile 相当于 docker 镜像的编译打包流程说明,其中也不乏一些技巧。

很多应用需要配置文件,如果想为每次启动容器的时候使用不同的配置参数,可以通过传递环境变量的方式来修改配置文件,前提是需要写一个 bash 脚本,脚本中来处理配置文件,再将这个脚本作为 entrypoint 入口,每当容器启动时就会执行这个脚本从而替换配置文件中的参数,也可以通过 CMD 传递参数给该脚本。

启动容器的时候通过传递环境变量的方式修改配置文件:

复制代码
docker run -d
--net=mynet
-e NAMESERVICE=nameservice
-e ACTIVE_NAMENODE_ID=namenode29 \
-e STANDBY_NAMENODE_ID=namenode63 \
-e HA_ZOOKEEPER_QUORUM=zk1:2181,zk2:2181,zk3:2181 \
-e YARN_ZK_DIR=rmstore \
-e YARN_CLUSTER_ID=yarnRM \
-e YARN_RM1_IP=rm1 \
-e YARN_RM2_IP=rm2 \
-e CPU_CORE_NUM=5
-e NODEMANAGER_MEMORY_MB=12288 \
-e YARN_JOBHISTORY_IP=jobhistory \
-e ACTIVE_NAMENODE_IP=active-namenode \
-e STANDBY_NAMENODE_IP=standby-namenode \
-e HA=yes \
docker-registry/library/hadoop-yarn:v0.1 resourcemanager

最后传递 resourcemanager 或者 nodemanager 参数指定启动相应的服务。

(二) 集群管理

我们自行开发程序调用 docker 的 API 来管理集群,也可以通过其他开源可视化页面来管理集群,比如 shipyard。

(三)自定义网络

Docker 容器跨主机互访一直是一个问题,Docker 官方为了避免网络上带来的诸多麻烦,故将跨主机网络开了比较大的口子,而由用户自己去实现。我们开发并开源了 Shrike 这个 docker 网络插件,大家可以在这里下载到: https://github.com/talkingdata/shrike

目前 Docker 跨主机的网络实现方案也有很多种, 主要包括端口映射,ovs, fannel 等。但是这些方案都无法满足我们的需求,端口映射服务内的内网 IP 会映射成外网的 IP,这样会给开发带来困惑,因为他们往往在跨网络交互时是不需要内网 IP 的,而 ovs 与 fannel 则是在基础网络协议上又包装了一层自定义协议,这样当网络流量大时,却又无端的增加了网络负载,最后我们采取了自主研发扁平化网络插件,也就是说让所有的容器统统在大二层上互通。架构如下:

我们首先需要创建一个 br0 自定义网桥,这个网桥并不是通过系统命令手动建立的原始 Linux 网桥,而是通过 Docker 的 cerate network 命令来建立的自定义网桥,这样避免了一个很重要的问题就是我们可以通过设置 DefaultGatewayIPv4 参数来设置容器的默认路由,这个解决了原始 Linux 自建网桥不能解决的问题. 用 Docker 创建网络时我们可以通过设置 subnet 参数来设置子网 IP 范围,默认我们可以把整个网段给这个子网,后面可以用 ipam driver(地址管理插件)来进行控制。还有一个参数 gateway 是用来设置 br0 自定义网桥地址的,其实也就是你这台宿主机的地址。

复制代码
docker network create
--opt=com.docker.network.bridge.enable_icc=true
--opt=com.docker.network.bridge.enable_ip_masquerade=false
--opt=com.docker.network.bridge.host_binding_ipv4=0.0.0.0
--opt=com.docker.network.bridge.name=br0
--opt=com.docker.network.driver.mtu=1500
--ipam-driver=talkingdata
--subnet= 容器 IP 的子网范围
--gateway=br0 网桥使用的 IP, 也就是宿主机的地址
--aux-address=DefaultGatewayIPv4= 容器使用的网关地址
mynet

IPAM 驱动是专门管理 Docker 容器 IP 的, Docker 每次启停与删除容器都会调用这个驱动提供的 IP 管理接口,然后 IP 接口会对存储 IP 地址的 Etcd 有一个增删改查的操作。此插件运行时会起一个 Unix Socket, 然后会在 docker/run/plugins 目录下生成一个.sock 文件,Docker daemon 之后会和这个 sock 文件进行沟通去调用我们之前实现好的几个接口进行 IP 管理,以此来达到 IP 管理的目的,防止 IP 冲突。

通过 Docker 命令去创建一个自定义的网络起名为“mynet”,同时会产生一个网桥 br0,之后通过更改网络配置文件(在 /etc/sysconfig/network-scripts/ 下 ifcfg-br0、ifcfg- 默认网络接口名)将默认网络接口桥接到 br0 上,重启网络后,桥接网络就会生效。Docker 默认在每次启动容器时都会将容器内的默认网卡桥接到 br0 上,而且宿主机的物理网卡也同样桥接到了 br0 上了。其实桥接的原理就好像是一台交换机,Docker 容器和宿主机物理网络接口都是服务器,通过 veth pair 这个网络设备像一根网线插到交换机上。至此,所有的容器网络已经在同一个网络上可以通信了,每一个 Docker 容器就好比是一台独立的虚拟机,拥有和宿主机同一网段的 IP,可以实现跨主机访问了。

(四)集群监控

如果使用 shipyard 管理集群会有一个单独的监控页面,可以看到一定时间段内的 CPU、内存、IO、网络使用状况。

我们自己开发了基于大数据的监控系统 Owl 也即将支持 docker 容器的监控。 https://github.com/TalkingData/OWL-v3

性能瓶颈与优化

大家可能会担心自定义网络的性能问题,为此我们用 iperf 进行了网络性能测试。我们对比了不同主机容器间的网速,同一主机上的不同容器和不同主机间的网速,结果如下表:

从表中我们可以看到,在这一组测试中,容器间的网速与容器是在想通主机还是在不同主机上的差别不大,说明我们的网络插件性能还是很优异的。

Hadoop 配置优化

因为使用 docker 将原来一台机器一个 nodemanager 给细化为了多个,会造成 nodemanager 个数的成倍增加,因此 hadoop 的一些配置需要相应优化。

  • yarn.nodemanager.localizer.fetch.thread-count 随着容器数量增加,需要相应调整该参数
  • yarn.resourcemanager.amliveliness-monitor.interval-ms 默认 1 秒,改为 10 秒,否则时间太短可能导致有些节点无法注册
  • yarn.resourcemanager.resource-tracker.client.thread-count 默认 50,改为 100,随着容器数量增加,需要相应调整该参数
  • yarn.nodemanager.pmem-check-enabled 默认 true,改为 false,不检查任务正在使用的物理内存量
  • 容器中 hadoop ulimit 值修改,默认 4096,改成 655350

关于未来

我们未来规划做的是 DC/OS,基于 Docker 的应用自动打包编译分发系统,让开发人员可以很便捷的申请资源,上下线服务,管理应用。要达到这个目标还有很多事情要做:

  • Service Control Panel:统一的根据服务来管理的 web 页面
  • Load balance:容器根据机器负载情况自动迁移
  • Scheduler:swarm 调度策略优化
  • 服务配置文件:提供镜像启动参数的配置文件,所有启动参数可通过文件配置
  • 监控:服务级别的监控

(点击放大图像)

作者简介

宋净超,TalkingData 大数据及云计算工程师。拥有多年的 Hadoop 大数据集群部署、管理、优化和实战经验,对 Hadoop 和 Docker 的结合落地进行了丰富的探索,主导了 TalkingData 的 Yarn on Docker 的改造和微服务落地,关注大数据开源软件及微服务的前沿发展。


感谢木环对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-03-21 17:314720

评论

发布
暂无评论
发现更多内容

大企业必读!五大纳税申报难题解析

用友BIP

如何计算真实的数据库成本

天翼云开发者社区

IP 地址是如何被创建和管理的?

海拥(haiyong.site)

三周年连更

2023全栈开发人员职业路线图

码语者

全栈开发

共创,共建,共赢,共荣!国云向新,翼起创未来!

天翼云开发者社区

SQL 解析在 CloudQuery 中的应用

BinTools图尔兹

数据库 SQL解析

安全第一,私有化部署IM让组织沟通更放心

BeeWorks

统一门户为什么能让企业数字化高效办公?

BeeWorks

Tapdata 的 ∞ 实践:中小企业如何轻量、高效地搭建起一个灵活易用的数字化平台

tapdata

数据库

数智化转型再加速,低代码开发助力企业转型

加入高科技仿生人

低代码 数智化 数字转型 数智转型

加快推进数智化转型,引领盐行业高质量发展

用友BIP

一文详解如何在 ChengYing 中通过产品线部署一键提升效率

袋鼠云数栈

开源

SpringBoot 中操作 Redis 及工具类的封装

做梦都在改BUG

Java redis spring Spring Boot

聊点技术 | 全新功能,让Bonree ONE变得更强

博睿数据

可观测性 智能运维 博睿数据 Bonree ONE ONE有引力

九科信息参加长三角智慧港口论坛,分享港口企业超级自动化实践

九科Ninetech

什么是人工智能领域模型的 temperature 参数?

汪子熙

人工智能 机器学习 深度学习 三周年连更

顶象uni-app版设备指纹上线,满足企业多平台服务需求

极客天地

喜讯!天翼云斩获NLP国际顶会比赛两项荣誉

天翼云开发者社区

CNBPA 新成员展示 | 启明信息技术股份有限公司

云原生技术社区

云原生 云原生技术实践联盟 CNBPA

玩转云端| 解密!业内首款存储资源盘活系统如何炼成?

天翼云开发者社区

iOS MachineLearning 系列(11)—— 自然语言之词句相似性分析

珲少

ChatGPT+私有数据=智能知识库+个性化AI

BeeWorks

看华为云Serverless 4大特性如何让软件架构更丝滑

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 5 月 PK 榜

聚能量赢未来,OpenHarmony开发者大会开发工具分论坛圆满落幕

最新动态

面对“失业焦虑”我们可以做些什么| 社区征文

峥岳

三周年征文

IPP SWAP孵化器LP算力系统开发技术

薇電13242772558

区块链

PostgreSQL JDBC 开发指导

攻城狮

postgresql JDBC 驱动程序

惊艳!阿里自爆用480页讲清楚了44种微服务架构设计模式

做梦都在改BUG

Java 架构 微服务 设计模式

SpringBoot集成ElasticSearch

做梦都在改BUG

Java elasticsearch Spring Boot

数据中心的Yarn on Docker集群方案_语言 & 开发_宋净超_InfoQ精选文章