ฉันจะโหลดทุกไฟล์ในโฟลเดอร์โดยใช้ PIG ได้อย่างไร

ฉันมีโฟลเดอร์ไฟล์ที่สร้างขึ้นทุกวันซึ่งทั้งหมดจะจัดเก็บข้อมูลประเภทเดียวกัน ฉันต้องการสร้างสคริปต์ที่โหลด 10 ตัวใหม่ล่าสุด UNION พวกมัน แล้วรันโค้ดอื่น ๆ กับพวกมัน เนื่องจาก pig มีวิธี ls อยู่แล้ว ฉันจึงสงสัยว่ามีวิธีง่ายๆ สำหรับฉันในการรับไฟล์ที่สร้างขึ้น 10 ไฟล์ล่าสุด และโหลดมันทั้งหมดภายใต้ชื่อทั่วไปโดยใช้ตัวโหลดและตัวเลือกเดียวกันหรือไม่ ฉันเดาว่ามันจะมีลักษณะดังนี้:

REGISTER /usr/local/lib/hadoop/hadoop-lzo-0.4.13.jar;
REGISTER /usr/local/lib/hadoop/elephant-bird-2.0.5.jar;
FOREACH file in some_path:
    file = LOAD 'file' 
    USING com.twitter.elephantbird.pig.load.LzoTokenizedLoader('\\t') 
    AS (i1, i2, i3);

person Eli    schedule 07.09.2011    source แหล่งที่มา


คำตอบ (3)


นี่ไม่ใช่สิ่งที่ฉันสามารถทำได้นอกกรอบ และเป็นสิ่งที่สามารถทำได้นอกสคริปต์ด้วยสคริปต์ตัวตัดคำหรือสคริปต์ตัวช่วยบางประเภท (bash, perl ฯลฯ ) หากคุณเขียนสคริปต์ชื่อ last10.sh ซึ่งจะส่งออกไฟล์ 10 ไฟล์ล่าสุดของคุณ โดยคั่นด้วยเครื่องหมายจุลภาค:

$ ./last10.sh
/input/file38,/input/file39,...,/input/file48

สิ่งนี้น่าจะได้ผลกับไฟล์ 10 ไฟล์ล่าสุด:

hadoop fs -ls /input/ | sort -k6,7 | tail -n10 | awk '{print $8}' | tr '\n' ','

คุณสามารถทำได้:

$ pig -p files="`last10.sh`" my_mr.pig

จากนั้นในสคริปต์หมูของคุณ ให้ทำดังนี้

data = LOAD '$files'
       USING com.twitter.elephantbird.pig.load.LzoTokenizedLoader('\\t')
       AS (i1, i2, i3);

Pig จะโหลดไฟล์แยกกันหากคั่นด้วยเครื่องหมายจุลภาคเช่นนี้ นี่จะเทียบเท่ากับการทำ:

data = LOAD '/input/file38,/input/file39,...,/input/file48'
       USING com.twitter.elephantbird.pig.load.LzoTokenizedLoader('\\t')
       AS (i1, i2, i3);
