เมื่อประมาณเกือบๆ 1 ปีที่ผ่านมา ผมได้ติดตั้ง Hadoop รุ่น 1.1.2 บน Ubuntu 12.04 LTS เรียบร้อยไปแล้ว ซึ่งตอนนั้นมีปัญหาในการติดตั้งบางอย่าง แต่ผมก็ได้แก้ปัญหาไปแล้ว แต่มาเมื่อสัปดาห์ก่อน ผมต้องการติดตั้ง Hadoop บนอีกเครื่องหนึ่ง ทำให้ผมต้องมารื้อฟื้นความจำว่าปัญหาเก่าๆที่เคยแก้ไปนั้น ผมทำอย่างไร แต่นึกเท่าไหร่ก็นึกไม่ออกสักที ไฟล์เก่าๆที่เคยบันทึก หรือ เขียนสคริปท์ไว้ ตอนนี้ก็ไม่รู้เก็บไว้ที่ไหนแล้ว เนื่องจากผมมีการ backup ไฟล์ไว้หลายที่ กระจัดกระจายกันไป ไม่มีเวลามาจัดให้เข้าที่เข้าทางสักที (ดูเหมือนจะเป็นปัญหาคลาสสิกสำหรับคนไอทีเลยก็ว่าได้ ใครมีไอเดียดีๆที่ช่วยแก้ปัญหานี้ได้น่าจะทำโปรแกรมขายได้นะครับ) ครั้งนี้ผมจึงอาศัยการบันทึกไว้ที่บล็อกนี้แทน และหวังว่าจะเป็นประโยชน์สำหรับบางคนที่ติดปัญหาเดียวกัน
Hadoop Version
รุ่นของ Hadoop ที่เมื่อก่อนผมเลือกใช้ คือ 1.1.2 ตอนนั้น น่าจะเป็นรุ่นใหม่ที่ stable ที่สุดแล้ว แต่ปัจจุบันนี้ มีรุ่นที่เป็น stable อยู่ 2 รุ่น เนื่องจากมีการแตกรุ่นออกเป็น 1.x และ 2.x โดยรุ่น stable ของ 1.x คือ 1.2.1 ส่วนรุ่น stable ของ 2.x คือ 2.2.0 ครับ
- 1.x stable -> 1.2.1 (1 Aug, 2013)
- 2.x stable -> 2.2.0 (15 Oct, 2013)
ทีแรกผมจะทดลองติดตั้ง 2.x แต่ก็เกรงว่า โปรแกรมเก่าจะใช้งานไม่ได้ ประกอบกับ เมื่อเข้าไปดาวโหลดไฟล์แล้ว ปรากฏว่า ไม่มี Debian Package ให้ดาวโหลด ผิดกับ 1.2.1 ที่มี Package ทั้งแบบ Debian (.deb) RedHat(.rpm) และ Binary(.tar.gz) รวมทั้งมีทั้งสถาปัตยกรรมแบบ i386 และ x86_64 ให้ครบหมด ผมจึงตัดสินใจดาวโหลด 1.2.1 มาลง ซึ่งก็พบว่าปัญหาเดิมที่พบใน 1.1.2 ยังไม่ได้รับการแก้ไข
Why Debian Package?
ระบบปฏิบัติการ Ubuntu นั้น มีพื้นฐานมาจาก Debian ดังนั้น Package สำหรับติดตั้งโปรแกรมจึงเป็นแบบ Debian ซึ่งสำหรับใครที่ติดตั้งด้วย Binary และทำตามคำแนะนำในเว็บไซต์ต่างๆ ก็ทำได้ครับ แต่จะไม่เหมือนกับ Debian Package ที่มีการวางระบบไฟล์ ไม่ว่าจะเป็น Configuration Library Script และอื่นๆไว้ในแบบของ Debian มีการกำหนดสิทธิ์ในการเข้าถึงไฟล์ต่างเหล่านี้อย่างเป็นระบบและเพื่อความปลอดภัยสูง ไม่ให้เกิดช่องโหว่ได้ ดังนั้น เราจึงควรทำตามที่กำหนดไว้จะดีที่สุด แต่สำหรับการทดลอง ทดสอบ หรือใช้พัฒนาโปรแกรมโดยเราใช้เองคนเดียว การติดตั้งแบบ Binary ก็จะสะดวกกว่ามากครับ เพราะทุกอย่างจะรวมอยู่ในโฟลเดอร์เดียวหมด แตกไฟล์มาก็แทบจะใช้ได้เลย
Users/Groups are not created during installation
เมื่อนำไฟล์ .deb มาติดตั้ง โดยปกติเมื่อ double-click ที่ไฟล์ โปรแกรม Package Installer จะทำงาน เปิดหน้าต่างมาให้เราติดตั้ง ซึ่งเป็น GUI ทำให้สะดวกมาก แต่จะทำให้เราไม่ทันได้สังเกตข้อความแจ้งเตือนต่างๆ จึงเข้าใจว่าติดตั้งเสร็จเรียบร้อยแล้ว แต่พอไปใช้งานก็จะมีปัญหา ซึ่งถ้าเราติดตั้งด้วยคำสั่ง
sudo -E dpkg -i hadoop_1.2.1-1_x86_64.deb
หมายเหตุ:
ที่กำหนด option -E ไว้ เพื่อให้มีการนำค่า JAVA_HOME ที่กำหนดไว้มาใช้ตอนติดตั้งปัญหาแรกที่เราจะพบเมื่อติดตั้ง คือข้อความ
Selecting previously unselected package hadoop.
(Reading database ... 336159 files and directories currently installed.)
Unpacking hadoop (from .../hadoop_1.2.1-1_x86_64.deb) ...
groupadd: GID '123' already exists
Setting up hadoop (1.2.1) ...
chown: invalid group: `root:hadoop'
ซึ่งปกติแล้ว จะเป็นขั้นตอนการสร้าง group ชื่อ hadoop และ user ชื่อ mapred และ hdfs โดยสามารถตรวจสอบได้ ด้วยการเปิดดูไฟล์ preinst ซึ่งเป็นสคริปท์ที่จะถูกรันหลังจากที่มีการแตกไฟล์(Unpacking)เรียบร้อยแล้ว ซึ่งสคริปท์นี้เขียนไว้ตายตัวคือ
getent group hadoop 2>/dev/null >/dev/null || /usr/sbin/groupadd -g 123 -r hadoop
หมายความว่าให้สร้าง group ชื่อ hadoop โดยกำหนดให้มี GID เป็น 123 ซึ่งถ้าหากในเครื่องของเรามี GID 123 อยู่แล้ว ก็จะเกิด error GID '123' already exists นั่นเอง ข้อผิดพลาดนี้ได้มีการรายงานไว้แล้วตั้งแต่รุ่น 1.0.3 แต่ยังไม่ได้รับการแก้ไข สาเหตุของปัญหานี้เกิดจากการใช้คำสั่ง groupadd ซึ่งปกติแล้ว บนระบบ Debian จะมีอีกคำสั่งหนึ่งคือ addgroup ซึ่งทำงานคล้ายกัน groupadd จะเป็นคำสั่งระดับล่าง ส่วน addgroup จะเป็นคำสั่งระดับบน ซึ่งถ้าเราไม่กำหนด GID คำสั่ง addgroup จะหาค่าที่เหมาะสมตามระบบของ Debian มาให้แทน ดังนั้น คำสั่งนี้ควรจะแก้เป็น
getent group hadoop 2>/dev/null >/dev/null || /usr/sbin/addgroup --system hadoop
แต่เนื่องจากเราได้ติดตั้งไฟล์ไปแล้ว จึงแก้ไขด้วยการสั่งเองภายหลังจากที่แตกไฟล์เรียบร้อยแล้ว ดังนี้
/usr/sbin/addgroup --system hadoop
/usr/sbin/adduser --shell /bin/bash --no-create-home --system --ingroup hadoop --home /var/lib/hadoop/mapred mapred
/usr/sbin/adduser --shell /bin/bash --no-create-home --system --ingroup hadoop --home /var/lib/hadoop/hdfs hdfs
ซึ่งจะสร้าง group ชื่อ hadoop และ user ชื่อ mapred และ hdfs ขึ้นมา
Configuration Files
ก่อนที่เราจะเริ่ม start Hadoop จะมี config ไฟล์ที่ต้องแก้ไขต่างๆ ซึ่งตามคำแนะนำใน Document ของ Hadoop 1.2.1 จะระบุชื่อไฟล์ในโฟลเดอร์ conf แต่ Debian Package จะย้ายไปอยู่ที่ /etc/hadoop โดยมีไฟล์ต่างๆที่ต้องแก้ไขดังนี้- hadoop-env.sh
- กำหนดค่า JAVA_HOME ใหม่ให้ถูกต้อง สำหรับค่า default ที่กำหนดไว้คือ /usr/lib/jvm/java-6-sun แต่เนื่องจากบน Ubuntu จะใช้ OpenJDK เป็นหลัก ผมจึงเปลี่ยนค่าให้เป็น /usr/lib/jvm/default-java ซึ่งจะใช้ default JDK ที่ติดตั้งไว้ โดยปกติแล้ว Ubuntu 12.04 LTS จะใช้ OpenJDK 6 ซึ่งน่าจะเข้ากันได้ดี แต่เนื่องจากผมมีโปรแกรมบางตัวที่ใช้ Java 7 จึงเปลี่ยนมาใช้ OpenJDK 7 (หวังว่าจะไม่มีปัญหา)
- หากต้องการเปลี่ยนค่า environment สามารถใช้คำสั่ง update-hadoop-env.sh ได้ โดยสั่ง
- sudo -E bash /usr/sbin/update-hadoop-env.sh --prefix=/usr --bin-dir=/usr/bin --sbin-dir=/usr/sbin --conf-dir=/etc/hadoop --log-dir=/var/log/hadoop --pid-dir=/var/run/hadoop
- master/slave
- master ไฟล์ จะเก็บรายชื่อเครื่องที่ทำหน้าที่เป็น NameNode ซึ่งจะเป็นเครื่องแม่ และสามารถเป็น JobTracker TaskTracker และ DataNode ได้ด้วย
- slave ไฟล์ จะเก็บรายชื่อเครื่องที่ทำหน้าที่เป็น DataNode และเป็น TaskTracker ได้ด้วย
- ถ้าติดตั้งในโหมด Single-Node ทั้งสองไฟล์จะมีค่าเป็น localhost
- *-site.xml
- core-site.xml เป็นไฟล์ที่เก็บค่าเกี่ยวกับ NameNode เช่น fs.default.name เป็นค่า URL ของเครื่อง NameNode ที่ Hadoop ในเครื่องนั้นๆจะติดต่อด้วย โดยค่า default ใน Debian Package กำหนดไว้เป็น hdfs://localhost:8020 แต่เว็บอื่นๆมักกำหนดค่าตัวอย่างไว้ที่พอร์ต 9000 หรือ 9001 ซึ่งจะต้องระวังการกำหนดค่าตรงนี้ให้ดี เพราะหากชนกับบริการอื่นๆที่มีอยู่ในเครื่อง NameNode ก็จะไม่สามารถ start ได้ ค่า default ต่างๆของไฟล์นี้ สามารถดูได้จากไฟล์ core-default.xml
- hdfs-site.xml เป็นไฟล์ที่เก็บค่าเกี่ยวกับ HDFS ว่าจะมีการจัดแบ่งข้อมูลของระบบอย่างไร โดยเฉพาะค่า dfs.replication ซึ่งเป็นจำนวนการทำซ้ำข้อมูล จำนวนนี้ไม่ควรเกินจำนวน DataNode ค่า default ต่างๆของไฟล์นี้ สามารถดูได้จากไฟล์ hdfs-default.xml
- mapred-site.xml เป็นไฟล์ที่เก็บค่าเกี่ยวกับ JobTracker ค่า default ต่างๆของไฟล์นี้ สามารถดูได้จากไฟล์ mapred-default.xml
Operation Mode
ระบบ Hadoop จะประกอบไปด้วยบริการ 4 ประเภทคือ
- NameNode เป็นบริการหลัก ทำหน้าที่ค้นหาและจัดการบริการอื่นๆในระบบ
- JobTracker ทำหน้าที่จัดคิวการทำงาน
- TaskTracker ทำหน้าที่ประมวลผล Map-Reduce หรืองานอื่นๆ
- DataNode ทำหน้าที่จัดการข้อมูลในระบบ HDFS (Hadoop Distributed File System)
ซึ่งบริการทั้ง 4 ประเภท สามารถทำงานอยู่บนเครื่องๆเดียวได้ (Single-Node โหมด) หรือจะแบ่งเป็นเครื่อง 2 กลุ่ม คือ master ซึ่งสามารถมีบริการทั้ง 4 ประเภทในเครื่องเดียว หรือ slave ซึ่งจะมีบริการเฉพาะ TaskTracker และ DataNode เท่านั้น เพื่อแบ่งหรือกระจายการประมวลผลและข้อมูลของระบบออกไปยังเครื่องลูกจำนวนมากๆ โดยการติดตั้งระบบ เราสามารถเลือกติดตั้งให้ทำงานได้ 3 โหมดคือ
- Local (Standalone)
- การทำงานจะอยู่บนเครื่องเดียว และไม่เป็นเครือข่าย
- โหมดนี้เป็น default ของโปรแกรม หากยังไม่มีการตั้งค่าใดๆ
- เหมาะกับการทดสอบและ debug มากกว่า
- Pseudo-Distributed (Single-Node)
- การทำงานจะอยู่บนเครื่องเดียว แต่เป็นเครือข่าย
- สามารถตั้งค่าต่างๆได้ง่ายด้วยโปรแกรม hadoop-setup-single-node.sh
- เหมาะกับการใช้งานเบื้องต้น และพร้อมที่จะขยายไปเป็น Fully-Distributed โหมด
- Fully-Distributed (Multi-Node)
- การทำงานจะเป็นเครือข่ายหลายเครื่องสมบูรณ์แบบ
- สามารถปรับแก้ไฟล์บางไฟล์จาก Pseudo-Distributed โหมด กลายเป็น Fully-Distributed โหมดได้ทันที
- เหมาะกับการใช้งานเต็มรูปแบบ รองรับภาระงานเพิ่มขึ้นโดยเพิ่มจำนวนเครื่องได้
Setup Single-Node Mode
หลังจากที่เราติดตั้ง Debian Package เรียบร้อยแล้ว ไฟล์ hadoop-env.sh จะถูกตั้งค่า environment ไว้เรียบร้อยแล้ว แต่หากค่าต่างๆยังไม่ถูกต้อง เช่นค่า JAVA_HOME ควรแก้ไขให้ถูกต้องเสียก่อนนะครับ จากนั้นเราจะต้องตั้งค่าไฟล์ *-site.xml ให้ครบถ้วน ก่อน ซึ่งขึ้นอยู่กับโหมดการใช้งานที่เราต้องการ โดยปกติแล้วถ้าเป็น Standalone โหมด ก็ไม่ต้องแก้ไขอะไร แต่ส่วนใหญ่แล้ว เราจะไม่ใช้โหมดนี้ เราจะใช้โหมด Single-Node มากกว่า ซึ่งค่าต่างๆที่ต้องกำหนด สามารถศึกษาได้จาก document ซึ่งผมจะไม่ขอกล่าวในที่นี้นะครับ แต่เราก็มีวิธีที่ง่ายกว่านั้น เนื่องจากมีสคริปท์ช่วยอำนวยความสะดวกให้แล้วคือ hadoop-setup-single-node.sh โดยมีลำดับของการทำงานคือ
- ตั้งค่า config ต่างๆ
- ทำการ Format NameNode (เหมือนเรา Format ฮาร์ดดิสก์นะครับ)
- จัดเตรียมโครงสร้างของไฟล์ในระบบ HDFS
- start บริการต่างๆของ Hadoop ซึ่งก็คือ NameNode DataNode JobTracker และ TaskTracker
- ตั้งค่าสำหรับให้บริการต่างๆ start อัตโนมัติเมื่อบู๊ตเครื่อง
เมื่อรัน hadoop-setup-single-node.sh แล้วตอบ y ทั้งหมด คือเลือกใช้ค่า default ทั้งหมด ผลปรากฏว่า มีปัญหาเกี่ยวกับ permission ของโฟลเดอร์ /var/hadoop/log/root เกิดขึ้นตอนรัน JobTracker และ TaskTracker ซึ่งมีข้อความตัวอย่างดังนี้
* Starting Apache Hadoop Job Tracker server hadoop-jobtracker chown: changing ownership of `/var/log/hadoop/root': Operation not permitted
starting jobtracker, logging to /var/log/hadoop/root/hadoop-root-jobtracker-SLOffice.out
/usr/sbin/hadoop-daemon.sh: line 137: /var/log/hadoop/root/hadoop-root-jobtracker-SLOffice.out: Permission denied
head: cannot open `/var/log/hadoop/root/hadoop-root-jobtracker-SLOffice.out' for reading: No such file or directory
/usr/sbin/hadoop-daemon.sh: line 147: /var/log/hadoop/root/hadoop-root-jobtracker-SLOffice.out: Permission denied
/usr/sbin/hadoop-daemon.sh: line 148: /var/log/hadoop/root/hadoop-root-jobtracker-SLOffice.out: Permission denied
[fail]
สาเหตุ เกิดจาก JobTracker และ TaskTracker จะถูกรันโดย user ชื่อ mapred แต่โฟลเดอร์ /var/log/hadoop/root ถูกสร้างขึ้น เพราะเราสั่งรัน hadoop-setup-single-node.sh ด้วย root ซึ่งตอนรัน NameNode และ DataNode จะรันโดย user ชื่อ hdfs ทำให้มีการเปลี่ยนสิทธิ์ของ /var/log/hadoop/root ให้เป็นของ hdfs:hadoop ด้วย chmod มีค่าเป็น 755 พอ mapred จะมาเปลี่ยน จึงเปลี่ยนไม่ได้ ผมจึงแก้ไขด้วย chmod ให้เป็น 775 แทน
Start/Stop Service
การสั่ง start/stop บริการต่างๆของ Hadoop ความจริงแล้ว จะมีสคริปท์ให้เรียกใช้ โดยเฉพาะคำสั่ง start-all.sh และ stop-all.sh ซึ่งจะไปเรียก start-dfs.sh/start-mapred.sh และ stop-dfs.sh/stop-mapred.sh อีกทีหนึ่ง โดย dfs นั้นจะมีบริการ NameNode และ DataNode อยู่ ส่วน mapred จะมี JobTracker และ TaskTracker ครับ ดังนั้น เราจึง start ได้ด้วยคำสั่ง
sudo start-all.sh
และ stop ด้วยคำสั่ง
sudo stop-all.sh
แต่ถ้าหากเรากำหนดให้ hadoop-setup-single-node.sh ติดตั้ง service ให้ start/stop Hadoop อัตโนมัติตอน boot/shutdown เครื่อง เราก็สามารถสั่ง start ได้ด้วยคำสั่ง
sudo service hadoop-xxx start
และ stop ได้ด้วยคำสั่ง
sudo service hadoop-xxx stop
โดยมีสคริปท์สำหรับบริการต่างๆอยู่ที่ /etc/init.d/hadoop-xxx คือ
- hadoop-namenode
- hadoop-datanode
- hadoop-jobtracker
- hadoop-tasktracker
- hadoop-secondarynamenode (ปกติจะไม่ start อัตโนมัติ)
และคำสั่งทั้งหมดนั้น จริงๆแล้วจะไปเรียกคำสั่ง hadoop-daemon.sh อีกทีหนึ่ง ซึ่งสามารถเรียกใช้ได้เช่นกัน มีรูปแบบคือ
hadoop-daemon.sh [start/stop] [ชื่อบริการ]
เช่น
hadoop-daemon.sh start namenode
หมายเหตุ:
หาก start ด้วยวิธีใด ให้ stop ด้วยวิธีที่คู่กัน
Startup Checking
จากการตรวจสอบการทำงานด้วยคำสั่ง jps จะพบว่ามีเพียง NameNode DataNode และ TaskTracker รันอยู่ แต่ JobTracker ไม่มี ผมจึงเข้าไปตรวจสอบ log ไฟล์ของ JobTracker ที่โฟลเดอร์ /var/log/hadoop พบข้อความผิดพลาดคือ
WARN org.apache.hadoop.mapred.JobTracker: Failed to operate on mapred.system.dir (hdfs://localhost:8020/mapred/mapredsystem) because of permissions.
WARN org.apache.hadoop.mapred.JobTracker: Manually delete the mapred.system.dir (hdfs://localhost:8020/mapred/mapredsystem) and then start the JobTracker.
WARN org.apache.hadoop.mapred.JobTracker: Bailing out ...
org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security.AccessControlException: Permission denied: user=mapred, access=WRITE, inode="":hdfs:supergroup:rwxr-xr-x
สาเหตุก็คือ เนื่องจากขั้นตอนที่ 3 ของ hadoop-setup-single-node.sh นั้น จะสร้างโฟลเดอร์ /tmp และ /usr ไว้ใน HDFS เท่านั้น จะไม่มีโฟลเดอร์ /mapred แต่เนื่องจากใน mapred-site.xml ได้กำหนดค่า mapred.system.dir ไว้ที่ /mapred/mapredsystem จึงทำให้ JobTracker พยายามที่จะเขียนข้อมูลไปที่นั่น แต่ก็ทำไม่ได้ และจบการทำงานไป วิธีการแก้ไขที่มีคนแนะนำไว้ก็คือ ให้ตั้งค่า mapred.system.dir ไปไว้ใน /tmp แทน โดยให้อิงกับค่า hadoop.tmp.dir ซึ่งจะต้องแก้ไขในไฟล์ mapred-site.xml ดังนี้
<property>
<name>mapred.system.dir</name>
<value>${hadoop.tmp.dir}/mapred/mapredsystem</value>
<final>true</final>
</property>
เมื่อแก้ไขเสร็จแล้ว สั่ง start JobTracker ใหม่ ก็จะพบปัญหาทำนองเดียวกันกับค่า mapred.job.tracker.history.completed.location จึงแก้ไขให้เป็น
<property>
<name>mapred.job.tracker.history.completed.location</name>
<value>${hadoop.tmp.dir}/mapred/history/done</value>
</property>
Web Interface
เมื่อแก้ไขข้อผิดพลาดต่างๆ และ start บริการต่างๆได้หมดแล้ว ก็สามารถเปิดดู NameNode ผ่านเว็บได้ที่ URL http://localhost:50070 ส่วน JobTracker เปิดดูได้ที่ http://localhost:50030อ้างอิง
- The Apache Software Foundation, Welcome to Apache™ Hadoop®!
- Michael G. Noll, Running Hadoop on Ubuntu Linux (Single-Node Cluster)
- Michael G. Noll, Running Hadoop on Ubuntu Linux (Multi-Node Cluster)
- The Apache Software Foundation, Hadoop 1.2.1 Documentation
ไม่มีความคิดเห็น:
แสดงความคิดเห็น