เนื่องจากกลับมาเล่น MongoDB แบบติดตั้งเองอีกรอบ ก็เลยมาลองเล่น relication ดูบ้าง เพราะ MongoDB รองรับ replication ด้วย ซึ่งการตั้งค่านั้นง่ายมากๆ หลักการของ replication คือการทำสำเนาข้อมูลให้เท่ากันทุกเครื่อง กรณีที่มีเครื่องใดเครื่องหนึ่งไม่สามารถให้บริการได้ MongoDB จะยังสามารถให้บริการได้จาก relicaset ที่เหลือได้ด้วยความสามารถในเรื่อง Automatic Failover อีกด้วย

replicaset

automatic failover

จากภาพเราจะมีเซิร์ฟเวอร์อยู่ 3 เครื่องทำหน้าที่เป็น Primary และ Secondary ซึ่งเครื่อง Primary ทำหน้าที่รับ request ที่มาจาก client ในส่วน Secondary ทำหน้าที่ replicate การทำงานต่างๆ จาก Primary มาและอาจทำหน้าที่เป็น Primary แทนในกรณีที่ Primary ไม่สามารถทำงานได้

เพื่อความเข้าใจ มาลองติดตั้ง MongoDB repication ดู มีเครื่อง 3 เครื่อง

  1. rep0 (Primary)
  2. rep1 (Secondary)
  3. rep2 (Secondary)

    ทุกเครื่องมองเห็นกันได้ในเครือข่าย ลองทดสอบ ping ชื่อเครื่องดู และติดตั้ง MongoDB ไปยังทุกเครื่องดังนี้

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.1.tgz
tar zxvf mongodb-linux-x86_64-2.6.1.tgz -C /opt/
export PATH=$PATH:/opt/mongodb-linux-x86_64-2.6.1/bin

จากนั้น สร้างที่เก็บฐานข้อมูลดังนี้

mkdir -p /data/rs0-0 /data/rs0-1 /data/rs0-2

เริ่ม start service ของ MongoDB ในแต่ละเครื่องด้วยคำสั่งดังนี้

เครื่อง rep0

mongod --dbpath /data/rs0-0 --replSet rs0 --smallfiles --oplogSize 128

เครื่อง rep1

mongod --dbpath /data/rs0-1 --replSet rs0 --smallfiles --oplogSize 128

เครื่อง rep2

mongod --dbpath /data/rs0-2 --replSet rs0 --smallfiles --oplogSize 128

จากนั้นในคำสั่ง mongo เรียกใช้งานเครื่อง rep0 ดังนี้

mongo --host rep0

จากนั้นสั่งให้ตั้งค่า relicaset ดังนี้

rs.initiate()

ใช้คำสั่ง rs.conf() เพื่อดูว่ามีข้อมูลการตั้งค่าเริ่มต้น repicaset แล้วหรือยัง

rs.conf()

ให้สังเกตว่า shell ของ MongoDB จะเปลี่ยนเป็น rs0:PRIMARY> และจะมีข้อมูลเริ่มต้นของ replicaset แล้ว ให้เพิ่ม host เข้าไปดังนี้

rs.add("rep1:27017")

rs.add("rep2:27017")

ลองใช้คำสั่ง rs.conf() ดูจะพบว่า rs0 ของเรามี host เพิ่มเข้ามารวมเป็น 3 host แล้ว

ใช้คำสั่ง rs.status() เพิ่อดูสถานะของ Repication Cluster

rs.status()

จะพบว่าเรามี 3 เครื่องที่ผูกกันใน repicaset ชื่อ rs0 และ 2 เครื่องที่เพิ่มเข้ามาถูกกำหนดให้เป็น Secondary อัตโนมัติ

ให้ลอง load data เข้าไป ให้สังเกต log จะพบว่าเครื่อง Primary จะส่งข้อมูลไปเขียนที่ Secondary ตลอด แต่เวลา query จะสลับกันระหว่างเครื่องเป็นลักษณะ round robbin ให้ลอง shutdown เครื่อง Primary ดู จะพบว่าเครื่อง Secondary ทั้ง 2 ตัวจะโหวดกัน แล้วได้ Primary ใหม่มา 1 ตัว จากนั้นให้ลอง query ข้อมูลจาก Primary ตัวใหม่ ก็จะพบว่าข้อมูลยังอยู่ครบ ;)

สำหรับท่านที่สนใจทำ MongoDB Replication ให้ลองศึกษาเพิ่มเติมที่ MongoDB Document ในส่วน Replication เพิ่มเติมครับ

