ป้ายกำกับ

วันพฤหัสบดีที่ 22 พฤษภาคม พ.ศ. 2557

หนังสือเก่ามีคุณค่าทางใจ

หนังสือเล่มนี้ซื้อมาตอนเรียนปริญญาตรี ปี 3 ขึ้นปี 4 (24 ปีมาแล้ว) แม้ว่าจะไม่ได้เขียน Assembly อีกเลยหลังจากเรียนจบ แต่ก็ได้นำความรู้มาใช้อยู่บ้างตอนทำชุมสายโทรศัพท์ขนาดเล็ก แม้ตอนนั้นจะเขียนด้วยภาษา C ควบคุมฮาร์ดแวร์ แต่พอเจอปัญหาลึกๆก็ถึงกับต้อง Disassembly ดู binary code ที่ Compiler แปลงมากันเลยทีเดียว

ถึงวันนี้เทคโนโลยีจะเปลี่ยนไปมากแล้ว หนังสือเล่มนี้ก็ไม่มีประโยชน์อีกต่อไป แต่เห็นมันทีไร ก็ทิ้งไม่ลงจริงๆ เพราะมันมีค่าทางใจที่หาค่าไม่ได้

วันอังคารที่ 6 พฤษภาคม พ.ศ. 2557

Ubuntu 14.04 LTS: ปัญหา Remote Desktop VNC

ปกติแล้วผมใช้ VNC ทำ Remote Desktop มาที่เครื่องเป็นประจำ แต่พออัพเกรดเครื่องเป็น 14.04 LTS แล้ว ปรากฏว่ามีปัญหา เข้าไม่ได้ ผมพยายามทดสอบหลายๆอย่างแล้ว พบว่าทุกอย่างเป็นปกติดี ไม่ว่าจะเป็นเรื่อง network หรือ security ต่างๆ ไม่ได้เป็นปัญหา เพราะมี VNC Viewer บางตัวใช้งานได้

ปัญหาที่ VNC Viewer?

ปกติแล้วบน Ubuntu ผมจะใช้ SSL/SSH VNC Viewer หรือที่เรียกชื่อโปรแกรมว่า ssvnc ซึ่งไม่เคยมีปัญหาเลย แต่คราวนี้ไม่ว่าจะเซ็ตค่าอย่างไรก็ไม่สามารถเข้าได้ สุดท้ายผมได้ทดลองโปรแกรม Remote Desktop Viewer หรือที่เรียกชื่อโปรแกรมว่า vinagre ตัวนี้กลับใช้งานได้ไม่มีปัญหา เพียงแต่ไม่ค่อยมีลูกเล่นให้ตั้งค่าอะไรมากมายนัก และการทำงานค่อนข้างช้า แต่บนเครื่อง iPad ของผมนั้น ผมใช้ iSSH ซึ่งก็มีปัญหาเช่นเดียวกัน และบน Android ก็คาดว่าคงจะมีปัญหา

หลังจากพยายามทดสอบและติดตามกระทู้ที่เกี่ยวข้องแล้ว ก็พบว่า ปัญหาอยู่ที่การตั้งค่า default ของ Gnome บน Ubuntu 14.04 เกี่ยวกับ Remote Desktop ไว้ว่า จะต้องใช้การเชื่อมต่อแบบเข้ารหัสเท่านั้น ซึ่งการใช้งานปกติของผมจะใช้ผ่าน SSH อยู่แล้ว ดังนั้น VNC จึงไม่เข้ารหัส และ VNC Viewer หลายๆตัวที่ใช้ก็เป็นลักษณะนี้ พอโดนบังคับให้ต้องเข้ารหัส ก็เลยทำให้ VNC Viewer หลายๆตัวใช้งานไม่ได้

วิธีแก้

ในกระทู้รายงาน Bug#1290666 เขาได้แนะนำให้ตั้งค่า org.gnome.desktop.remote-access ใหม่ โดย disable ค่า require-encryption ซึ่งจะต้องใช้เครื่องมือช่วยตั้งค่าชื่อ dconf-editor ช่วย ผมจึงต้องติดตั้งโปรแกรมนี้เสียก่อนด้วยคำสั่ง
sudo apt-get install dconf-editor
จากนั้น ก็เรียกใช้งานโปรแกรม dconf-editor ดังภาพ
เมื่อ disable ค่า require-encryption แล้ว ทุกอย่างก็กลับมาใช้งานได้เป็นปกติ

วันพุธที่ 30 เมษายน พ.ศ. 2557

Ubuntu 14.04 LTS: ปัญหา Subversion Server ทำงานไม่เสถียร

วันก่อนผมได้เล่าให้เพื่อนๆฟังไปแล้ว เกี่ยวกับปัญหาการใช้งาน Subversion บน Eclipse ซึ่งเมื่อผมทำการ Checkout โปรเจ็คออกมา บางโปรเจ็คก็ไม่มีปัญหาอะไร แต่บางโปรเจ็คก็เกิดอาการดาวโหลดบางไฟล์ไม่ได้ โดยฟ้อง
RA layer request failed
GET ... Internal Server Error

เกี่ยวอะไรกับ MySQL?

ทีแรกนึกว่ามีบางไฟล์เสียหาย แต่เมื่อผมทดลองซ้ำๆหลายๆรอบ ดูเหมือนว่าอาการจะไม่แน่นอน ไม่ซ้ำไฟล์เดิม และบางครั้ง Error ก็เปลี่ยนไปเป็น server close connection ผมจึงคิดว่าปัญหามันน่าจะเกิดที่ Apache Web Server มากกว่า โดยเมื่อเข้าไปดู Log ไฟล์ ก็แทบจะไม่มีอะไรบอกเกี่ยวกับ svn เลย แต่กลับมีข้อความเกี่ยวกับ MySQL เช่น query ไม่ได้ database connection lost อะไรทำนองนั้น ทีแรกผมก็ไม่ได้เอะใจ เพราะคิดว่าไม่เกี่ยวข้องกับ Subversion สักหน่อย แต่ทำไมมันดูเหมือนจะเกี่ยวกัน เพราะฟ้อง warning ตรงตอน GET ไฟล์ แต่เอาเถอะโปรแกรมรุ่นใหม่อาจจะมีการเปลี่ยนไปใช้ฐานข้อมูล MySQL ร่วมด้วยก็ได้ ผมก็เลยพุ่งเป้าไปที่ MySQL

ทีแรกก็ลองปรับค่า max_allowed_packet จาก 16M เป็น 64M ค่า max_connection จาก 100 เป็น 200 ค่า query_cache_limit จาก 1M เป็น 16M ด้วยเหตุผลที่ว่า อาการคล้ายๆกับ MySQL ทำงานไม่ได้ อาจจะเพราะตอน Checkout ไฟล์จำนวนมากๆ เกิด connection จำนวนมาก (ถ้าเป็น 1 ไฟล์ต่อ 1 connection) ก็จะเกิดปัญหาประมาณนี้ ซึ่งก็ช่วยให้สามารถ Checkout ไฟล์ได้มากขึ้น แต่สุดท้ายก็ตายทุกครั้ง

ผมเข้าไปดูค่าใน /var/log/mysql/error.log แล้ว ก็ไม่พบความผิดปกติอะไรเลย ดูเหมือน MySQL จะทำงานได้เป็นปกติดีทุกประการ ผมก็คิดไม่ออกว่ามันเกิดอะไรขึ้น และคิดว่า มันต้องมีปัญหาที่คำสั่ง SQL เพราะ error ใน Apache Web Server ระบุว่า query ไม่ได้ บางครั้งมีคำว่า "SELECSELECT ..." เหมือนคำสั่งมันกลายเป็นขยะไป ทำให้ระบบรวนไปหมด ผมจึงต้องลงลึกเข้าไปในระดับทุกๆคำสั่งที่ส่งให้กับ MySQL เลยว่ามีปัญหาอะไร ผมจึงไปตั้งค่า general_log_file และ general_log (ปกติจะปิดไว้) เพื่อดูค่าการทำงานในแต่ละคำสั่งของ MySQL ซึ่งจะบันทึกไว้ที่ /var/log/mysql/mysql.log (ปกติจะไม่มีไฟล์นี้อยู่)

สุดท้ายผมก็เห็นคำสั่ง
SELECT xxx FROM profiles WHERE login_name=? AND disabledtext = ''
ก็ได้ถึงบางอ้อว่า จริงๆแล้ว คำสั่งนี้เป็นคำสั่งที่เกิดจาก Apache Module ที่มีชื่อว่า mod_auth_mysql เป็นโมดูลที่เกี่ยวกับ การ Authentication เข้าใช้งาน และ Authorization สำหรับยืนยันสิทธิ์ในการเข้าถึงไฟล์ต่างๆของ Subversion  ซึ่งผมเลือกใช้โมดูลนี้เพื่อตั้งค่าให้มีการใช้ account จากฐานข้อมูล MySQL ของ Bugzilla ดังนั้น ทุกๆครั้งที่มีการดาวโหลดไฟล์ จะมีการตรวจสอบสิทธิ์ทุกครั้ง และทำให้เกิดการ query ด้วยคำสั่งข้างบนซ้ำๆจำนวนมาก อาจจะทำให้เกิดอาการไม่เสถียร

Multi-Processing Module (MPM) Prefork vs. Worker

เมื่อรู้ว่าปัญหาเกิดจากโมดูล mod_auth_mysql ทำงานไม่เสถียรแล้ว ผมจึงคิดว่าน่าจะต้องปรับค่าที่เกี่ยวกับการจัดการประมวลผลโมดูล หรือที่เรียกว่า MPM ซึ่งเมื่อตรวจสอบ Apache Web Server ก็พบว่า มีการตั้งค่าแตกต่างไปจากรุ่นก่อน (Ubuntu 12.04) คือ การแยก MPM ออกเป็นโมดูล และเลือกตั้งค่าไว้เป็น mpm_event ในขณะที่ค่าเก่าที่ผมเคยตั้งไว้เป็น mpm_prefork ผมเองก็จำไม่ได้แล้วว่าทำไมถึงใช้ prefork แต่ไหนๆก็ไหนๆแล้ว ผมก็เลยทดลองปรับค่าดู ซึ่งค่าเดิมที่ตั้งไว้คือ default ตามข้างล่างนี้
<IfModule mpm_event_module>
    StartServers                    2
    MinSpareThreads          25
    MaxSpareThreads         75
    ThreadLimit                   64
    ThreadsPerChild            25
    MaxClients                   150
    MaxRequestsPerChild      0
