AWS Elastic MapReduce(以下简称 EMR) 是集齐数据接入、存储、计算、交互式查询、机器学习等一系列开源社区组件封装的云上托管大数据平台,用户可以基于 EMR 迅速拉起一套大数据集群,用于大规模数据处理、分析,使用时可根据实际业务所需灵活调配计算资源,一定程度上降低底层基础设施运维成本。AWS 是最早将大数据管理平台上云的云厂商,查询其官网发行版本记录,能检索到的最古老版本 EMR-4.2.0 发布日期为 2015 年 11 月 18 日,当是时大数据领域最火的三家 Hadoop 发行厂商:Cloudera、Hortonwoks、MapR,三分天下,互为犄角,世事难料的是几年后的今天惟 Cloudera 一家尚存。 笔者 2015 年开始接触大数据,管理大数据平台方式从早期的 Apache 逐渐过渡到自动化管理 (CDH、HDP),于 2020 年初入职朴朴后开始使用 AWS EMR,目前我司大数据平台为混合云架构模式:AWS EMR 结合 IDC CDH。朴朴大数据团队在平台构建过程中积累了大量的 EMR 使用实践和运维经验,受篇幅所限,无法一一展开说明,本文旨在提供一些关于如何玩转 EMR 的使用思路,中间夹以部分我司实践案例佐证,权作抛砖引玉之举。
朴朴数据平台基础技术架构简图
朴朴云上主体业务数据流转简图
EMR 在朴朴云上大数据平台担任计算单元角色,数据计算完毕后经由服务通道输出给业务平台 (平台架构图最顶层部分),核心计算场景有:离线、实时、查询,三者比例约为 7:2:1。至于云上主体业务数据流转链路,我们使用 Apache Hudi 作为数据湖仓支撑基石,目前是以离线 + 实时双线同步链路方式支持数据入湖。湖仓架构是一种灵活的架构设计模式,本文篇幅有限,后续有机会笔者单开一篇进行论述。
我司近七成为离线计算,所支撑的业务场景繁杂多样:业务数据入湖仓 ETL、算法、数据报表、数据分析、仓储配送等,这些离线任务我们内部按照对业务影响程度制定了相关故障等级标准,达到核心故障级别的有:
目前我司实时计算平台,已上线实时计算任务有 200+,场景涵盖:业务数据实时入湖仓 ETL、算法、数据报表、门店大屏等,与离线计算所不同的是实时计算要求响应时效性更高,基本等同于朴朴主体业务 (A/C 端) 响应速度,随着业务场景不断深化,会逐步按需提升实时计算任务。
查询计算平台基于 presto 封装实现,目前在我司应用场景涉及:BI 平台、即席式交互、跨源融合查询,因云上虚拟机自建 Clickhouse,其存储瓶颈较明显且成本又高,因此引入 Presto 实现跨源融合查询以支持 BI 平台查询湖仓 Hudi 明细表,如此一来湖仓中的数据可无需再同步至 Clickhouse,降低明细表数据传输及落地存储至 Clickhouse 过程开销。
除此之外,数据平台团队已在规划、开发实现统一查询服务平台,该平台上线后会提供如下功能:
开篇伊始,先简单了解下 EMR 集群单元架构。
AWS 官网介绍 EMR 部署模式有:EC2、EKS、Outposts、Serverless 这几种,后两者目前尚未在国内上线,而当前阶段 EMR On EKS 模式有使用场景限制 (仅支持 Spark 应用),待之后具体调研使用后再作评论,本文着重于 EMR On EC2 模式进行说明。EMR 集群由三个组类构成:MASTER、CORE、TASK,典型的 EMR 集群实例组架构如下图所示:
在 EMR 集群中 master node 扮演着管理者角色,诸如:
master node | -- zookeeper server | -- hdfs namenode、hdfs journalnode、hdfs zkfc | -- yarn resourcemanager | -- presto coordinator
复制代码
等服务进程在此节点运行,因此一个集群中至少有一个 master node,若需要 HA 架构,可在部署时选择 Multi master 模式 (3 实例),然后静待 EMR 集群初始化完毕即可。
以 HDFS 和 YARN 为例,Multi master 架构下 EMR5 集群中两个 namenode 节点以 active/standby 状态工作,resourcemanager 三节点分别以 active/standby/standby 状态工作;而 EMR6 集群中有所不同的是全部 master node 会启动 namenode 进程,并分别以 active/standby/standby 状态工作,间接提高 HDFS 集群可用性。集群中可通过如下命令获取服务进程状态:
// hdfs namenode服务状态获取hdfs haadmin -getServiceState
// yarn resourcemanager服务状态获取yarn rmadmin -getAllServiceState
复制代码
高可用架构下当出现某个 master node 崩溃时,ZK/HDFS/YARN 等组件服务因具备故障转移机制,整体集群服务不受影响,EMR 后台会将故障 EC2 实例从集群中剔除并新增一个新 EC2 实例,待初始化完毕后 (含高可用配置操作) 重加入集群。
core node 为弹性且可选实例组类型,承载着 datanode、nodemanager、worker 等计算存储角色,用户可自定义 HDFS 副本参数,若不设置会依据 EMR 默认值进行设定:
node < 4, 默认设为14 < node < 10,默认设为2node > 10, 默认设为3
复制代码
task node 为计算节点,一般承载着 nodemanager、worker 等计算角色,适用于应对不同计算资源所需的弹性计算场景,对于弹性 scale 频繁的计算场景,通过调整 task node 使用比例,起到消峰填谷作用的同时又能一定程度上控制和节省成本。
作为新手玩家,如何上手管理 EMR 集群呢?笔者大致总结后可从以下方面初窥门径:
EMR 控制台提供两种部署模式:快速、高级,快速选项模式用户可根据提供的模板,简单配置后即可构建集群,高级选项模式则提供给用户更多自主选择,支持从软件、硬件、集群设置、安全性四大方面自定义配置构建集群。一般而言,作为刚接触 EMR 的新手玩家,选择前者会比较方便,有开源大数据集群运维经验的用户,建议使用后者,可以相对灵活方式管理和部署 EMR 集群。
自定义配置支持集群全局范围和实例组范围,参数项变更操作支持 json 或表格两种格式编辑,这里要注意的是 EMR 控制台页面<集群配置>只允许在集群构建初始化阶段定义,集群上线后即不可被修改,EMR 控制台在 5.21.0 及之后的版本支持实例组级别 (运行中) 服务配置项修改,具体配置项分发支持可检索参考官网发行版<配置分类>说明。
EMR 原生提供部分指标并集成至 cloudwatch,用户可在控制台查看或到 cloudwatch 检索,常用指标基本已提供,若指标项不足以满足需求,可基于 Prometheus+Grafana 套件自行实现指标采集与监控告警。
用户在构建 EMR 集群前,建议事先定义创建好 VPC 网络、安全组及 IAM 角色,部署过程中引用这些安全性定义,当集群构建完毕后,所有 EC2 实例的安全访问即可实现受控,避免集群出现访问安全方面隐患。
此外,依据笔者亲身经历的经验教训总结,构建 EMR 集群时可参考如下原则:
原因:防止单 Master 节点崩溃导致重要集群被销毁。
原因:若 master 角色所在 EC2 实例节点分布不均,集中在个别底层硬件上,当此硬件出问题时波及的就是整个集群,较新的 EMR 版本因引入 placement group 机制,会在部署时自动分散开,为防万一,建议再核实一遍。
原因:AMD CPU 机型虽然便宜一些,但在 AWS 北京 a、b 可用区域数量占比较少,容易集中在某些底层物理设施单元上 (机柜、服务器等),且经测试验证系统稳定性相比 Intel CPU 机型也略差一些。
对于 EMR 已有初步认知和管理能力而言,下一步就是如何提高对其掌控力。
入门篇已简单介绍如何在控制台创建 EMR 集群,官网有详细的操作文档给予用户指引,在此介绍其他创建方式。
当集群出现故障或人为手动终止且该集群上存在许多用户自定义配置项时,在 EMR 控制台页面有个克隆功能,可通过此功能镜像式创建新集群,新集群构建时会自动同步旧集群用户自定义配置项,避免配置项丢失或遗漏。
除 EMR 控制台外,用户还可基于 AWS CLI、AWS SDK、AWS WEB API 三种更高级定义的方式创建集群,先以 JSON 格式定义好集群模板,一键 POST 提交后静待十分钟,一个新鲜出炉的集群即已创建完毕。
一个 EMR 集群要上线,并不止于构建完毕,还需对集群环境做初始化工作,通常初始化操作分两步:操作系统及平台组件环境。
EMR 底层 EC2 实例所引用的系统映像已由后台针对大数据场景做针对性系统参数优化,因此,一般情况下用户无需再做定制化修改,只要初始化系统时区、Prometheus node_exporter 服务、dnsmasq、docker(若有网段定义冲突) 等基础服务设施即可。
泛指 HDFS/YARN/SPARK 之类组件配置项,EMR 初始化生成的组件配置项大多为默认值或者通用化模板配置,部分场景会存在不适用问题,因此建议用户务必按照集群运行环境所需进行修改。
例:spark-env.sh 在初始化过程若不去掉 Standalone 配置,提交 SPARK Application 后会因运行架构冲突导致访问时无法正确解析 SPARK MASTER WEB 服务地址。
export STANDALONE_SPARK_MASTER_HOST=ip-xxx-xxx-xxx-xxxexport SPARK_MASTER_PORT=7077export SPARK_MASTER_IP=$STANDALONE_SPARK_MASTER_HOSTexport SPARK_MASTER_WEBUI_PORT=8080
export SPARK_WORKER_DIR=${SPARK_WORKER_DIR:-/var/run/spark/work}export SPARK_WORKER_PORT=7078export SPARK_WORKER_WEBUI_PORT=8081export SPARK_PUBLIC_DNS=ip-xxx-xxx-xxx-xxx
复制代码
若用户需在 EMR 集群范围集成较多复杂组件,却又不想花费太多精力在部署运维上,可尝试使用自定义 AMI 映像方案。以我司为例,早期出于提交计算任务便利性和提高资源利用率考量,将调度平台 Airflow 与 EMR 混部,又因我司在 Airflow 使用场景较为复杂,部署运维不便,经调研后引入自定义 AMI 映像解决掉部署运维上带来的麻烦。
祸福相依的是此模式在持续稳定运行约一年后的某天突然爆雷:EMR 集群底层 EC2 实例所引用的自定义 AMI 映像被误删,这直接导致当天所有 EMR 集群无法扩容启动新 EC2 实例,基本处于半瘫状态。事发当天重新构建 AMI 映像,优先恢复 PROD 属性 EMR 集群,之后其余 EMR 集群分批铲除重新构建,过程持续近一个月才恢复到此前状态。
因此,备份的重要性,不言而喻。建议有在 EMR 集群内使用自定义 AMI 映像的用户,切记一定要保管好它,避免对线上生产环境造成损失。
具体是指对 EC2 实例和 EMR 平台服务打标签,便于之后告警项治理。打标签应成为一种习惯,从管理角度其价值不言而喻。
在我司,EC2 实例上线前会以类 userData 方式自动安装 node_exporter 服务,之后由 Prometheus server 拉取这些系统层指标,指标落地后使用 Grafana 展示,最后结合 Alertmanager 及自研监控平台实现指标项告警。
EMR 所提供的组件指标不能完全满足我司实际指标监控诉求,作为管理员可自行开发 exporter 服务将组件指标采集后汇聚到监控中心,依托于监控中心实现平台组件服务监控覆盖和告警能力,也可以将这些指标推送至 AWS cloudWatch 服务进行告警实现。
在没有 scale 机制的自建 Hadoop 集群,不可避免地会碰到计算资源问题 (不足或未用满),一种典型的做法是将计算引擎运行在 K8S 上,与业务平台错峰使用,以提高整体资源利用率。在 EMR 上用户可基于 cluster 或 InstanceGroup 两个层面定义 scaling 规则,规则触发后即进行集群节点扩缩容操作。
scale 一般是应用在需动态伸缩的 Core/Task 节点,Core 相对而言伸缩偏稳定保守一些,建议按比例固定。因此 scale 着重应用于 Task 节点并分别按 OnDemand&Spot 机型灵活配比,scale 配置时支持多种指标定义,用户可择其一或多指标组合形成多层次弹性伸缩规则。定义弹性伸缩策略时可参考如下规则:
客观地说,EMR Scaling 确实是个很棒的功能,激进一点调配使用,集群资源利用基本可达如下效果
一个 EMR 集群从触发创建请求到上线会大致经历这几个阶段:
于 EMR 初阶用户而言,上述阶段能感知到只有首尾阶段,其余部分基本像盲盒,对于中间过程执行情况一概不知。事实上这里列举的各个阶段皆有脉络可循:
local路径: /var/log/provision-node/apps-phase/<provision-number>
或
S3路径: s3://<bucket-name-for-emr-log>/<emr-id>/node/<master-node-id>/provision-node/apps-phase/<provision-number>
当上述阶段步骤执行全无问题后,即确认为集群节点服务部署正常,最后状态变更上线。
EMR 集群上线时会设定一些资源调度策略,该策略会最终影响计算任务调度分布。为提高单集群可承载计算任务并行数量,我们对该策略设定做了一些调整:在原有的 Core NodeLabel 设置基础之上,修改为 exclusive=true , 即分区独占模式。结合 YARN DominantResourceCalculator 调度策略,调整后 Core 队列有多少核 CPU,即可最高支撑多少个计算任务并行运行,在存算分离较彻底的 EMR 集群中使用 m5.8x、m5.12x 等实例机型作为 Core 节点,显著减低集群 Core 使用成本的同时还能提高集群计算并行度。
注意:EMR5 集群初始化时默认会将 CORE 节点设定为一个单独的 Node Label,YARN application 启动时 application master 进程只在 CORE 节点上运行,而 EMR6 集群已将此 CORE Node Label 机制默认关闭。
我司基于 Hive 构建企业级大数据平台元数据服务,存在多集群复用统一元数据库现象,从元数据库高可用及运维投入产出比方面考虑,选择 RDS 作为 Hive 等组件元数据库无疑是个明智之举,对于 Hive 元数据库这类读写 IO 要求不高的应用场景,甚至可开启多 A-Z 模式以提高其健壮性。
优点:
缺点:
既已使用了 EMR,那么选择 AWS S3 作为主数据存储就是自然而然的选择,一者存算分离是使用趋势,二者 EBS 与 S3 相比存储成本不在一个量级。在 EMR 体系中,Core 节点作为主数据存储节点,承载着分布式文件系统角色,典型应用有:
application log //存储YARN运行中、运行完成的application log
checkpoint //流计算作业状态存储
hdfs&hbase //KV型分布式数据库
我们仅将 EMR 用于计算而不涉及主数据存储,基于 S3 存储强一致性前提 (2021 年 12 月上线),已具备 checkpoint 或 hbase 场景迁移至 S3 可行性,我们将 checkpoint 从 HDFS 迁移至 AWS S3 后,集群 Core 节点只需存储 application log 及 hdfs 部分应用文件,显著降低存储成本。目前实时计算集群已支持近 200 个 Flink job 运行暂未发现明显问题,今后随着 Flink job 大规模使用,需关注 AWS S3 Bucket 吞吐性能,防止 put、get 达到一定上限,如存在此问题,建议与 AWS 团队沟通,或通过分区倒排序、加盐等方式进行处理,以支撑不断高并发、高吞吐场景。
以客观角度而言,AWS EMR 这一产品确实是提供了诸如节省成本、AWS 服务集成、部署、可灵活地扩展、安全性、监控、界面化管理这些功能特性。相较于其他云厂商亦或开源社区集群管理解决方案相比,虽各有千秋,但也存在有一定的改进空间。
节省成本:小规模场景使用综合成本节省比较明显,当规模达到 PB 级时,EC2、EMR、S3、网络流量四者成本累计则未必,所以需要进一步进行架构优化,以获取最佳性价比。
监控方面:集群缺乏组件服务状态如健康程度、HA 状态等类指标查看,可根据需要利用 exporter 采集。
集群部署 & 管理:基于快速构建集群设计思想,导致部署操作集成度较高,若过程出现异常,只能重新执行构建操作,无法断点连续操作,个别场景下集群验证有明显等待时间成本;EMR 组件只提供 initctl/systemd 系统进程管理方式,不支持按组件 / 进程级别进行启 / 停。
扩展伸缩:EMR scale 机制不支持以 CPU vCore 指标作为弹性伸缩规则,在混合计算业务场景 scale 伸缩某些时刻会不符合预期。
安全性:依托于 VPC 子网、安全组、IAM Role 等多重机制提供安全性保障,若结合 S3 层面数据安全访问管控,详见 AWS EMR 云上数据安全管控实践 一文。
该阶段标志着用户对 EMR 这套产品体系架构的理解程度已达入木三分之境地,日常 EMR 相关使用问题随手可解。因此,笔者认为这一阶段的特点应当不拘泥于官方对 EMR 使用定义,而是要结合各自企业应用场景,灵活调配组装以适应和满足业务需求,形成独有的解决方案架构。
早期,数据平台承载业务量不太,离线、实时计算任务集中在单一集群运行倒也问题不大,随着任务量暴涨、任务重要等级制定、任务属性划分的事项推进,我们按如下原则对集群进行拆分:
数据平台环境:PROD、GRAY、TEST
计算属性:离线、实时
拆分后集群单元从 3 个裂变为 4 个 (成本考量,GRAY、TEST 环境集群任务依然为混合模式运行)。
同城跨可用区集群切换实现
要知道云计算设计之初衷,便是假设一切皆不可靠。实际使用中 EMR 集群发生局部范围崩溃是个常态化现象,更有甚者,集群级别停服也偶有发生,因此早在 2020 下半年我们已开始规划当集群出现大面积崩溃或停服时如何快速恢复的方案,恢复方案历经多个迭代,迄今为止,我们已实现计算集群恢复时长从 2 小时 + 缩短至分钟级,实现思路请看下文。
不同计算属性集群切换方案因其集群计算依赖差异性,切换方案自然有所不同,因此在切换操作前务必先按离线、实时计算属性做好分离工作。
离线集群切换实现前提有四:
当需要进行集群切换操作时,只需修改调度 Airflow 集群中环境信息、Livy 或 Kyuubi 服务域名解析指向到新 EMR 集群即可实现切换。
受限于此前实时计算集群灾备切换尚未实现,未将计算任务按 (CPU/MEM) 属性分流到不同集群,个别任务会因底层计算 container 资源争抢受影响,导致计算延迟。相比于离线计算,实时计算集群切换实现要更加复杂,在计算存储分离、元数据统一的前提下,我们从以下方面实现了实时集群平滑切换:
我司当前 Flink 任务主要分为 FlinkSQL、JAR 两种类型,前者占比约九成,为方便用户使用 Flink 实时计算能力,数据平台研发人员基于 Flink+YARN API 另行开发实现一套流计算作业管理平台,既用于流计算作业编码提交,也用于集群作业管理,收拢实时计算任务提交入口。早期流计算作业管理平台与 EMR 集群捆绑式部署,使得仅支持单一集群提交指向,经迭代几个版本之后,目前已具备多集群指向提交能力。
checkpoint 机制作为卡死实现实时计算集群切换最重要的一道关卡,这点是毋庸置疑的。我司一开始使用 Spark StructedStreaming 处理实时计算任务,基于开发易用性、流计算处理机制、实时计算趋势等方面考虑于 2021 年上半年全面切换为 Flink。在使用 StructedStreaming 及 Flink 期间每逢有集群切换操作时,checkpoint 迁移与恢复都是令人无比头疼的事,中间分别做了两次 checkpoint on S3 方案调研工作,都受限于 S3 最终一致性问题效果不佳,所幸的是 AWS S3 在 2021 年底实现强一致性支持,简单验证了下基本满足 checkpoint 使用需求,最后基于 checkpoint on s3 可行性前提,我们规划及开发了任务在多集群内切换功能实现。
结合 PROD 环境离线、实时集群拆分操作,至此集群单位裂变为 7+(中间为保障实时计算高等级任务运行,再独立出一个集群单元)。
我们在 EMR 集群底层 EC2 实例使用选择上基本围绕着 C、M、R 三种机型,几种机型主要区别在于 vCPU/memory 的比例,C 型适用于 CPU 计算密集型任务 (除非极度需要 CPU 算力,不然成本相近条件下,不妨优先考虑 M 型),R 型适用于内存需求比较高的计算场景 (需缓存大量数据在内存中计算)。基于实际计算任务运行所需,在较大规模生产集群中我们选择以 m5/m5a.8xlarge 机型为主,m5/m5a.4xlarge 机型为辅,次之规模集群则按业务计算属性灵活搭配。
至于 G 型属于 ARM 芯片架构,因 EMR 是个多组件嵌套大型集群平台,且我司有对部分组件做二开,从集群组件底层兼容性适配验证考量,暂未纳入使用,我司目前将 G 型用于 Cassandra 数据库集群,计算效率有比较明显的提升。
EMR 集群构建时可选择实例组管理方式: 统一实例组、实例队列。
我们主要使用统一实例组方式构建集群,结合自定义 scale 规则管理集群计算资源,原因如下:
a. EMR-Managed scaling 方式按照节点负载进行弹性伸缩,规则局限性很明显。
b. 至于不使用实例队列 (InstanceFleet) 的原因也是因为规则存在明显局限性,如一旦在集群创建时定义好实例组类型,之后无法进行实例组配置修改,对于需长期运行的生产集群,管理灵活度欠佳。
C. 使用自定义 scale 规则,管理员可以定义多个指标 (如集群存储使用占比、Container Pending 值、内存使用值等) 作为弹性规则供 AWS 后台判断是否需对集群进行扩缩容。
因 Spot 类型资源较容易出现紧俏现象,为提高集群计算稳定性,避免节点频繁上下线带来的波动影响,我们基本将其从生产集群使用中剔除,主力使用 OnDemand 类型,结合主动 + 被动伸缩策略管理 OnDemand 机型数量。被动策略跟之前一样,由 EMR 监控集群状态指标被动进行伸缩调整,主动伸缩策略初期规划是根据历史资源占用指标值,将资源所需换算成具体 EC2 实例所需数量,提前主动发起资源申请,在业务计算节点来临之前准备好计算资源,最大程度保证计算效率及利用集群计算资源,主动伸缩效果如下图所示:
因离线计算集群存在资源争抢问题,有一定几率促使高优先等级任务运行时申请不到资源,为保证该类型任务申请时有足够资源,集群资源管控策略需做调整优化。EMR YARN 默认以 capacity-scheduler 策略管理及调度集群计算资源,资源调配上不如 fair-scheduler 策略灵活。
笔者曾尝试 EMR 集群集成 fair-scheduler 可行性调研,结论是 YARN 集群所有 nodemanager 节点上需存在 fair-scheduler.xml,方可执行 fair-scheduler 调度策略,而 emr 控制台不支持 fair-scheduler 配置分发,虽可勉强通过 bootstrap 方式支持,但远没有 capacity-scheduler 兼容性好。退而求其次,转为研究 capacity-scheduler 队列资源隔离划分,目前已验证可行并即将上线至生产集群。
受历史包袱影响,当前我司数据平台基础组件部分版本有些错综不一,出于提高平台整体服务执行效率和统一数据平台基础组件版本信息考量,长远规划,有必要对数据平台基础设施进行整改升级,主要升级列表如下:
EMR: 5 --> 6Spark: 2 --> 3Flink: 1.12 --> 1.13Hudi: 0.6 --> 0.11
复制代码
数据平台基础设施大范围升级牵扯范围极大且操作复杂,以上述列表中所涉及平台组件为例,稍有差池即为平台级别故障,因篇幅有限,加上我们目前尚在实施过程中,待完成后有机会的话笔者单写一篇介绍。
伴随我司业务快速发展,数据平台底层基础设施也在不断调整以适应这种变化,而繁多的集群环境和庞大组件矩阵也给数据平台使用者、管理者带来极大的不便。例如:数据平台使用者应专注于业务开发本身而无需过多关注平台底层基础设施运转逻辑、环境信息,避免增加学习使用成本。
为此,我们针对性规划一个平台,开发实现多集群统一管理、数据平台计算资源治理、离线 / 实时任务管理、数据生命周期等功能,辅助平台使用者更便捷地使用数据平台资产的同时为下一步推动降本增效的开展提供治理依据。
自 2020 年开始使用 EMR 至今,我们从多种渠道了解、探索 EMR 相关实践,自身也在不断地深入压榨 EMR 以满足业务计算所需,即便如此,仍有力所不逮之处:
文末,感谢在此过程中 AWS EMR 相关团队对我们的支持。
作者介绍:
吴建阳,朴朴科技大数据运维负责人,主要负责支撑朴朴大数据平台离线 / 实时计算、数据湖、OLAP 等基础设施,具有多年的大数据实战经验。
翁建清,AWS 资深解决方案架构师,具有多年 IT 从业经验,涉及移动互联网、企业、金融、政府等行业,曾任职咨询总监、CIO、企业架构师等岗位,具有多年丰富的各类项目经验,尤其在数据仓库、大数据、数据应用场景等方面具有丰富的实战经验,目前专注于企业整体上云的架构规划、设计和实施。
领取专属 10元无门槛券
私享最新 技术干货