ผมได้มีโอกาสได้ไปเรียน Hadoop กับทีมงาน ThaiGird ที่ SiPA แต่ไม่ได้เรียนจบคอร์สเพราะมีเวลาน้อยมากในการเข้าฟังบรรยายและทำ lab สุดท้ายก็ได้เพียงแนวความคิดของ Hadoop ซึ่งมีบางอย่างที่น่าสนใจ ซึ่งไม่ใช่เครื่อง HPC ซะทีเดียว แต่เป็นเรื่อง Distributed Storage ที่ใช้ HDFS ซึ่งสร้างความประทับใจมากๆ แนวคิดของ HDFS ง่ายๆ คือการสร้าง Storage ขนาดใหญ่โดยใช้ Storage ที่ติดอยู่กับเครื่องโหนดหลายๆ เครื่อง เอามารวมกัน ซึ่งคุณสามารถสร้าง Storage ขนาด PetaByte ได้สบายๆ แต่ HDFS ใช้กับ Hadoop เท่านั้น! เอามาใช้งานแบบปกติๆ ไม่ได้ จากแนวคิดเรื่อง Distributed Storage ที่ได้มาจาก Hadoop File System ทำให้นึกขึ้นได้ว่า เราสามารถสร้าง Distributed Storage แบบ HDFS ได้ง่ายๆ เช่นกัน โดยใช้ GlusterFS เจ้า GlusterFS นี้ช่วยให้เราสร้าง Storage ผ่านจากเครือข่ายเน็ตเวิร์คได้ง่ายๆ และใช้แนวคิดเดียวกันกับ HDFS แต่เราสามารถเรียกใช้งานได้เหมือนกันการใช้งาน Storage ปกติ และนั่นก็หมายความว่าคุณสามารถเอาเครื่องคอมพิวเตอร์มาต่อๆ กันเพื่อสร้าง Stroage ขนาดใหญ่แบบ PetaByte ได้สบายๆ How-To นี้จะพูดถึงวิธีการติดตั้ง GlusterFS บนเครื่อง 2 เครื่องพร้อมทำ HA (High-Availability) โดยใช้คุณสมบัติ Automatic File Replication ของ GlusterFS เอง มาลงมือกันเลย

ก่อนลงมือทำมาทำความเข้าใจกันก่อน เราต้องมีเครื่อง Server อย่างน้อย 2 เครื่องในการทำ Replication หรือที่เรียกกันง่ายๆ ว่า Mirroring และเครื่อง Client อย่างน้อย 1 เครื่องสำหรับเรียกใช้งาน Storage สำหรับงานจริงควรใช้เน็ตเวิร์กขนาด 10 GigE ขึ้นไปจึงจะได้ประสิทธิภาพสูง เข้าใจกันแล้วมาลงมือทำกันเลย

Server 1 ของผมมี IP Address : 172.16.16.11 Domain Name : server1.example.com
Server 2 ของผมมี IP Address : 172.16.16.12 Domain Name : server2.example.com
Client 1 ของผมมี IP Address : 172.16.16.13 Domain Name : client1.example.com

เครื่องทุกเครื่องเชื่อมต่อกันในเครือข่ายอ้างอิงผ่าน hostname/domain name ได้ถูกต้อง Linux Distribution ที่ใช้เป็น Ubuntu 10.10 ใครใช้ Debian ก็จะสามารถใช้วิธีการเดียวกันได้ครับ :) เมื่อเตรียมทุกอย่างครบแล้วลงมากันได้!

ติดตั้ง GlusterFS Server ที่เครื่อง Server1 และ Server 2 ดังนี้

กระโดดเป็น root ก่อนครับ

sudo -s

จากนั้นติดตั้ง package ที่ชื่อ glusterfs-server ดังนี้

aptitude install glusterfs-server

จากนั้นสร้างไดเรคทอรีสำหรับเก็บข้อมูลผ่านเครือข่าย ดังนี้

mkdir -p /data/export
mkdir -p /data/export-ns

กรณีที่แบ่งพาร์ทิชั่นสำหรับเก็บข้อมูลให้ mout เป็น /data แล้วสร้างไดเรคทอรี /export แบะ /export-ns ขึ้นมา จากนั้นแก้ไข config ในส่วน glusterfs deamon ในไฟล์ /etc/glusterfs/glusterfsd.vol ดังนี้

volume posix
type storage/posix
option directory /data/export
end-volume

volume locks
type features/locks
subvolumes posix
end-volume

volume brick
type performance/io-threads
option thread-count 8
subvolumes locks
end-volume