</IfModule>
เมื่อทดลองปรับค่า เช่น MaxClient ลดให้น้อยลง MaxRequestsPerChild กำหนดให้เป็นค่า 1000 แทนที่จะเป็น 0 ซึ่งหมายถึงไม่จำกัด ค่า MaxSpareThreads ลดลง ค่า ThreadLimit ลดลง ThreadsPerChild ลดลง ผลปรากฏว่า เมื่อ Checkout การทำงานค่อนข้างดีขึ้น แต่สุดท้ายแล้วก็นิ่งไปนาน แล้วเกิด connection timeout ขี้น เมื่อดูใน Log ไฟล์ ไม่มีข้อมูลใดๆ เพราะ Apache Web Server ตายไปเรียบร้อยแล้ว ผมก็พยายามทดลองปรับค่าต่างๆแล้ว สุดท้ายสรุปว่าโมดูล mod_auth_mysql ไม่ใช่ thread safe โมดูล (ในขณะที่ข้อมูลจากบางเว็บไซต์ระบุว่าเป็น thread safe) ไม่สามารถใช้งานกับ mpm_worker หรือ mpm_event ได้

prefork เป็นการประมวลผลแบบไม่ใช้ thread โดย root process จะมีการแตก child process ออกมา และแต่ละ child process จะดูแล connection หลาย connection ต่อ process

worker เป็นการประมวลผลแบบใช้ thread โดย root process จะมีการแตก child process ออกมา และแต่ละ child process จะแตก thread ออกมาเพื่อดูแลแต่ละ connection

prefork เหมาะกับการทำงานที่รองรับโมดูลที่ไม่ได้ออกแบบมาให้เป็น thread safe และสำหรับประสิทธิภาพแล้ว ทั้ง prefork และ worker ทำงานได้พอๆกัน แต่ prefork จะใช้ทรัพยากรณ์ หน่วยความจำมากกว่า worker ส่วน event นั้นเป็น worker อีกรูปแบบหนึ่งที่จะจัดการ thread ได้ดีขึ้น

สรุปว่า mod_auth_mysql ไม่เป็น thread safe ต้องใช้กับ prefork เท่านั้น ซึ่งเมื่อผมทดลองปรับไปใช้ prefork ปัญหาทุกอย่างก็หมดไป นิ่งเสถียรดีมาก แต่ด้วยความคิดที่ว่า event มันดูดีกว่า prefork นะ ใช้ทรัพยากรณ์น้อยกว่า ผมจึงคิดว่า เราน่าจะหาทางใช้ event นะ

Apache DBD Module

ผมค้นไปค้นมาก็พบว่า Apache มีโมดูลที่ทำงานกับฐานข้อมูล SQL อยู่แล้ว ชื่อว่า mod_dbd ดังรายละเอียดในหน้า Apache DBD API ที่น่าสนใจคือ
  1. ไม่ยึดติดกับฐานข้อมูลใดๆ โดยจะต้องติดตั้ง driver สำหรับแต่ละฐานข้อมูลเพิ่ม เช่นฐานข้อมูลที่มี driver แล้วคือ MSSQL, SyBase, MySQL, Oracle, PostgreSQL, SQLite, และ ODBC
  2. ใช้กับ MPM ได้หลายแบบทั้งแบบ threaded หรือ non-threaded
  3. จัดการ connection pooling แบบไดนามิกส์เพื่อรองรับโปรแกรมใหญ่ๆได้
และนอกจากนี้ยังมีโมดูล mod_authn_dbd สำหรับการทำ Authentication และโมดูล mod_authz_dbd สำหรับการทำ Authorization ด้วย ทำให้ตอบโจทย์ที่ผมคิดไว้พอดี ผมจึงตัดสินใจทดสอบการใช้งานดู โดยติดตั้งโมดูลต่างๆ และแก้ไข config ไฟล์ ตามตัวอย่างใน document ของ mod_authn_dbd ดังนี้
# mod_dbd configuration
# UPDATED to include authentication cacheing
DBDriver pgsql
DBDParams "dbname=apacheauth user=apache password=xxxxxx"
DBDMin  4
DBDKeep 8
DBDMax  20
DBDExptime 300
<Directory /usr/www/myhost/private>
  # mod_authn_core and mod_auth_basic configuration
  # for mod_authn_dbd
  AuthType Basic
  AuthName "My Server"
  # To cache credentials, put socache ahead of dbd here
  AuthBasicProvider socache dbd
  # Also required for caching: tell the cache to cache dbd lookups!
  AuthnCacheProvideFor dbd
  AuthnCacheContext my-server
  # mod_authz_core configuration
  Require valid-user
  # mod_authn_dbd SQL query to authenticate a user
  AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"
</Directory>
ในตัวอย่างนี้ จะมีการใช้ AuthBasicProvider โดยเน้นว่าให้ใช้ socache เพื่อทำ cache ให้กับ credential ด้วย ผมก็ได้ทำตามคือ ติดตั้ง socache เพิ่ม และที่สำคัญคือ AuthDBUserPWQuery ที่ต้องสั่ง query รหัสผ่านสำหรับผู้ใช้มาเพื่อตรวจสอบ โดยใส่ %s ไว้ตรงที่เป็นชื่อผู้ใช้ที่จะกรอกผ่าน browser มา ผลการรันปรากฏว่าเกิด Segmentation fault error ครับ Apache สตาร์ทไม่ขึ้น ผมจึงค่อยๆถอดบางคำสั่งที่ไม่จำเป็นออก และสุดท้ายพบว่าปัญหาอยู่ที่ AuthnCacheProvideFor และ AuthnCacheContext ครับ เมื่อตัดสองคำสั่งนี้ออก Apache ก็ทำงานได้ตามปกติ

Password Format

จากคำอธิบายของคำสั่ง AuthDBUserPWQuery ระบุว่า ผลของการ query จะนำเอาเฉพาะข้อความที่อยู่ใน row แรก column แรกเท่านั้นมาพิจารณาเป็นรหัสผ่านในรูปแบบรหัสที่เข้ารหัสแล้ว ซึ่งวิธีพิจารณามีสองแบบคือ แบบ Basic หรือ แบบ Digest ตามที่ได้ระบุ provider ไว้ (ผมขอไม่พูดถึงแบบ Digest นะครับ) เช่นในกรณีนี้ ผมใช้ AuthBasicProvider มีรายละเอียดรูปแบบของข้อมูลรหัสที่จะนำมาเปรียบเทียบตามที่ระบุไว้ชัดเจนในเอกสารคู่มือของ Apache เรื่อง Password Format โดยแบบ Basic มีอยู่ 5 รูปแบบคือ
  1. bcrypt: ข้อความ "$2y$" + ข้อความที่เข้ารหัสด้วยอัลกอริทึม crypt_blowfish
  2. MD5: ข้อความ "$apr1$" + ข้อความที่เข้ารหัสด้วยอัลกอริทึม MD5 ในแบบของ Apache เอง (ไม่เหมือนกับ MD5 อื่นๆ ผมเสียเวลาเข้าใจผิดทดสอบอยู่นานเหมือนกัน)
  3. SHA1: ข้อความ "{SHA}" + ข้อความที่เข้ารหัสด้วย Base64 ของอัลกอริทึม SHA-1 (ไม่ปลอดภัย)
  4. CRYPT: ข้อความที่เข้ารหัสด้วยฟังก์ชัน crypt บนระบบ Unix เท่านั้น (ไม่ปลอดภัย)
  5. PLAIN: ข้อความที่ไม่เข้ารหัส เฉพาะบนระบบ Windows และ Netware (ไม่ปลอดภัย)
อ๊ะๆ สังเกตเห็นอะไรไหมครับ รหัสผ่านที่เข้ารหัสแล้ว จะมีการใส่สัญลักษณ์พิเศษไว้เพื่อให้รู้ว่าเข้ารหัสด้วยวิธีไหน แต่ไม่ต้องกังวลนะครับ อัลกอริทึมที่เข้ารหัสพวกนี้ เป็นอัลกอริทึมที่ออกแบบมาให้ย้อนกลับได้ยาก ทางเดียวที่ง่ายกว่าคือ ต้องหารหัสมาเข้ารหัสด้วยวิธีเดียวกันแล้วได้ค่าที่ตรงกันจึงจะบอกได้ว่าเป็นรหัสที่ถูกต้อง ใครสนใจเรื่องรูปแบบของรหัสสามารถอ่านเพิ่มเติมจากลิ้งค์ที่ให้ไว้ได้นะครับ ในนั้นมีการแนะนำการใช้คำสั่ง htpasswd และคำสั่ง openssl เพื่อทดสอบดูว่า รหัสที่เข้าด้วยอัลกอริทึมแบบต่างๆแล้วได้รูปแบบเป็นอย่างไร

