Storage Engine ของ MongoDB by

31
Mar
0

MongoDB คือ NoSQL ที่ได้รับความนิยมสูงมากในช่วงหลายปีที่ผ่านมา แทบจะเป็นเบอร์หนึ่งในงานทั่วๆ ไปแล้วละมั้ง (แต่ผมยังยินยันเหมือนเดิมว่าไม่ควรใช้โดยที่ไม่มองทางเลือกอื่นก่อน มันไม่สามารถแทน MySQL ได้ 100% จึงควร Choose the right thing at the right job นะครับ อ่านเพิ่มเติมได้ที่บทความเก่าที่นี่) สำหรับคนที่ไม่ได้ตามข่าว ตั้งแต่ MongoDB 3.0 เป็นต้นมา MongoDB ได้ปรับปรุงระบบใหม่ เพิ่มระบบ Storage Engine เข้ามา คล้ายกับ MySQL ที่มี MyISAM และ InnoDB ให้เลือก หรือจะเปลี่ยนเป็น Storage Engine ตัวอื่นก็ได้ตามอิสระ

Storage Engine พูดง่ายๆ ก็คือวิธีการเก็บข้อมูลว่าจะเก็บในรูปแบบไหน อย่างไร ซึ่งเราสามารถ Download Storage Engine จากผู้พัฒนารายอื่นมาเชื่อมต่อได้อย่างอิสระให้เหมาะสมกับลักษณะงานของเราได้ ปัจจุบันมี Storage Engine ดังนี้

engines-timeline

  1. MMAPv1 – แถมมากับ MongoDB ซึ่งถูกใช้งานมาอย่างยาวนานตั้งแต่ MongoDB version แรกจนปัจจุบัน และตั้งแต่เวอร์ชั่น 3.2 เป็นต้นไป จะไม่ใช่ default engine อีกต่อไป หลักการทำงานคือใช้ Memory Map ของ OS มาเป็นตัวช่วยจัดการ Memory ให้ทั้งหมด ไม่มีระบบจัดการ Memory เป็นของตัวเอง ทำให้สมัยก่อนขึ้นชื่อเรื่องสวาปาม Ram อย่างมาก และห้ามมี application ตัวอื่นรันพร้อมๆ กันในเครื่องเดียวกันเด็ดขาด หากต้องการใช้ MongoDB หนักๆ ควรแยกเครื่องออกจากกันซะ มิเช่นนั้น application อื่นๆ จะโดนดูด Ram จนหมดตัว (น่ากลัวไหมล่ะ) และยังมีข้อจำกัดอีกมากมายเช่น ไม่มีระบบบีบอัดข้อมูลที่บันทึกลง Disk ทำให้นอกจากกิน Ram เยอะมากแล้วยังกิน Disk เยอะมากอีกตะหาก และ Collection ของระบบนี้ (เทียบได้กับ Table ใน MySQL) จะไม่มีระบบ Lock เฉพาะ Document เวลาแก้ไข (Document เทียบได้กับ row ใน table) เวลาโดน Lock จะ Lock ทั้ง Collection ซึ่งส่งผลเสียอย่างมากหากต้องมีการแก้ไขข้อมูลเยอะๆ ปัจจุบันไม่แนะนำให้ใช้งานครับ
  2. WireTiger – เป็น Storage Engine น้องใหม่ที่มาจากการที่ MongoDB ไปซื้อบริษัท WireTiger ผนวกรวมเข้ากับตัวเอง และปัจจุบันเป็น Default Storage Engine ตั้งแต่เวอร์ชั่น 3.2 เป็นต้นไป แก้ไขปัญหาของ MMapv1 ไปหลายอย่างเช่นมีระบบบีบอัดข้อมูลที่บันทึกลง Disk ทำให้ขนาดไฟล์เล็กลง 10 เท่า!! และมีการ Lock ที่ระดับ Document ทำให้ไม่ต้องแย่ง resource กันเวลา update ไม่เกิดการรอกันไปมามากเกินไป และหาก Data Set สามารถยัดลง Memory ได้พอ WireTiger จะเป็น Storage Engine ที่เร็วที่สุดและดีที่สุด! แต่ถ้าข้อมูล Data Set ใหญ่กว่า Memory ความเร็วการใช้งานจะช้าลงเรื่อยๆ อย่างมีนัยยะเลยทีเดียวซึ่งจะหลายเป็น Binary Tree Engine ธรรมดาๆ ไป จึงช้าลง
  3. PerconaFT – เป็น Storage Engine ที่ต้อง download เป็น MongoDB เวอร์ชั่นพิเศษจากเว็บ percona และจะมีเลขเวอร์ชั่นและ feature ตามท้าย MongoDB ตัวหลักอยู่ประมาณหนึ่ง (ปัจจุบันเป็น MongoDB 3.0 ตามหลังเวอร์ชั่นหลักคือ 3.2) เมื่อก่อนชื่อ TokuMX และโดน Percona ซื้อไป เปลี่ยนชื่อใหม่เป็น Percona for MongoDB ตัวนี้มีจุดเด่นคือมี Percona เป็น Back ซึ่งเชี่ยวชาญด้านการ Modify Database ดังๆ มาปรับปรุงให้เทพขึ้น (เช่น MySQL ซึ่งผมใช้อยู่ และติดงอมแงม) และมี Tools ของตัวเองมาช่วยมากมายเช่น Tools ที่ช่วยเรื่อง Hot Backup และ Tools อื่นๆ ที่ช่วยให้ชีวิต DBA ง่ายขึ้นตามมา จุดเด่นอีกอย่างคือนอกจากจะมีทั้งการบีบอัดข้อมูล, Document Level Lock เหมือน WireTiger แล้วยังปรับปรุงเรื่องความเร็วหาก Data Set มีขนาดใหญ่กว่า Memory โดยจะยังรักษาความเร็วไว้ได้อย่างคงที่ เพราะใช้เทคโนโลยีส่วนตัวที่ชื่อว่า Fractal Tree ซึ่งผมเองเลือกใช้ตัวนี้ครับ สาเหตุหนึ่งเพราะผมเป็นติ่ง Percona มาตั้งแต่ MySQL แล้วด้วย 555
  4. RocksDB – Storage Engine น้องใหม่จาก Facebook เป็นการันตี สร้างขึ้นจาก LevelDB ซึ่งเป็นฐานข้อมูลแบบ key-value ที่ open source จาก Google ถ้า Download จาก website Percona ก็จะแถม Engine ตัวนี้มาให้เลือกเลยโดยไม่ต้อง setup เพิ่มเช่นกัน ใช้ LSM Tree ในการเก็บข้อมูล ทำให้ Write ได้เร็วกว่า PerconaFT เหมาะกับการเก็บ Log มาก แต่แลกกับการที่ Read ข้อมูลได้ช้ากว่า PerconaFT