volume server
type protocol/server
option transport-type tcp
option auth.addr.brick.allow 172.16.*
subvolumes brick
end-volume

ในส่วน option auth.addr.brick.allow 172.16.* หมายถึงให้เครื่องที่อยู่ในเครือข่าย 172.16.* สามารถ mount มายังเครื่องนี้ได้ เมื่อตั้งค่าได้แล้วให้ start services ของ glusterfs ดังนี้

/etc/init.d/glusterfs-server start

เมื่อติดตั้ง GlusterFS ทั้ง 2 เครื่องเรียบร้อยแล้ว ให้คุณกลับมาที่เครื่อง Client ของเราเพื่อทำการ mouth file system แบบ GlusterFS กัน เริ่มต้นด้วการติดตั้ง glusterfs srever และ gluster client ดังนี้

แปลงร่างเป็น root ก่อน

sudo -s

จากนั้นติดตั้ง package ดังนี้

aptitude install glusterfs-client glusterfs-server

สร้างไดเรดทอรีที่กำหนดจุด mount ดังนี้

mkdir /mnt/glusterfs

แก้ไขไฟล์ /etc/glusterfs/glusterfs.vol เพื่อกำหนดรูปแบบในการทำงานของ glusterfs client ดังนี้

volume remote1
type protocol/client
option transport-type tcp
option remote-host server1.example.com
option remote-subvolume brick
end-volume

volume remote2
type protocol/client
option transport-type tcp
option remote-host server2.example.com
option remote-subvolume brick
end-volume

volume replicate
type cluster/replicate
subvolumes remote1 remote2
end-volume

volume writebehind
type performance/write-behind
option window-size 1MB
subvolumes replicate
end-volume

volume cache
type performance/io-cache
option cache-size 512MB
subvolumes writebehind
end-volume

เมื่อได้ config แล้วเราสามารถ mount เจ้า GlusterFS ได้ 2 วิธีครับ คือ

glusterfs -f /etc/glusterfs/glusterfs.vol /mnt/glusterfs

หรือ

mount -t glusterfs /etc/glusterfs/glusterfs.vol /mnt/glusterfs

หากต้องการให้ mount ตั้งแต่ตอนเครื่อง boot ให้เพิ่มลงใน /etc/fstab ดังนี้

/etc/glusterfs/glusterfs.vol /mnt/glusterfs glusterfs defaults 0 0

เมื่อ mount ได้แล้วจะพบว่า เรามีพื้นที่เพิ่มเข้ามาในระบบดังนี้

/etc/glusterfs/glusterfs.vol 18G 848M 16G 5% /mnt/glusterfs

จาก config ข้างต้นผมมีพื้นที่เอาไว้สำหรับ GlusterFS อยู่ 18GB ทั้ง 2 Server แต่พื้นที่ที่เราจะได้นั้นไม่ได้เป็น 18GB x 2 แต่จะได้เพียง 18GB เท่านั้นเพราะเราทำ Mirroring พร้อม Replication ครับ :)

ทีนี้ให้ลองทดสอบ สร้างไฟล์เปล่าๆ ขึ้นมาสัก 3 ไฟล์ดังนี้

touch /mnt/glusterfs/test1
touch /mnt/glusterfs/test2
touch /mnt/glusterfs/test3

แล้วกลับไปดูที่เครื่อง Server 1 และ Server 2 เราจะพบไฟล์ test1, test2 และ test3 อยู่ใน /data/export ให้ทดสอบกรณี Replication เมื่อเครื่องใดเครื่องหนึ่งตาย ให้คุณปิดเครื่อง Server 2 แล้ว เขียนไฟล์เปล่าๆ ลงไปเพิ่ม

touch /mnt/glusterfs/test4
rm -rf /mnt/glusterfs/test1
rm -rf /mnt/glusterfs/test2

จากนั้นกลับไปดูเครื่อง Server 1 จะพบไฟล์ test3 และ test4 เท่านั้น จากนั้นให้ Start Server 2 ขึ้นมา แล้วดูไฟล์ไดเรคทอรี /data/export อีกรอบจะพบไฟล์เดิมอยู่ยังไม่มีการ replication ให้คุณเรียกดูไฟล์ใน /mnt/glusterfs อีกครั้ง แล้วกลับไปดูที่ Server 2 ก็จะพบว่ามีไฟล์เท่ากันแล้ว คือ test3 และ test4 :) ในครั้งหน้าเราจะมารวมพื้นที่ (Strip) เพื่อสร้าง Storage ขนาดใหญ่กันครับ :)