กลับมาเข้าเรื่องปัญหาของผมต่อนะครับ จากฐานข้อมูลผู้ใช้ใน MySQL ของ Bugzilla รหัสผ่านที่เข้ารหัสไว้แล้วนั้น มีรูปแบบไม่เหมือนกับที่ Apache ระบุไว้ ดังนั้น คำสั่งที่จะ query รหัสผ่านมานั้น จะต้องมีการจัดรูปแบบใหม่ให้ถูกต้อง โดยรูปแบบของ Bugzilla จะอยู่ในแบบ
รหัสที่เข้ารหัสแล้ว + "{" + ชื่อ Digest อัลกอริทึม + "}"
เช่น (ขอสมมติรหัสนะครับ)
123456789ABCDEFGHIjklmnopqrstuvwxyZ{MD5}
ถ้าหากผม query มาตรงๆ ก็จะทำให้ mod_authn_dbd ตรวจสอบรหัสผ่านไม่ถูก เพราะถ้าเป็น MD5 จะต้องมีรหัสเป็นประมาณ
$apr1$123456789ABCDEFGHIjklmnopqrstuvwxyZ
ซึ่งก็ไม่ใช่เรื่องยากสักเท่าไรนักที่จะใช้คำสั่ง substring ของ SQL ตัดและต่อคำเข้าไป แต่ปัญหาใหญ่ของผมตอนนี้คือ รหัส MD5 แบบทั่วไปที่ใช้อยู่ใน Bugzilla ซึ่งเขียนด้วยภาษา perl โดยใช้ Digest::MD5 นั้นไม่เหมือนกับ Apache MD5 หรือที่เรียกว่า APR1 ทำให้ผมต้องไปควานหาว่า perl มีอัลกอริทึมเข้ารหัสแบบไหนให้ใช้บ้าง ซึ่งถ้าเป็นไปตาม man page ของ Digest ก็คือมีดังนี้ (เรียงตามลำดับความเร็ว)
Algorithm   Size  Implementation               MB/s
MD4         128   Digest::MD4 v1.3            165.0
MD5         128   Digest::MD5 v2.33            98.8
SHA-256     256   Digest::SHA2 v1.1.0          66.7
SHA-1       160   Digest::SHA v4.3.1           58.9
SHA-1       160   Digest::SHA1 v2.10           48.8
SHA-256     256   Digest::SHA v4.3.1           41.3
Haval-256   256   Digest::Haval256 v1.0.4      39.8
SHA-384     384   Digest::SHA2 v1.1.0          19.6
SHA-512     512   Digest::SHA2 v1.1.0          19.3
SHA-384     384   Digest::SHA v4.3.1           19.2
SHA-512     512   Digest::SHA v4.3.1           19.2
Whirlpool   512   Digest::Whirlpool v1.0.2     13.0
MD2         128   Digest::MD2 v2.03             9.5
Adler-32     32   Digest::Adler32 v0.03         1.3
CRC-16       16   Digest::CRC v0.05             1.1
CRC-32       32   Digest::CRC v0.05             1.1
MD5         128   Digest::Perl::MD5 v1.5        1.0
CRC-CCITT    16   Digest::CRC v0.05             0.8
ผมควานหา package อื่นๆที่เกี่ยวข้องหมดแล้วพบคำสั่งเข้ารหัส Apache MD5 อยู่ใน libcrypt-passwdmd5-perl แต่นั่นเป็น Crypt::PasswdMD5 ไม่ใช่ Digest ซึี่งหากจะใช้คำสั่งนี้ ผมจะต้องเข้าไปแก้ Bugzilla ซึ่งเป็นวิธีที่ไม่น่าทำสักเท่าไรนัก (แต่จริงๆแล้วก็อยากจะลองดูเหมือนกันนะ ☺) จึงต้องตัดสินใจลดระดับความปลอดภัยลงมาเป็น SHA-1

สรุป

ความจริงแล้วปัญหายังไม่ได้จบแค่นี้นะครับ แต่เนื่องจากผมไม่แน่ใจว่า การเปิดเผยอะไรมากไปกว่านี้ จะทำให้ Server ของผมโดนของหรือเปล่า ผมยิ่งไม่ค่อยมีเวลาคอยตรวจดูซะด้วยสิ จึงขอจบเรื่องนี้ไว้แค่นี้ หากใครอยากทราบประสบการณ์เชิงลึก ก็มาคุยกันได้นะครับ ยินดีเล่าให้ฟัง(ถ้าสัญญาว่าจะไม่มาแฮ็คเครื่องผม ☺) เอ้า สรุปว่า ปัญหาต่างๆก็แก้ไปได้ด้วยดี มีความปลอดภัยพอสมควร และเสถียรแล้วสำหรับ Subversion server

วันจันทร์ที่ 28 เมษายน พ.ศ. 2557

Ubuntu 14.04 LTS: ปัญหา Subversion บน Eclipse 3.8

หลังจากที่ผมติดตั้ง Ubuntu 14.04 LTS ไปประมาณหนึ่งสัปดาห์ ตอนนี้ก็ได้ฤกษ์ใช้งาน Eclipse เขียนโปรแกรมสักที และเนื่องจากโปรแกรมหลายๆตัวที่ผมเขียน ผมใช้ Subversion เก็บซอสโค้ดไว้ จึงทำการ Import โปรแกรมมา แต่ปรากฏว่าเกิดปัญหาขึ้น 2 เรื่อง

ปัญหาที่ 1 SVN มี 2 เมนู

เมื่อเลือกเมนู File/Import จะปรากฏหน้าต่าง ซึ่งปกติแล้ว เราก็จะเลือกหัวข้อย่อย SVN โดยจะมีหัวข้อ Checkout Projects from SVN ดังภาพ (ขออภัยที่ผมลืมเก็บภาพตอนที่มี 2 หัวข้อ) แต่ปรากฏว่ามี SVN อีกอันหนึ่ง มีหัวข้อย่อยคล้ายๆกัน ผมก็เกิดความสงสัยขึ้น แอ๊ะเกิดอะไรขึ้นกับ Eclipse และเมื่อเปิดไปที่เมนู Window/Preferences/Team เพื่อดูการตั้งค่าของ Subversion ก็ปรากฏว่า มีหัวข้อ SVN อยู่ 2 หัวข้อเช่นกัน

หลังจากที่ตรวจสอบ Plug-In ต่างๆที่ติดตั้ง (เลือกลิ้งค์ Uninstall or update ที่เมนู Window/Preferences/Install/Update) ก็ได้ข้อสรุปว่า ผมติดตั้ง Eclipse Team Provider สำหรับ Subversion ไปสองตัวคือ Subversive และ Subclipse ซึ่งปกติแล้ว ผมจะใช้ Subversive อยู่เป็นประจำ เพราะมี Connector หลายแบบให้เลือกใช้ แต่เอ Subclipse มันมาได้ไง? เราเผลอไปติดตั้งตอนไหนนะ? จะเอาออกดีหรือเปล่า? เพื่อให้มั่นใจ ผมจึงศึกษาข้อมูลดูจาก StackOverflow และพบว่า เขาแนะนำให้ใช้ Subclipse ดีกว่า เพราะทีมพัฒนา(มาตอบเอง) บอกว่า ทีมงานเขา Active กว่า Subversive ที่มีผู้พัฒนาอยู่น้อย และยังติดวงเล็บต่อท้ายว่า Incubation ตั้งนานแล้ว นอกจากนี้ เขายังทำงานร่วมกับทีมที่พัฒนา Subversion บนระบบอื่นๆ เช่น AnkhSVN และ TortoiseSVN อย่างไกล้ชิด เพื่อให้สามารถทำงานเข้ากันได้

โอเคครับ ผมก็เลยตัดสินใจ ถอน Subversive ออก แต่ตอนที่ถอนออก เราจะต้องไล่ถอน Plug-In ต่างๆที่เกี่ยวข้องออกให้หมดนะครับ ไม่อย่างนั้นแล้ว เมนู SVN ของ Subversive จะยังคงปรากฏให้เห็นอยู่ อาจจะทำให้เกิดความสับสนในการใช้งานได้ เพราะมันจะคล้ายๆกัน สำหรับ Plug-In ที่เกี่ยวข้องกับ Subversive ก็คือ
  • Subversive SVN Team Provider (Incubation)
  • Subversive SVN JDT Ignore Extensions (Optional) (Incubation)
  • Subversive SVN Integration for the Mylyn Project (Optional) (Incubation)
  • Subversive Revision Graph (Optional) (Incubation)
  • Subversive SVN Connectors
  • Native JavaHL x.x Implementation (Optional)
  • SVNKit x.x.x Implementation (Optional)

ปัญหาที่ 2 Subclipse 1.8 ไม่สามารถทำงานร่วมกับ JavaHL 1.8 ได้

เมื่อเหลือแต่ Subclipse แล้ว ผมก็เริ่มต้น Import โปรแกรมใหม่ แต่ก็ไม่สำเร็จเนื่องจาก Subclipse ฟ้องว่าไม่สามารถทำงานร่วมกับ JavaHL ที่มีอยู่ได้ ต้องใช้รุ่น 1.7.x ดังภาพ
เมื่อตรวจสอบระบบแล้ว พบว่า Ubuntu 14.04 มี Package ของ Subclipse รุ่น 1.8 และ JavaHL รุ่น 1.8 เช่นกัน แต่จากคำอธิบายในบทความเรื่อง Wiki ของ JavaHL ระบุรุ่นที่ทำงานร่วมกันไว้คือ
Subclipse VersionSVN/JavaHL Version
1.10.x1.8.x
1.8.x1.7.x
1.6.x1.6.x
1.4.x1.5.x
1.2.x1.4.x
1.0.x1.4.x
นั่นหมายความว่า ถ้าใช้ Subclipse 1.8 ก็จะต้องติดตั้ง JavaHL 1.7 ซึ่ง Ubuntu 14.04 ไม่มีให้ และถ้าจะใช้ JavaHL 1.8 ตามที่ Ubuntu 14.04 มีให้ ก็ต้องอัพเกรด Subclipse เป็น 1.10 โดยทีแรกผมพยายามจะหา JavaHL 1.7 มาติดตั้งแล้ว แต่เกิดปัญหาว่า ในระบบอาจจะมีโปรแกรมอื่นๆที่ต้องใช้งาน JavaHL ด้วยเช่นกัน ไม่ใช่มีเพียง Eclipse เท่านั้น ทำให้เกิดปัญหา dependency ต่างๆพันกันไปหมด สุดท้ายผมก็เลยตัดสินใจ อัพเกรด Subclipse โดยเข้าไปที่ Install New Software และเพิ่ม Repository สำหรับ Subclipse รุ่น 1.10.x ตรงช่อง Work with ด้วย URL http://subclipse.tigris.org/update_1.10.x เท่านี้ก็จะปรากฏ Plug-In รุ่น 1.10 และส่วนที่เกี่ยวข้องอื่นๆมาให้เราเลือกติดตั้งได้ทันทีดังภาพ
เมื่อติดตั้งแล้ว ก็จะสามารถใช้งาน Subversion ได้ตามปกติ

วันศุกร์ที่ 21 มีนาคม พ.ศ. 2557

Setup Android on Ubuntu

