我正在探索 Oozie 管理 Hadoop 工作流的功能。我正在尝试设置调用一些配置单元命令的 shell 操作。我的 shell 脚本 hive.sh 看起来像:
#!/bin/bash
hive -f hivescript
hive 脚本(已独立测试)创建一些表等的位置。我的问题是将 hivescript 保存在哪里,然后如何从 shell 脚本中引用它。
我尝试了两种方法,首先使用本地路径,比如 hive -f/local/path/to/file,然后使用像上面那样的相对路径,hive -f hivescript,在这种情况下,我将我的 hivescript 保存在 oozie 应用程序路径目录中(与 hive.sh 和 workflow.xml 相同),并将其设置为通过 workflow.xml 转到分布式缓存。
使用这两种方法我都得到了错误信息:
oozie web 控制台上的“主类 [org.apache.oozie.action.hadoop.ShellMain],退出代码 [1]”。此外,我已经尝试在 shell 脚本中使用 hdfs 路径,据我所知这不起作用。
我的 job.properties 文件:
nameNode=hdfs://sandbox:8020
jobTracker=hdfs://sandbox:50300
queueName=default
oozie.libpath=${nameNode}/user/oozie/share/lib
oozie.use.system.libpath=true
oozieProjectRoot=${nameNode}/user/sandbox/poc1
appPath=${oozieProjectRoot}/testwf
oozie.wf.application.path=${appPath}
和 workflow.xml:
<shell xmlns="uri:oozie:shell-action:0.1">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<configuration>
<property>
<name>mapred.job.queue.name</name>
<value>${queueName}</value>
</property>
</configuration>
<exec>${appPath}/hive.sh</exec>
<file>${appPath}/hive.sh</file>
<file>${appPath}/hive_pill</file>
</shell>
<ok to="end"/>
<error to="end"/>
</action>
<end name="end"/>
我的目标是使用oozie通过shell脚本调用hive脚本,请大家提出建议。
最佳答案
Oozie 工作流的一个棘手问题是 bash 脚本的执行。 Hadoop 是为大规模并行而创建的,因此该体系结构的行为与您想象的大不相同。
当 oozie 工作流执行 shell 操作时,它将从集群中任何节点上的作业跟踪器或 YARN 接收资源。这意味着为您的文件使用本地位置将不起作用,因为本地存储专门位于您的边缘节点上。如果作业恰好在你的边缘节点上产生,那么它会工作,但任何其他时候它都会失败,而且这个分布是随机的。
为了解决这个问题,我发现最好将我需要的文件(包括 sh 脚本)保存在 hdfs 中的 lib 空间或与我的工作流程相同的位置。
这是实现您想要实现的目标的好方法。
<shell xmlns="uri:oozie:shell-action:0.1">
<exec>hive.sh</exec>
<file>/user/lib/hive.sh#hive.sh</file>
<file>ETL_file1.hql#hivescript</file>
</shell>
您会注意到的一件事是 exec 只是 hive.sh,因为我们假设该文件将移动到完成 shell 操作的基本目录
为确保最后一条注释是真实的,您必须包括文件的 hdfs 路径,这将强制 oozie 通过操作分发该文件。 在你的情况下,hive 脚本启动器应该只编码一次,并简单地提供不同的文件。因为我们有一对多的关系,hive.sh 应该保存在一个库中而不是分发每个工作流程。
最后你会看到一行:
<file>ETL_file1.hql#hivescript</file>
这一行做了两件事。在 # 之前我们有文件的位置。它只是文件名,因为我们应该使用我们的工作流分发我们独特的配置单元文件
user/directory/workflow.xml
user/directory/ETL_file1.hql
运行 sh 的节点将自动将其分发给它。最后,# 之后的部分是我们在 sh 脚本中分配给它的两个变量名。这使您能够一遍又一遍地重复使用相同的脚本并简单地为其提供不同的文件。
HDFS目录注释,
如果文件嵌套在与工作流相同的目录中,那么您只需要指定子路径:
user/directory/workflow.xml
user/directory/hive/ETL_file1.hql
会产生:
<file>hive/ETL_file1.hql#hivescript</file>
但如果路径在工作流目录之外,您将需要完整路径:
user/directory/workflow.xml
user/lib/hive.sh
会产生:
<file>/user/lib/hive.sh#hive.sh</file>
希望对大家有所帮助。
关于bash - Oozie shell 脚本 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22391274/
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
我有一个rubyonrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来
有没有一种简单的方法可以判断ruby脚本是否已经在运行,然后适本地处理它?例如:我有一个名为really_long_script.rb的脚本。我让它每5分钟运行一次。当它运行时,我想看看之前运行的是否还在运行,然后停止第二个脚本的执行。有什么想法吗? 最佳答案 ps是一种非常糟糕的方法,并且可能会出现竞争条件。传统的Unix/Linux方法是将PID写入文件(通常在/var/run中)并在启动时检查该文件是否存在。例如pid文件位于/var/run/myscript.pid然后你会在运行程序之前检查它是否存在。有一些技巧可以避免
我正在开发一个Ruby脚本,需要在没有Ruby解释器的情况下部署到系统上。它将需要在使用ELF格式的FreeBSD系统上运行。我知道有一个ruby2exe项目可以编译在Windows上运行的ruby脚本,但是在其他操作系统上这样做容易吗?甚至可能吗? 最佳答案 您是否检查过Rubinius或JRuby是否允许您预编译您的代码? 关于ruby-ruby脚本可以预编译成二进制文件吗?,我们在StackOverflow上找到一个类似的问题: https://
如何在Ruby的if语句中检查bash命令的返回值(true/false)。我想要这样的东西,if("/usr/bin/fswscell>/dev/null2>&1")has_afs="true"elsehas_afs="false"end它会提示以下错误含义,它总是返回true。(irb):5:warning:stringliteralincondition正确的语法是什么?更新:/usr/bin/fswscell寻找afs安装和运行状态。它会抛出这样的字符串,Thisworkstationbelongstocell如果afs没有运行,命令以状态1退出 最