Screen Shot 2558-02-05 at 12.05.16 PM
จากการแบ่งปันเรื่อง Elasticsearch มาหลายครั้ง
คำถามที่ได้รับการถามมากๆ คือ เรื่องการ Scaling ของ Elasticsearch
ดังนั้น จึงทำการเขียนตอบ แบบคนเริ่มต้นใหม่ๆ
ว่าถ้าต้องการจะ Scaling ต้องรู้ และ ทำอะไรบ้าง
เพื่อให้เป็นพื้นฐานสำหรับศึกษาต่อไป

เริ่มด้วยการเรียนรู้ความสามารถของ Elasticsearch ก่อน

แน่นอนว่าเราต้องเอาไปเปรียบเทียบกับสิ่งที่ developer ทุกๆ คนถนัดก็คือ
RDBMS (Relational Database Management System)
ดังนั้นมาดูว่า คำที่ใช้เรียกแต่ละอย่างมันเทียบกันได้อย่างไร ?

  • Database => Index
  • Table => Type
  • Row => Document
  • Column => Field
  • Schema => Mapping
  • Index => ทุกๆ อย่างที่ให้ Elasticsearch ทำการ indexed
  • SQL => Query DSL

Elasticsearch สามารถ query แบบ multiple index ได้นะ

เช่นมีข้อมูลแยกกันอยู่ 2 index สามารถ query ข้อมูลได้พร้อมๆ กันดังนี้

GET /log-2015-02-01,log-2015-02-02/_search

ว่าด้วยเรื่องของการ Scale และ ความยึดหยุ่น

ในการสร้าง index ใน Elasticsearch นั้นเราสามารถกำหนดค่าต่างๆ ได้ เช่น

  • จำนวนของ shard
  • จำนวนของการ replicate ข้อมูล

ซึ่งจำนวนของ shard เราไม่สามารถแก้ไขได้นะครับ
รวมทั้งสามารถเพิ่ม node หรือ Elasticsearch server เข้าได้ทีหลัง

ตัวอย่างเช่น

รวมทั้งยังอนุญาตให้เราทำการติดตั้ง plug-in ต่างๆ ไปด้วย
เพื่อเพิ่มความสามารถในด้านต่างๆ เช่น

  • Head สำหรับการจัดการ Elasticsearch
  • Bigdesk สำหรับการ monitoring การทำงาน

มาดูการ configuration บ้างสิ

สามารถทำการ configuration ได้จากไฟล์ <ELASTICSEARCH_HOME>/config/elasticsearch.yml
ซึ่งถ้าคุณใช้เพียงการทดสอบ สามารถใช้ค่า default ได้เลย

แต่ถ้าต้องการใช้งาน production จริงๆ แล้ว
ต้องทำการ tunning performance และแก้ไขมันซะ

ตัวอย่างการแก้ไขแบบง่ายๆ

หัดใช้งาน REST APIs

รู้หรือไม่ว่า Elasticsearch ได้เตรียม REST APIs ไว้ให้ใช้งานอยู่แล้ว
ดังนั้นหัดใช้มันให้คล่องซะ เพราะว่ามีให้ใช้งานครบ
ทั้ง CRUD operation และ การดูสถานะการทำงานของ server
โดยมีรูปแบบของ URL ดังนี้

http://host:port/<index>/<type>/<action | id>

มาถึงส่วนสำคัญ คือ การ Optimize performance

1. จำนวนของการ open file
เมื่อจำนวนข้อมูลมากขึ้น จำนวนไฟล์ index ก็เพิ่มมากขึ้นเช่นเดียวกัน
เนื่องจากการทำงานจริงมันคือ Apache Lucene ซึ่งเป็น file-based system
อาจจะทำให้เกิดปัญหา Max open file ขึ้นมาได้

ดังนั้น ให้ทำการเพิ่มด้วยการใช้งานผ่านคำสั่ง ulimit
ค่าที่มักใช้ในระบบที่มีข้อมุลเยอะๆ คือ 32,000 – 64,000
แต่ค่าสามารถเปลี่ยนแปลงได้ตามขนาดของข้อมูลนะ
ซึ่งต้อง monitoring อยู่ตลอด

2. ขนาดของ memory ที่ใช้งาน
แน่นอนว่าถ้าข้อมูลเยอะ ก็ต้องใช้ memory เยอะขึ้นเช่นเดียวกัน
ไม่เช่นนั้นจะเจอปัญหา OutOfMemory อย่างแน่นอน
ซึ่งปกตินั้น เราจะจอง memory ให้ Elasticsearch ใช้งานเพียงครึ่งหนึ่งของ memory ทั้งหมด
เนื่องจากต้องให้ทาง OS ใช้งานด้วยนะ

โดยเราสามารถกำหนดขนาดของ memory ที่ใช้งานผ่าน ES_HEAP_SIZE
หรือส่งเป็น parameter ของ JVM ไปได้คือ -Xms และ -Xmx

ตัวอย่างเช่น
bin/ElasticSearch -Xmx=2G -Xms=2G

แต่ว่าเมื่อใช้งาน Elasticsearch ไปแล้วก็อาจจะเจอปัญหา OutOfMemory อีกก็ได้
เนื่องจากอาจจะมีการทำ caching ขึ้นมา และมันเกิดขนาดของ memory ที่จองเอาไว้
ก็ให้ทำการแก้ไข index.cache.field.type เป็น soft ซะ
แล้วปัญหาจะหายไป

3. Index optimization
ในการจัดการข้อมูล เช่น การสร้าง index สำคัญมากๆ
ก่อนอื่นต้องดูว่า รูปแบบข้อมูลของคุณมีรูปแบบอย่างไร
มีรูปแบบการใช้งานอย่างไร