ตั้งแต่ที่ผมได้ทดลองเขียนโปรแกรมบน Android ครั้งแรกก็นานมากแล้ว หลายๆอย่างเปลี่ยนไปเร็วมาก จาก Android เวอร์ชั่น 2.3 มาตอนนี้เป็นเวอร์ชั่น 4.4 ดูตัวเลขแล้วก็ไม่ได้มากมายอะไรเลย แต่ถ้านับเป็นรุ่นของ Platform API ก็คือตั้งแต่ Platform API 10 (2.3.3) มาเป็น Platform API 19 (4.4.2)  ผ่านไปตั้งเกือบ 10 รุ่น ทำให้หลายๆคนก็ท้อแท้ไปเลยก็มี เพราะว่าตามไม่ทันจริงๆ สำหรับผมนั้น ขอเรียกว่าตามดูอยู่ห่างๆก็แล้วกัน พอดียังไม่ค่อยจะมีงานที่ต้องใช้ จึงยังไม่ทุ่มเทเวลาให้มันมากนัก วันนี้พอจะมีเวลา ก็เลยลองกลับมารื้อฟื้นความจำสักหน่อย แต่บังเอิญเครื่องที่ใช้อยู่ไม่ได้ลงโปรแกรมไว้ ก็เลยต้องเริ่มต้นใหม่ตั้งแต่การติดตั้งกันเลย

เครื่องที่ผมใช้เป็น Ubuntu 12.04 LTS ติดตั้ง Eclipse 3.7.2 ซึ่งเป็น Eclipse ที่มากับ Ubuntu นะครับ ผมจะเน้นใช้ Package ที่มาพร้อมกับ OS มากกว่าการดาวโหลด Eclipse มาใหม่ๆ เพราะมักจะเจอปัญหาเข้ากันไม่ได้กับ Package โน่น นั่น นี่ ทำให้เราปวดหัว แต่ถ้าจำเป็นจริงๆ ผมก็จะใช้ตัวใหม่นะครับ

ADT (Android Developer Tools)

Android Developer Tools หรือเรียกย่อๆว่า ADT นั้น เป็นเครื่องมือสำหรับพัฒนาโปรแกรมบน Android ซึ่งทั้งหมดจะประกอบไปด้วย
  • Eclipse + ADT Plugin: Eclipse IDE ที่ติดตั้ง ADT Plugin เพื่อให้ Eclipse เชื่อมต่อกับ Tools ต่างๆของ Android ได้
  • Android SDK Tools: ประกอบไปด้วยเครื่องมือต่างๆสำหรับการพัฒนา ทดสอบ และดีบั๊กโปรแกรม เช่น ตัว emulator เป็นต้น เครื่องมือเหล่านี้จะอยู่ในโฟลเดอร์ <ANDROID_SDK>/tools
  • Android Platform Tools: ประกอบไปด้วยเครื่องมือที่ขึ้นอยู่กับแพล็ตฟอร์มสำหรับการพัฒนา ทดสอบ และดีบั๊กโปรแกรม เช่น ตัว debugger เป็นต้น เครื่องมือเหล่านี้จะอยู่ในโฟลเดอร์ <ANDROID_SDK>/platform-tools
  • Android Platform: ประกอบไปด้วย API Library ต่างๆของ Platform แต่ละรุ่น โดยเฉพาะไฟล์ android.jar โดยเราสามารถเลือกรุ่นที่เราต้องการพัฒนามาติดตั้งไว้ได้ (แต่ควรเป็นรุ่นล่าสุด) ซึ่งจะอยู่ในโฟลเดอร์ <ANDROID_SDK>/platforms/android-<รุ่น>
  • Android System Image: ประกอบไปด้วย Image ไฟล์ของ OS บนแต่ละสถาปัตยกรรม เช่น ARM หรือ x86 เป็นต้น โดยแยกเป็น Platform แต่ละรุ่น ซึ่งเราสามารถเลือกรุ่นที่เราต้องการพัฒนามาติดตั้งไว้ได้ (แต่ควรเป็นรุ่นล่าสุด) ซึ่งจะอยู่ในโฟลเดอร์ <ANDROID_SDK>/system-images/android-<รุ่น>
ทั้งหมดที่แจกแจงไปนั้นเป็นเฉพาะเครื่องมือที่จำเป็นสำหรับพัฒนาเท่านั้นนะครับ แต่จริงๆแล้ว สิ่งที่ขาดไม่ได้เลยสำหรับนักพัฒนาก็คือ คู่มือ ครับ เพราะมีคำสั่งมากมายที่เราเองก็ไม่เคยจำได้ ต้องเปิดคู่มือเป็นประจำ แต่ส่วนใหญ่เท่าที่พบเห็นมือใหม่ทั้งหลาย เมื่อติดตั้ง IDE เสร็จแล้ว ก็ไม่ค่อยจะสนใจติดตั้ง API Document กันเลย เวลาเขียนโปรแกรมก็เลยต้องเปิดบราวเซอร์ไปด้วยเขียนโปรแกรมไปด้วย จริงๆแล้ว ถ้าสามารถติดตั้งได้ เช่น มีเนื้อที่ใน HDD เหลือเฟือ ก็ควรจะติดตั้งไว้ในเครื่องด้วย จะได้ไม่ต้องต่ออินเตอร์เน็ตอยู่ตลอดเวลาที่พัฒนาโปรแกรมครับ อีกทั้งส่วนใหญ่ IDE เก่งอย่าง Eclipse จะสามารถดึงเอาคำอธิบายใน Document มาให้เราอ่านได้ทันทีที่เราพิมพ์คำสั่งที่ต้องการ จะสะดวกมากๆเลยจริงๆครับ

Setup

เมื่อเรารู้แล้วว่าเครื่องมือต่างๆที่จำเป็นจะต้องมีอะไรบ้าง ต่อไปก็ถึงขั้นตอนการติดตั้ง ซึ่งจริงๆแล้วก็ไม่ได้ยุ่งยากอะไร เพราะ Google ได้จัดทำ package สำเร็จรูปไว้แล้ว ผมจึงขอแยกวิธีการติดตั้งออกเป็น 3 วิธีนะครับ
  1. Bundle: เป็น package ที่มีทุกอย่างทั้ง Eclipse และ SDK ครบถ้วน บีบอัดไว้อยู่ในไฟล์เดียว สามารถดาวโหลดมาแล้วแตกไฟล์ออกมา และใช้งานได้เลยทันที โดยเข้าไปที่โฟลเดอร์ eclipse แล้วรันโปรแกรม eclipse เท่านี้ก็พัฒนาโปรแกรมได้เลย ทำให้สะดวกใช้มาก แต่ก็มีข้อเสียคือ เราแทบจะไม่รู้อะไรเลย
  2. Existing IDE: หากเรามี Eclipse อยู่แล้ว ก็สามารถติดตั้งทุกอย่างลงใน Eclipse ที่มีอยู่ได้เลย เพราะ Eclipse ออกแบบมาให้สามารถเพิ่มเติมความสามารถต่างๆได้ด้วย plugin ทำให้เราไม่ต้องมี Eclipse อยู่ถึงสองตัวในเครื่องเดียว ส่วนวิธีการนั้น จะขออธิบายในหัวข้อถัดไปนะครับ
  3. Android Studio: เป็น package แบบใหม่ที่คล้ายกับ Bundle คือมีทุกอย่างครบถ้วนใน package เดียว เพียงแต่ใช้กับ IntelliJ IDEA ซึ่งเป็น IDE ของ JetBrains ใครชอบ IDE ตัวนี้ก็สามารถดาวโหลดมาทดลองใช้ได้เลยนะครับ จริงๆแล้วผมเองไม่ค่อยประทับใจ Eclipse มากสักเท่าไรครับ ภาพข้างล่างนี้คือหน้าตาของ Android Studio แต่ผมยังไม่มีเวลาทดลองใช้ แค่รันดูเฉยๆครับ
Android Studio

Existing IDE Setup

หากมี Eclipse อยู่แล้ว (ซึ่งผมต้องการใช้ Eclipse ที่มีมากับ Ubuntu ตามที่ได้เกริ่นไว้) ขั้นตอนแรกเลยก็คือการติดตั้ง ADT Plugin ซึ่งจะเป็นตัวเชื่อมทุกอย่างเข้ากับ Eclipse โดยเราสามารถเลือกเมนู Help/Install New Software ใน Eclipse จากนั้นกดปุ่ม Add เพื่อเพิ่ม Repository โดยอาจจะตั้งชื่อว่า ADT Plugin และป้อน URL ดังนี้
https://dl-ssl.google.com/android/eclipse/
เมื่อติดตั้ง Plugin เสร็จแล้ว restart Eclipse จะปรากฎหน้าต่าง "Welcome to Android Development"  และให้เราป้อนโฟลเดอร์ของ Android SDK ซึ่งมีสองทางเลือก คือ ป้อนโฟลเดอร์ใหม่ โดยจะดาวโหลด Android SDK มาติดตั้ง หรือ เลือกโฟลเดอร์ที่เราได้แตกไฟล์ Android SDK ที่ดาวโหลดมาไว้แล้ว ในกรณีนี้ ผมยังไม่เคยแนะนำให้ดาวโหลด Android SDK มาก่อน จึงเลือกที่จะป้อนโฟลเดอร์ใหม่ให้ดาวโหลดมาติดตั้ง ซึ่งเมื่อติดตั้งเสร็จ จะปรากฎหน้าต่าง Android SDK Manager ดังภาพ
Android SDK Manager
ใน Android SDK Manager นี้ เราสามารถเลือกที่จะติดตั้ง Tools และ Platform ต่างๆได้ โดย Tools ที่จะต้องติดตั้งหลักๆก็คือ SDK Platform และ Build ส่วน Platform API ให้เลือกรุ่นที่ตรงกับอุปกรณ์เป้าหมายที่โปรแกรมของเราจะนำไปติดตั้ง สามารถเลือกติดตั้งไว้หลายๆรุ่นก็ได้ แล้วเลือกใช้อีกทีตอนพัฒนาโปรแกรมนะครับ เมื่อเลือกเสร็จแล้ว กดปุ่ม Install จะมีการติดตั้งส่วนอื่นๆที่จำเป็นร่วมด้วย สังเกตุให้ดีว่า เราได้ติดตั้งทุกอย่างครบถ้วนแล้วนะครับ ที่สำคัญ อย่าลืมเลือกติดตั้ง Documentation ด้วยนะครับ

