Bigdata ติดตั้ง Hadoop แบบ Pseudo Distributed และการใช้งาน HDFS

หากเราต้องประมวลผล ข้อมูลขนาดใหญ่ (Bigdata) ควรต้องเลือกทำงานในแบบ Distributed Program หรือการรันงานแบบกระจายตัวไปยังหลายๆเครื่อง เพื่อช่วยลดเวลารวมในการประมวลผล (อารมณ์เหมือนแทนที่จะทำงานคนเดียว เราก็แบ่งงานเป็นงานย่อยๆ ให้หลายๆคนทำพร้อมๆกัน มันคือการทำงานแบบขนาน หรือ parallel processing นั่นเอง)

เพื่อให้สามารถจำลองสภาพแวดล้อมตามความต้องการด้านบน เราจึงเลือกใช้ Apache Hadoop ที่ช่วยให้งาน Distributed Processing ทำได้ง่ายขึ้นโดยเน้นไปที่ซอฟต์แวร์ และสามารถขยายระบบเพิ่มเติมในภายหลังโดยไม่มีข้อจำกัด (เพิ่มโหนดประมวลผล เพิ่มพื้นที่เก็บข้อมูล)

โครงสร้างของ Hadoop

hadoop technology stack

จากภาพจะเป็นพัฒนาการของ Hadoop 1.x จนปัจจุบัน เป็น Hadoop 2.x (2.7.2) ซึ่งประกอบไปด้วยส่วนต่างๆ และการทำงานไล่จากล่างขึ้นบนดังนี้

  • HDFS (Hadoop Distributed File System) : คือระบบจัดการไฟล์ แบบพิเศษของ Hadoop , เราอาจจะเคยรู้จักระบบไฟล์อื่นๆ เช่น FAT32, NTFS, NFS เป็นต้น แต่ความเก่งของ HDFS คือมันสามารถรองรับไฟล์ขนาด TB หรือ PB ซึ่งการเก็บก็จะแยกเก็บเป็น Block ย่อยๆ (ขั้นต่ำคือ Block ละ 64MB) โดยต้องมีเครื่องหนึ่งตั้งเป็น namenode สำหรับเก็บชื่อและตำแหน่งที่เก็บข้อมูล (คล้ายๆ กับ FAT Table ของระบบไฟล์ปกติ) ส่วนเครื่องอื่นๆที่ใช้เก็บข้อมูลจะเรียกว่า data-node และจะมีการสำรอง block ที่เหมือนกันไว้อย่างน้อย 2 ที่เพื่อป้องกันกรณีที่ มีบาง node ล่มไป
  • YARN : เป็นตัวที่เพิ่มเข้ามาใน  Hadoop 2.0 ซึ่งจะเป็นพระเอกมาคอยช่วยในการจัดการ cluster ของเราเวลาที่จ่ายงาน (Job กับ Task) และการติดตามงานของ MapReduce ที่เราส่งไปประมวลผล รวมถึงจัดการพวก Resource Manager และ Node Manager ดูแลเรื่องของ CPU, Memory, Disk, และ Network
  • MapReduce: คือ Distributed Programming Framework ที่เหมาะกับปัญหาง่ายๆ ที่ไม่ค่อยซับซ้อน แต่มีจำนวนข้อมูลปริมาณมหาศาล ซึ่งเดี๋ยวเราจะมาลองเขียนกันตั้งแต่พื้นฐานเลย
  • Pig : เป็นภาษาสคริปต์ที่เหมาะกับงาน Pipeline processing ประมาณประมวลผล ฝากเข้าตัวแปร แล้วเอาไปทำอย่างอื่นต่อ มักใช้ในการเตรียมข้อมูล บางกรณีสามารถใช้แทน MapReduce ได้
  • Hive: (อ่านว่า “ไฮฟ์”) ถ้าจะมองว่าเป็น Distribute Database Management System ก็ได้เพราะถ้าพวก RDBMS (row-oriented) ทั่วๆไป จะไม่รองรับการเก็บข้อมูลแบบกระจายไปอยู่ในหลายๆที่ แจะการจัดการกับข้อมูลขนาดใหญ่ ส่วนใหญ่ถ้าเราอยากให้การสรุปข้อมูลได้ง่ายขึ้น ก็จะมีการ load ไฟล์จาก  HDFS มาเข้า Hive ก่อนแล้วค่อยเขียน Query เหมือนกับการใช้ SQL ทั่วๆไป ซึ่งโดยรวมจะเร็วกว่าการทำ MapReduce หรือเขียน Pig
  • HBase: ใช้วิธีเก็บข้อมูลแบบ column-oriented นั่นคือเราสามารถเพิ่ม column ได้ไม่จำกัด เพียงแต่ต้องกำหนด column-family ให้เรียบร้อยก่อนแค่นั้น เพื่อแก้ปัญหาการเก็บข้อมูลของ Hive ที่เป็นเหมือน RDBMS ทั่วไปที่จะต้องมี Schema (โครงสร้างตาราง) ที่ชัดเจนก่อน เวลาจะเพิ่ม column จะต้องมานั่ง alter table ดังนั้น HBase จึงเหมาะสำหรับข้อมูลที่มี Schema ไม่แน่นอน และอาจมีการเพิ่ม column ในภายหลังได้โดยที่ไม่กระทบกับโครงสร้างการเก็ฐข้อมูล อารมณ์คล้ายพวก NoSQL หรือ MongoDB นั่นเองแต่สามารถทำงานแบบกระจายตัวได้บนพื้นฐานของ HDFS

