Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
771 views
in Technique[技术] by (71.8m points)

bash - Copying files from a hdfs directory to another with oozie distcp-action

My actions

start_fair_usage ends with status okey, but test_copy returns

Main class [org.apache.oozie.action.hadoop.DistcpMain], main() threw exception, null

In /user/comverse/data/${1}_B I have a lot of different files, some of which I want to copy to ${NAME_NODE}/user/evkuzmin/output. For that I try to pass paths from copy_files.sh which holds an array of paths to the files I need.

  <action name="start_fair_usage">
    <shell xmlns="uri:oozie:shell-action:0.1">
      <job-tracker>${JOB_TRACKER}</job-tracker>
      <name-node>${NAME_NODE}</name-node>
      <exec>${copy_file}</exec>      
      <argument>${today_without_dash}</argument>
      <argument>${mta}</argument>
      <!-- <file>${path}#${start_fair_usage}</file> -->
      <file>${path}${copy_file}#${copy_file}</file>
      <capture-output/>
    </shell>
    <ok to="test_copy"/>
    <error to="KILL"/>
  </action>

  <action name="test_copy">
    <distcp xmlns="uri:oozie:distcp-action:0.2">
      <job-tracker>${JOB_TRACKER}</job-tracker>
      <name-node>${NAME_NODE}</name-node>
      <arg>${wf:actionData('start_fair_usage')['paths']}</arg>
      <!-- <arg>${NAME_NODE}/user/evkuzmin/input/*</arg> -->
      <arg>${NAME_NODE}/user/evkuzmin/output</arg>
    </distcp>
    <ok to="END"/>
    <error to="KILL"/>
  </action>

start_fair_usage starts copy_file.sh

echo ${1} 
echo ${2}

dirs=(
    /user/comverse/data/${1}_B
    )
args=()

for i in $(hadoop fs -ls "${dirs[@]}" | egrep ${2}.gz | awk -F " " '{print $8}')
do
    args+=("$i")
    echo "copy file - "${i}
done

paths=${args}
echo ${paths}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is what I did in the end.

  <start to="start_copy"/>

  <fork name="start_copy">
    <path start="copy_mta"/>
    <path start="copy_rcr"/>
    <path start="copy_sub"/>
  </fork>

  <action name="copy_mta">
    <distcp xmlns="uri:oozie:distcp-action:0.2">
      <prepare>
        <delete path="${NAME_NODE}${dstFolder}mta/*"/>
      </prepare>
      <arg>${NAME_NODE}${srcFolder}/*mta.gz</arg>
      <arg>${NAME_NODE}${dstFolder}mta/</arg>
    </distcp>
    <ok to="end_copy"/>
    <error to="KILL"/>
  </action>

  <action name="copy_rcr">
    <distcp xmlns="uri:oozie:distcp-action:0.2">
      <prepare>
        <delete path="${NAME_NODE}${dstFolder}rcr/*"/>
      </prepare>
      <arg>${NAME_NODE}${srcFolder}/*rcr.gz</arg>
      <arg>${NAME_NODE}${dstFolder}rcr/</arg>
    </distcp>
    <ok to="end_copy"/>
    <error to="KILL"/>
  </action>

  <action name="copy_sub">
    <distcp xmlns="uri:oozie:distcp-action:0.2">
      <prepare>
        <delete path="${NAME_NODE}${dstFolder}sub/*"/>
      </prepare>
      <arg>${NAME_NODE}${srcFolder}/*sub.gz</arg>
      <arg>${NAME_NODE}${dstFolder}sub/</arg>
    </distcp>
    <ok to="end_copy"/>
    <error to="KILL"/>
  </action>

  <join name="end_copy" to="END"/>

  <kill name="KILL">
    <message>Action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
  </kill>
  <end name="END"/>

Turned out it was possible to use wildcards in distcp, so I didn't need bash at all.

Also. Some people adviced me to write it in scala.

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileSystem, Path, FileUtil}

val conf = new Configuration()
val fs = FileSystem.get(conf)

val listOfFileTypes = List("mta", "rcr", "sub")
val listOfPlatforms = List("B", "C", "H", "M", "Y")

for(fileType <- listOfFileTypes){
  FileUtil.fullyDeleteContents(new File("/apps/hive/warehouse/arstel.db/fair_usage/fct_evkuzmin/file_" + fileType))
  for (platform <- listOfPlatforms) {
    var srcPaths = fs.globStatus(new Path("/user/comverse/data/" + "20170404" + "_" + platform + "/*" + fileType + ".gz"))
    var dstPath = new Path("/apps/hive/warehouse/arstel.db/fair_usage/fct_evkuzmin/file_" + fileType)

    for(srcPath <- srcPaths){
      println("copying " + srcPath.getPath.toString)
      FileUtil.copy(fs, srcPath.getPath, fs, dstPath, false, conf)
    }
  }
}

Both things work, thought I haven't tried to run the scala script in Oozie.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...