ผมขอจบเรื่องไว้เท่านี้ก่อนนะครับ เรื่องการพัฒนาโปรแกรมบน Android ไว้โอกาสหน้าจะมาเล่าต่อว่า ผมจะทำอะไรบ้าง

วันเสาร์ที่ 8 กุมภาพันธ์ พ.ศ. 2557

HBase Installation

หลังจากที่ผมได้ทำการติดตั้ง Hadoop 1.2.1 บน Ubuntu 12.04 LTS ไปเรียบร้อยแล้ว ซึ่งก็จะได้โครงสร้างพื้นฐานของการประมวลผลแบบกระจายแบบ MapReduce บน HDFS (Hadoop Distributed File System) แต่การประมวลผลแบบ MapReduce บน HDFS นั้น ค่อนข้างมีความซับซ้อนพอสมควร ผมจึงยังไม่อยากแนะนำ ถ้าหากใครสนใจ สามารถอ่านเพิ่มเติมได้จากลิ้งค์อ้างอิงท้ายบทความนี้นะครับ

แต่สิ่งที่ผมอยากจะแนะนำในบทความนี้ก็คือ HBase ครับ ซึ่งก็คือระบบฐานข้อมูลแบบกระจายของ Hadoop และสามารถรองรับข้อมูลขนาดใหญ่มาก (Big Data) ในระดับ พันล้าน row และ ล้าน column ได้ โดย HBase จะจัดเก็บข้อมูลแบบกระจายอยู่บน HDFS และคำสั่งที่จะ Create Read Update Delete (CRUD) นั้นจะเป็นการประมวลผลแบบกระจายแบบ MapReduce น่าสนใจไหมครับ หากใครสนใจก็คอยติดตามอ่านบทความต่อๆไปด้วยนะครับ เพราะครั้งนี้ผมจะเริ่มต้นที่การติดตั้งก่อน

HBase Version

สำหรับรุ่น stable ปัจจุบันนั้น เป็นรุ่น 0.94.15 แต่มีรุ่นใหม่ล่าสุดคือ 0.96.1.1 เนื่องจาก Hadoop ได้แตกออกเป็น 2 รุ่นคือ 1.x และ 2.x ซึ่ง HBase รุ่นไหนควรใช้กับ Hadoop รุ่นไหนนั้น สามารถดูได้จากตารางในหัวข้อ 2.1.3 บทที่ 2 เรื่อง Apache HBase Configuration ของหนังสือ The Apache HBase™ Reference Guide

เนื่องจากผมใช้ Hadoop 1.2.1 และ HBase 0.96.0 ผ่านการทดสอบกับ Hadoop 1.1.x แล้ว (เสียดายที่ไม่มีข้อมูลรุ่นใหม่ล่าสดุ) ผมจึงคาดว่า HBase รุ่นใหม่ล่าสุดนี้ น่าจะใช้กับ Hadoop 1.2.1 ได้ (หวังว่าผมจะคาดการณ์ไม่ผิดนะ) จึงทดลองดาวโหลด Binary Package (hbase-0.96.1.1-hadoop1-bin.tar.gz) มาติดตั้ง

Operation Mode

HBase จะประกอบไปด้วยบริการ 3 ประเภทคือ
  1. master (HMaster) เป็นบริการหลักของ HBase ซึ่งจะคอยตรวจสอบการทำงานของ regionserver โดยปกติแล้วจะทำงานอยู่บน NameNode ของ Hadoop
  2. regionserver (HRegionServer) เป็นบริการที่ทำหน้าที่ดูแลและจัดการข้อมูลภายใน region นั้นๆ โดยปกติแล้วจะทำงานอยู่บน DataNode ของ Hadoop
  3. zookeeper (HQuorumPeer) เป็นบริการที่ทำหน้าที่ผสานงานระหว่างเครื่องต่างๆในระบบประมวลผลแบบกระจาย ซึ่ง HBase นำมาใช้ผสานงานระหว่างเครื่อง HMaster และ HRegionServer
ซึ่งบริการทั้ง 3 ประเภท สามารถทำงานอยู่บนเครื่องๆเดียวได้ (Single-Node โหมด) โดย HBase มีโหมดการทำงาน 3 โหมดเช่นเดียวกัน Hadoop  คือ Standalone Pseudo-Distributed และ Fully-Distributed สำหรับ Standalone นั้น จะไม่ทำงานเป็นเครือข่าย และข้อมูลจะถูกจัดเก็บแบบไฟล์ปกติ จะไม่ใช้ HDFS ส่วนการทำงานในโหมด Pseudo-Distributed และ Fully-Distributed จะทำงานเป็นเครือข่าย และข้อมูลจะถูกจัดเก็บอยู่ใน HDFS ของ Hadoop

Setup Single-Node Mode

เนื่องจาก HBase ไม่มี Debian Package ให้ มีแต่ Binary Package และภายใน Package จะมีทั้งโปรแกรมและ config ไฟล์รวมๆกันอยู่ ไม่ได้แยก config ไฟล์ไปไว้ที่ /etc แต่อย่างใด ผมจึงเลือกที่จะแตกไฟล์ไว้ที่ /usr/local แทน ด้วยคำสั่ง
cd /usr/local
sudo tar xzf /path/to/hbase-0.96.1.1-hadoop1-bin.tar.gz
Configuration ไฟล์ที่เกี่ยวข้องจะอยู่ในโฟลเดอร์ conf มีไฟล์ต่างๆดังนี้
  1. hbase-env.sh
    • กำหนดค่า JAVA_HOME ใหม่ให้ถูกต้อง สำหรับค่า default ที่กำหนดไว้คือ /usr/java/jdk1.6.0/ แต่เนื่องจากบน Ubuntu จะใช้ OpenJDK เป็นหลัก ผมจึงเปลี่ยนค่าให้เป็น /usr/lib/jvm/default-java ซึ่งจะใช้ default JDK ที่ติดตั้งไว้ โดยปกติแล้ว Ubuntu 12.04 LTS จะใช้ OpenJDK 6 ซึ่งน่าจะเข้ากันได้ดี แต่เนื่องจากผมมีโปรแกรมบางตัวที่ใช้ Java 7 จึงเปลี่ยนมาใช้ OpenJDK 7 (หวังว่าจะไม่มีปัญหา)
    • กำหนดค่า HBASE_MANAGES_ZK=true ซึ่งจะทำให้มีการ start zookeeper อัตโนมัติพร้อมๆกับตอน start HBase (โดย default ค่านี้จะเป็น true อยู่แล้ว เราอาจจะไม่กำหนดก็ได้)
  2. hbase-site.xml
    • ค่า default ต่างๆระบุไว้ที่หัวข้อ 2.3.1.1 เรื่อง HBase Default Configuration ของหนังสือ The Apache HBase™ Reference Guide ทำให้เราไม่จำเป็นต้องระบุค่าทุกๆค่า ซึ่งมีจำนวนมาก เราสามารถระบุเฉพาะค่าที่ไม่ตรงกับ default ก็พอ
    • กำหนดค่า hbase.rootdir เพื่อระบุว่าข้อมูล HBase ทั้งหมดจะอยู่ที่ไหน เช่น เก็บไว้ที่ /hbase ใน HDFS ซึ่งสามารถเข้าถึงได้ดังนี้
          <property>
              <name>hbase.rootdir</name>
              <value>hdfs://localhost:8020/hbase</value>
          </property>
    • กำหนดค่า hbase.cluster.distributed เป็น true
    • กำหนดค่า hbase.zookeeper.quorum เป็นรายชื่อเครื่องทั้งหมดที่อยู่ในกลุ่มของ HBase ในที่นี้เราตั้งค่าสำหรับ Single-Node จึงกำหนดให้มีเพียง localhost เท่านั้น
เนื่องจากเรากำหนดให้ HBase จัดเก็บข้อมูลไว้ที่ /hbase ตามที่ตั้งค่าไว้ใน hbase-site.xml เราจึงต้องสร้างโฟลเดอร์เตรียมไว้ด้วยคำสั่ง
hadoop fs -mkdir /hbase
หากไม่สามารถสร้างได้ เนื่องจากปกติแล้ว Hadoop ที่ติดตั้งด้วย Debian Package จะใช้ user ชื่อ hdfs ในการจัดการ HDFS แทนที่จะใช้ root เราจึงอาจจะต้องสั่งสร้าง /hbase ด้วยคำสั่ง
sudo -u hdfs hadoop fs -mkdir /hbase
จากนั้น จึงสร้าง user root บนระบบ Hadoop ด้วยคำสั่ง
hadoop-create-user.sh -u root
แล้วกำหนดสิทธิ์ให้ user root สามารถจัดการ /hbase ได้ ด้วยการเปลี่ยนเจ้าของ โดยสั่ง
sudo -u hdfs hadoop fs -chown root /hbase
หากตรวจสอบโฟลเดอร์ที่สร้างขึ้นด้วยคำสั่ง hadoop fs -ls / ดูจะพบว่า /hbase เปลี่ยนเป็นของ root เรียบร้อยดังนี้
# hadoop fs -ls /
Found 3 items
drwx------   - root supergroup          0 2014-02-08 17:58 /hbase
drwxrwxrwx   - hdfs supergroup          0 2014-02-07 10:29 /tmp
drwxr-xr-x   - hdfs supergroup          0 2014-02-07 15:19 /user

Start/Stop Service