เกริ่นพอประมาณละกันครับเดี๋ยวยาว อันนี้แค่ส่วนหลักๆ ที่เราจะใช้ใน 4-5 บทความหลังจากนี้ ยังไม่รวม eco-system ตัวอื่นๆ ที่เลือกมาใช้ตามสถานการณ์อีก มีให้เล่นกันไม่รู้จบครับ ถ้าติดตามกันต่อเนื่องก็จะมีพูดถึงตัวอื่นๆ กับตัวที่เค้านิยมใช้กันเรื่อยๆ ^_^

HDFS ทำงานยังไง ทำไมต้องใช้มันด้วย?

อย่างที่เรารู้กัน Bigdata จะเป็นการทำงานกับข้อมูลขนาดใหญ่มากๆ ไฟล์แต่ละไฟล์ที่ต้องจัดเก็บอาจจะขนาดเป็น TB หรือ PB ซึ่งจะหา Disk ที่ขนาดเป็น PB นี่คงจะหายากซักหน่อย แถมแพงอีก หวยก็เลยมาออกที่วิธีเก็บแบบแยกเป็น block ย่อยๆอย่างที่เคยเกริ่นไว้ เนื่องจาก block ขั้นต่ำของ HDFS จะอยู่ที่ 64MB ดังนั้น HDFS จะไม่เหมาะกับไฟล์เล็กๆจำนวนมาก แต่จะเหมาะกับไฟล์ใหญ่ๆ ไม่กี่ไฟล์ซะมากกว่า

 ตัวอย่างเช่น ถ้าเรามีไฟล์ขนาด 1MB อยู่ 100 ไฟล์ จะต้องใช้พื้นที่ในการเก็บถึง 100 block นั่นคือ 100 x 64MB = 6,400 MB ทางเลือกที่ควรทำมากกว่าคือการรวมไฟล์เป็นไฟล์เดียวขนาด 100MB จะใช้พื้นที่เก็บแค่ 100/64 ปัดขึ้นก็ประมาณ 2 block จะเท่ากับ 128MB (จริงๆ ตรงนี้ไม่ใช่ประเด็นหลัก แต่อยากให้รู้ธรรมชาติของ HDFS ก่อนว่าเค้าทำมาเพื่อไฟล์ใหญ่ๆ จริงๆ)

hdfs-001

อย่างที่เห็นในรูป จริงๆ ข้อมูล 1 ไฟล์ อาจไม่ได้สำเนาไว้แค่ block เดียว ตัวระบบของ HDFS จะทำการคัดลอกซ้ำ และกระจาย block ไปยัง data-node หลายๆตัว เพื่อลดความเสียงในกรณีที่บาง node เกิดความเสียหายส่วนของการคัดลอกนี้เราเรียกว่าการทำ replicate ข้อมูล ซึ่งใครที่เคยเซตพวก disk-raid ก็น่าจะเข้าใจหลักการได้ไม่ยาก ^_^