หากใครมี use case แบบไหนก็เลือกใช้ให้เหมาะสมกับตัวเองนะครับ ขอให้โชคดี :)

อ้างอิงข้อมูล:

https://www.percona.com/blog/2015/12/23/percona-server-for-mongodb-storage-engines-in-iibench-insert-workload/
https://www.percona.com/blog/2016/01/06/mongodb-revs-you-up-what-storage-engine-is-right-part-1/
https://www.percona.com/blog/2016/01/11/mongodb-revs-you-up-what-storage-engine-is-right-for-you-part-2/
https://www.percona.com/blog/2016/01/20/mongodb-revs-you-up-what-storage-engine-is-right-for-you-part-3/
https://www.percona.com/blog/2016/01/27/mongodb-revs-you-up-what-storage-engine-is-right-for-you-part-4/

ทำไมถึงต้องใช้ MongoDB แทน MySQL? by

29
Nov
6

MongoDB คือ NoSQL ชนิดหนึ่ง ก่อนอื่นบทความนี้บอกก่อนว่าเราจะไม่บอกว่าใช้ MongoDB แทน MySQL ไปเลยได้ 100% เพราะอย่างไรก็ตาม NoSQL ก็ยังคงมีข้อจำกัดความสามารถบางอย่างที่ไม่สามารถใช้แทน MySQL ได้ หรือทำได้แต่จะยากกว่าการใช้ MySQL มากเราต้อง Choose the right tools at the right job ครับ และสำหรับใครที่ยังไม่ได้คลุกคลีกับ MySQL จนกระทั่งเจอปัญหาว่ามันช้าจนรับไม่ได้แล้วละก็ คุณไม่จำเป็นต้องเปลี่ยนมาใช้ MongoDB เลยแม้แต่น้อยครับ ใช้ MySQL ไปเถอะครับ