เนื่องจากการ start/stop บริการต่างๆของ HBase นั้น จะมีการติดต่อไปยัง Hadoop ด้วย ssh ซึ่งจะมีการถามรหัสผ่านทุกครั้ง ทำให้ไม่สะดวกต่อการสั่งงาน โดยเฉพาะหากเราต้องการตั้งให้มีการ start/stop อัตโนมัติ การที่เราจะใช้ ssh โดยไม่ต้องป้อนรหัสผ่านเลยนั้น จะต้องใช้กุญแจอิเล็กทรอนิกส์เป็นรหัสผ่านแทน ซึ่งสามารถตรวจสอบว่ามีการตั้งค่ากุญแจอิเล็กทรอนิกส์สำหรับ root ไว้แล้วหรือยังโดยใช้คำสั่ง
sudo ssh localhost
หากสามารถเข้าได้โดยไม่ต้องป้อนรหัสผ่าน แสดงว่าเราได้เคยตั้งค่ากุญแจรหัสอิเล็กทรอนิกส์ไว้แล้ว (อาจจะมีโปรแกรมบางชนิดมีการแนะนำให้ทำไว้แล้ว) ถ้าหากต้องป้อนรหัสผ่าน แสดงว่ายังไม่ได้ตั้งค่ากุญแจอิเล็กทรอนิกส์ไว้ เราจะต้องสร้างกุญแจขึ้นมาใหม่ด้วยคำสั่ง ssh-keygen ดังนี้
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
คำสั่งนี้ จะสร้างกุญแจรหัสของเราขึ้นมา โดยเก็บไว้ที่ไฟล์ ~/.ssh/id_dsa ซึ่งเป็นกุญแจส่วนตัวของเรา (Private Key) และจะมีไฟล์ ~/.ssh/id_dsa.pub ซึ่งเป็นกุญแจสาธารณะ (Public Key) สำหรับให้ผู้ที่เราจะติดต่อแลกเปลี่ยนข้อมูลกัน โดยเราจะต้องนำเอากุญแจสาธารณะไปไว้ที่ไฟล์ ~/.ssh/authorized_keys ของเครื่องที่เราจะติดต่อด้วย โดยใช้คำสั่งดังนี้
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
เมื่อตั้งค่ากุญแจรหัสอิเล็กทรอนิกส์แล้ว ก็จะสามารถสั่ง start/stop บริการต่างๆของ HBase ได้อย่างราบรื่น ซึ่งมีสคริปท์ให้เราเรียกใช้ได้อยู่ในโฟลเดอร์ bin คือ สั่ง start ด้วยคำสั่ง
sudo /path/to/hbase/bin/start-hbase.sh
สั่ง stop บริการด้วย
sudo /path/to/hbase/bin/stop-hbase.sh

ปัญหาที่อาจจะเกิดขึ้น

เมื่อ start HBase แล้ว ตรวจสอบบริการต่างๆด้วยคำสั่ง jps ต้องพบบริการ master (HMaster) regionserver (HRegionServer) และ zookeeper (HQuorumPeer) หากบริการใดไม่ทำงาน ควรตรวจสอบดูข้อผิดพลาดใน log ไฟล์ เช่น ถ้า master ไม่ทำงาน log ไฟล์ของ master แสดงข้อความ
FATAL [master:SLOffice:60000] master.HMaster: Unhandled exception. Starting shutdown.
org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="":hdfs:supergroup:rwxr-xr-x

ซึ่งหมายความว่า HBase กำลังเข้าถึง HDFS ด้วย user root เพื่อที่จะเขียนข้อมูล แต่ไม่มีสิทธิ์ แสดงว่าเราอาจจะลืมทำขั้นตอนที่สร้าง /hbase และเปลี่ยนสิทธิ์ให้ root เป็นต้น

อ้างอิง

  1. สมชัย หลิมศิโรรัตน์, Hadoop 1.x Installation on Ubuntu
  2. The Apache Software Foundation, MapReduce Tutorial
  3. The Apache Software Foundation, HDFS Architecture Guide
  4. The Apache Software Foundation, HBase
  5. The Apache Software Foundation, The Apache HBase™ Reference Guide

วันจันทร์ที่ 20 มกราคม พ.ศ. 2557

Eclipse cannot start after upgrade Ubuntu to 13.10

สองวันมานี้ผมเสียเวลาไปกับการอัพเกรดเครื่องจาก Ubuntu 12.04 LTS ไปเป็น 13.10 เนื่องจากผมต้องการทดลองใช้งานโปรแกรมใหม่ๆ จึงคิดว่าถึงเวลาเตรียมพร้อมสำหรับ 14.04 LTS ที่จะออกมาประมาณเดือนเมษายนนี้แล้ว โดยผมใช้วิธีค่อยๆอัพเกรดเป็นขั้นๆ เนื่องจากมีโปรแกรมหลายๆอย่างที่ผมไม่อยากตั้งค่าใหม่ และอยากจะเห็นความเปลี่ยนแปลงของแต่ละรุ่นด้วย แต่ก็เสียเวลามากหน่อยเพราะต้องอัพเกรดดังนี้

  • จาก 12.04 LTS ไปเป็น 12.10
  • จาก 12.10 ไปเป็น 13.04
  • จาก 13.04 ไปเป็น 13.10
เสียเวลาไปเกือบสองวัน สุดท้ายก็ได้ทุกอย่างสมกับที่ยอมเสียเวลาเหนื่อย

แต่ก็มีปัญหากับ Eclipse ที่รันไม่ได้ ปัญหานี้มักจะเจอบ่อยๆในหลายๆครั้งที่ผมอัพเกรด Ubuntu ครั้งนี้มี Error คือ

!SESSION Mon Jan 20 21:15:05 ICT 2014 ------------------------------------------
!ENTRY org.eclipse.equinox.launcher 4 0 2014-01-20 21:15:05.091
!MESSAGE Exception launching the Eclipse Platform:
!STACK
java.lang.ClassNotFoundException: org.eclipse.core.runtime.adaptor.EclipseStarter
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:626)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
at org.eclipse.equinox.launcher.Main.main(Main.java:1414)

มีหลายคนแนะนำให้แก้ไขไฟล์ eclipse/configuration/config.ini เนื่องจากชื่อไฟล์ org.eclipse.osgi_x.x.x.jar ไม่ตรงกับรุ่นที่ติดตั้ง ซึ่งเมื่อผมตรวจสอบ พบว่า ในเครื่องของผมไม่มีไฟล์นี้อยู่ ไม่รู้ว่าหายไปไหน และก็ไม่รู้ว่าจะเอามาจากไหนดีด้วย ค้นไปค้นมา ก็พบว่ามันอยู่ใน Package ชื่อ libequinox-osgi-java ครับ แต่ในเครื่องมันแสดงว่าผมติดตั้งไว้แล้ว ซึ่งควรจะมีไฟล์อยู่ ผมจึง reinstall ใหม่ ก็ใช้ได้เลยครับ

วันพุธที่ 15 มกราคม พ.ศ. 2557

Hadoop 1.x Installation on Ubuntu

เมื่อประมาณเกือบๆ 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 โดยมีไฟล์ต่างๆที่ต้องแก้ไขดังนี้
  1. 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
  2. master/slave
    • master ไฟล์ จะเก็บรายชื่อเครื่องที่ทำหน้าที่เป็น NameNode ซึ่งจะเป็นเครื่องแม่ และสามารถเป็น JobTracker TaskTracker และ DataNode ได้ด้วย
    • slave ไฟล์ จะเก็บรายชื่อเครื่องที่ทำหน้าที่เป็น DataNode และเป็น TaskTracker ได้ด้วย
    • ถ้าติดตั้งในโหมด Single-Node ทั้งสองไฟล์จะมีค่าเป็น localhost
  3. *-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 ประเภทคือ
  1. NameNode เป็นบริการหลัก ทำหน้าที่ค้นหาและจัดการบริการอื่นๆในระบบ
  2. JobTracker ทำหน้าที่จัดคิวการทำงาน
  3. TaskTracker ทำหน้าที่ประมวลผล Map-Reduce หรืองานอื่นๆ
  4. DataNode ทำหน้าที่จัดการข้อมูลในระบบ HDFS (Hadoop Distributed File System)
ซึ่งบริการทั้ง 4 ประเภท สามารถทำงานอยู่บนเครื่องๆเดียวได้ (Single-Node โหมด) หรือจะแบ่งเป็นเครื่อง 2 กลุ่ม คือ master ซึ่งสามารถมีบริการทั้ง 4 ประเภทในเครื่องเดียว หรือ slave ซึ่งจะมีบริการเฉพาะ TaskTracker และ DataNode เท่านั้น เพื่อแบ่งหรือกระจายการประมวลผลและข้อมูลของระบบออกไปยังเครื่องลูกจำนวนมากๆ โดยการติดตั้งระบบ เราสามารถเลือกติดตั้งให้ทำงานได้ 3 โหมดคือ
  1. Local (Standalone)
    • การทำงานจะอยู่บนเครื่องเดียว และไม่เป็นเครือข่าย
    • โหมดนี้เป็น default ของโปรแกรม หากยังไม่มีการตั้งค่าใดๆ
    • เหมาะกับการทดสอบและ debug มากกว่า
  2. Pseudo-Distributed (Single-Node)
    • การทำงานจะอยู่บนเครื่องเดียว แต่เป็นเครือข่าย
    • สามารถตั้งค่าต่างๆได้ง่ายด้วยโปรแกรม hadoop-setup-single-node.sh
    • เหมาะกับการใช้งานเบื้องต้น และพร้อมที่จะขยายไปเป็น Fully-Distributed โหมด
  3. 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 โดยมีลำดับของการทำงานคือ
  1. ตั้งค่า config ต่างๆ
  2. ทำการ Format NameNode (เหมือนเรา Format ฮาร์ดดิสก์นะครับ)
  3. จัดเตรียมโครงสร้างของไฟล์ในระบบ HDFS
  4. start บริการต่างๆของ Hadoop ซึ่งก็คือ NameNode DataNode JobTracker และ TaskTracker
  5. ตั้งค่าสำหรับให้บริการต่างๆ 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

อ้างอิง



วันเสาร์ที่ 11 มกราคม พ.ศ. 2557

การแก้ไข Debian Package

วันนี้ผมมีปัญหากับการติดตั้ง Hadoop บน Ubuntu ซึ่งติดตั้งจาก Debian Package (.deb ไฟล์) แต่เนื่องจากภายใน package มีสคริปท์ที่เขียนไว้สำหรับติดตั้งมีปัญหาบางอย่าง จึงทำให้การติดตั้งไม่สมบูรณ์ ผมจึงอยากจะแก้ไข จึงค้นหาวิธีการมาฝากดังนี้

