写点什么

数据中心的 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:314559

评论

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

天润融通"恶意感知系统":提前预警,化解315公关危机

天润融通

甲子光年专访天润融通CEO吴强:客户经营如何穿越低速周期?

天润融通

人工智呢

利用反射API和AOP实现业务逻辑的自动化重构

技术冰糖葫芦

API Explorer API boy api 货币化 API 文档

介绍几种 MySQL 官方高可用方案

Simon

MySQL 数据库 MySQL高可用

蓝易云 - 详解SpringBoot的常用注解

百度搜索:蓝易云

云计算 Linux 运维 springboot 云服务器

深入理解Spring AOP中的@EnableAspectJAutoProxy

华为云开发者联盟

Java spring 华为云 华为云开发者联盟 企业号2024年6月PK榜

原生鸿蒙,激活数字内容一池活水

最新动态

未来LED显示屏方向:超薄、散热、柔性

Dylan

国际化 LED显示屏 全彩LED显示屏 户外LED显示屏 led显示屏厂家

蓝易云 - 海外云主机的选择要注意什么?

百度搜索:蓝易云

云计算 运维 服务器 云主机 云服务器

Markdown一键生成PPT!这2个AI工具软件值得推荐!

彭宏豪95

markdown PPT 在线白板 效率软件 AI生成PPT

KaiwuDB 事务中的 Raft 协议

KaiwuDB

数据一致性 raft协议 KaiwuDB

TDengine 新能源行业研讨会上都说了啥?精彩回顾!

TDengine

数据库 tdengine 时序数据库

接口测试:Mock 工具与定制化

测试人

软件测试 Mock

蓝易云 - Nacos启动常见报错解决方法

百度搜索:蓝易云

云计算 运维 nacos 服务器 云服务器

蓝易云 - npm install报错问题解决合集

百度搜索:蓝易云

云计算 运维 Node 云服务器 install

Apache Flink类型及序列化研读&生产应用|得物技术

得物技术

flink 技术分享 企业号2024年6月PK榜

三大国际产业与标准组织正式成立,引领全球产业创新与发展

最新动态

2024年中国零信任发展趋势展望

芯盾时代

iam 统一身份认证 零信任 零信任模型 sdp

我的私人助理 | 办公小浣熊

六月的雨在InfoQ

数据分析 数据可视化 数据分析预测 办公小浣熊 莫比乌斯环

mac苹果单机游戏推荐:古墓丽影11:暗影 for Mac安装包

你的猪会飞吗

Mac游戏下载 mac单机游戏

Qt(C++)绘制指针仪表盘显示当前温度

DS小龙哥

6 月 优质更文活动

数字黄金 vs 全球计算机:比特币与以太坊现货 ETF 对比

TechubNews

“逐代传承”提升强化学习效果;LLM重塑Multi-agent建模与仿真

算AI

深度学习 强化学习 NLP 大模型 #人工智能 LLM

蓝易云 - 简单shell脚本的编写教程

百度搜索:蓝易云

Linux 运维 Shell 服务器 云服务器

【开发者推荐】告别繁琐:一键解锁国产ETL新贵,Kettle的终结者

敏捷调度TASKCTL

kettle 国产数据库 TASKCTL 数据集成平台

通过搭建 24 点小游戏应用实战,带你了解 AppBuilder 的技术原理

百度Geek说

企业号 6 月 PK 榜 AI 原生云 AppBuilder

文献解读-基因编辑-第十二期|《CRISPR-detector:快速、准确地检测、可视化和注释基因组编辑事件引起的全基因组范围突变》

INSVAST

基因数据分析 生信服务 基因编辑

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