จุดเด่นของ NoSQL ส่วนใหญ่ (แต่ไม่ใช่ทุกอย่าง) คือความสามารถในการ write ข้อมูลได้เร็วกว่า MySQL เป็นอย่างมาก หากงานที่เราทำนั้นเน้นการ write ข้อมูลมากๆ เช่นต้องเก็บ Log แบบตลอดเวลาแบบ Real-time ทุกการกระทำ และข้อมูลมีขนาดใหญ่โตมาก การใช้งาน MongoDB ก็จะตอบโจทย์ได้เป็นอย่างดี

MongoDB เป็น database แบบ Document-Oriented โดยลักษณะข้อมูลที่ทำการเก็บจะคล้ายกับ JSON เป็นอย่างมาก มีข้อดีอย่างมากคือ Row แต่ละ Row ไม่จำเป็นต้องมีโครงสร้างข้อมูลเหมือนกัน เช่น คุณอาจจะมีข้อมูลปากกา 1 row ที่ระบุแค่สีแดง และอีก row เป็นข้อมูลปากกาที่ระบุว่าสีน้ำเงิน และอีก field ระบุว่าเป็นปากกาชนิดมีด้ามเสียบ ซึ่งมีข้อมูลมากกว่า 1 อย่าง ก็สามารถเก็บได้โดยไม่ต้องเปลี่ยน schema หากใครใช้ MySQL ทำงานกับข้อมูลมากๆ จะรู้ว่าการสั่ง ALTER TABLE เพื่อเปลี่ยนโครงสร้างตารางข้อมูลนั้นช้าเพียงใด (table โดน lock อีกตะหาก) และถ้า requrement จำเป็นต้องเพิ่ม field เข้าไปเรื่อยๆ แล้วละก็เรื่องใหญ่ทีเดียว

บางคนอาจเคยได้ยินว่า MongoDB จะกิน Memory ของเครื่องไปเรื่อยๆ จนกระทั่งหมด เรื่องนี้ไม่เป็นความจริง เพราะ Memory ใน MongoDB ที่มีการใช้งานนั้นจะมีการใช้งานเยอะขึ้นเรื่อยๆ จริง ถ้าดูจาก top แต่ถ้าดูจาก free -m จะทราบว่าจริงๆ Memory ที่ยังใช้งานได้ยังเหลืออีกเยอะ หากมี Process อื่นเกิดต้องการใช้ memory จำนวนมาก ตัว MongoDB จะ Memory ที่ใช้ให้โดยอัตโนมัติ เป็นเพราะ MongoDB ใช้ระบบเดียวกับ cached memory ใน linux ซึ่งจะปล่อยให้ OS เป็นคนจัดการ Memory ให้เลยหลอกตาเหมือนว่าจะกิน Memory เยอะ คล้ายกับเราเปิด top ขึ้นมาครั้งแรกแล้วเห็น free เหลืออยู่นิดเดียว แต่ memory ส่วน cached จะยังมีเหลืออยู่อีกมาก สำหรับรายละเอียดอ่านเหตุผลได้ที่เว็บนี้

ผมขอสรุปข้อดี-ข้อเสียของ MongoDB เป็นข้อๆ ดีกว่าครับ

ข้อดี

  1. write to disk เร็วส์มากกกกก
  2. ถ้าเน้นเอามา write อย่างเดียว ไม่มีการ read (เช่นเก็บ Log ไว้ให้ admin ดู) จะกินแรมน้อยมากกกกก CPU ก็กินน้อยสุดๆ เทียบกับ InnoDB ของ MySQL แล้วต่างกันราวฟ้ากับเหว
  3. write แบบ asynchronous (คล้าย INSERT DELAYED ของ MyISAM ใน MySQL)  คือไม่ต้องรอ Insert เสร็จจริงก็ทำงานต่อได้
  4. read อย่างเดียวก็เร็วกว่า MySQL มากเช่นกัน (ภายใต้ข้อจำกัดว่าข้อมูลของฐานข้อมูลที่เรียกใช้บ่อยๆ ต้องใส่ใน memory ที่เหลือได้พอดี)
  5. มี Capped Collection ซึ่งจะทยอยลบข้อมูลเก่าที่เก็บไว้นานเกินไปแล้วเอาข้อมูลใหม่มาใส่แทนได้ เหมาะแก่การนำมาทำ Log มากเพราะจะ clear ข้อมูลที่เก็บมานานเกินไปไว้ให้อัตโนมัติ ข้อมูลไม่โตกว่าที่เรากำหนด ไม่ต้องมาสั่ง cron ให้คอยลบข้อมุล log ทุกๆ กี่วัน
  6. Scaling เพิ่มเครื่องได้ง่ายกว่า MySQL มากๆๆๆๆ