Debian Package File Format

สำหรับโครงสร้างไฟล์นั้น เป็น Archive ไฟล์แบบหนึ่ง (ไฟล์บีบอัด) เราสามารถใช้โปรแกรม Archive Manager เปิดดูไฟล์ภายในได้ หรือแม้แต่ใช้โปรแกรม Package Installer ก็สามารถดูข้อมูลภายในได้เช่นกัน สามารถแตกไฟล์ออกมาได้ แต่ถ้าเรามีไฟล์อยู่แล้วต้องการจะรวมเป็น Debian Package เขาแนะนำให้ใช้โปรแกรม dpkg-deb จะสะดวกมากครับ

Control Files

โดยโครงสร้างซึ่งเป็นไฟล์แบบบีบอัด ดังนั้น โปรแกรมของเราจะมีไฟล์อะไรบ้าง เราก็เตรียมไว้ให้มีโครงสร้างเป็นโฟลเดอร์ต่างๆตามแบบของ Debian เช่น Configuration ต่างๆควรอยู่ที่ /etc ส่วนโปรแกรมเฉพาะส่วนที่เป็น read-only ควรอยู่ที่ /usr และข้อมูลอื่นๆที่เปลี่ยนแปลงบ่อยๆก็ควรอยู่ที่ /var  เป็นต้น (อ่านรายละเอียดได้จากเรื่อง  Filesystem Hierarchy Standard)

นอกจากนี้ยังมีโฟลเดอร์พิเศษชื่อ DEBIAN สำหรับเก็บไฟล์ที่สำคัญของการติดตั้ง Package ซึ่งประกอบไปด้วยไฟล์ดังนี้ (อ้างอิง How to create a Debian .deb package)

  1. control - เก็บข้อมูลหลักของ package เช่น ชื่อ package, รุ่น, สถาปัตยกรรม ฯลฯ
  2. conffiles - เก็บรายชื่อ config ไฟล์ ที่จะไม่ลบทิ้งเมื่อ uninstall เนื่องจากผู้ใช้อาจจะต้องการลงโปรแกรมใหม่ด้วยค่า config เดิม
  3. md5sums - เก็บค่า md5sum ของทุกๆไฟล์ใน package เพื่อใช้ตรวจสอบความถูกต้องของข้อมูล
  4. preinst - เป็นสคริปท์ที่จะถูกเรียกหลังจากที่แตกไฟล์ต่างๆเสร็จแล้ว และก่อนที่จะทำการติดตั้งใดๆ เช่น สคริปท์สำหรับสร้าง user/group เป็นต้น
  5. postinst - เป็นสคริปท์ที่จะถูกเรียกหลังจากที่รัน preinst เสร็จแล้ว เพื่อติดตั้งค่าต่างๆรวมทั้ง init สคริปท์ต่างๆสำหรับให้โปรแกรมทำงานในสภาวะต่างๆ
  6. prerm - เป็นสคริปท์ที่จะถูกเรียกก่อนที่จะลบโปรแกม เพื่อยกเลิกการทำงานที่ค้างอยู่ ลบข้อมูลบางอย่างที่ถูกสร้างขึ้นจาก postinst
  7. postrm - เป็นสคริปท์ที่จะถูกเรียกหลังจากที่รัน prerm เสร็จแล้ว เพื่อลบสิ่งที่สร้างขึ้นจาก preinst

Extract Debian Package

สมมติว่าไฟล์ต่างๆที่เราจะแตกออกมา เราจะไปไว้ในโฟลเดอร์ชื่อ tmp โดยใช้คำสั่ง dpkg-deb เช่น สมมติว่า package ที่ต้องการจะแก้ไขชื่อ application.deb ใช้ -x เพื่อแตกไฟล์โปรแกรม ส่วน -e เพื่อแตก Control ไฟล์ ซึ่งจะต้องอยู่ในโฟลเดอร์ชื่อ DEBIAN นะครับ
dpkg-deb -x /path/to/application.deb tmp
dpkg-deb -e /path/to/application.deb tmp/DEBIAN
จากนั้นก็แก้ไขไฟล์ตามที่ต้องการได้เลย

Rebuild Package

เมื่อแก้ไขทุกอย่างเรียบร้อยแล้ว เราก็สามารถใช้ -b เพื่อที่จะ build Package ใหม่ดังนี้
dpkg-deb -b tmp /path/to/application-new.deb
ก็จะได้ Debian Package ใหม่ตามที่ต้องการ

วันอังคารที่ 17 ธันวาคม พ.ศ. 2556

CDN (Content Delivery Network) คืออะไร

CDN คืออะไร?

ความจริงคำว่า CDN มีมานานพอสมควรแล้ว แต่อาจจะไม่แพร่หลายเหมือนอย่างคำว่า Cloud ซึ่ง CDN นี้ ย่อมาจากคำว่า Content Delivery Network หรือบางท่านอาจจะเรียกว่า Content Distributed Network ความหมายสั้นๆตรงๆเลยก็คือ ระบบเครือข่ายที่จะทำหน้าที่ส่งข้อมูลให้ถึงผู้รับได้อย่างรวดเร็วโดยวิธีการกระจายเครื่องแม่ข่ายออกไปยังภูมิภาคต่างๆให้ไกล้กับผู้รับมากที่สุด เช่น เมื่อเราเปิดเว็บ Facebook ถ้าสังเกตข้อความแสดงสถานะการรอคอยข้อมูลด้านล่างของ Browser เราจะพบว่า แทนที่จะมีการดึงข้อมูลจาก www.facebook.com อย่างเดียว กลับมีการดึงข้อมูลมาจาก xxx.akamixx.net ซึ่งเป็น server ของบริษัท Akamai Technologies ที่ให้บริการ CDN ให้กับ Facebook นั่นเอง

แล้วมันยังไง?

หลายคนอาจจะสงสัยว่า แล้วเขาทำอย่างนั้นได้อย่างไร? คำตอบก็คือว่า จะมีการกระจายเครื่องแม่ข่ายออกไปตามภูมิภาคต่างๆ เช่น เว็บหลักอยู่ที่อเมริกา แต่มีการตั้งเครื่องแม่ข่ายกระจายไปยังประเทศอื่นๆ ไม่ว่าจะเป็น ญี่ปุ่น จีน อังกฤษ ออสเตรีย สิงคโปร์ เป็นต้น โดยจะมีการกระจายเนื้อหาที่เป็นแบบ static มาไว้บนเครื่องแม่ข่ายเหล่านี้ก่อน เช่น ไฟล์ภาพ ไฟล์วีดีโอคลิป ไฟล์ CSS และไฟล์ JavaScript เป็นต้น เมื่อมีการร้องขอข้อมูลใดๆไปยังเครื่องหลักที่ใช้ระบบ CDN การร้องขอนั้นก็จะถูก Re-Direct ไปยังเครื่องแม่ข่ายในระบบเคลือข่ายของ CDN ที่อยู่ไกล้ที่สุด ทำให้เราได้รับข้อมูลอย่างรวดเร็ว และลดภาระงานให้กับเครื่องหลักได้มาก นอกจากนี้ หากเครื่องใดรับภาระงานมากเกินไป ระบบก็สามารถกระจายภาระงานออกไปยังเครื่องแม่ข่ายอื่นๆที่อยู่ไกล้เคียงได้อย่างเหมาะสมอีกด้วย โดยที่เราแทบจะไม่รู้สึกเลยว่าข้อมูลนั้นมาจากไหน

ฟังดูแล้วมันเหมือน Cloud เลยหรือเปล่าล่ะครับ?
จะเรียกว่าใช่ก็ไม่เชิงครับ เอาเป็นว่า ระบบ Cloud Computing ที่เป็น Public Cloud ก็ใช้เทคโนโลยีนี้เป็นส่วนหนึ่งดีกว่าครับ เพราะระบบ Cloud Computing ยังมีอีกหลายๆเรื่องที่เป็นองค์ประกอบ ไว้วันหลังถ้าผมมีเวลาจะมาเขียนเล่าให้ฟังครับ

วันพุธที่ 30 ตุลาคม พ.ศ. 2556

Visual Studio 2013 ดาวโหดฟรีสำหรับนักศึกษา

วันนี้เมื่อผมเปิดใช้ Visual Studio 2012 มันเตือนให้ Update โดยขณะนี้เป็น Update 3 แล้ว ผมจำได้ว่าไม่ได้ใช้ Visual Studio เพียงไม่กี่เดือนเท่านั้นนี่นา เอแต่ทำไมจึงยังไม่เคยเห็น Update 2 เลย แต่ไม่ว่าจะเป็นรุ่นไหน ยังไงก็ขอ Update ซะหน่อย ปรากฏว่ามีปัญหาเล็กน้อย เนื่องจากไฟล์โปรแกรม Update ที่มันให้ดาวโหลดมาติดตั้งนั้น เมื่อรันแล้ว มันจะดาวโหลดส่วนอื่นๆที่เหลือมาลง และปรากฎว่า มันดาวโหลดมาเพียง Package เดียวแล้วก็ติดตั้งเลย ซึ่งทำให้เกิด Error ว่าหา Package อื่นๆไม่เจอ ผมก็เลยต้องดาวโหลดไฟล์เต็มๆมา ขนาดทั้งหมด 2.2GB เสียเวลาไปเป็นชั่วโมง สุดท้ายก็ติดตั้งได้เรียบร้อย

เมื่อเสร็จแล้ว ผมก็เลยคิดว่า แล้ว Visual Studio มีอะไรใหม่ๆเพิ่มขึ้นมาบ้าง ก็เลยเข้าเว็ปของไมโครซอฟต์ดู ปรากฏว่ามี Visual Studio 2013 ออกมาแล้วครับ ตามข่าวในเว็ปบอกว่าออกมาตั้งแต่เมื่อวันที่ 17 ตุลาคม 2556(2013) นี้  อืมช้าไปประมาณ 10+1 เดือน เพราะตามข่าวบอกว่าตอนนี้ปล่อยออกมาทางเว็ปให้ดาวโหลดไปทดลองกันดู เป็นรุ่น Released Candidate (RC) และจะปล่อยจริงเดือนหน้าครับ