ตัวอย่างเช่น
ระบบ log จะทำการเก็บข้อมูลแบบรายวัน
เนื่องจากในแต่ละวันมีจำนวน log เยอะมาก
รวมทั้งการใช้งานจะดูข้อมูลเป็นรายวัน และ ช่วงวันเท่านั้น
รวมทั้งยังสามารถจัดการ index ได้ง่าย เช่น การลบข้อมูลในวันที่ไม่ต้องการออกไปได้เลย

เมื่อทำการลบ index ไปแล้ว สิ่งที่ขาดไม่ได้เลยคือ การ optimize
เพื่อเพิ่มประสิทธิภาพการทำงานให้ดีขึ้น
แต่ควรที่จะสั่งให้ optimize ในช่วงเวลาที่มีการใช้งานน้อยๆ นะ

4. เรื่องการทำ Sharding และ Replicate
เมื่อเราทำการกำหนดจำนวนของ shard ในแต่ละ index ไปแล้ว ไม่สามารถแก้ไขได้นะ
แต่ถ้าอยากแก้ไขต้องทำการสร้าง index ใหม่ และ migrate ข้อมูลเข้ามาใหม่
ดังนั้น จึงเป็นเรื่องที่คุณต้องตัดสินใจอย่างระมัดระวัง
ว่าจะกำหนดให้จำนวน shard เป็นเท่าไร

ถ้าจำนวน shard ยิ่งมาก แน่นอนว่าระบบของคุณก็สามารถรองรับข้อมูลได้สูงขึ้นเช่นเดียวกัน
เพราะว่าในการ query ข้อมูล มันจะทำแบบกระจายไปยังทุกๆ shard
แต่จำนวน shard ต้องเหมาะสมด้วยเช่นกัน
ไม่เช่นนั้นมันจะทำให้มีการใช้งาน traffic ใน network มากจนเกินไป
ซึ่งส่งผลต่อการทำงานของระบบด้วยเช่นกัน

ดังนั้น ควรต้องทำการทดสอบ performance พอสมควรนะครับ

5. การ config Cluster Topology
ใน Elasticsearch นั้นจะมีชนิดของ node ที่อยู่ใน cluster 3 กลุ่มคือ

  • Data node ทำหน้าที่เก็บข้อมูลอย่างเดียว
  • Master node ทำหน้าที่ดูแล cluster และการ indexing ข้อมูล และ ค้นหาข้อมูลจาก data node
  • Search/Query node ทำหน้าที่รับคำสั่งการค้นหาข้อมูล จากนั้นทำการค้นหา รวบรวมข้อมูลจาก data node และส่งข้อมูลกับให้ผู้ที่ร้องขอ

แต่โดยปกติของ Elasticsearch นั้นจะมีทั้ง 3 กลุ่มใน node เดียวกัน
เมื่อข้อมูล และ การใช้งาน มีจำนวนสูงขึ้นมากๆ
มันจะไม่สามารถรองรับได้ !!

ดังนั้น
ถ้าต้องการให้ระบบสามารถ scale ได้ดี

  • แนะนำให้สร้าง data node ออกมา เพื่อเก็บข้อมูลเท่านั้น
  • แนะนำให้สร้าง master node สำหรับดูแล cluster และ indexing ข้อมูล
  • แนะนำให้สร้าง search node สำหรับการค้นหาต่างๆ จาก application ของเรา

เมื่อแยก node การทำงานแล้ว
เราสามารถลด spec ของ master node และ search node ลงไปได้ด้วยนะ
เพราะว่า ไม่ต้องเก็บข้อมูลแล้ว

แสดงดังรูป
Screen Shot 2558-02-05 at 11.56.46 AM

6. ว่าด้วยเรื่องของ Routing
เมื่อข้อมูลเยอะขึ้น การ indexing ข้อมูลก็เยอะขึ้น
ดังนั้น จำนวน shard ก็เยอะขึ้นเช่นเดียวกัน
และแน่นอนว่าจำนวนของ node ก็เยอะขึ้น
ทำให้ traffic ที่เกิดขึ้นในการค้นหาข้อมูลก็สูงขึ้นตามไป

ตัวอย่างเช่น
ถ้ามีอยู่ 100 shard และมี 5 node
เมื่อมี request เพื่อค้นหาข้อมูลจะต้องวิ่งไปดึงข้อมูลจากทุกๆ shard มา
เพื่อรวบรวม และ สรุปผล เพื่อส่งข้อมูลกลับไป
ซึ่งมันส่งผลแย่ต่อ cluster อย่างมาก
ยิ่งมีจำนวนการใช้งานสูง ก็จะทำให้ระบบไม่สามารถรองรับได้เช่นกัน
แสดงดังรูป
Screen Shot 2558-02-05 at 11.47.48 AM

ดังนั้นสามารถแก้ไขด้วยการใช้ routing
ว่าข้อมูลใดควรไปอยู่ shard ไหน
ซึ่งจะช่วยลดเวลาในการดึงข้อมูลลงไปได้อย่างมาก
แสดงดังรูป
Screen Shot 2558-02-05 at 11.49.30 AM

โดยรวมแล้ว

ทั้งหมดที่ผมแนะนำมานั้น เป็นเพียงส่วนหนึ่งที่ผู้เริ่มต้นใช้งาน Elasticsearch ควรศึกษาและเข้าใจ
เพื่อนำมาใช้ให้เกิดประโยชน์นะครับ

ใครมีเทคนิคดีๆ สามารถแนะนำมาได้นะครับ