ข้อเสีย

  1. ถ้า project เก่าคุณมีการ JOIN กันซับซ้อนละก็ จะเปลี่ยนมาใช้ได้ยากมากทีเดียว
  2. การใช้งานผ่านเว็บไม่ง่ายเท่า phpmyadmin เช่นการ query เรื่องวันที่ผ่านเว็บจะลำบากพอสมควร ต้องเขียนหน้า admin ใช้งานเอง และการค้นหาข้อมูลทั่วๆ ไปก็ยากเช่นกัน
  3. กินพื้นที่การเก็บข้อมูลมากกว่า MySQL พอสมควร เหตุผลเพราะไม่มี schema ดังนั้น schema จริงๆ มันจะแอบอยู่ในทุก row ของฐานข้อมูล ทำให้ข้อมูลใหญ่กว่า MySQL
  4. หากใช้งานจน disk เต็ม จะ clear พื้นที่ disk ให้ใช้งานต่อยาก เพราะการสั่ง delete row ไม่ทำให้ฐานข้อมูลเล็กลง!! ต้องสั่ง compact เองซึ่งต้องมีที่ว่างที่ disk อีกลูกมากพอๆ กับพื้นที่ข้อมุลที่ใช้อยู่ปัจจุบันเป็น buffer ในการลดขนาด (การลดขนาดจริงๆ คือการสร้างใหม่มาเลยอีกก้อน จึงต้องมี buffer เยอะมาก)
  5. หากต้องการใช้งานเป็นฐานข้อมูลหลักแทน MySQL ควรมีเครื่องอย่างน้อย 3 เครื่องที่เป็น physical แยกกันทำ replication กัน เพื่อเพิ่ม durability ของข้อมูล เนื่องจากข้อมูลส่วนใหญ่ของ MongoDB จะเก็บใน Memory เป็นระยะเวลาหนึ่ง หากเครื่องดับไปเครื่อง ข้อมูลที่ยังค้างใน Memory แต่ยังไม่ write ลง disk จะสูญหายทันที

สำหรับผมตอนนี้ใช้งาน MongoDB แค่เพียงส่วนของ Log เนื่องจากยอมให้ durability ต่ำไปนิดหน่อยได้ครับ ส่วนอื่นๆ ยังคงใช้ MySQL ตามปกติ ขอให้โชคดีกับการ Scale ระบบของคุณนะครับ :)

HandlerSocket NoSQL ในรูปแบบของ MySQL by

30
Sep
2

ก่อนอื่นต้องเท้าความก่อนว่า HandlerSocket คืออะไร HandlerSocket คือ Plugin MySQL ของ InnoDB Engine (เท่านั้น) ที่จะช่วยให้เราสามารถใช้ NoSQL ในรูปแบบของ MySQL ทำให้ได้ speed เพิ่มขึ้นมากหลายเท่าโดยที่โครงสร้างข้อมูลยังอยู่ในรูปแบบของตารางอยู่ (ผู้เขียน HandlerSocket claim ว่าเร็วกว่า Memcache ถ้าปริมาณข้อมูลใส่ใน memory ได้พอเลยนะเออ!) ซึ่งหลักการของ HandlerSocket คือตัดขั้นตอนที่ไม่จำเป็นออกจาก MySQL ทั้งหมด โดยเฉพาะอย่างยิ่ง SQL Parse ซึ่งเป็นขั้นตอนที่กินเวลามากที่สุด แต่ก่อนอื่น เรามาทำความเข้าใจกันสักนิดก่อนจะใช้งาน HandlerSocket

  • ต้องแก้ Code ใหม่เนื่องจากไม่สามารถใช้ SQL query ได้อีกต่อไป ต้องใช้ function ที่ตัวเชื่อมกับ HandlerSocket มีให้เท่านั้น
  • Join ไม่ได้เพราะเป็นการใช้งานแบบ NoSQL เต็มรูปแบบ ใช้ได้เฉพาะ Query ง่ายๆ ของ SELECT,INSERT, UPDATE, DELETE ที่อ้างอิงกับ primary key
  • Replication ไม่ได้ถ้าใช้เป็นรูปแบบการ write (แก้ปัญหาได้ด้วยการใช้แค่ read อย่างเดียว write ยังใช้เป็น SQL เหมือนเดิม)
  • ไม่มีระบบ Autenticatation ไม่มี Security ใดๆ (ต้องเข้าใจก่อนว่า NoSQL เจ้าอื่นๆ เช่น Redis, Memcache ก็เป็นแบบนี้เช่นกัน) แต่สามารถใช้ Firewall block port ที่จะใช้งานจากภายนอกแทนได้
  • ควรปิดระบบ query cache เวลาใช้งานไม่งั้นค่าที่อ่านมาได้อาจผิดพลาด (แต่เนื่องจากมันเร็วส์อยู่แล้ว ปิด query cache ก็ไมได้กระทบกับระบบอะไรมากหรอก)
  • ถ้า insert รัวๆ Auto Increment จะนับข้ามบ้างเป็นบางครั้ง ถ้าไม่ serious ว่าเลขต้องเรียงต่อกันก็ไม่เป็นไรครับ
  • ใช้ได้กับ InnoDB Storage Engine เท่านั้น!

