基于Mesos/Docker构建数据处理平台
本文深入介绍了去哪儿网利用Mesos和Docker构建私有云服务的全过程,分享了从无状态应用向有状态应用逐步过度的经验与心得。
平台概览
2014年下半年左右,去哪儿完成了有关构建私有云服务的技术调研,并最终拍定了Docker/Mesos这一方案。下图1展示了去哪儿数据平台的整体架构:
图1:去哪儿数据平台的整体架构
该平台目前已实现了如下多项功能:
每天处理约340亿/25TB的数据;
90%的数据在100ms内完成处理;
最长3h/24h的数据回放;
私有的Elasticsearch Cloud;
自动化监控与报警。
为什么选择Docker/Mesos
目前为止,这个数据平台可以说是公司整个流数据的主要出入口,包括私有的Elasticsearch Cloud和监控报警之类的数据。那么为什么选择Docker/Mesos?
选择Docker有两大原因。第一个是打包:对于运维来讲,业务打完包之后,每天面对的是用脚本分发到机器上时所出现的各种问题。业务包是一个比较上层的话题,这里不做深入的讨论,这里讲的“打包”指软件的Runtime层。如果用Docker的打包机制,把最容易出现问题的Runtime包装成镜像并放在registry里,需要的时候拿出来,那么整个平台最多只执行一个远程脚本就可以了,这是团队最看好的一个特性。第二个是运维:Docker取消了依赖限制,只要构建一个虚拟环境或一个Runtime的镜像,就可以直接拉取到服务器上并启动相应的程序。此外Docker在清理上也较为简单,不需要考虑环境卸载不干净等问题。
以常见的计算框架来说,它们本质上仍然属于运行在其上的Job的Runtime。综合上述情况,团队选择针对Runtime去打包。
选择Mesos是因为它足够简单和稳定,而且拥有较成熟的调度框架。Mesos的简单体现在,与Kubernetes相比其所有功能都处于劣势,甚至会发现它本身都是不支持服务的,用户需要进行二次开发来满足实际要求,包括网络层。不过,这也恰好是它的强项。Mesos本身提供了很多SDN接口,或者是有模块加载机制,可以做自定义修改,平台定制功能比较强。所以用Mesos的方案,需要考虑团队是否可以Hold住整个开发过程。
从框架层面来看,Marathon可以支撑一部分长期运行的服务,Chronos则侧重于定时任务/批处理。
以下图2是Mesos的一个简单结构图:
图2:Mesos结构
数据平台的最终目标架构如下图3所示:
图3:平台目标
组件容器化与部署
组件的容器化分为JVM容器化和Mesos容器化。JVM容器化需要注意以下几方面:
潜在创建文件的配置都要注意
java.io.tmpdir
-XX:HeapDumpPath
-Xloggc
-Xloggc会记录GC的信息到制定的文件中。现在很少有直接用XLoggc配置的了(已经用MXBean方式替代了)。如果有比较老的程序是通过-Xloggc打印GC日志的话,那么要额外挂载volume到容器内。
时区与编码
–env TZ=Asia/Shanghai
–volume /etc/localtime:/etc/localtime:ro
–env JAVA_TOOL_OPTIONS=”-Dfile.encoding=UTF-8 -Duser.timezone=PRC
时区是另一个注意点。上面所列的三种不同的方法都可以达到目的,其中第一/三个可以写在Dockerfile里,也可以在docker run时通过–env传入。第二种只在docker run时通过volume方式挂载。另外,第三种额外设置了字符集编码,推荐使用此方式。
主动设置heap
防止ergonomics乱算内存
这是Docker内部实现的问题。即使给Docker设置内存,容器内通过free命令看到的内存和宿主机的内存是一样的。而JVM为了使用方便,会默认设置一个人机功能会根据当前机器的内存计算一个堆大小,如果我们不主动设置JVM堆内存的话,很有可能计算出一个超过 Memory Cgroup限制的内存,启动就宕掉,所以需要注意在启动时就把内存设置好。
CMS收集器要调整并行度
-XX:ParallelGCThreads=cpus
-XX:ConcGCThreads=cpus/2
CMS是常见的收集器,它设置并行度的时候是取机器的核数来计算的。如果给容器分配2个CPU,JVM仍然按照宿主机的核数初始化这些线程数量,GC的回收效率会降低。想规避这个问题有两点,第一点是挂载假的Proc文件系统,比如Lxcfs。第二种是使用类似Hyper的基于Hypervisor的容器。
Mesos容器化要求关注两类参数:配置参数和run参数。
需要关注的配置参数
MESOS_systemd_enable_support
MESOS_docker_mesos_image
MESOS_docker_socket
GLOG_max_log_size
GLOG_stop_logging_if_full_disk
Mesos是配置参数最多的。在物理机上,Mesos默认使用系统的Systemd管理任务,如果把Mesos通过Docker run的方式启动起来,用户就要关systemd_Enable_support,防止Mesos Slave拉取容器运行时数据造成混乱。
第二个是Docker_Mesos_Image,这个配置告诉Mesos Slave,当前是运行在容器内的。在物理机环境下,Mesos Slave进程宕掉重启,、就会根据executor进程/容器的名字做recovery动作。但是在容器内,宕机后executor全部回收了,重启容器,Slave认为是一个新环境,跳过覆盖动作并自动下发任务,所以任务有可能会发重。
Docker_Socket会告诉Mesos,Docker指定的远端地址或本地文件,是默认挂到Mesos容器里的。用户如果直接执行文件,会导致文件错误,消息调取失败。这个时候推荐一个简单的办法:把当前物理机的目录挂到容器中并单独命名,相当于在容器内直接访问整个物理机的路径,再重新指定它的地址,这样每次一有变动Mesos就能够发现,做自己的指令。
后面两个是Mesos Logging配置,调整生成logging文件的一些行为。
需要关注的run参数
–pid=host
–privileged
–net=host (optional)
root user
启动Slave容器的时候最好不加Pid Namespace,因为容器内Pid=1的进程一般都是你的应用程序,易导致子进程都无法回收,或者采用tini一类的进程启动应用达到相同的目的。–privileged和root user主要是针对Mesos的持久化卷功能,否则无法mount到容器内,–net=host是出于网络效率的考虑,毕竟源生的bridge模式效率比较低。
图4:去哪儿数据平台部署流程图
上图4就是去哪儿数据平台部署的流程图。
基于Marathon的Streaming调度
拿Spark on Mesos记录子,即使是基于Spark的Marathon调度,也需要用户开发一个Frameworks。上生产需要很多代码,团队之前代码加到将近一千,用来专门解决Spark运行在Master中的问题,但是其中一个软件经常跑到Master,对每一个框架写重复性代码,而且内部逻辑很难复用,所以团队考虑把上层的东西全都跑在一个统一框架里,例如后面的运维和扩容,都针对这一个框架做就可以了。团队最终选择了Marathon,把Spark作为Marathon的一个任务发下去,让Spark在Marathon里做分发。
除去提供维标准化和自动化外,基于Spark的Marathon还可以解决Mesos-Dispatcher的一些问题:
配置不能正确同步;这一块更新频率特别慢,默认速度也很慢,所以需要自己来维护一个版本。第一个配置不能正确同步,需要设置一些参数信息、Spark内核核数及内损之类,这里它只会选择性地抽取部分配置发下去。
基于attributes的过滤功能缺失;对于现在的环境,所设置的Attributes过滤功能明显缺失,不管机器是否专用或有没有特殊配置,上来就发,很容易占满ES的机器。
按role/principal接入Mesos;针对不同的业务线做资源配比时,无法对应不同的角色去接入Mesos。
不能re-registery;框架本身不能重注册,如果框架跑到一半挂掉了,重启之后之前的任务就直接忽略不管,需要手工Kill掉这个框架。
不能动态扩容executor。最后是不能扩容、动态调整,临时改动的话只能重发任务。
整个过程比较简单,如下图5所示:
图5:替代Spark Mesos Dispatcher
不过还是有一些问题存在:
Checkpoint & Block
动态预留 & 持久化卷
setJars
清理无效的卷
关于Checkpoint&Block,通过动态预留的功能可以把这个任务直接“钉死”在这台机器上,如果它挂的话可以直接在原机器上重启,并挂载volume继续工作。如果不用它预留的话,可能调度到其他机器上,找不到数据Block,造成数据的丢失或者重复处理。
持久化卷是Mesos提供的功能,需要考虑它的数据永存,Mesos提供了一种方案:把本地磁盘升级成一个目录,把这个转移到Docker里。每次写数据到本地时,能直接通过持久化卷来维护,免去手工维护的成本。但它目前有一个问题,如果任务已被回收,它持久化卷的数据是不会自己删掉的,需要写一个脚本定时轮巡并对应删掉。
临时文件
java.io.tmpdir=/mnt/mesos/sandbox
spark.local.dir=/mnt/mesos/sandbox
如果使用持久化卷,需要修改这两个配置,把这一些临时文件写进去,比如shuffle文件等。如果配置持久化卷的话,用户也可以写持久化卷的路径。
Coarse-Grained
Spark有两种资源调度模式:细粒度和粗粒度。目前已经不太推荐细粒度了,考虑到细粒度会尽可能的把所有资源占满,容易导致Mesos资源被耗尽,所以这个时候更倾向选择粗粒度模式。
图6:Storm on Marathon
上图6展示了基于Storm的Marathon调度,Flink也是如此。结合线上的运维和debug,需要注意以下几方面:
源生Web Console
随机端口
openresty配合泛域名
默认源生Web Console,前端配置转发,直接访问固定域名。
Filebeat + Kafka + ELK
多版本追溯
日常排错
异常监控
大部分WebUI上看到的都是目前内部的数据处理情况,可以通过ELK查询信息。如果任务曾经运行在不同版本的Spark上,可以把多版本的日志都追踪起来,包括日常、问题监控等,直接拿来使用。
Metrics
第三个需要注意的就是指标。比如Spark ,需要配合Metrics 把数据源打出来就行。
ELK on Mesos
目前平台已有近50个集群,约100TB+业务数据量,高峰期1.2k QPS以及约110个节点,Elasticsearch需求逐步增多。
图7:ELK on Mesos
上图7是ELK on Mesos结构图,也是团队的无奈之选。因为Mesos还暂时不支持multi-role framework功能,所以选择了这种折中的方式来做。在一个Marathon里,根据业务线设置好Quota后,用业务线重新发一个新的Marathon接入进去。对于多租户来讲,可以利用Kubernetes做后续的资源管控和资源申请。
部署ES以后,有一个关于服务发现的问题,可以去注册一个callback,Marathon会返回信息,解析出master/slave进程所在的机器和端口,配合修改Haproxy做一层转发,相当于把后端整个TCP的连接都做一个通路。ES跟Spark不完全相同,Spark传输本身流量就比较大,而ES启动时需要主动联系Master地址,再通过Master获取相应集群,后面再做P2P,流量比较低,也不是一个长链接。
监控与运维
这部分包括了Streaming监控指标与报警、容器监控指标与报警两方面。
Streaming监控指标与报警
Streaming监控含拓扑监控和业务监控两部分。
Streaming拓扑监控
业务监控
Kafka Topic Lag
处理延迟mean90/upper90
Spark scheduler delay/process delay
Search Count/Message Count
Reject/Exception
JVM
拓扑监控包括数据源和整个拓扑流程,需要用户自己去整理和构建,更新的时候就能够知道这个东西依赖谁、是否依赖线上服务,如果中途停的话会造成机器故障。业务监控的话,第一个就是Topic Lag,Topic Lag每一个波动都是不一样的,用这种方式监控会频繁报警,90%的中位数都是落在80—100毫秒范围内,就可以监控到整个范围。
容器监控指标与报警
容器监控上关注以下三方面:
Google cAdvisor足够有效
mount rootfs可能导致容器删除失败 #771
–docker_only
–docker_env_metadata_whitelist
Statsd + Watcher
基于Graphite的千万级指标监控平台
Nagios
容器这一块比较简单,利用Docker并配合Mesos,再把Marathon的ID抓取出来就可以了。我们这边在实践的过程发现一个问题,因为Statsd Watcher容易出现问题,你直接用Docker的时候它会报一些错误出来,这个问题就是Statsd Watcher把路径给挂了的原因。目前我们平台就曾遇到过一次,社区里面也有人曝,不过复现率比较低。用的时候如果发现这个问题把Statsd Watcher直接停掉就好。指标的话,每台机器上放一个statsd再发一个后台的Worker,报警平台也是这个。
其实针对Docker监控的话,还是存在着一些问题:
基础监控压力
数据膨胀
垃圾指标增多
大量的通配符导致数据库压力较高
单个任务的容器生命周期
发布
扩容
异常退出
首先主要是监控系统压力比较大。原来监控虚拟机时都是针对每一个虚拟机的,只要虚拟机不删的话是长期汇报,指标名固定,但在容器中这个东西一直在变,它在这套体系下用指标并在本地之外建一个目录存文件,所以在这种存储机制下去存容器的指标不合适。主要问题是数据膨胀比较厉害,可能一个容器会起名,起名多次之后,在Graphite那边对应了有十多个指标,像这种都是预生成的监控文件。比如说定义每一秒钟一个数据点,要保存一年,这个时候它就会根据每年有多少秒生成一个RRD文件放那儿。这部分指标如果按照现有标准的话,可能容器的生命周期仅有几天时间,不适用这种机制。测试相同的指标量,公司存储的方式相对来说比Graphite好一点。因为Graphite是基于文件系统来做的,第一个优化指标名,目录要转存到数据库里做一些索引加速和查询,但是因为容器这边相对通配符比较多,不能直接得知具体对应的ID,只能通配符查询做聚合。因为长期的通配符在字符串的索引上还是易于使用的,所以现在算是折中的做法,把一些常用的查询结果、目录放到里边。
另一个是容器的生命周期。可以做一些审计或者变更的版本,在Mesos层面基于Marathon去监控,发现这些状态后打上标记:当前是哪一个容器或者哪一个TASK出了问题,对应扩容和记录下来。还有Docker自己的问题,这样后面做整个记录时会有一份相对比较完整的TASK-ID。
作者简介:徐磊,去哪儿网平台事业部运维开发工程师,2015年加入去哪儿网,负责实时日志相关的开发与运维工作。有多年电信、云计算行业经验,曾供职于红帽中国。 本文来自徐磊在CCTC 2017上的演讲整理。
全天候聚焦IaaS/PaaS/SaaS最新技术动态,深度挖掘技术大咖第一手实践,及时推送云行业重大新闻,一键关注,总览国内外云计算大势!
基于Mesos/Docker构建数据处理平台相关推荐
- 中国电信基于Mesos+Docker的运维自动化在CDN中的实践
本文讲的是中国电信基于Mesos+Docker的运维自动化在CDN中的实践[编者的话]本次分享将讲解容器技术在CDN系统中的应用,包括应用的容器化,使用Mesos.Marathon.ZooKeeper ...
- 基于openvswitch+Docker构建SDN网络测试环境 (使用ovs-docker进行构建)
这是一篇之前写的笔记,主要记录了使用openvswitch + Docker 等进行一个小型的SDN网络搭建的操作步骤.由于 之前临时有其他任务,耽搁了一下,最近开始重新整理,并计划开发一个简单的Py ...
- 视频私有云实战:基于Docker构建点播私有云平台
私有云是为一个客户单独使用而构建的,因而提供对数据.安全性和服务质量的最有效控制.前置条件是客户拥有基础设施,并可以使用基础设施在其上部署应用程序.其核心属性是专有的资源.本篇文章将会结合网易云信的实 ...
- 省时省事省力 巧用阿里ECS D1构建大数据处理平台
随着人们逐渐认识到 "大数据"的价值,互联网.电商到金融业.政企等各行业开始处理海量数据.如何低成本.敏捷高效地搭建大数据处理平台,成为影响大数据创新效率的关键. 为了让用户以最简 ...
- grafana计算不同时间的差值_大数据时代!如何基于Spark Streaming构建实时计算平台...
随着互联网技术的迅速发展,用户对于数据处理的时效性.准确性与稳定性要求越来越高,如何构建一个稳定易用并提供齐备的监控与预警功能的实时计算平台也成了很多公司一个很大的挑战. 自2015年携程实时计算平台 ...
- 中国人寿张青南:中国人寿如何基于容器构建PaaS平台
口述/作者: 张青南 中国人寿研发中心高级架构师 编辑: Rancher Labs 中国人寿研发中心高级架构师 张青南 从2017年起,中国人寿正式开始利用容器技术搭建PaaS平台"稻客云& ...
- 【Kubernetes 企业项目实战】06、基于 Jenkins+K8s 构建 DevOps 自动化运维管理平台(上)
目录 一.k8s 助力 DevOps 在企业落地实践 1.1 传统方式部署项目为什么发布慢,效率低? 1.2 上线一个功能,有多少时间被浪费了? 1.3 如何解决发布慢,效率低的问题呢? 1.4 什么 ...
- 陌陌基于Kubernetes和Docker容器管理平台的架构实践
为什么选择使用Kubernetes? 在使用Kubernetes之前,陌陌在应用发布和运行环境方面遇到的具体问题,如下: 应用发布时间很长,主要是因为发布过程中需要做隔离.恢复等动作,还需要登录查看实 ...
- 人工智能,丹青圣手,全平台(原生/Docker)构建Stable-Diffusion-Webui的AI绘画库教程(Python3.10/Pytorch1.13.0)
世间无限丹青手,遇上AI画不成.最近一段时间,可能所有人类画师都得发出一句"既生瑜,何生亮"的感叹,因为AI 绘画通用算法Stable Diffusion已然超神,无需美术基础,也 ...
最新文章
- 寫博客過程中遇到的問題
- 第十三期:你不想错过的那些JSON工具
- Hive 行转列,列传行 - Impala 暂不支持
- nemesis什么车_nemesis是什么意思_nemesis的翻译_音标_读音_用法_例句_爱词霸在线词典...
- 新版微软Edge浏览器:支持安装Chrome扩展
- 数据分析写作——程序员的另外一种输出
- NOIP 2005 等价表达式 (TYVJ P1060)
- 怎样让电脑中的jar包显示Java图标
- SQL中的n+1次select语句查询问题
- 锡兰1.1.0现已上市
- 镁光闪存颗粒对照表_最全的内存颗粒编码规则说明,教你看穿内存条到底用的什么颗粒...
- 项目动态|Apache Pulsar 2.10.0 版本介绍
- fatal error C1083: 无法打开包括文件: “afx.h”: No such file or directory
- SQL格式日志转为syslog格式:触发器中执行Shell命令
- 设置允许从网络访问计算机的用户账户(加入guest组),网络共享
- 手把手看如何制作本地yun源
- 5个一见钟情的手机APP软件 使用过后必须赞赞赞
- Android 8.1 中Systemui中的常见修改(六)NavigationBar加载流程
- 五大券商研报:逢大跌买入这些股
- N1盒子恢复官改系统最简单的ddbr大法(适用小钢炮以及各种变砖)(转载)
热门文章
- oracle存储过程 取时间格式,Oracle存储过程获取YYYY-MM-DD的时间格式
- unet作为服务器不显示画面,UNet:无法生成服务器对象(不使用NetworkManager)
- python dag调度系统开发_基于机器学习的DAG调度平台
- windows功能_这 12 个好用 Windows 软件,让你也能用上 macOS 的独占功能
- 2019 年度十大 AI 安防热点事件丨年终盘点
- 历史上54位伟大科学家、数学家的专属LOGO,你能认出几个?
- 南大用“推荐算法”分宿舍666,新生配好舍友美滋滋
- mysql 备份成文件的脚本_Mysql自动全量备份脚本
- python达梦数据库_python 操作达 梦数据库
- d630 无线驱动 linux,fedora 8下DELL D630无线网卡驱动的安装