person Donald Miner    schedule 07.09.2011
comment
หวาน! คงจะดีกว่านี้ถ้า PIG ให้วิธีดำเนินการโดยตรงแก่ฉัน แต่วิธีนี้ใช้ได้ผลแน่นอน ขอบคุณ! - person Eli; 08.09.2011
comment
ฉันเห็นด้วย. Pig เก่งในเรื่องการวิเคราะห์ แต่เมื่อพูดถึงการผสานรวมที่แท้จริงนอกเหนือจากการวิเคราะห์ มันก็ไม่ได้มีอะไรมากมายนัก ทีมของฉันยอมรับค่อนข้างมากว่าสคริปต์หมูของเราทั้งหมดจำเป็นต้องถูกห่อด้วยทุบตี - person Donald Miner; 08.09.2011
comment
ช่างเถอะ. ปรากฎว่า pig ไม่ชอบช่องว่าง ดังนั้นบางอย่างเช่น pig -p files=file1 file2 script.pig ไม่ทำงานและตายด้วย Encountered arguments on command line error คุณมีวิธีแก้ไขปัญหานั้นหรือไม่? - person Eli; 08.09.2011
comment
อ๊ะ! ความผิดฉันเอง! ชอบใช้ลูกน้ำ ไม่เว้นวรรค ฉันกำลังอัปเดตคำตอบเพื่อแทนที่การขึ้นบรรทัดใหม่ด้วยเครื่องหมายจุลภาค แจ้งให้เราทราบหากใช้งานได้ ฉันรู้จักบางคนที่ใช้ { } รอบๆ เส้นทางเช่น {file1,file2,file3} แต่ฉันคิดว่าพวกเขาให้ผลแบบเดียวกัน - person Donald Miner; 08.09.2011
comment
เย็น! ข้อเสนอแนะเดียวของฉันคือคุณเพิ่มอีกหนึ่งไพพ์เพื่อ awk ในตอนท้ายเพื่อกำจัดวงเล็บที่สร้างขึ้นที่จุดเริ่มต้นและจุดสิ้นสุด นี่จะเป็นคำตอบของคุณด้านบนพร้อมและเพิ่ม: | awk '{ พิมพ์ย่อย ($0, 1, ความยาว ($0)-1 ) }' - person Eli; 09.09.2011

คำตอบของ Donald Miner ยังคงทำงานได้อย่างสมบูรณ์แบบ แต่ IMO มีวิธีที่ดีกว่าในการดำเนินการนี้โดยใช้ Embedded Pig ใน Python O'Reilly มีคำอธิบายสั้นๆ ที่นี่. นอกจากนี้ยังมีการนำเสนอว่าทำไมคุณถึงอยากทำ และวิธีการทำงาน ที่นี่. สรุปสั้นๆ ก็คือ มีฟังก์ชันมากมายที่สามารถเข้าถึงได้ก่อนที่จะรันสคริปต์ Pig เพื่อกำหนดส่วนต่างๆ ของสคริปต์ การห่อและ/หรือการสร้างส่วนของสคริปต์ใน Jython แบบไดนามิกช่วยให้คุณทำเช่นนั้นได้ ชื่นชมยินดี!

person Eli    schedule 08.03.2013

ฉันชอบ 2 วิธีข้างต้น แค่อยากให้อีกหนึ่งทางเลือกสำหรับผู้ที่ชื่นชอบ oozie การกระทำของ Java ใน oozie คายไฟล์ในตำแหน่งที่กำหนดค่าโดย "oozie.action.output.properties" และการกระทำของ Pig จะส่งผ่านไปยังสคริปต์ของหมู นี่ไม่ใช่วิธีแก้ปัญหาที่หรูหราอย่างแน่นอนเมื่อเทียบกับ 2 ข้างต้น ฉันมีปัญหาในการกำหนดค่าหมูที่ฝังโดยใช้กำหนดการ java ใน oozie ดังนั้นฉันจึงต้องใช้วิธีแก้ปัญหานี้

<workflow-app xmlns='uri:oozie:workflow:0.1' name='java-wf'>
<start to='java1' />

<action name='java1'>
    <java>
        <job-tracker>${jobTracker}</job-tracker>
        <name-node>${nameNode}</name-node>
        <configuration>
           <property>
                <name>mapred.job.queue.name</name>
                <value>${queueName}</value>
            </property>
        </configuration>
        <main-class>org.apache.oozie.test.MyTest</main-class>
        <arg>${outputFileName}</arg>
        <capture-output/>
    </java>
    <ok to="pig1" />
    <error to="fail" />
</action>


<action name='pig1'>
    <pig>
        <job-tracker>${jobTracker}</job-tracker>
        <name-node>${nameNode}</name-node>
        <configuration>
            <property>
                <name>mapred.job.queue.name</name>
                <value>${queueName}</value>
            </property>
        </configuration>
        <script>script.pig</script>
        <param>MY_VAR=${wf:actionData('java1')['PASS_ME']}</param>
    </pig>
    <ok to="end" />
    <error to="fail" />
</action>

<kill name="fail">
    <message>Pig failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
<end name='end' />

person satish    schedule 08.06.2013