นอกจาก HDFS จะช่วยในเรื่องของ ลดปัญหาการเกิด fail over แล้วยังช่วยลดปัญหาการเข้าถึงข้อมูลที่จุดเดียวกันที่เราเรียกปัญหาคอขวด (bottleneck) เหตุผลเพราะในการดึงข้อมูลมาใช้ มันจะติดต่อขอที่อยู่จาก namenode หลังจากนั้นมันจะดึงข้อมูลโดยตรงจาก datanode ที่เก็บข้อมูล block นั้นๆ โดยตรง

การติดตั้ง Hadoop ในโหมด Pseudo Distributed

การติดตั้งในโหมดนี้ จะเหมาะสำหรับการพัฒนาโปรแกรม เพราะเป็นการจำลองการทำงานทุกอย่างอยู่บนเครื่องเดียวทั้งหมด ทำให้ไม่ต้องเชื่อมต่อกับหลายๆเครื่อง และไม่จำเป็นต้องมี cluster จริงๆ เท่าที่ใช้งานอยู่ ให้ RAM ที่ 4GB ก็ยังทำงานได้ดีอยู่ โดยก่อนจะติดตั้งจะต้องติดตั้งในแบบ Stand-alone มาก่อนแล้วค่อยมาเพิ่มส่วนของการตั้งค่าในไฟล์ xml พร้อมกับการ start server ของ hdfs และ yarn สรุปเป็นขั้นตอนสั้นๆ ดังนี้:

  1. Stand-alone installation (สร้าง user hadoop, สร้างคีย์ ssh , ติดตั้ง Java , ติดตั้ง Hadoop) ใครยังไม่ได้ทำกลับไปดูของตอนแรกได้ครับ [ Link ]
  2. แก้ไขไฟล์ config
    • $HADOOP_HOME/etc/hadoop/core-site.xml
    • $HADOOP_HOME/etc/hadoop/hdfs-site.xml
    • $HADOOP_HOME/etc/hadoop/yarn-site.xml
    • $HADOOP_HOME/etc/hadoop/mapred-site.xml
  3. ฟอร์แมต namenode
  4. Start Hadoop: yarn, hdfs

::แก้ไขไฟล์ core-site.xml

$ gedit $HADOOP_HOME/etc/hadoop/core-site.xml

เพิ่มข้อมูลแล้ว Save

<configuration>
   <property>
       <name>fs.default.name</name>
       <value>hdfs://localhost:9000</value>
   </property>
   <property>
      <name>hadoop.tmp.dir</name>
      <value>/var/app/hadoop/data</value>
   </property>
</configuration>

** เพื่อให้แน่ใจว่า /var/app/hadoop/data ได้ถูกสร้างและได้รับสิทธิอย่างถูกต้อง ให้สร้างโฟล์เดอร์ตามนี้
$ sudo mkdir /var/app/
$ sudo mkdir /var/app/hadoop
$ sudo mkdir /var/app/hadoop/data
$ sudo chown hadoop:hadoop -R /var/app/hadoop

::แก้ไขไฟล์ hdfs-site.xml

$ gedit $HADOOP_HOME/etc/hadoop/hdfs-site.xml

เพิ่มข้อมูลแล้ว Save

<configuration>
<property>
       <name>dfs.replication</name>
       <value>1</value>
   </property>

   <property>
      <name>dfs.name.dir</name>
      <value>file:///home/hadoop/hadoopinfra/hdfs/namenode </value>
   </property>

   <property>
      <name>dfs.data.dir</name>
      <value>file:///home/hadoop/hadoopinfra/hdfs/datanode </value>
   </property>
</configuration>

** ส่วนของ /home/hadoop/hadoopinfra/hdfs/namenode และ /home/hadoop/hadoopinfra/hdfs/datanode จะถูกสร้างขึ้นมาอัตโนมัติ เมื่อเราทำการ start hdfs และ format namenode

::แก้ไขไฟล์ yarn-site.xml

$ gedit $HADOOP_HOME/etc/hadoop/yarn-site.xml

เพิ่มข้อมูลแล้ว Save

<configuration>
   <property>
       <name>yarn.nodemanager.aux-services</name>
       <value>mapreduce_shuffle</value>
   </property>
</configuration>

::แก้ไขไฟล์ mapred-site.xml

