-
HDFS的DataNode在低频率重启过程中,HBase集群的RegionServer WAL写流程,会偶现以下WAL超时卡住错误,如何解决呢:2024-08-26 15:35:13,294 ERROR [RS_CLOSE_REGION-regionserver/cqbs028:60020-1] executor.EventHandler: Caught throwable while processing event M_RS_CLOSE_REGIONjava.lang.RuntimeException: org.apache.hadoop.hbase.exceptions.TimeoutIOException: Failed to get sync result after 300000 ms for txid=818811, WAL system stuck?at org.apache.hadoop.hbase.regionserver.handler.CloseRegionHandler.process(CloseRegionHandler.java:116)at org.apache.hadoop.hbase.executor.EventHandler.run(EventHandler.java:104)Caused by: org.apache.hadoop.hbase.exceptions.TimeoutIOException: Failed to get sync result after 300000 ms for txid=818811, WAL system stuck?at org.apache.hadoop.hbase.regionserver.wal.SyncFuture.get(SyncFuture.java:148)at org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL.blockOnSync(AbstractFSWAL.java:711)at org.apache.hadoop.hbase.regionserver.wal.AsyncFSWAL.sync(AsyncFSWAL.java:631)at org.apache.hadoop.hbase.regionserver.wal.WALUtil.doFullAppendTransaction(WALUtil.java:158)at org.apache.hadoop.hbase.regionserver.wal.WALUtil.writeMarker(WALUtil.java:136)at org.apache.hadoop.hbase.regionserver.wal.WALUtil.writeRegionEventMarker(WALUtil.java:101)at org.apache.hadoop.hbase.regionserver.HRegion.writeRegionCloseMarker(HRegion.java:1145)at org.apache.hadoop.hbase.regionserver.HRegion.doClose(HRegion.java:1684)at org.apache.hadoop.hbase.regionserver.HRegion.close(HRegion.java:1501)at org.apache.hadoop.hbase.regionserver.handler.CloseRegionHandler.process(CloseRegionHandler.java:104)在停止RegionServer的过程中,也有可能会因为WAL卡住,停止RegionServer慢:java.lang.RuntimeException: org.apache.hadoop.hbase.exceptions.TimeoutIOException: Failed to get sync result after 300000 ms for txid=818767, WAL system stuck?at org.apache.hadoop.hbase.regionserver.handler.CloseRegionHandler.process(CloseRegionHandler.java:116)at org.apache.hadoop.hbase.executor.EventHandler.run(EventHandler.java:104)at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)at java.base/java.lang.Thread.run(Thread.java:829)Caused by: org.apache.hadoop.hbase.exceptions.TimeoutIOException: Failed to get sync result after 300000 ms for txid=818767, WAL system stuck?at org.apache.hadoop.hbase.regionserver.wal.SyncFuture.get(SyncFuture.java:148)at org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL.blockOnSync(AbstractFSWAL.java:711)at org.apache.hadoop.hbase.regionserver.wal.AsyncFSWAL.sync(AsyncFSWAL.java:631)at org.apache.hadoop.hbase.regionserver.wal.WALUtil.doFullAppendTransaction(WALUtil.java:158)at org.apache.hadoop.hbase.regionserver.wal.WALUtil.writeMarker(WALUtil.java:136)at org.apache.hadoop.hbase.regionserver.wal.WALUtil.writeRegionEventMarker(WALUtil.java:101)at org.apache.hadoop.hbase.regionserver.HRegion.writeRegionCloseMarker(HRegion.java:1145)at org.apache.hadoop.hbase.regionserver.HRegion.doClose(HRegion.java:1684)at org.apache.hadoop.hbase.regionserver.HRegion.close(HRegion.java:1501)at org.apache.hadoop.hbase.regionserver.handler.CloseRegionHandler.process(CloseRegionHandler.java:104)
-
profile 这是sqoop 路径这是测试sqoop是否安装成功所返回的
-
环境:FusionInsight HD 6513背景: 1. 原集群datanode 机器基本为ARM,且配置较高,设备较新; 2. 现有一批低性能、低配置X86主机,需扩容到集群中;计划:启动HDFS NodeLabel 功能,对HDFS 目录进行打标签,将后扩容主机设置成指定标签目录的主机,以此来规避机器异构可能出现的负载不均等问题。需求: 1. 帮忙确认一下该方案是否可行,是否有更好的方案。 2. 如果此方案可行,是否有需要注意的方向,是否有踩坑案例(越详细越好)可以提供一下。烦请社区的大佬,帮帮忙!
-
1 背景Yarn的任务的统计结果在HDFS的指定文件(/mr-history/done/2023/05/15 目录 xxx.jhist 文件)存放。解析该文件,即可最小化影响HDFS性能(统计每个MR的counter只需访问1次HDFS,获取该20K文件,然后在客户端解析文件内容即可)2 获取xxx.jhist文件查看对应日期的jhist文件(如:2023年5月23日):hdfs dfs -ls /mr-history/done/2023/05/23/000000下载jhist文件:hdfs dfs -get /mr-history/done/2023/05/23/000000/job_1683342225080_0138-1684848693047-Loader%3A+testsftp2hive_1684848475163-1684848723140-1-0-SUCCEEDED-default-1684848703642.jhist3 解析counter示例使用java代码解析counter3.1 添加依赖<dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>${hadoop.version}</version></dependency><dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-common</artifactId> <version>${hadoop.version}</version></dependency><dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-hs</artifactId> <version>${hadoop.version}</version></dependency><dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.8.5</version></dependency>3.2 解析代码package com.huawei.bigdata.mapreduce.examples;import static org.mockito.Mockito.mock;import org.apache.hadoop.mapreduce.Counter;import org.apache.hadoop.mapreduce.CounterGroup;import org.apache.hadoop.mapreduce.v2.hs.CompletedJob;import org.apache.hadoop.mapreduce.v2.hs.HistoryFileManager.HistoryFileInfo;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path;import org.apache.hadoop.mapred.JobACLsManager;import org.apache.hadoop.mapreduce.v2.api.records.JobId;import java.io.IOException;public class TestYarnCounter { public static void main(String args[]) { Path fullHistoryPath = new Path("D:\\history\ job_1683342225080_0138-1684848693047-Loader%3A+testsftp2hive_1684848475163-1684848723140-1-0-SUCCEEDED-default-1684848703642.jhist"); Configuration conf = new Configuration(); boolean loadTasks = false; HistoryFileInfo info = mock(HistoryFileInfo.class); JobId jobId = null; JobACLsManager jobAclsManager = new JobACLsManager(conf); try { CompletedJob completedJob = new CompletedJob(conf, jobId, fullHistoryPath, loadTasks, "user", info, jobAclsManager); CounterGroup counterGroup = completedJob.getAllCounters() .getGroup("org.apache.hadoop.mapreduce.FileSystemCounter"); for (Counter counter : counterGroup) { System.out.println(counter.getName() + ":" + counter.getValue()); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}4 运行结果FILE_BYTES_READ:0FILE_BYTES_WRITTEN:393363FILE_READ_OPS:0FILE_LARGE_READ_OPS:0FILE_WRITE_OPS:0HDFS_BYTES_READ:204HDFS_BYTES_WRITTEN:153HDFS_READ_OPS:3HDFS_LARGE_READ_OPS:0HDFS_WRITE_OPS:3运行的结果也可在ResourceManager WebUI页面查看:点击对应的application id,显示如下页面 在该页面点击history,查看counter信息
-
目前ambari已经停服,ambari默认只能运行在python2。7的环境上
-
一、Hadoop常见的三种运行模式1、单机模式(独立模式)(Local或Standalone Mode) 默认情况下Hadoop就是处于该模式,用于开发和调式。不对配置文件进行修改。使用本地文件系统,而不是分布式文件系统。 Hadoop不会启动NameNode、DataNode、JobTracker、TaskTracker等守护进程,Map()和Reduce()任务作为同一个进程的不同部分来执行的。 用于对MapReduce程序的逻辑进行调试,确保程序的正确。2、伪分布式模式(Pseudo-Distrubuted Mode) Hadoop的守护进程运行在本机机器,模拟一个小规模的集群,在一台主机模拟多主机。 Hadoop启动NameNode、DataNode、JobTracker、TaskTracker这些守护进程都在同一台机器上运行,是相互独立的Java进程。 在这种模式下,Hadoop使用的是分布式文件系统,各个作业也是由JobTraker服务,来管理的独立进程。在单机模式之上增加了代码调试功能,允许检查内存使用情况,HDFS输入输出,以及其他的守护进程交互。类似于完全分布式模式,因此,这种模式常用来开发测试Hadoop程序的执行是否正确。3、全分布式集群模式(Full-Distributed Mode) Hadoop的守护进程运行在一个集群上 Hadoop的守护进程运行在由多台主机搭建的集群上,是真正的生产环境。下载并解压Hadoop、JDK安装包并配置好环境变量、节点域名解析、防火墙、端口等组成相互连通的网络。进入Hadoop的解压目录,编辑hadoop-env.sh文件(注意不同版本后配置文件的位置有所变化)编辑Hadoop中配置文件core-site.xml(Hadoop集群的特性,作用于全部进程及客户端)、hdfs-site.xml(配置HDFS集群的工作属性)、mapred-site.xml(配置MapReduce集群的属性)、yarn-site.xml四个核心配置文件配置ssh,生成密钥,使到ssh可以免密码连接localhost,把各从节点生成的公钥添加到主节点的信任列表。格式化HDFS后 使用./start-all.sh启动Hadoop集群二、Hadoop常见组件Hadoop由HDFS、Yarn、Mapreduce三个核心模块组成,分别负责分布式存储、资源分配和管理、分布式计算。1、Hadoop-HDFS模块HDFS:是一种分布式存储系统,采用Master和Slave的主从结构,主要由NameNode和DataNode组成。HDFS会将文件按固定大小切成若干块,分布式存储在所有DataNode中,每个文件块可以有多个副本,默认副本数为3。NameNode: Master节点,负责元数据的管理,处理客户端请求。DataNode: Slave节点,负责数据的存储和读写操作。2、Hadoop-Yarn模块Yarn:是一种分布式资源调度框架,采用Master和Slave的主从结构,主要由ResourceManager . ApplicationMaster和NodeManager组成,负责整个集群的资源管理和调度。ResourceManager:是一个全局的资源管理器,负责整个集群的资源管理和分配。ApplicationMaster:当用户提交应用程序时启动,负责向ResourceManager申请资源和应用程序的管理。NodeManager:运行在Slave节点,负责该节点的资源管理和使用。Container: Yarn的资源抽象,是执行具体应用的基本单位,任何一个Job或应用程序必须运行在一个或多个Container中。3、Hadoop-Mapreduce模块Mapreduce:是一种分布式计算框架,主要由Map和Reduce两个阶段组成。支持将一个计算任务划分为多个子任务,分散到各集群节点并行计算。Map阶段:将初始数据分成多份,由多个map任务并行处理。Reduce阶段:收集多个Map任务的输出结果并进行合并,最终形成一个文件作为reduce阶段的结果。全分布式集群模式(Full-Distributed Mode)搭建【基本环境】三台鲲鹏km1.2xlarge.8内存优化型 8vCPUs | 64GB CentOS 7.6 64bit with ARM CPU:Huawei Kunpeng 920 2.6GHz其中jack20节点作为NameNode, Node1、 Node2作为DataNode,而Node1也作为辅助NameNode ( Secondary NameNode )。【基本流程】下载并解压Hadoop、JDK安装包并配置好环境变量、节点域名解析、防火墙、端口进入Hadoop的解压目录,编辑hadoop-env.sh文件(注意不同版本后配置文件的位置有所变化)编辑Hadoop中配置文件core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml四个核心配置文件配置ssh,生成密钥,使到ssh可以免密码连接localhost 格式化HDFS后 使用./start-all.sh启动Hadoop集群关闭防火墙和selinux(1)各个节点都执行命令关闭防火墙:systemctl stop firewalldsystemctl disable firewalldsystemctl status firewalld(2)关闭selinux进入selinux的config文件,将selinux原来的强制模式(enforcing)修改为关闭模式(disabled)setenforce 0getenforcesed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinuxgrep SELINUX=disabled /etc/sysconfig/selinuxcat /etc/sysconfig/selinux1.安装openJDK-1.8.01.1. 下载安装openJDK-1.8.0下载openJDK-1.8.0并安装到指定目录(如“/home”)。进入目录:cd /home下载openJDK-1.8.0并安装:wget https://sandbox-experiment-resource-north-4.obs.cn-north-4.myhuaweicloud.com/hadoop-performance-tuning/OpenJDK8U-jdk_aarch64_linux_hotspot_8u252b09.tar.gz#解压tar -zxf OpenJDK8U-jdk_aarch64_linux_hotspot_8u252b09.tar.gz1.2. 配置环境变量执行如下命令,打开/etc/profile文件:vim /etc/profile点击键盘"Shift+g"移动光标至文件末尾,单击键盘“i”键进入编辑模式,在代码末尾回车下一行,添加如下内容:export JAVA_HOME=/home/jdk8u252-b09export PATH=$JAVA_HOME/bin:$PATHexport CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar添加完成,单击键盘ESC退出编辑,键入“:wq”回车保存并退出。 1.3. 环境变量生效使环境变量生效:source /etc/profile验证openJDK-1.8.0安装是否成功:java -version1.4.配置域名解析vim /etc/hosts2.安装dstat资源监控工具yum install dstat-0.7.2-12.el7 -y验证dstat是否安装成功:dstat -V3. 部署hadoop-3.1.13. 1. 获取hadoop-3.1.1软件包①下载hadoop-3.1.1安装包到/home目录下:cd /homewget https://sandbox-experiment-resource-north-4.obs.cn-north-4.myhuaweicloud.com/hadoop-performance-tuning/hadoop-3.1.1.tar.gz#解压hadoop-3.1.1tar -zxvf hadoop-3.1.1.tar.gz②建立软链接ln -s hadoop-3.1.1 hadoop③配置hadoop环境变量,打开/etc/profile文件:vim /etc/profile点击键盘"Shift+g"移动光标至文件末尾,单击键盘“i”键进入编辑模式,在代码末尾回车下一行,添加如下内容:export HADOOP_HOME=/home/hadoopexport PATH=$HADOOP_HOME/bin:$PATH添加完成,单击键盘ESC退出编辑,键入“:wq”回车保存并退出。④使环境变量生效:source /etc/profile⑤验证hadoop安装是否成功:hadoop version执行结果如下图所示,表示安装成功:3.2. 修改hadoop配置文件hadoop所有的配置文件都在$HADOOP_HOME/etc/hadoop目录下,修改以下配置文件前,需要切换到"$HADOOP_HOME/etc/hadoop"目录。cd $HADOOP_HOME/etc/hadoop/①修改hdfs-env.xml打开hadoop-env.sh文件:vim hadoop-env.sh找到hadoop-env.sh的第54行中的java目录(在命令模式下输入“:set nu”,查看行数),输入java的安装目录(),然后删除行左端“#”取消注释,并保存退出② 修改core-site.xml打开core-site.xml文件vim core-site.xml在标签之间添加如下代码并保存退出 fs.defaultFS hdfs://jack20:9000/ 设定NameNode的主机名及端口 hadoop.tmp.dir /home/hadoop/tmp/hadoop-${user.name} 指定hadoop 存储临时文件的目录 hadoop.proxyuser.hadoop.hosts * 配置该superUser允许通过代理的用户 hadoop.proxyuser.hadoop.groups * 配置该superUser允许通过代理用户所属组 ③ 修改hdfs-site.xml,打开hdfs-site.xml文件vim hdfs-site.xml在标签之间添加如下代码并保存退出 dfs.namenode.http-address jack20:50070 NameNode 地址和端口 dfs.namenode.secondary.http-address node1:50090 Secondary NameNode地址和端口 dfs.replication 3 设定 HDFS 存储文件的副本个数,默认为3 dfs.namenode.name.dir file:///home/hadoop/hadoop3.1/hdfs/name NameNode用来持续存储命名空间和交换日志的本地文件系统路径 dfs.datanode.data.dir file:///home/hadoop/hadoop3.1/hdfs/data DataNode在本地存储块文件的目录列表 dfs.namenode.checkpoint.dir file:///home/hadoop/hadoop3.1/hdfs/namesecondary 设置 Secondary NameNode存储临时镜像的本地文件系统路径。如果这是一个用逗号分隔的文件列表,则镜像将会冗余复制到所有目录 dfs.webhdfs.enabled true 是否允许网页浏览HDFS文件 dfs.stream-buffer-size 1048576 默认是4 KB,作为Hadoop缓冲区,用于Hadoop读HDFS的文件和写HDFS的文件, 还有map的输出都用到了这个缓冲区容量(如果太大了map和reduce任务可能会内存溢出) ④修改mapred-site.xml打开mapred-site.xml文件:vim mapred-site.xml在标签之间添加如下代码并保存退出 mapreduce.jobhistory.address jack20:10020 指定历史服务器端地址和端口 mapreduce.jobhistory.webapp.address jack20:19888 历史服务器web端地址和端口 mapreduce.application.classpath /home/hadoop/etc/hadoop, /home/hadoop/share/hadoop/common/*, /home/hadoop/share/hadoop/common/lib/*, /home/hadoop/share/hadoop/hdfs/*, /home/hadoop/share/hadoop/hdfs/lib/*, /home/hadoop/share/hadoop/mapreduce/*, /home/hadoop/share/hadoop/mapreduce/lib/*, /home/hadoop/share/hadoop/yarn/*, /home/hadoop/share/hadoop/yarn/lib/* mapreduce.map.memory.mb 6144 map container配置的内存的大小(调整到合适大小防止物理内存溢出) mapreduce.reduce.memory.mb 6144 reduce container配置的内存的大小(调整到合适大小防止物理内存溢出) yarn.app.mapreduce.am.env HADOOP_MAPRED_HOME=/home/hadoop mapreduce.map.env HADOOP_MAPRED_HOME=/home/hadoop mapreduce.reduce.env HADOOP_MAPRED_HOME=/home/hadoop ⑤修改yarn-site.xml打开yarn-site.xml文件:vim yarn-site.xml在标签之间添加如下代码并保存退出 yarn.resourcemanager.hostname jack20 指定ResourceManager的主机名 yarn.nodemanager.resource.memory-mb 53248 NodeManager总的可用物理内存。 注意:该参数是不可修改的,一旦设置,整个运行过程中不可动态修改。 该参数的默认值是8192MB,即使你的机器内存不够8192MB,YARN也会按照这些内存来使用, 因此,这个值通过一定要配置。 yarn.nodemanager.aux-services mapreduce_shuffle 指定MapReduce走shuffle yarn.nodemanager.aux-services.mapreduce.shuffle.class org.apache.hadoop.mapred.ShuffleHandler yarn.resourcemanager.address jack20:8032 指定ResourceManager对客户端暴露的地址和端口,客户端通过该地址向RM提交应用程序,杀死应用程序等 yarn.resourcemanager.scheduler.address jack20:8030 指定ResourceManager对ApplicationMaster暴露的访问地址。ApplicationMaster通过该地址向RM申请资源、释放资源等 yarn.resourcemanager.resource-tracker.address jack20:8031 指定ResourceManager对NodeManager暴露的地址。NodeManager通过该地址向RM汇报心跳,领取任务等 yarn.resourcemanager.admin.address jack20:8033 指定ResourceManager 对管理员暴露的访问地址。管理员通过该地址向RM发送管理命令等 yarn.resourcemanager.webapp.address jack20:8088 指定ResourceManager对外web UI地址。用户可通过该地址在浏览器中查看集群各类信息 yarn.log-aggregation-enable true 开启日志聚集功能 yarn.log.server.url http://jack20:19888/jobhistory/logs 设置日志聚集服务器地址 yarn.log-aggregation.retain-seconds 604800 设置日志保留时间为7天 ⑥将各个节点加入到workersecho jack20 > workersecho node1 > workersecho node2 > workers⑦修改dfs和yarn的启动脚本,添加root用户权限(1)打开start-dfs.sh和stop-dfs.sh文件:vim /home/hadoop/sbin/start-dfs.shvim /home/hadoop/sbin/stop-dfs.sh单击键盘“i”键进入编辑模式,在两个配置文件的第一行添加并保存退出:HDFS_DATANODE_USER=rootHDFS_DATANODE_SECURE_USER=hdfsHDFS_NAMENODE_USER=rootHDFS_SECONDARYNAMENODE_USER=root(2)打开start-yarn.sh 和 stop-yarn.sh文件vim /home/hadoop/sbin/start-yarn.shvim /home/hadoop/sbin/stop-yarn.sh单击键盘“i”键进入编辑模式,在两个配置文件的第一行添加并保存退出:YARN_RESOURCEMANAGER_USER=rootHADOOP_SECURE_DN_USER=yarnYARN_NODEMANAGER_USER=root4.集群配置&节点间免密登录(1)连通性测试(2)从主节点同步各个节点域名解析文件scp /etc/hosts node1:/etc/hostsscp /etc/hosts node2:/etc/hosts(3) 配置各节点间SSH免密登录分别在三台服务器中输入命令生成私钥和公钥(提示输入时按回车即可):ssh-keygen -t rsajack20:node1:node2:然后分别在三台服务器上输入命令以复制公钥到服务器中:ssh-copy-id -i ~/.ssh/id_rsa.pub root@jack20ssh-copy-id -i ~/.ssh/id_rsa.pub root@node1ssh-copy-id -i ~/.ssh/id_rsa.pub root@node2①继续连接:输入“yes”回车;②输入密码(输入密码时,命令行窗口不会显示密码,输完之后直接回车)查看所有协商的秘钥SSH免密登录测试:Jack20->node1->node2->jack20->node2->node1->jack20(4) 复制hadoop到各datanode并修改把jack20的hadoop目录、jdk目录、/etc/hosts、/etc/profile复制到node1,node2节点cd $HADOOP_HOME/..#hadoop目录scp -r hadoop node1:/homescp -r hadoop node2:/home #java目录scp -r jdk8u252-b09 node1:/homescp -r jdk8u252-b09 node2:/home登录修改各服务器java和haoop环境变量vim /etc/profile点击键盘"Shift+g"移动光标至文件末尾,单击键盘“i”键进入编辑模式,在代码末尾回车下一行,添加如下内容并保存退出:export JAVA_HOME=/home/jdk8u252-b09export PATH=$JAVA_HOME/bin:$PATHexport CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarexport HADOOP_HOME=/home/hadoopexport PATH=$HADOOP_HOME/bin:$PATH使环境变量生效:source /etc/profile5.启动hadoop注意:如果启动报错,请检查hadoop配置文件是否配置有误。第一次启动前一定要格式化HDFS:hdfs namenode -format注意:提示信息的倒数第2行出现“>= 0”表示格式化成功,如图。在Linux中,0表示成功,1表示失败。因此,如果返回“1”,就应该好好分析前面的错误提示信息,一 般来说是前面配置文件和hosts文件的问题,修改后同步到其他节点上以保持相同环境,再接着执行格式化操作执行脚本命令群起节点cd /home/hadoop/sbin#群起节点./start-all.sh 启动HDFS后,可以发现jack20节点作为NameNode, Node1、 Node2作为DataNode,而Node1也作为辅助NameNode ( Secondary NameNode )。可以通过jps命令在各节点上验证HDFS是否启动。jps 也是Windows中的命令,表示开启的Java进程如果出现下图所示的结果,就表示验证成功。客户端Web访问测试:(1)RMwebUI界面http://IP:8088(2)NameNode的webUI界面http://IP:500706.集群基准测试(1)使用Hadoop自带的WordCount例子/share/Hadoop/mapredu icehadoop-mapreduce-examples-3.1.1.jar验证集群#创建目录,目录/data/wordcount用来存储Hadoop自带的WordCount例子的数据文件,运行这个MapReduce任务的结果输出到目录中的/output/wordcount文件中hdfs dfs -mkdir -p /data/wordcounthdfs dfs -mkdir -p /output/ #将本地文件上传到HDFS中(这里上传一个配置文件),执行如下命令hdfs dfs -put /home/hadoop/etc/hadoop/core-site.xml /data/wordcount可以查看,上传后的文件情况,执行如下命令hdfs dfs -ls /data/wordcount下面运行WordCount案例,执行如下命令hadoop jar /home/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.1.jar wordcount /data/wordcount /output/wordcount(2)DFSIO测试使用hadoop的DFSIO写入50个文件,每个文件1000Mhadoop jar /home/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.1-tests.jar TestDFSIO -write -nrFiles 50 -filesize 1000可以在RMwebUI界面查看当前任务的基本情况,包括内存使用量,CPU使用量等在NameNode的webUI界面查看刚刚DFSIO测试的各个节点HDFS占用情况(3)计算圆周率的大小hadoop jar /home/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.1-tests.jar pi 20 20静静等待结果就可以~
-
如图,decimal类型的数据写入hdfs后,通过hive external表读取,两边类型一致(均为decimal)时,hive读取的值为NULL,当修改hive external数据类型为String时,读取到的值为7014XXXX,烦请专家予以解答。
-
1. 问题描述HUAWEI,Kunpeng 920Kylin Linux Advanced Server release V10 (Sword)达梦V8在使用Ambari安装包ambari-2.7.3.0-openEuler20.03.tar.gz后,安装配置Ambari-server报错,其中使用达梦v8替代oracle作为ambari元数据库关键步骤1:将DmJdbcDriver18.jar重命名为ojdbc7.jar,放置在/usr/share/java下ambari-server setup --jdbc-db=oracle --jdbc-driver=/usr/share/java/ojdbc7.jarchmod 644 /usr/share/java/ojdbc7.jar:关键步骤2:修改配置文件ambari.properties如下:vim /etc/ambari-server/conf/ambari.propertiesulimit.open.files=65536server.jdbc.driver.path=/usr/share/java/DmJdbcDriver18.jarjava.home=/opt/jdk8u222-b10server.jdbc.hostname=arm-ky10-23-2#server.jdbc.driver=oracle.jdbc.driver.OracleDriverserver.jdbc.driver=dm.jdbc.driver.DmDriverserver.jdbc.rca.user.name=ambariserver.jdbc.database=oracleserver.jdbc.database_name=ambari#server.jdbc.rca.url=jdbc:oracle:thin:@arm-ky10-23-2:5236/ambariserver.jdbc.rca.url=jdbc:dm://arm-ky10-23-2:5236?schema=ambaricustom.oracle.jdbc.name=DmJdbcDriver18.jarbootstrap.script=/usr/lib/ambari-server/lib/ambari_server/bootstrap.pyserver.version.file=/var/lib/ambari-server/resources/versiongpl.license.accepted=truejdk1.8.dest-file=jdk-8u112-linux-x64.tar.gzserver.task.timeout=1200#server.jdbc.rca.driver=oracle.jdbc.driver.OracleDriverserver.jdbc.rca.driver=dm.jdbc.driver.DmDriver#server.jdbc.url=jdbc:oracle:thin:@arm-ky10-23-2:5236/ambariserver.jdbc.url=jdbc:dm://arm-ky10-23-2:5236?schema=ambari执行ambari-server start后报错:INFO: An exception was caught and reported. Message: java.lang.RuntimeException: The database type could be not determined from the JDBC URL jdbc:dm://arm-ky10-23-2:5236/ambarijava.lang.RuntimeException: The database type could be not determined from the JDBC URL jdbc:dm://arm-ky10-23-2:5236/ambari at org.apache.ambari.server.configuration.Configuration.getDatabaseType(Configuration.java:4944) at org.apache.ambari.server.controller.ControllerModule.getPersistenceProperties(ControllerModule.java:224) at org.apache.ambari.server.controller.ControllerModule.buildJpaPersistModule(ControllerModule.java:418) at org.apache.ambari.server.controller.ControllerModule.configure(ControllerModule.java:343) at com.google.inject.AbstractModule.configure(AbstractModule.java:62) at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340) at com.google.inject.spi.Elements.getElements(Elements.java:110) at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:138) at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:104) at com.google.inject.Guice.createInjector(Guice.java:99) at com.google.inject.Guice.createInjector(Guice.java:73) at com.google.inject.Guice.createInjector(Guice.java:62) at org.apache.ambari.server.controller.AmbariServer.main(AmbariServer.java:1079)Exception in thread "main" com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalStateException: Recursive load of: org.apache.ambari.server.events.publishers.STOMPUpdatePublisher.() at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2203) at com.google.common.cache.LocalCache.get(LocalCache.java:3937) at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941) at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824) at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4830) at com.google.inject.internal.FailableCache.get(FailableCache.java:48) at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:50) at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:138) at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:550) at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:887) at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:808) at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:285) at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:217) at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:893) at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46) at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50) at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:134) at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107) at com.google.inject.Guice.createInjector(Guice.java:99) at com.google.inject.Guice.createInjector(Guice.java:73) at com.google.inject.Guice.createInjector(Guice.java:62) at org.apache.ambari.server.controller.AmbariServer.main(AmbariServer.java:1079)
-
大佬们好,我们再对接华为大数据平台【FusionInsight Manager】时出现了一下问题问题描述:我们设计的Yarn任务提交设计以下几个步骤:检测 Yarn执行资源是否充足 【成功】QueueInfo queueInfo = yarnClient.getQueueInfo(amClientContext.getQueueName());设置yarn运行相关信息【成功】//部分代码 appContext.setApplicationName(amClientContext.getAppName()); appContext.setAttemptFailuresValidityInterval(20000); Set tags = new HashSet<>(1); tags.add("ddmp"); appContext.setApplicationTags(tags); ApplicationId appId = appContext.getApplicationId();上传待运行的任务至HDFS 【成功】 以下是部分代码,上传资源,包括设置yarn执行相关的环境变量,将AppMaster任务信息设置好/** * 添加一个本地资源到远程 * * @param fs 文件系统 * @param fileSrcPath 要上传的文件 * @param fileName 文件名 * @param appId 应用id * @param localResources 本地文件资源映射 * @param resources 文件资源 ,有时候我们并没有实际的资源信息,只有一个类似于命令操作,如果我们想将该命令生成一个文件并上传,就可以将该命令写在这里 * @throws IOException 异常信息 */ private void addToLocalResources(String appName, FileSystem fs, String fileSrcPath, String fileName, String appId, Map localResources, String resources) throws IOException { //获取要上传的目录路径 String suffix = appName + "/" + appId + "/" + fileName; Path dst = new Path(fs.getHomeDirectory(), suffix); //当要上传的文件不存在的时候 尝试将 resources 文件写入到一个目录中 if (fileSrcPath == null) { FSDataOutputStream ostream = null; try { //赋予 可读,可写,可执行的权限 ostream = FileSystem.create(fs, dst, new FsPermission((short) 456)); ostream.writeUTF(resources); } finally { IOUtils.closeStream(ostream); } } else { //将要上传的文件拷贝到对应的目录中 fs.copyFromLocalFile(new Path(fileSrcPath), dst); } //获取刚刚上传的文件的状态 FileStatus scFileStatus = fs.getFileStatus(dst); //创建一个本地资源映射 hdfs URI uri = dst.toUri(); URL url = URL.fromURI(uri); long len = scFileStatus.getLen(); long modificationTime = scFileStatus.getModificationTime(); LocalResource scRsrc = LocalResource.newInstance(url, LocalResourceType.FILE, LocalResourceVisibility.APPLICATION, len, modificationTime); //放入到资源映射中 localResources.put(fileName, scRsrc); }提交AppMaster任务到Yarn引擎 【失败】// 为应用程序主机设置容器启动上下文 ContainerLaunchContext amContainer = ContainerLaunchContext.newInstance(localResourceMap, env, commands, null, null, null); //权限处理 securityCheck(amContainer, amClientContext); //将容器设置进上下文对象 appContext.setAMContainerSpec(amContainer); //配置任务优先级状态 Priority pri = Priority.newInstance(0); appContext.setPriority(pri); //配置队列名称 appContext.setQueue(amClientContext.getQueueName()); yarnRunCallHook.doMessage("任务准备完成,开始提交任务!"); yarnClient.submitApplication(appContext);程序再运行到 yarnClient.submitApplication(appContext); 时执行卡住,通过日志观察,出现一下日志:48833 [main] INFO org.apache.hadoop.io.retry.RetryInvocationHandler - com.google.protobuf.InvalidProtocolBufferException: Protocol message end-group tag did not match expected tag., while invoking ApplicationClientProtocolPBClientImpl.getApplicationReport over 27. Trying to failover immediately. 48833 [main] INFO org.apache.hadoop.yarn.client.ConfiguredRMFailoverProxyProvider - Failing over to 28 49849 [main] INFO org.apache.hadoop.io.retry.RetryInvocationHandler - java.net.ConnectException: Call From DESKTOP-BTSFCSH/10.0.55.152 to 10-0-120-162:26004 failed on connection exception: java.net.ConnectException: Connection refused: no further information; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused, while invoking ApplicationClientProtocolPBClientImpl.getApplicationReport over 28 after 1 failover attempts. Trying to failover after sleeping for 35465ms. 85315 [main] INFO org.apache.hadoop.yarn.client.ConfiguredRMFailoverProxyProvider - Failing over to 27 85366 [main] INFO org.apache.hadoop.io.retry.RetryInvocationHandler - com.google.protobuf.InvalidProtocolBufferException: Protocol message end-group tag did not match expected tag., while invoking ApplicationClientProtocolPBClientImpl.getApplicationReport over 27 after 2 failover attempts. Trying to failover after sleeping for 30581ms.请重点关注 Protocol message end-group tag did not match expected tag. 连接主节点的时候,出现协议不一致的问题连接信息如下:fs.defaultFS=hdfs://hacluster yarn.resourcemanager.address.27=10-0-120-161:26004 yarn.resourcemanager.address.28=10-0-120-162:26004 yarn.resourcemanager.ha.rm-ids=27,28 dfs.client.failover.proxy.provider.hacluster=org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider yarn.resourcemanager.scheduler.address.28=10-0-120-162:26002 dfs.nameservices=hacluster yarn.resourcemanager.scheduler.address.27=10-0-120-161:26002 dfs.namenode.rpc-address.hacluster.14=10-0-120-161:25000 dfs.namenode.rpc-address.hacluster.15=10-0-120-162:25000 yarn.resourcemanager.ha.enabled=true yarn.resourcemanager.recovery.enabled=true yarn.log-aggregation-enable=true dfs.ha.namenodes.hacluster=14,15 yarn.http.policy=HTTPS_ONLYFusionInsight Manager 已经开启Kereros,再本次提交中,kerberos认证已经通过 以上配置信息来自于 FusionInsight Manager 配置,确认端口信息等无误!以下是引入的Maven依赖 3.1.1 1.3.1 3.1.0 8 8 org.apache.hadoop hadoop-common ${hadoop.version} org.apache.hadoop hadoop-client ${hadoop.version} org.apache.hadoop hadoop-mapreduce-client-app ${hadoop.version} org.apache.hadoop hadoop-mapreduce-client-common ${hadoop.version} org.apache.hadoop hadoop-mapreduce-client-core ${hadoop.version} org.apache.hbase hbase-client ${hbase.version} org.apache.hbase hbase-common ${hbase.version} org.apache.hbase hbase-protocol ${hbase.version} org.apache.hbase hbase-server ${hbase.version} org.apache.hive hive-jdbc ${hive.version} org.apache.hive hive-service ${hive.version} 上述依赖,模仿华为云大数据平台 客户端案例的依赖!
-
推荐学习顺序:请知:编号顺序相同的可并行学习;知识图谱:课程链接:组件名称组件介绍链接Manager华为FusionInsight HD是一个分布式数据处理系统,对外提供大容量的数据存储、查询和分析能力基础知识安装教程运维知识HBaseHBase是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的BigTable建模,实现的编程语言为 Java。它是Apache软件基金会的Hadoop项目的一部分,运行于HDFS文件系统之上,为 Hadoop 提供类似于BigTable 规模的服务。基础串讲+运维知识最佳实践KafkaKafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。 该项目的目标是为处理实时数据提供一个统一、高吞吐、低延迟的平台。基础串讲+运维知识最佳实践HiveHive 是一个架构在 Hadoop 之上的数据仓库基础工具,它可以处理结构化和半结构化数据,它使得查询和分析存储在 Hadoop 上的数据变得非常方便基础串讲+运维知识最佳实践SparkApache Spark 是一种用于大数据工作负载的分布式开源处理系统。它使用内存中缓存和优化的查询执行方式,可针对任何规模的数据进行快速分析查询。基础串讲+运维知识最佳实践FlinkApache Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。基础串讲+运维知识最佳实践
-
【摘要】 随着大数据时代的来临,数据量不断增长,传统小机上跑数据库的模式扩容困难且成本高昂,难以支撑业务发展。很多用户开始转向分布式计算路线,用多台廉价的PC服务器组成集群来完成大数据计算任务。Hadoop/Spark就是其中重要的软件技术,由于开源免费而广受欢迎。经过多年的应用和发展,Hadoop已经被广泛接受,不仅直接应用于数据计算,还发展出很多基于它的新数据库,比如Hive、Impala等。 H...本文分享自华为云社区《Hadoop Spark太重,esProc SPL很轻》,作者:石臻臻的杂货铺。随着大数据时代的来临,数据量不断增长,传统小机上跑数据库的模式扩容困难且成本高昂,难以支撑业务发展。很多用户开始转向分布式计算路线,用多台廉价的PC服务器组成集群来完成大数据计算任务。Hadoop/Spark就是其中重要的软件技术,由于开源免费而广受欢迎。经过多年的应用和发展,Hadoop已经被广泛接受,不仅直接应用于数据计算,还发展出很多基于它的新数据库,比如Hive、Impala等。Hadoop/Spark之重Hadoop的设计目标是成百上千台节点的集群,为此,开发者实现了很多复杂、沉重的功能模块。但是,除了一些互联网巨头企业、国家级通信运营商和大型银行外,大多数场景的数据量并没有那么巨大。结果,经常能看到只有几个到十几个节点的Hadoop集群。由于目标和现实的错位,对很多用户来讲,Hadoop成了一个在技术、应用和成本上都很沉重的产品。技术之重如果真的有几千台计算机组成的集群,是不可能依靠手工个性化管理的。试想,将这些计算机罗列出来,运维人员看都看不过来,更别说管理和分配任务了。再说,这么多机器,难免会不断出现各种故障,怎么保证计算任务顺利执行?Hadoop/Spark的开发者为了解决这些问题,编写了大量代码,用于实现自动化节点管理、任务分配和强容错功能。但是,这些功能本身就要占用很多计算资源(CPU、内存和硬盘等),如果用到几台到十几台节点的集群上,就太过沉重了。集群本来就不大,Hadoop还要占用相当一部分的资源,非常不划算。不仅如此,Hadoop产品线很长,要把这些模块都放在一个平台上运行,还要梳理好各个产品之间的相互依赖性,就不得不实现一个包罗万象的复杂架构。虽然大多数场景只用其中一两个产品,也必须接受这个复杂、沉重的平台。后来出现的Spark弥补了Hadoop对内存利用的不足,技术上是不是可以变轻呢?很遗憾,Spark走向了另一个极端,从理论模型上就只考虑内存计算了。特别是Spark 中的 RDD 采用了 immutable 机制,在每个计算步骤后都会复制出新的 RDD,造成内存和 CPU 的大量占用和浪费,离开大内存甚至无法运行,所以技术上还是很重。使用之重Hadoop技术上太过复杂,也就意味着安装和运维会很麻烦。集群只有几台计算机时,却不得不使用为几千台节点集群设计的节点管理、任务分配和容错功能。可想而知,安装、配置、调试都很困难,日常运行的维护、管理工作也不容易。即使克服这些困难让Hadoop运行起来了,编写大数据计算代码时还会面临更大的麻烦。Hadoop编程的核心框架是MapReduce,程序员要编写并行程序,只要写 Map 和 Reduce 动作即可,用来解决求和、计数等简单问题也确实有效。但是,遇到复杂一些的业务逻辑,用MapReduce编程就会变得非常困难。例如,业务计算中很常见的JOIN计算,就很难用MapReduce实现。再比如,很多和次序有关的运算实现起来也很困难。Spark的Scala语言具备一定的结构化数据计算能力,是不是能简单一些呢?很可惜,Scala使用难度很大,难学更难精。遇到复杂一些的运算逻辑,Scala也很难写出来。MapReduce、Scala都这么难,所以Hadoop/Spark计算语法开始回归SQL语言。Hive可以将SQL转化为MapReduce所以很受欢迎,Spark SQL的应用也比Scala广泛的多。但是,用SQL做一些常规查询还算简单,用于处理多步骤过程计算或次序相关运算还是非常麻烦,要写很复杂的UDF。而且,许多计算场景虽然勉强能用SQL实现,但是计算速度却很不理想,也很难进行性能调优。成本之重虽然 Hadoop 软件本身开源免费,但它技术复杂、使用困难,会带来高昂的综合成本。前面说过,Hadoop自身会占用过多的CPU、内存和硬盘,而Spark需要大内存支撑才能正常运行。所以不得不为Hadoop/Spark采购更高配置的服务器,要增加硬件支出。Hadoop/Spark使用困难,就需要投入更多的人力去完成安装、运维,保证Hadoop/Spark的正常运转;还要投入更多的开发人员,编程实现各种复杂的业务计算,要增加人力资源成本。由于使用过于困难,很多用户不得不采购商业公司的收费版本Hadoop/Spark,价格相当可观,会大幅增加软件采购成本。既然Hadoop如此沉重,为什么还有很多用户会选择它呢?答案很简单:暂时找不到别的选择,也只有Hadoop勉强可用,好歹知名度高一些。如此一来,用户就只能安装、配置Hadoop的重型应用,并忍受Hadoop本身对计算资源的大量消耗。小规模集群的服务器数量本来就不多,Hadoop又浪费了不少,小马拉大车,最后运行的效果可想而知。花了大价钱采购、费事费力的使用Hadoop,实际计算的性能却不理想。就没有别的选择了?轻量级的选择开源的esProc SPL是轻量级大数据计算引擎,采用了全新的实现技术,可以做到技术轻、使用简单、成本低。技术轻本文开头说过,越来越大的数据量让传统数据库撑不住,所以用户只能转向分布式计算技术。而数据库之所以撑不住,是因为SQL难以实现高速算法,大数据运算性能只能指望数据库的优化引擎,遇到复杂计算时,优化引擎又常常无能为力。所以,我们应该想办法设计更高效的算法,而不是一味地追求分布式计算。按照这个思路,SPL提供了众多高性能算法(有许多是业界首创)以及高效的存储方案,同等硬件环境下可以获得远超过数据库的运算性能。安装在单机上的SPL就可以完成很多大数据计算任务,架构比集群简单很多,从技术上自然就轻的多了。SPL的高性能算法有下面这些:对于数据量更大的情况,SPL实现了轻量级集群计算功能。这一功能的设计目标是几台到十几台节点的集群,采用了与Hadoop完全不同的实现方法。SPL集群不提供复杂沉重的自动化管理功能,而是允许对每个节点进行个性化配置。程序员可以根据数据特征和计算目标来决定各节点存储什么样的数据,完成哪些计算。这样做,不仅大大降低了架构复杂度,也是提升性能的重要手段。以订单分析为例,订单表很大,要通过产品号字段与较小的产品表主键做关联,再按照产品供应商分组汇总订单金额。SPL集群可以很容易的将订单表分段存放在各个节点的硬盘上,再将较小的产品表读入每个节点的内存中。计算时,每个节点仅对本机上的订单分段和产品数据做关联、分组汇总,可以缩短总计算时间;再将结果传输到一个节点上做二次汇总。由于传输的是第一次汇总的结果,数据量小、网络传输时间较短。总体来说,这个方案可以获得最佳性能,虽然程序员需要做一些更细致的工作,但对于小规模集群来说,增加的工作量并不大。SPL也不提供超强的容错能力,不会像Hadoop那样,在有节点故障的情况下,还要保证任何一个任务都会执行成功。实际上,大多数计算任务的执行时间都在几个小时以内,而几台、十几台机器的集群一般都能做到较长时间正常运行,不会这么频繁的出故障。即使偶尔出现节点故障导致任务执行失败,再重新计算一遍也可以接受,毕竟这种情况不会经常发生。所以,SPL的容错能力只是保证有少数节点故障的时候,整个集群还能继续工作并接受新任务(包括重算的任务),这就大大降低了SPL集群的复杂度。在内存计算方面,SPL没有使用Spark RDD的 immutable机制,而是采用了指针式复用机制,利用地址(指针)访问内存,在数据结构没有改变的情况下,直接用原数据的地址形成结果集,不必每个计算都将数据复制一遍,仅仅多保存一个地址(指针),可以同时减少 CPU 和内存的消耗,运行起来要比Spark轻很多了。并且,SPL改进了当前的外存计算算法体系,降低了复杂度并扩大了适应范围,可以做到内外存计算结合,充分提升计算性能的同时,还不像Spark那样依赖大内存。使用简单SPL采用轻量级技术,自然更容易安装、配置和运行维护。SPL不仅可以作为独立服务器使用,还很容易集成到需要高性能计算的应用中,比如即时查询系统,只要引入几个jar包即可。Hadoop则很难集成,只能在边上作为一个数据源运行。有些临时性数据需要随时进行处理,则可使用SPL的桌面集成开发环境可视化地计算,快速得到结果。如果要安装部署Hadoop,那么等环境搭建好时临时数据任务已经过期了。前面展示的众多SPL高性能算法,也能让大数据计算编程变得简单。程序员可以在较短时间内掌握这些算法函数,学习成本相对较低。而且,使用这些现成的函数很容易实现各种复杂的计算需求,不仅比MapReduce/Scala简单,比SQL也简单很多。比如,以电商网站常见的漏斗分析为例,用SQL实现三步漏斗的代码大致如下:with e1 as ( select gid,1 as step1,min(etime) as t1 from T where etime>= to_date('2021-01-10', 'yyyy-MM-dd') and etime<to_date('2021-01-25', 'yyyy-MM-dd') and eventtype='eventtype1' and … group by 1 ), with e2 as ( select gid,1 as step2,min(e1.t1) as t1,min(e2.etime) as t2 from T as e2 inner join e1 on e2.gid = e1.gid where e2.etime>= to_date('2021-01-10', 'yyyy-MM-dd') and e2.etime<to_date('2021-01-25', 'yyyy-MM-dd') and e2.etime > t1 and e2.etime < t1 + 7 and eventtype='eventtype2' and … group by 1 ), with e3 as ( select gid,1 as step3,min(e2.t1) as t1,min(e3.etime) as t3 from T as e3 inner join e2 on e3.gid = e2.gid where e3.etime>= to_date('2021-01-10', 'yyyy-MM-dd') and e3.etime<to_date('2021-01-25', 'yyyy-MM-dd') and e3.etime > t2 and e3.etime < t1 + 7 and eventtype='eventtype3' and … group by 1 ) select sum(step1) as step1, sum(step2) as step2, sum(step3) as step3 from e1 left join e2 on e1.gid = e2.gid left join e3 on e2.gid = e3.gidSQL写出来要三十多行,理解起来有相当的难度。如果用MapReduce/Scala来写,会更加困难。即使是用SQL实现,写出来的这段代码和漏斗的步骤数量相关,每增加一步就要再增加一段子查询。相比之下,SPL 就简单得多,处理任意步骤数都是下面这样简洁的代码:AB1=["etype1","etype2","etype3"]=file("event.ctx").open()2=B1.cursor(id,etime,etype;etime>=date("2021-01-10") && etime<date("2021-01-25") && A1.contain(etype) && …)3=A2.group(id).(~.sort(etime))=A3.new(~.select@1(etype==A1(1)):first,~:all).select(first)4=B3.(A1.(t=if(#==1,t1=first.etime,if(t,all.select@1(etype==A1.~ && etime>t && etime<t1+7).etime, null))))5=A4.groups(;count(~(1)):STEP1,count(~(2)):STEP2,count(~(3)):STEP3)SPL集群计算的代码也非常简单,比如前面提到的订单分析计算,具体要求是:大订单表分段存储在4个节点上,小产品表则加载到每个节点的内存中,两表关联之后要按照产品供应商分组汇总订单金额。用SPL写出来大致是下面这样:AB1["192.168.0.101:8281","192.168.0.102:8281",…, "192.168.0.104:8281"]2fork to(4);A1=file("product.ctx").open().import()3>env(PRODUCT,B2)4=memory(A1,PRODUCT)5=file("orders.ctx":to(4),A1).open().cursor(p_id,quantity)6=A5.switch(p_id,A4)7=A7.groups(p_id.vendor;sum(p_id.price*quantity))这段代码执行时,任务管理(内存加载、任务拆分、合并等)所需要的计算资源,远远小于关联和分组汇总计算的消耗。如此轻便的任务管理功能,可以在任意节点、甚至是集成开发环境IDE上执行。成本低与Hadoop相同,SPL也是开源软件,不同的是SPL不仅软件免费,综合成本也非常低。SPL安装、配置、运维很容易,可以大大降低支持人员的人力资源成本。同时,由于SPL降低了大数据计算编程的难度,程序员很容易实现各种复杂的计算,开发效率显著提高,也就节省了程序员的人力资源成本。而且,由于SPL技术体系非常轻,平台自身占用的CPU、内存和硬盘很少,可以让更多的资源用于业务计算,能大幅提高硬件利用率。SPL也不像Spark那样依赖大内存,总体来说,大大减少了硬件采购成本。SPL既轻且快SPL技术轻、自身消耗小,而且还提供了众多高性能算法,所以,在几个到几十个节点的集群,甚至单机的情况下,比Hadoop/Spark有更好的性能表现。案例1:某电商漏斗分析计算。Spark:6节点,每节点4CPU核,平均计算时间:25秒。SPL:单机,8线程计算,平均计算时间可达10秒。代码量仅有Spark Scala的一半。案例2:某大型银行用户画像分析。Hadoop上某OLAP服务器:虚拟机100CPU核,计算时间:120秒。SPL:虚拟机12CPU核,计算时间:仅4秒。性能提高250倍。案例3:某商业银行的手机银行APP,活期明细查询,数据量大且高并发。基于Hadoop的某商用数据仓库:高并发时无法达到秒级的响应速度,只好换用6台ES集群。SPL单机:达到6台ES集群同样的并发和响应能力。总结来说,Hadoop/Spark是源自头部互联网企业的重型解决方案,适合需要有超大规模集群的巨大企业。很多场景的数据虽然也不少,但小集群甚至无集群就足够处理,远没多到这些巨大企业的规模,也没有那么多的硬件设备和维护人员。这种情况下,轻量级的大数据计算引擎SPL是首选,投入很低的成本,就可以做到技术轻、使用简便,而且还能提高开发效率、达到更高的性能。SPL资料SPL下载SPL源代码
-
# 一、问题背景 在DWS生产环境创建HDFS外表后,查询产生如下报错: ``` ERROR: The number of partition columns defined of foreign table ~~xxx~~ is larger than it should be. ``` 不指定分布列时,查询外表不报错; # 二、排查步骤 1、HDFS侧表定义分区列是在partition by里指定,列定义时不需声明,DWS侧表定义侧列定义需声明,然后在partition by里指定; DWS侧获取外表定义(8.0以上版本可用) ``` select pg_get_tabledef(模式名.表名); ``` 2、对应HDFS侧表定义和DWS侧外表定义,定义列的顺序保持一致; 3、DWS侧不指定分布列时查询外表无报错,查询分区个数总共80个,在HDFS侧指定的外表路径下查询到分区有82个; ``` HDFS进入目录统计分区个数 DWS侧语句去重查询分区列 ``` 通过和HD侧确认,为源分区删除文件残留场景 # 三、解决方法 HDFS侧清理无效分区后,重新创建指定分布列外表,查询已无报错,查询到的分区数和HDFS侧保持一致; # 四、问题总结 该问题在生产环境较为少见,报错显示为分区列不匹配,遇到后可参考以上步骤排查,如有其它场景后续继续补充。
-
>摘要:OBSA项目是围绕OBS建立的大数据和AI生态,其在不断的发展和完善中,目前有如下子项目:hadoop-obs项目和flink-obs项目。 文章作者:存储服务产品部开发者支持团队 # OBS存储服务概述 华为云OBS存储服务提供了“对象存储服务”和”并行文件系统服务”。 1.对象存储服务:提供传统的对象存储语义。 2.并行文件系统服务:简称文件桶,基于对象存储服务提供了一种经过优化的高性能文件系统,其实现了追加写,文件截断,目录重命名原子操作等一系列特性,并和对象存储服务一样提供了毫秒级别访问时延,TB级别带宽和百万级别的IOPS,因此非常适用于大数据分析等场景,华为云的MRS,DLI等大数据分析服务均已支持OBS服务作为其底层的存储服务。 # OBSA项目概述 1.OBSA项目是围绕OBS建立的大数据和AI生态,其在不断的发展和完善中,目前有如下子项目: (1)hadoop-obs项目:基于华为云OBS存储服务实现了hadoop文件系统抽象; (2)flink-obs项目:基于华为云OBS存储服务实现了Flink文件系统抽象; 2.OBSA官方文档:方案概述_对象存储服务 OBS_最佳实践_大数据场景下使用OBS实现存算分离_华为云 3.OBSA社区地址:https://github.com/huaweicloud/obsa-hdfs # hadoop-obs原理和实践建议 ## 简述 1.hadoop-obs项目基于OBS并行文件系统服务/对象存储服务实现了hadoop的FileSystem抽象(即HDFS协议)OBSFileSystem,可以像使用 HDFS分布式文件系统一样访问OBS中的数据,实现大数据计算引擎Spark、MapReduce、Hive等与OBS存储服务的对接,为大数据计算提供“数据湖”存储。 2.OBSFileSystem继承实现了FileSystem抽象类,适配为对OBS http/https rest API接口的访问,下述章节将详细剖析OBSFileSystem的实现和实践。 3.hadoop-obs以jar包的形式对外发布,hadoop-huaweicloud-x.x.x-hw-y.jar包含义:前三位x.x.x为配套hadoop版本号;最后一位y为hadoop-obs版本号;如:hadoop-huaweicloud-3.1.1-hw-40.jar,3.1.1是配套hadoop版本号,40是hadoop-obs的版本号。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058825990555476.png) ## 认证和鉴权机制 在了解OBSFileSystem的认证和鉴权机制之前,我们先对OBS服务的认证和鉴权机制做一个简单的介绍。其主要支持两种认证鉴权机制: 1.桶策略:桶拥有者通过桶策略可为IAM用户或其他帐号授权桶及桶内对象精确的操作权限,桶策略有20KB的大小限制,超出此限制可以选择IAM策略 2.IAM策略:IAM权限是作用于云资源的,IAM权限定义了允许和拒绝的访问操作,以此实现云资源权限访问控制 不管上述哪种机制,访问OBS时均需要IAM用户对应的永久aksk或是临时aksk(其包含ak,sk,securityToken三部分,其是有时效限制的,一般为24小时) 在通过OBSFileSystem访问OBS时首先需要配置永久aksk或是临时aksk,OBSFileSystem支持如下几种方式获取aksk:(优先级由高到低排序) 1.从core-site配置文件中获取:通过fs.obs.access.key和fs.obs.secret.key和fs.obs.session.token配置项获取。其支持hadoop的CredentialProvider机制,即通过CredentialProvider机制对aksk进行保护,避免aksk的明文暴露,注意不能将其保存在OBSFileSystem存储系统的路径上因为循环依赖问题https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/CredentialProviderAPI.html 附:关于CredentialProvider机制相关配置项: hadoop.security.credential.provider.path:存放机密信息的keystore文件路径,例如aksk可以存储在其中 hadoop.security.credential.clear-text-fallback:当从keystore文件中获取不到机密信息时回落到配置项的明文中去获取hadoop.security.credstore.java-keystore-provider.password-file:keystore被加密时,其密码文件的路径 2.从URL中获取:其格式为obs://{ak}:{sk}@obs-bucket/ 3.从Provider中获取:自定义aksk提供器,通过fs.obs.security.provider配置项进行配置Provider需要继承com.obs.services.IObsCredentialsProvider接口,目前支持的Provider: (1)com.obs.services.EnvironmentVariableObsCredentialsProvider:从环境变量里寻找aksk,需要在环境变量中定义OBS_ACCESS_KEY_ID和OBS_SECRET_ACCESS_KEY分别代表永久的AK和SK (2)com.obs.services.EcsObsCredentialsProvider:从ECS元数据中自动获取临时aksk并进行定期自动刷新 (3)com.obs.services.OBSCredentialsProviderChain:以链式的形式依次从环境变量,ECS服务器上进行搜索以获取对应的访问密钥,且会以第一组成功获取到的访问密钥访问obs 也可以自定义Provider完成符合您架构和安全要求的实现。 (MRS和DLI等华为云服务有自己的provider实现) 注意事项: (1)对于类似mapreduce的分布式任务,因为分布式任务通过OBSFileSystem访问OBS且分布式任务被不确定的分配到集群节点上,所以需要能在集群的每一个节点上都能够获取aksk,例如如果通过EnvironmentVariableObsCredentialsProvider方式获取,则需要在每一个节点上都进行环境变量设置 (2)当通过临时aksk机制访问OBS时注意临时aksk的时效性 (3)注意EcsObsCredentialsProvider机制中访问ECS元数据时的流控,即访问ECS元数据获取aksk是有频次限制的 # 写相关流程 ## 覆盖写 当调用OBSFileSystem的create相关方法时将获取FSDataOutputStream,通过该流写数据到OBS中。此流程总的实现思路是通过“缓存”和“并发多段上传”来实现较高的写性能: (1)通过FSDataOutputStream写入数据时,数据首先将被缓存然后并发多段上传到OBS (2)通过参数fs.obs.multipart.size设置缓存的大小,当数据写入量达到此阈值时将对应产生一次range上传请求,且是异步发起的range上传请求,当异步range上传任务完成时将及时清理其对应的缓存,例如当缓存机制为disk时,将及时清理本地磁盘中的缓存文件; (3)当调用FSDataOutputStream的close方法时将等待所有的range上传异步任务完成,并发起多段合并请求完成文件的真正写入;并发多段上传线程池相关配置参数: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058867197718508.png) 附obs java sdk 多段上传:https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0607.html 实践建议: (1)当缓存fs.obs.fast.upload.buffer设置为disk时(默认),建议使用高性能存储介质(例如SSD盘)承载,且当集群中有大量并行任务时,确保缓存盘的空间足够(可以配置多个目录) (2)当缓存fs.obs.fast.upload.buffer设置为array或bytebuffer时,生产环境谨慎使用,计算任务的内存分配时请注意此机制占用的内存空间 ## 追加写 当调用OBSFileSystem的append方法时将获取FSDataOutputStream,通过该流追加写数据到OBS中,其依赖于OBS服务的追加写特性: (1)通过流write数据时当达到缓存阈值fs.obs.multipart.size时将立刻写入数据到OBS; (2)OBS的追加写特性不支持“并发range追加写”,所以其失去了“并发range写”的优势,相对覆盖写性能将会有所下降; (3)OBS的追加写特性在频繁小数据追加写的场景其性能表现并不是很好 flush/hflush/hsync/sync OBSFileSystem的create或是append相关方法将返回FSDataOutputStream,其实现了flush/hflush/hsync/sync等相关方法。 文件桶场景: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058888784664960.png) 对象桶场景: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058897151915291.png) 注意:hadoop-obs 46版本才开始支持fs.obs.outputstream.hflush.policy策略,之前的版本实现机制等同于fs.obs.outputstream.hflush.policy=Sync的行为。 ## 截断 OBSFileSystem真正实现了FileSystem定义的截断接口truncate,其依赖于OBS文件桶的截断特性。 (1)此接口将可以很好的支撑flink的StreamingFileSink的exactly once场景或是其他场景 (2)普通对象桶不具备截断特性; ## 读相关流程 当调用OBSFileSystem的open相关方法时将获取FSDataInputStream,通过该流读取OBS中的数据。此流程总的实现思路是通过obs的“range读取”特性进行实现,相关配置项如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058917744443658.png) 附OBS range读:当读取一个较大的文件时例如1000MB,可以将其分为0-100MB,100MB-200MB。。。10个段并发读取以提升性能。范围下载_对象存储服务 OBS_Java_下载对象_华为云 实践建议: (1)对于需要顺序读取文件的场景:例如hdfs命令下载文件,DistCp,sql查询文本文件 - 在primary策略下:可以大幅度提高fs.obs.readahead.range的值(默认1MB),例如可以设置为100MB 例如hadoop fs -Dfs.obs.readahead.range=104857600 -get obs://obs-bucket/xxx - 在advance策略下:可以适度提高fs.obs.readahead.range和fs.obs.readahead.max.number的值或是保持默认值不变 (2)对于大量随机访问的场景:例如orc或parquet文件读取 在primary策略和advance策略下均保持默认值即可,或是针对你的场景进行调优测试。 # list相关流程 因为对象存储的特点,其逻辑模型是KV模型,因此其list操作是耗时的,其每次最多只能返回1000条数据,类似分页查询。因此在超大目录场景,OBSFileSystem中的listXXX接口其性能是相对低的,因为其要发起多次list请求才能获取完整的列表。 并行文件桶场景下OBSFileSystem对于list的优化: 1.根据目录结构尝试并发list。 2.例如当要列举A目录时,A目录下有B,C,D目录,将会并发列举B,C,D目录以提升列举性能。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058958380814974.png) 实践建议: 1.对于超大目录的list或是getContentSummary(即hdfs du命令): (1)不要在前台列举或是du一个超大目录 (2)可以精确到某一个分区目录以避免超大目录场景下前台进行列举或是du操作时出现的长时间等待 # 删除相关流程 目录删除操作在OBSFileSystem中不是O(1)操作,其实现分为两个步骤: 1.先递归列举出目录下的所有文件 2.利用对象存储的批量删除特性将其删除,批量删除的最大条数1000,对于文件桶必须先删除目录下的文件才能删除父目录 hadoop-obs的快速删除机制:即将删除操作转为rename操作,rename到指定目录,目的是利用文件桶rename的高效性解决删除性能 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058975539891770.png) 实践建议: 1.对于超大目录的删除:建议可以采用OBS服务的生命周期特性,通过OBS后台任务进行删除。 2.快速删除机制:开启后需要配合OBS服务的生命周期特性,定期删除fs.obs.trash.dir目录中的数据 # rename相关流程 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659058989676213351.png) # 垃圾回收机制 在大数据应用场景中,往往存在防止数据误删除的诉求,通过OBSFileSystem的垃圾回收机制实现。 1.在相关组件的core-site.xml文件中配置如下内容: ``` fs.trash.interval 1440 垃圾回收机制开关,设置为大于0 的值即可 ``` 2.配置OBS服务的生命周期策略:垃圾目录中的文件无法自动清除,需通过OBS生命周期策略进行定期清除 3.场景: (1)hdfs命令: ``` hadoop fs -rm obs://obs-bucket/test.txt; ``` 会将test目录转移到obs://obs-bucket/user/${username}/.Trash/Current垃圾目录下 (2)hive语句: ``` drop table obstable; ``` 如果obstable是一张内表,会将obstable表对应的目录转移到obs://obs-bucket/user/${username}/.Trash/Current垃圾目录下 # 日志机制 1.hadoop-obs项目对应的jar包放置于hadoop,hive,spark等组件的目录下,受这些组件的日志机制控制;例如对于hadoop组件,在${HADOOP_HOME}/etc/hadoop/log4j.properties文件中增加如下配置项以避免产生大量info级别的日志: ``` log4j.logger.com.obs=ERROR或是WARN log4j.logger.org.apache.hadoop.fs.obs=INFO ``` 2.关于warn级别的404状态码:OBSFileSystem在实现一些FileSystem的接口时为了语义的准确实现,在一些流程中会去探测文件是否存在,例如在实现create接口时会先获取文件的状态用以判断是文件还是目录,当为目录时则抛出异常,当为文件或是文件不存在时则正常创建文件,在此过程中会打印warn级别的带404状态码的日志(当日志级别调整为info或是warn时),此warn级别的日志属于正常现象。 # 重试机制 1.访问OBS服务时可能会因为网络短暂抖动,服务突发故障,服务突发流控等瞬时故障导致访问失败,hadoop-obs为了应对上述瞬时故障进行了必要的重试机制; 注:对于OBS服务处于长期故障状态重试机制是无力解决的 2.重试策略:采取退让重试策略,即随着失败次数的增加重试间隔梯次增加 ``` 1.hadoop-obs的通用重试策略: fs.obs.retry.maxtime:默认值180000ms,控制最大重试时间,重试间隔为max(fs.obs.retry.sleep.basetime*2的重试次数次方,fs.obs.retry.sleep.maxtime) fs.obs.retry.sleep.basetime:默认值50ms,重试间隔的基数 fs.obs.retry.sleep.maxtime:默认值30000ms,重试间隔最大等待时间 2.hadoop-obs的流控重试策略:您可视您的业务情况独立配置 fs.obs.retry.qos.maxtime:默认值180000ms fs.obs.retry.qos.sleep.basetime:默认值1000ms fs.obs.retry.qos.sleep.maxtime:默认值30000ms 3.什么情况下会进行重试: (1)尚未与obs服务建立连接或是IO中断,例如ConnectException,SocketTimeoutException等 (2)obs服务返回5xx:obs服务指示服务状态不正常 注: (1)50.1版本开始才实现了独立的流控重试策略 (2)50.1版本开始写入流程才被施加重试机制 ``` # flink-obs原理和实践建议(待完善) ## 大数据各组件优化 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059076770317337.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059103201417735.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059135383225525.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059161530333960.png) # 其他 ## OBS 带宽评估 在基于OBS的大数据存算分离解决方案中OBS侧QOS(主要是读写带宽)的评估没有一个准确的计算公式,也因业务场景的复杂性导致难有一个一以贯之的公式。根据经验和理论的沉淀现阶段能够采用的OBS QOS评估方法如下: 算法一:根据CPU核数估算 此算法的依据是现网观察后的经验估算。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059183914463814.png) 算法二:根据POC估算 此算法的依据是根据客户在POC测试时的真实业务场景观测到的OBS侧的实际带宽消耗峰值,然后依据计算集群的规模进行推算。 例如:POC时搭建了10个计算节点,对OBS的读带宽需求峰值能达到200Gb,写带宽需求峰值能达到15Gb; 商用时需要搭建120个计算节点,OBS的读带宽=200Gb/8*(120/10)=300GB; OBS的读带宽=15Gb/8*(120/10)=22.5GB; ## HDFS-OBS映射 通过HDFS地址映射到OBS地址的方式,支持将HDFS中的数据迁移到OBS后,不需要变动业务逻辑中的数据地址,即可完成数据访问。 配置HDFS映射方式对接OBS文件系统_MapReduce服务 MRS_用户指南_配置存算分离_华为云 ## 附:hadoop-obs约束与限制 hadoop-obs不支持以下HDFS语义: - Lease - Symbolic link operations - Proxy users - File concat - File checksum - File replication factor - Extended Attributes(XAttrs) operations - Snapshot operations - Storage policy - Quota - POSIX ACL - Delegation token operations ## 附:hadoop-obs常见问题 0.大数据场景强烈建议使用并行文件系统,即文件桶 1.hadoop-obs性能基准测试 可以通过开源的DFSIO和NNbench基准测试工具进行大数据场景的性能基准测试 注:OBS服务是基于HDD存储介质,请不要和基于ssd的HDFS服务进行性能对比 2.OBS服务流控问题 (1)每个region可以独立设置租户级别和桶级别的流控阈值 (2)OBS服务流控相关阈值:主要包含读写带宽Gb/s,读写TPS,并发连接数三个阈值 (3)流控准则: 当达到带宽/TPS阈值时HTTP请求依然会成功返回200状态码,但访问时延会增大; 当达到并发连接数阈值时OBS服务将拒绝访问返503/GetQosTokenException ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059223874875453.png) 3.hadoop-obs权限问题 通过hadoop-obs访问OBS时需要aksk/临时aksk才能访问OBS服务,OBSFileSystem支持如下几种方式获取aksk:(优先级由高到低排序) - (1)通过core-site.xml的fs.obs.access.key和fs.obs.secret.key和fs.obs.session.token配置项获取。 其支持hadoop的CredentialProvider机制,即通过CredentialProvider机制对aksk进行保护,避免aksk的明文暴露 - (2)从provider中获取:自定义aksk提供器,通过fs.obs.security.provider配置项进行配置。 provider实现需要继承com.obs.services.IObsCredentialsProvider接口,目前hadoop-obs内置的provider如下: com.obs.services.EnvironmentVariableObsCredentialsProvider:从环境变量里寻找aksk,需要在环境变量中定义OBS_ACCESS_KEY_ID和OBS_SECRET_ACCESS_KEY分别代表永久的AK和SK - com.obs.services.EcsObsCredentialsProvider:从ECS元数据中自动获取临时aksk并进行定期自动刷新 com.obs.services.OBSCredentialsProviderChain:以链式的形式依次从环境变量,ECS服务器上进行搜索以获取对应的访问密钥,且会以第一组成功获取到的访问密钥访问obs 也可以自定义provider实现完成符合您架构和安全要求的实现,例如MRS服务提供了自己的provider实现 4.写入操作缓存盘注意事项 当通过hadoop-obs写数据到obs时,其通过缓存机制提升写入性能,当缓存介质fs.obs.fast.upload.buffer设置为disk时(默认),可以通过fs.obs.buffer.dir配置项设置缓存目录(默认与hadoop.tmp.dir相同目录),可以设置多目录以逗号分隔;建议使用高性能存储介质(例如SSD盘)承载,且当集群中有大量并行任务时,确保缓存盘的空间足够(可以配置多个目录) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059253004196553.png) 5.读取操作实践建议: (1)对于需要顺序读取文件的场景:例如hdfs命令下载文件,DistCp,sql查询文本文件 在primary策略下:可以大幅度提高fs.obs.readahead.range的值(默认1MB),例如可以设置为100MB 例如hadoop fs -Dfs.obs.readahead.range=104857600 -get obs://obs-bucket/xxx 在advance策略下:可以适度提高fs.obs.readahead.range和fs.obs.readahead.max.number的值或是保持默认值不变 (2)对于大量随机访问的场景:例如orc或parquet文件读取 在primary策略和advance策略下均保持默认值即可,或是针对你的场景进行调优测试。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059263497564783.png) 6.快速删除特性实践建议 因为hadoop-obs的删除操作不是O(1)操作,其操作耗时和目录大小成正比例,即随着目录结构的增大其操作耗时将持续增长;如果您的应用场景存在频繁的删除操作,且删除的是超大目录,建议可以开启快速删除特性。相关配置项: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059272483773120.png) 注:文件桶才支持快速删除特性,普通对象桶不支持,因为快速删除是利用文件桶的rename性能优势实现的 注:快速删除开启后需要配合OBS服务的生命周期特性,定期删除fs.obs.trash.dir目录中的数据 7.OBS服务监控 通过华为云的云监控服务CES,其是华为云资源的监控平台,提供了实时监控、及时告警、资源分组、站点监控等能力。 8.问题排查 通过客户端日志和服务端日志进行问题排查,通常以客户端日志为问题排查的优先手段。 (1)客户端日志: OBS服务两层返回码用于指示访问状态: 状态码:符合HTTP规范的HTTP状态码,例如2xx,4xx,5xx 错误码:在状态码之下又细分了错误码,例如403状态码/InvalidAccessKeyId错误码表示 注:错误码描述https://support.huaweicloud.com/api-obs/obs_04_0115.html (2)服务端日志:开启桶日志功能,OBS会自动对这个桶的访问请求记录日志,并生成日志文件写入用户指定的桶中,可用于进行请求分析或日志审计 6.问题反馈渠道 华为云工单系统 9.跨云访问obs问题(待完善) 附:hadoop-obs完整配置项 见https://clouddevops.huawei.com/domains/2301/wiki/8/WIKI2021080300343 # 附:存算分离解决方案 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659059286942397407.png)
-
本文分享自华为云社区《[FusionInsight MRS HDFS 细粒度锁优化实践](https://bbs.huaweicloud.com/blogs/353362?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=ei&utm_content=content)》,作者:pippo。 # 背景 HDFS依赖NameNode作为其元数据服务。NameNode将整个命名空间信息保存在内存中提供服务。读取请求(getBlockLocations、listStatus、getFileInfo)等从内存中获取信息。写请求(mkdir、create、addBlock)更新内存状态,并将日志事务写入到日志服务(QJM)。 HDFS NameNode的性能决定了整个Hadoop集群的可扩展性。命名空间性能的改进对于进一步扩展Hadoop集群至关重要。 - Apache HDFS 整体架构如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653615824071691620.png) - Apache HDFS 交互信息如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653615845153231628.png) # 痛点 HDFS NameNode的写操作的性能受全局命名空间系统锁的限制。每个写操作都会获取锁并保留锁,直到该操作执行完成。这样可以防止写入操作的并发执行,即使它们是完全独立的,例如命名空间中的对象不相交部分。 # 什么是Fine Grained Locking(FGL) FGL【细粒度锁】的主要目的是通过在独立命名空间分区上用多个并发锁替换全局锁,允许写入操作的并发。 # 当前状态 HDFS设计思路为一次写,多次读。读操作使用共享锁,写操作使用独占锁。由于HDFS NameNode元数据被设计为单个内存空间中的命名空间树,因此树的任何级别的写操作都会阻塞其它写操作,直到当前写操作完成。虽然写是一次,但是当涉及大量并发读/写操作时,这就会影响整体性能。 在HDFS NameNode中,内存中的元数据有三种不同的数据结构: - INodeMap: inodeid -> INode - BlocksMap: blockid -> Blocks - DataNodeMap: datanodeId -> DataNodeInfo INodeMap结构中包含inodeid到INode的映射,在整个Namespace目录树种存在两种不同类型的INode数据结构:INodeDirectory和INodeFile。其中INodeDirectory标识的是目录树中的目录,INodeFile标识的是目录树中的文件。 BlocksMap结构中包含blockid到BlockInfo的映射。每一个INodeFile都会包含数量不同的Block,具体数量由文件大小以及每个Block大小来决定,这些Block按照所在文件的先后顺序组成BlockInfo数组,BlockInfo维护的是Block的元数据;通过blockid可以快速定位Block。 DataNodeMap结果包含datanodeid到DataNodeInfo的映射。当集群启动过程中,通过机架感知逐步建立起整个集群的机架拓扑结构,一般在NameNode的生命周期内不会发生大变化。 通过INodeMap和BlocksMap共同标识存储在HDFS中的每个文件及其块的信息。随着文件数量的增加,此数据结构大小也会随之增加,并对单个全局锁的性能产生很大影响。下面我们采用简单的文件目录树结构来演示现有的单一全局锁在文件系统的缺点。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653615920936272267.png) HDFS NameNode 内存目录树结构 如上图所示,/D11/D21/D31/F2 和 /D12/D24/D38/F16是不相交的文件,即有不同的父节点和祖父节点。可以看到F2和F16是两个独立的文件,对其中一个文件的任何操作都不应该影响另一个文件。 # 设计 如前所述,HDFS NameNode将文件信息和元数据结构在内存中保存为一个目录树结构。当修改任意两个独立的文件时,第二次操作需要等到第一次操作完成并释放锁。释放锁以后,只有第二个操作获取锁后才能继续修改文件系统。类似的,后续操作也会阻塞,直到第二次操作释放锁。 在下面的例子中,我们考虑2个文件并发写入(创建、删除、追加。。。)操作。F2和F16是文件系统下的2个独立文件(具有不同的父节点和祖父节点)。在将内容追加到F2时,F16也可以同时进行修改。但是由于整个目录树全局对象锁,对F16的操作必须等对F2的操作完成后才能执行。 代替全局锁,可以将锁分布在一组名为“分区”的文件中,每个分区都可以有自己的锁。现在F2属于分区-1,F16属于分区-2。F2文件操作可以通过获取分区-1的锁来进行修改,F16文件操作可以通过获取分区-2的锁来进行修改。 和以前一样,需要先获取全局锁,然后搜索每个文件属于哪个分区。找到分区后,获取分区锁并释放全局锁。因此全局锁并不会完全被删除。相反,通过减少全局锁时间跨度,一旦释放全局锁,则其它写操作可以获取全局锁并继续获取分区锁来进行文件操作。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653615954378433039.png) 分区的数量如何决定?如果有效的定义分区从而获得更高的吞吐量? 默认情况下,分区大小为65K,溢出系数为1.8。一旦分区达到溢出条件,将会创建新分区并加入到分区列表中。理想情况下,可以拥有等于NameNode可用CPU核数的分区数,过多的分区数量将会使得CPU过载,而过少的分区数量无法充分利用CPU。 # 实现 引入新的数据结构-PartitionedGSet,它保存命名空间创建的所有分区信息。PartitionEntry是一个分区的对象结构。LatchLock是新引入的锁,用于控制两级锁--顶层锁和子锁。 # PartitionedGSet PartitionedGSet是一个两级层次结构。第一层RangeMap定义了INode的范围,并将它们映射到相应的分区中。分区构成了层次结构的第二级,每个分区存储属于指定范围的INode信息。为了根据键值查找INode,需要首先在RangeMap中找到对应键值的范围,然后在对应的RangeSet,使用哈希值获取到对应的INode。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653615992450186918.png) HDFS NameNode 两级层次结构 RangeGSet的容量有一定的阈值。当达到阈值后,将创建新的RangeGSet。空的或者未充分利用的RangeGSet由后台RangeMonitor守护程序来进行垃圾回收。 HDFS NameNode启动时,根据镜像中的INode数量计算合理的初始分区数。同时还需要考虑CPU核数,因为将分区数量提高到远超CPU核数并不会增加系统的并行性。 - 动态分区:分区的大小有限,可以像平衡树一样可以进行分裂和合并。 - 单个分区:只有一个分区,且只有一个与之相对应的锁,并且应和全局锁类似。这适用于小型集群或写入负载比较轻的集群。 - 静态分区:有一个固定的RangeMap,不添加或者合并现有分区。这适用于分区均匀增长的文件系统。而且这将消除锁定RangeMap的要求,允许并行使用锁。 # Latch Lock RangeMap与RangeGSet分别有单独的锁。Latch Lock是一种锁模式,其中首先获取RangeMap的锁,以查找与给定INode键对应的范围,然后获取与分区对应的RangeGSet的锁,同时释放RangeMap锁。这样针对任何其它范围的下一个操作都可以开始并发执行。 在RangeMap上持有锁类似于全局锁。目录删除、重命名、递归创建目录等几个操作可能需要锁定多个RangeGSet。这要确保当前HDFS语义所要求的操作的原子性。例如,如果重命名将文件从一个目录移动到另一个目录,则必须锁定包含文件、源和目标目录的RangeMap,以便使重命名成为原子。此锁定模式的一个理想优化是允许某些操作的Latch Lock与其他操作的全局锁结合使用。 # INode Keys HDFS中的每个目录和文件都有一个唯一的INode,即使文件被重命名或者移动到其它位置,该INode会保持不变。INode键是以文件INode本身结尾,前面包含父INode的固定长度序列。 Key Definition: key(f) = selfId是文件的INodeId,pId是父目录的INodeId,ppId是父目录的父目录的INodeId。INode键的这种表达不仅保证了同级,同时也保证了表亲(相同祖父节点)在大多数情况下被分区到相同的范围中。这些键基于INodeId而非文件名,允许简单的文件和目录进行重命名,称为就地重命名,而无需重新进行分区。 # 效果 经过测试验证使用和不使用FGL功能性能,在主要写入操作情况下,吞吐量平均提高了25%左右。 ## 详细性能对比 使用Hadoop NN Benchmarking工具(NNThroughputBenchmark)来验证NameNode的性能。每个写入API验证并观察到平均25%的性能提升。有很少一部分轻微或者没有提升的API,分析并发现这些API均是轻量级API,因此没有太大的提升。 NNThroughputBenchmark是用于NameNode性能基准测试工具。该工具提供了非常基本的API调用,比如创建文件,创建目录、删除。在这个基础上进行了增强,从而能够支持所有写入API,并能够捕获使用和不使用FGL的版本的性能数据。 用于测试的数据集:线程数 1000、文件数 1000000、每个目录文件数 40。 # 写入调用频率高的API ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653616077867487794.png) # 其它内部写API ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653616090511168604.png) # 常用读取API: 通过完整的FGL实现,读取API也有很好的性能提升。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/27/1653616112137858409.png) # 运行基准测试工具的命令: ./hadoop org.apache.hadoop.hdfs.server.namenode.NNThroughputBenchmark -fs file:/// -op create -threads 200 -files 1000000 -filesPerDir 40 –close ./hadoop org.apache.hadoop.hdfs.server.namenode.NNThroughputBenchmark -fs hdfs:x.x.x.x:dddd/hacluster -op create -threads 200 -files 1000000 -filesPerDir 40 -close # 参考 与FGL相关的社区讨论 Hadoop Meetup Jan 2019 — HDFS Scalability and Consistent Reads from Standby Node, which covers Three-Stage Scalability Plan. Slides 21–25 社区中跟踪与NameNode可扩展性相关的其它Jira HDFS-5453. Support fine grain locking in FSNamesystem HDFS-5477. Block manager as a service HDFS-8286. Scaling out the namespace using KV store HDFS-14703. Namenode Fine Grained Locking (design inspired us to implement it fully) # 总结 华为云FusionInsight MRS云原生数据湖为政企客户提供湖仓一体、云原生的数据湖解决方案,构建一个架构可持续演进的离线、实时、逻辑三种数据湖,支撑政企客户全量数据的实时分析、离线分析、交互查询、实时检索、多模分析、数据仓库、数据接入和治理等大数据应用场景。 华为云FusionInsight MRS通过FGL对HDFS NameNode锁机制进行优化,有效提升了NameNode的读写吞吐量,从而能够支持更多数据,更多业务请求访问,从而更好的支撑政企客户高效用数,业务洞见更准,价值兑现更快。
-
环境输入实践版本:Apache azkaban 4.0.0 (以单机版举例,集群版本配置过程类似),MRS 3.1.0 普通集群。Azkaban 插件地址Azkaban 官网Azkaban 源码地址安装azkaban-solo-serverAzkaban不提供二进制包,需要用户下载源码编译打包,获取到“azkaban-solo-server.zip”和“azkaban-db.zip”。环境准备。在华为云购买Linux弹性云服务器ECS,用于安装运行MRS集群客户端和Azkaban,并绑定弹性公网IP。在弹性云服务器ECS上安装运行MRS集群客户端,例如安装目录为“/opt/client”。准备数据表,参考MySQL教程。安装MySQL并授予本机访问权限。注意:Azkaban 4.0.0版本默认适配MySQL 5.1.28版本。创建Azkaban数据库,解压“azkaban-db.zip”获取“create-all-sql-*.sql”,并初始化。上传安装包并解压上传“azkaban-solo-server.zip”至“/opt/azkaban”目录执行以下命令解压并删除安装包unzip azkaban-solo-server.zip rm -f unzip azkaban-solo-server.zip修改配置文件“azkaban-solo-server/conf/azkaban.properties”配置端口根据实际情况修改,“jetty.port”和“mysql.port”端口号可使用默认值jetty.port=8081 database.type=mysql mysql.port=3306 mysql.host=x.x.x.x mysql.database=azkaban mysql.user=xxx mysql.password=xxx启动azkaban-solo-serversource /opt/client/bigdata_env cd /opt/azkaban/azkaban-solo-server sh bin/start-solo.sh访问Azkaban WEB UI在浏览器输入“http://ECS弹性IP:port”网址,进入Azkaban WebUI登录界面,输入用户信息登录Azkaban服务。说明默认端口(port):8081;用户名/密码:azkaban/azkaban;用户账号配置文件: /opt/azkaban/azkaban-solo-server/conf/azkaban-users.xmlazkaban-hdfs-viewer plugin配置指导连接HDFS需要用户下载源码编译获取“az-hdfs-viewer.zip”,并已完成安装azkaban-solo-server。环境准备配置Azkaban用户,添加supergroup用户组授予访问HDFS权限在HDFS的配置文件“core-stie.xml”中增加Azkaban代理用户a. 登录Manager页面,选择“集群 > 服务 > HDFS > 配置 > 全部配置 > HDFS(服务) > 自定义”b. 在参数文件“core-site.xml”中添加如下配置项: 名称值hadoop.proxyuser.azkaban.groups*hadoop.proxyuser.azkaban.hosts*c. 配置完成后,单击左上角“保存”d. 选择“概览 > 更多 > 重启服务”输入密码后重启HDFS服务上传安装包并解压上传“az-hdfs-viewer.zip”至“/opt/azkaban/azkaban-solo-server/plugins/viewer”目录执行以下命令解压并删除安装包unzip az-hdfs-viewer.zip rm -f az-hdfs-viewer.zip重命名解压后的文件名为"hdfs"mv az-hdfs-viewer hdfs修改并保存配置文件修改"azkaban-solo-server/plugins/viewer/hdfs/conf/plugin.properties"文件中的代理用户为步骤1中配置的Azkaban代理用户。修改"execute-as-user"的存放目录为Azkaban安装目录,如"opt/azkaban/azkaban-solo-server"。viewer.name=HDFS viewer.path=hdfs viewer.order=1 viewer.hidden=false viewer.external.classpaths=extlib/* viewer.servlet.class=azkaban.viewer.hdfs.HdfsBrowserServlet hadoop.security.manager.class=azkaban.security.HadoopSecurityManager_H_2_0 azkaban.should.proxy=false proxy.user=azkaban // mrs集群中配置的azkaban代理用户名 allow.group.proxy=true file.max.lines=1000 #Specifying the error message we want user to get when they don't have permissionsviewer.access_denied_message=The folder you are trying to access is protected. execute.as.user=false // execute-as-user存放目录 azkaban.native.lib=/opt/azkaban/azkaban-solo-server若不存在该文件需手动创建并配置以上内容拷贝HDFS插件所需包至"/opt/azkaban/azkaban-solo-server/extlib"目录cp /opt/client/HDFS/hadoop/share/hadoop/hdfs/*.jar /opt/azkaban/azkaban-solo-server/extlib cp /opt/client/HDFS/hadoop/share/hadoop/client/hadoop-client-api-3.1.1-mrs-2.0.jar /opt/azkaban/azkaban-solo-server/extlib cp /opt/client/HDFS/hadoop/share/hadoop/common/*.jar /opt/azkaban/azkaban-solo-server/extlib不同MRS版本所需Hadoop相关版本不同,通过find /opt/client查询目检查目录结构目录结构应当为:- azkaban-solo-server - bin - conf - extlib (hadoop相关插件第三方包) - lib - logs - plugins - jobtypes(job插件目录) - commonprivate.properties - hive - plugin.properties - private.properties - hadoopJava - plugin.properties - private.properties - viewer - hdfs - conf - plugin.properties - lib (az-hdfs-viewer.zip解压后的lib) - temp - web重启Azkaban-solo-server服务cd /opt/azkaban/azkaban-solo-server sh bin/shutdown-solo.sh sh bin/start-solo.sh访问HDFS Browser在浏览器输入“http://ECS弹性IP:8081”网址,进入Azkaban WebUI登录界面,输入用户信息登录Azkaban服务单击"HDFS"plugins-jobtypes hadoop-job 部署运行安装azkaban-solo-server完成后,再部署验证hadoop-job环境准备获取"azkaban-plugins-3.0.0.zip"压缩包编译获取azkaban提供的hadoopjava-wordcount实例程序包“az-hadoop-jobtype-plugin.jar”上传插件配置文件解压"azkaban-plugins-3.0.0.zip" 获取"azkaban-plugins-3.0.0\plugins\jobtype\jobtypes"下"hadoopJava"文件夹将“hadoopJava”文件夹上传至“/plugin”目录。目录不存在则需新建修改配置文件"azkaban-solo-server/plugins/jobtypes/commonprivate.properties"# set execute-as-user execute.as.user=false hadoop.security.manager.class=azkaban.security.HadoopSecurityManager_H_2_0 azkaban.should.proxy=false obtain.binary.token=false proxy.user=azkaban // MRS集群中配置的Azkaban代理用户名 allow.group.proxy=true // execute-as-user存放目录 azkaban.native.lib=/opt/azkaban/azkaban-solo-server # hadoop hadoop.home=/opt/client/HDFS/hadoop //opt/client为MRS集群客户端安装目录 hive.home=/opt/client/Hive/Beeline spark.home=/opt/client/Spark/spark hadoop.classpath=${hadoop.home}/etc/hadoop,${hadoop.home}/share/hadoop/common/*,${hadoop.home}/share/hadoop/common/lib/*,${hadoop.home}/share/hadoop/hdfs/*,${hadoop.home}/share/hadoop/hdfs/lib/*,${hadoop.home}/share/hadoop/yarn/*,${hadoop.home}/share/hadoop/yarn/lib/*,${hadoop.home}/share/hadoop/mapreduce/*,${hadoop.home}/share/hadoop/mapreduce/lib/* jobtype.global.classpath=${hadoop.home}/etc/hadoop,${hadoop.home}/share/hadoop/common/*,${hadoop.home}/share/hadoop/common/lib/*,${hadoop.home}/share/hadoop/hdfs/*,${hadoop.home}/share/hadoop/hdfs/lib/*,${hadoop.home}/share/hadoop/yarn/*,${hadoop.home}/share/hadoop/yarn/lib/*,${hadoop.home}/share/hadoop/mapreduce/*,${hadoop.home}/share/hadoop/mapreduce/lib/*示例程序验证准备测试数据"input.txt"文件,文件内容可参考如下格式进行自定义,存放路径如"/opt/input.txt"Ross male 33 3674 Julie male 42 2019 Gloria female 45 3567 Carol female 36 2813通过HDFS客户端将测试数据"input.txt"上传至"hdfs /tmp/azkaban_test"a. 以客户端安装用户,登录安装客户端的节点b. 执行以下命令,切换到客户端安装目录 cd /opt/clientc. 执行以下命令配置环境变量 source bigdata_envd. 执行HDFS Shell命令上传文件 hdfs dfs -put /opt/input.txt /tmp/azkaban_test用户在本地编写并保存“wordcount.job”文件,内容如下type=hadoopJava job.extend=false job.class=azkaban.jobtype.examples.java.WordCount classpath=./lib/*,/opt/azkaban-solo-server-0.1.0-SNAPSHOT/lib/* force.output.overwrite=true input.path=/tmp/azkaban_test output.path=/tmp/azkaban_test_out在浏览器输入“http://ECS弹性IP:port”网址,进入Azkaban WebUI登录界面,输入用户信息登录Azkaban服务,提交job运行验证Spark command job—参考客户端命令spark任务有两种运行方式,一种是command方式,另一种是spark jobtype方式。Command方式:需要指定spark_home为/opt/client/Spark/spark/在MRS集群客户端节点可以通过echo $SPARK_HOME获取实际Spark安装地址。设置azkanban所在ECS全局环境变量,添加source {MRS客户端}后需要重启azkaban才可生效jobtype方式:参考plugins-jobtypes hadoop-job 部署运行。链接:https://bbs.huaweicloud.com/blogs/352933
推荐直播
-
华为AI技术发展与挑战:集成需求分析的实战指南
2024/11/26 周二 18:20-20:20
Alex 华为云学堂技术讲师
本期直播将综合讨论华为AI技术的发展现状,技术挑战,并深入探讨华为AI应用开发过程中的需求分析过程,从理论到实践帮助开发者快速掌握华为AI应用集成需求的框架和方法。
去报名 -
华为云DataArts+DWS助力企业数据治理一站式解决方案及应用实践
2024/11/27 周三 16:30-18:00
Walter.chi 华为云数据治理DTSE技术布道师
想知道数据治理项目中,数据主题域如何合理划分?数据标准及主数据标准如何制定?数仓分层模型如何合理规划?华为云DataArts+DWS助力企业数据治理项目一站式解决方案和应用实践告诉您答案!本期将从数据趋势、数据治理方案、数据治理规划及落地,案例分享四个方面来助力企业数据治理项目合理咨询规划及顺利实施。
去报名
热门标签