อย่างไรก็ตาม ไมโครซอฟต์ก็ยังคงนโยบายเดิมคือมีรุ่น Express ให้ดาวโหลดไปใช้กันฟรีๆด้วย ซึ่งก็เรียกว่าเป็นปกติมาตั้งแต่สมัย Visual Studio 2005 แล้ว และยิ่งกว่านั้นคือ มีรุ่น Professional ให้ดาวโหลดฟรี สำหรับนักศึกษาด้วย อันนี้มีมาตั้งแต่สมัย Visual Studio 2012 ครับ งานนี้ไมโครซอฟต์ทุ่มทุนอย่างมากเลย แต่ก็ดีครับ เราก็จะได้ไม่ต้องใช้ของเถื่อน ละเมิดลิขสิทธิ์กัน ยังไงไมโครซอฟต์ก็ไม่ขาดทุนอยู่แล้ว ยิ่งมีนักพัฒนาบน Windows มากเท่าไหร่ ก็ยิ่งขายดีมากขึ้น

วันอังคารที่ 8 ตุลาคม พ.ศ. 2556

Professional jQuery

Title:Professional JQuery
Authors:Cesar Otero & Rob Larsen
Formats:PDF
Ids:GoogleDouban Books,9781118026687
Tags:JavaScript, jQuery, Programming Language, Web
Publishers:John Wiley & Sons
Author Sort:Otero, Cesar & Larsen, Rob
Title Sort:Professional JQuery
Date:08 ต.ค. 2013
uuid:0d8f471b-3b3a-428d-bec3-fe77f0382add
id:5953
Published:พ.ค. 2012
Modified:08 ต.ค. 2013
Size:22.69MB
Languages:English
Type:book

Over the past several years JavaScript has undergone a remarkable transformation. It is now one of the most important programming languages in the world. With the ongoing importance of Ajax-based development and the rise of full-featured JavaScript libraries, most of the stigma around JavaScript has vanished. The most beginner-friendly library, jQuery, is responsible for most of this turnaround. jQuery is used at some of the largest organizations in the world, including Amazon, IBM, Twitter, NBC, Best Buy, and Dell. In 2011 there were three major releases in jQuery and the community surrounding it continues to grow. jQuery is prominently featured at the front end of Java/Spring, PHP, .NET, Ruby on Rails, and Python/Django stacks all over the Web. If you have experience with HTML, CSS, and JavaScript, this book is for you. It will expand your jQuery knowledge by focusing on the core library with the benefit of strong core JavaScript expertise in many of the lessons.This book is aimed at three groups of readers: Experienced server-side web application developers looking to move into the client-side using the world's most popular front-end libraryExperienced JavaScript programmers looking to ramp up quickly on jQueryNovice to intermediate jQuery developers looking to expand their jQuery knowledge into more advanced topicsThis book is not aimed at beginners. For those looking to start with the basics of HTML, CSS, and JavaScript/jQuery development, " Beginning JavaScript and CSS Development with jQuery (Wrox Programmer to Programmer)" by Richard York will most likely help you more.This book covers a lot of information about jQuery including a developer-level introduction as well as providing an in-depth look into some of the more advanced features. The book is divided into two parts, jQuery Fundamentals and Applied jQuery. jQuery Fundamentals introduces the core concepts while Applied jQuery focuses on more advanced subjects. The first part of the book offers an in-depth introduction to jQuery fundamentals, which includes selecting elements, manipulating the DOM, and binding and reacting to browser books. After providing a solid foundation, the book will then outline more advanced topics such as plugin development, unit testing with JavaScript, and other advanced features of the library. The book also focuses on features available as of jQuery 1.7.1. but also tries to incorporate feature support in older versions of the library wherever it is relevant.The first few chapters will help you set up a development environment and they also review important JavaScript concepts. Chapters 3-7 examine the jQuery core concepts. The second half of the book focuses on applying jQuery in the real world as well as detailing jQuery UI, plugin development, and templates among other lessons.Part 1, jQuery Fundamentals, contains chapters 1-7. Chapter 1 sets up an environment for developing and debugging jQuery and JavaScript code. It also defines the code standards that will be used throughout the book. Chapter 2 goes through the basics of JavaScript programming language to strengthen the foundation that the rest of the book is built upon. Chapter 3 introduces the basic functions that make up the library and illuminates usages of the core jQuery functions. It also introduces many of the functions that you will need to perform varieties of tasks. Chapter 4 goes in-depth into one of the core features of jQuery, which is the ability to select and manipulate HTML elements. Chapter 5 introduces another feature of jQuery: the cross-browser ability to bind and manage browser events. Chapter 6 explores one of the biggest revolutions in web development in recent years--Ajax. Chapter 7 focuses on some of the shortcuts jQuery offers for animating components in your web applications. These include moving, fading, toggling, and resizing elements.Part 2, Applied jQuery, contains chapters 8-14. Chapter 8 introduces jQuery UI, which is an associated user interface library for jQuery and contains things such as widgets, effects, animations, and interactions. Chapter 9 explores additional jQuery UI features including moving, sorting, resizing, and selection elements with a mouse. Chapter 10 teaches a variety of techniques, best practices, and patterns that you can apply to your code to immediately make it more efficient, maintainable, and clear. Chapter 11 focuses on the jQuery Template plugin. Templates are a standard way of marrying data and markup snippets. Chapter 12 focuses on authoring jQuery plugins. It is important to know how to extend the power of jQuery with custom methods as it is a fundamental skill for a top jQuery developer. Chapter 13 introduces the jQuery Deferred Object, which was introduced in version 1.5. It is a chainable utility object that provides control over the way callback functions are handled. Chapter 14 introduces the general concept of unit testing and goes into detail with the specific unit testing framework created by and used by the jQuery project itself, QUnit.In order to use this book effectively, you will need one of the following web browsers to run the samples provided within the book: Firefox 3.6, Current -1 VersionInternet Explorer 6+Safari 5.0xOpera current - 1 VersionChrome Current - 1 VersionCesar Otero is a freelance web developer. His technical interests include Python, Django, JavaScript, and jQuery. He sometimes contributes articles to IBM's developer works. He holds a degree in electrical engineering.Rob Larsen has many years' experience as a front-end engineer and team leader. He has built websites and applications for some of the world's biggest brands. He is currently a Senior Specialist, Platform at Sapient Global markets. Rob is an active writer and speaker on web technology with a special focus on emerging standards like HTML5, CSS3, and JavaScript.

jQuery Ui 1.8

Title:jQuery Ui 1.8
Authors:Wellman, Dan
Formats:PDF
Ids:GoogleDouban Books,9781849516525
Tags:JavaScript, jQuery, Programming Language, UI, Web Programming
Publishers:Packt Publishing, Limited
Author Sort:Dan, Wellman,
Title Sort:jQuery Ui 1.8
Date:08 ต.ค. 2013
uuid:4ba7f0a4-6a55-4ba5-82aa-80865000c5d1
id:5952
Published:ส.ค. 2011
Modified:08 ต.ค. 2013
Size:7.11MB
Languages:English
Type:book

jQuery UI, the official suite of plugins for the jQuery JavaScript library, gives you a solid platform on which to build rich and engaging interfaces with maximum compatibility, stability, and a minimum of time and effort.jQuery UI has a series of ready-made user interface widgets and a comprehensive set of core interaction helpers to reduce the amount of code that you need to write to take a project from conception to completion.jQuery UI 1.8: The User Interface Library for jQuery has been specially revised for version 1.8 of jQuery UI. It is written to maximize your experience with the library by breaking down each component and walking you through examples that progressively build upon your knowledge, taking you from beginner to advanced usage in a series of easy-to-follow steps.Throughout the book, you'll learn how each component can be initialized in a basic default implementation and then customize and configure each component to tailor it to your application. You'll look at the configuration options and the methods exposed by each component's API to see how these can be used to bring out the best of the library. Each chapter will also show you the custom events fired by the component covered and how these events can be intercepted and acted upon.What you will learn from this book :How the CSS framework consistently themes the widgets and how these styles can be used in your own codeCreate a custom jQuery UI widget using the widget libraryThe underlying mark-up required by different components, and how each widget or interaction helper is initializedConfigure the different components, and the different options that each component usesWork with each widget programmatically using its methods and event hooksPractical examples of how each component can be usedAdd flair to your interface with animation effectsApproachAn example-based approach leads you step-by-step through the implementation and customization of each library component and its associated resources. Reference tables of each configuration option, method, and event for each component are provided, alongside detailed explanations of how each widget is used.Who this book is written forThis book is for front-end designers and developers who need to quickly learn how to use jQuery UI. To get the most out of this book you should have a good working knowledge of HTML, CSS, and JavaScript, and should ideally be comfortable using jQuery.

jQuery Pocket Reference

Title:jQuery Pocket Reference
Authors:David Flanagan
Formats:PDF
Ids:GoogleDouban Books,9781449397227
Tags:HTML, JavaScript, jQuery, Programming Languages, Reference, Web, Web Programming
Publishers:O'Reilly
Author Sort:Flanagan, David
Title Sort:jQuery Pocket Reference
Date:08 ต.ค. 2013
uuid:e6a094f5-2e20-412d-a9cb-0d176e71c239
id:5949
Published:ธ.ค. 2010
Modified:08 ต.ค. 2013
Size:0.71MB
Languages:English
Type:book

"As someone who uses jQuery on a regular basis, it was surprising to discover how much of the library I’m not using. This book is indispensable for anyone who is serious about using jQuery for non-trivial applications." -- Raffaele Cecco, longtime developer of video games, including Cybernoid, Exolon, and Stormlord
jQuery is the "write less, do more" JavaScript library. Its powerful features and ease of use have made it the most popular client-side JavaScript framework for the Web. This book is jQuery's trusty companion: the definitive "read less, learn more" guide to the library.
jQuery Pocket Reference explains everything you need to know about jQuery, completely and comprehensively. You'll learn how to:
* Select and manipulate document elements
* Alter document structure
* Handle and trigger events
* Create visual effects and animations
* Script HTTP with Ajax utilities
* Use jQuery's selectors and selection methods, utilities, plugins and more
The 25-page quick reference summarizes the library, listing all jQuery methods and functions, with signatures and descriptions.