** สร้างไฟล์ mapred-site จาก template
$ cp $HADOOP_HOME/etc/hadoop/mapred-site.xml.template mapred-site.xml

$ gedit $HADOOP_HOME/etc/hadoop/mapred-site.xml

เพิ่มข้อมูลแล้ว Save
<configuration>
   <property>
      <name>mapreduce.framework.name</name>
      <value>yarn</value>
   </property>
</configuration>

:: Format HDFS name-node

$ cd
$ hdfs  namenode  -format

:: Start service ของ hdfs และ yarn

** เพื่อความสะดวก เพิ่ม $HADOOP_HOME/sbin ในตัวแปร PATH

$ gedit ~/.bashrc
export HADOOP_HOME=/srv/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

$ source  ~/.bashrc

** เพิ่ม JAVA_HOME ในไฟล์ $HADOOP_HOME/etc/hadoop/hadoop-env.sh
#export JAVA_HOME=${JAVA_HOME}
export JAVA_HOME=/usr/lib/jvm/jdk-8u91

เสร็จแล้ว Save และจะสามารถรัน start script ได้

$ start-dfs.sh &
$ start-yarn.sh &

** ใช้คำสั่ง jps เพื่อตรวจสอบ process
$ jps

** สามารถเรียกใช้  start-all.sh เพื่อเรียกแบบรวมทั้งสองคำสั่งได้

ทดสอบโดยการรัน wordcount อ่าน input จาก HDFS กัน

จากของครั้งก่อน เราได้ทดลองรัน wordcount โดยอ่านไฟล์ .txt จาก local input ในเมื่อตอนนี้เรามี HDFS แล้วก็ลองใช้กันดูซะหน่อยละกัน
** หมายเหตุ: คำสั่งพื้นฐานในการจัดการกับ HDFS ผ่านคำสั่ง hadoop สามารถดูได้ที่ [ Link ]

** สร้างโฟล์เดอร์ /user/input ใน HDFS และ copy *.txt จาก home input ไปยัง /user/input
$ hadoop fs –mkdir /user
$ hadoop fs –mkdir /user/input
$ hadoop fs –put ~/input/*.txt /user/input

** ตรวจสอบดูว่าไฟล์ถูก copy ไปอยู่ใน /user/input ของ HDFS เรียบร้อย
$ hadoop fs -ls /user/input

** รัน wordcount ผ่านคำสั่ง hadoop jar
$ hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/input /user/output

ติดตามงานที่กำลังรันที่
http://localhost:8088/ –> Job Tracker
http://localhost:50070/ –> HDFS manager

** เมื่อทำงานเสร็จ 100% ลองดูไฟล์ part ที่เกิดขึ้นใน /user/output
$ hadoop fs -ls /user/output
$ hadoop fs -cat /user/output/part*

** หากต้องการ copy ไฟล์จาก HDFS มาเก็บที่ Local สามารถทำได้
$ hadoop fs -get /user/output/ ~/output/

น่าจะพอเห็นภาพการทำงานคร่าวๆ ของการใช้งาน HDFS และ การรันงาน MapReduce ผ่านสภาพแวดล้อมแบบ cluster distributed processing ถ้าเป็นงานที่ต้อง process ไฟล์ขนาดใหญ่มากๆ มันจะต้องใช้ทรัพยากรมหาศาลรวมถึงเวลา (บางงานอาจรันเป็นวัน) และถ้าส่วนใดส่วนหนึ่งเสียหายไป หรือทำงานไม่สำเร็จ อาจจะต้องมานั่งเริ่มรันทุกอย่างใหม่หมดก็ได้ ตัว Hadoop Distributed  File System และ Map Reduce จึงเข้ามาช่วยแก้ปัญหานี้ให้เรา

สำหรับวิดีโอสอนของบทความนี้ ผมวางไว้ที่ Youtube ให้แล้วนะครับ

[ Youtube Link ]

AjBee.Me: ครั้งหน้าเราจะติดตั้ง Netbean IDE บน Ubuntu แล้วของเขียนโปรแกรม MapReduce  เองดู ถ้าชอบแนวนี้ก็ติดตามกันไปเรื่อยๆ นะครับ ^_^

ติดตามข้อมูลผ่าน FanPage เข้าไปกด Like ที่: https://www.facebook.com/AjBeeMePage