มาดูที่ข้อดีกันบ้าง

  • เร็วส์ (750,000 query/sec แต่อันนี้เป็นคำโม้จากคนสร้างนะครับ ใช้จริงอาจไม่ถึง แต่เร็วกว่า memcache ถ้า memory พอดีกับข้อมูลครับ)
  • INSERT, UPDATE ตัว HandlerSocket จะจับมัดเป็นก้อนเดียวกันโยนไปทีเดียวเลยเหมือนใช้ Transaction ในตัว (เฉพาะ performance นะครับ ไม่ได้ใช้ transaction ได้เต็มรูปแบบ) จริงๆ ก็คือ เร็วส์แหละครับ
  • ข้อมูลยังคงออกมาเป็นรูปแบบของตาราง MySQL ที่เราคุ้นเคย เรายังใช้ SQL มาดึงข้อมูลภายหลังได้ หากเกิดเปลี่ยนใจไม่อยากใช้ HandlerSocket แล้ว
  • เร็วส์ เร็วส์ เร็วส์ (ไม่มีข้อดีอย่างอื่นแล้ว)

ถ้าพิจารณาข้อจำกัดต่างๆ แล้ว ทุกอย่างผ่านหมด ก็มาดูที่วิธีติดตั้งได้เลย

1. install percona server ก่อนเลยครับ ถ้าไม่ใช้ Percona Server ก็ต้อง compile plugin ใช้เองซึ่งวุ่นวายกว่ามากครับ วิธี Install ตามนี้เลย

- apt-get
- yum

2. แก้ไขไฟล์ my.cnf เพิ่มบรรทัดเหล่านี้เข้าไป


loose_handlersocket_port = 9998
# the port number to bind to for read requests
loose_handlersocket_port_wr = 9999
# the port number to bind to for write requests
loose_handlersocket_threads = 16
# the number of worker threads for read requests
loose_handlersocket_threads_wr = 1
# the number of worker threads for write requests
open_files_limit = 65535
# to allow handlersocket to accept many concurrent
# connections, make open_files_limit as large as
# possible.

9998 คือ port สำหรับ read อย่างเดียว ส่วน 9999 คือ port สำหรับ write นะครับ (แก้เลขเป็น port อื่นได้)

3. login เข้า MySQL เป็น root แล้วพิมพ์คำสั่งไปว่า

install plugin handlersocket soname 'handlersocket.so';

4. สั่ง SHOW PROCESS LIST ถ้า Install สำเร็จจะปรากฏ Worker ใน process list ดังนี้


mysql> SHOW PROCESSLIST;
+----+-------------+-----------------+---------------+---------+------+-------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------------+---------------+---------+------+-------------------------------------------+------------------+
| 1 | system user | connecting host | NULL | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL |
| 2 | system user | connecting host | NULL | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL |
...
| 16 | system user | connecting host | NULL | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL |
| 17 | system user | connecting host | handlersocket | Connect | NULL | handlersocket: mode=wr, 0 conns, 0 active | NULL |

5. เสร็จสิ้น หลังจากนี้ก็ต้องหา library ที่สามารถติดต่อกับ HandlerSocket มาใช้ละครับ เช่น php ใช้ php-handlersocket nodejs ใช้ node-handlersocket

 เราชนะรอบ 4 | ยืมเงิน 3000 ด่วน | แอพกู้เงิน | แอพเงินด่วน | สินเชื่อออนไลน์อนุมัติทันที | Site Map | กู้เงินก้อน | กระเป๋าตัง | thisshop และ ยืมเงินฉุกเฉิน 5000 ด่วน