Elasticsearch

เคล็ดลับการปรับปรุงประสิทธิภาพใน Elasticsearch ส่วนที่ 1

Written by Ajit Gadge

| Jul 20, 2020

2 MIN READ

ในบทความก่อนหน้าได้นำเสนอเกี่ยวกับการปรับขนาดคลัสเตอร์ของ ELK และแสดงให้คุณเห็นปัจจัยที่ต้องพิจารณาในการตั้งค่าคลัสเตอร์ ELK วันนี้จะพูดถึงวิธีที่เราสามารถปรับปรุงประสิทธิภาพของ Elasticsearch โดยเฉพาะอย่างยิ่งเมื่อคุณอยู่ในการผลิต (หรือวางแผนที่จะใช้มันในไม่ช้า) ด้วยการตั้งค่า Elasticsearch เริ่มต้นหากคุณไม่ได้รับประสิทธิภาพตามที่ต้องการนี่คือบางสิ่งที่คุณควรพิจารณา:

1. การจัดสรรหน่วยความจำ

เราต้องการผลการค้นหาที่รวดเร็วและเกี่ยวข้อง ดังนั้นหน่วยความจำและดิสก์ I/O มีบทบาทสำคัญมาก
แนะนำให้ใช้ RAM 64 GB พร้อมที่เก็บข้อมูล SSD แต่มีหน่วยความจำน้อยกว่าและเร็วกว่า HDD เช่นกัน เป็นการแลกเปลี่ยนกับปริมาณและโหนดข้อมูลมากขึ้น
Elasticsearch ทำงานบนกระบวนการ java ดังนั้นจึงเป็นเรื่องสำคัญมากที่จะต้องตั้งค่าปริมาณที่เหมาะสมของ JVM ไปยังโหนดข้อมูล ขอแนะนำให้ตั้งค่าน้อยกว่า 50% ของ RAM เป็นฮีป JVM น้อย ตัวอย่าง: หากคุณมี RAM 64 GB ในช่องข้อมูล Elasticsearch ขอแนะนำให้ตั้งค่า ~ 30 GB และไม่เกิน 32 GB
คุณสามารถตั้งค่านี้ใน Xms และ Xmx ในไฟล์ jvm.option เช่น
-Xms30g
-Xmx30g
นอกจากนี้คุณยังสามารถตั้งค่าหน่วยความจำขนาดฮีพเป็นตัวแปรสภาพแวดล้อมโดยการตั้งค่าพารามิเตอร์ ES_JAVA_OPTS แต่ให้แน่ใจว่าได้แสดงความคิดเห็น –Xms, -Xms ใน jvm.option หากคุณตั้ง env ตัวแปร
อย่างไรก็ตามเรามีหน่วยความจำ 64 GB ในกล่องและเราได้จัดสรรประมาณ 30 GB ให้กับ Elasticsearch ซึ่งจะถูกใช้โดยบริการอย่างเดียว เหตุใดเราจึงไม่จัดสรร 64GB ให้กับ Elasticsearch มันเป็นปัญหาที่พบบ่อยมาก
นอกเหนือจาก Elasticsearch แล้วยังมีอีกผู้ใช้หนึ่งของกองนี้คือ Lucene:
Lucene ถูกออกแบบมาเพื่อใช้ประโยชน์จากระบบปฏิบัติการพื้นฐานสำหรับการแคชโครงสร้างข้อมูลในหน่วยความจำ ส่วน Lucene ถูกเก็บไว้ในไฟล์แต่ละไฟล์ (เราจะวนรอบนี้ในจุดที่ 5) เนื่องจากเซกเมนต์ไม่เปลี่ยนแปลง ไฟล์เหล่านี้จึงไม่มีการเปลี่ยนแปลง สิ่งนี้ทำให้พวกเขาเป็นมิตรกับแคชมากและระบบปฏิบัติการพื้นฐานจะทำให้เซกเมนต์ที่อาศัยอยู่ในหน่วยความจำมีประสิทธิภาพดีสำหรับการเข้าถึงที่รวดเร็ว กลุ่มเหล่านี้มีทั้งดัชนีคว่ำ (สำหรับการค้นหาแบบเต็ม) และค่าเอกสาร (สำหรับการสรุปรวม)
ประสิทธิภาพของ Lucene ขึ้นอยู่กับการมีปฏิสัมพันธ์กับระบบปฏิบัติการนี้ แต่ถ้าคุณให้หน่วยความจำทั้งหมดที่มีให้กับกองของ Elasticsearch จะทำให้ Lucene ไม่มีหน่วยความจำเหลือ โดยสิ่งนี้สามารถส่งผลกระทบต่อประสิทธิภาพโดยเฉพาะอย่างยิ่งประสิทธิภาพการค้นหา ดังนั้นเราจึงทำให้มันสมดุล
สังเกตการใช้หน่วยความจำของฟรีและสังเกตการแลกเปลี่ยนพารามิเตอร์ที่ใช้

2. เธรดพูล

คลัง Elasticsearch มีกลุ่มหัวข้อต่างๆเช่นการเขียน, ค้นหา, ภาพรวม, ได้รับ ฯลฯ เพื่อจัดการปริมาณการใช้หน่วยความจำที่จัดสรรให้กับฮีป JVM แต่ละเธรดพูลจะมีจำนวนเธรดที่จัดสรรซึ่งจะพร้อมใช้งานสำหรับภารกิจที่กำหนดให้ดำเนินการสำหรับส่วนนั้นของเธรดพูล แต่ละพูลมีจำนวนเธรดที่จัดสรร ‘ขนาด’ และ ‘ขนาดคิว’
การตั้งค่าเริ่มต้นของเธรดพูลนั้นเป็นเวลาที่เหมาะสมที่สุดสำหรับเวิร์กโหลดหลายประเภท และคุณสามารถดูประสิทธิภาพของเธรดพูลในแบบสอบถามด้านล่าง แต่หากคุณต้องการเปลี่ยน (นี่เป็นการตั้งค่าขั้นสูงและไม่แนะนำ) คุณสามารถดูคิวและคอลัมน์ที่ถูกปฏิเสธในแบบสอบถามด้านล่าง หากเธรดพูลเฉพาะแสดงคิวที่ไม่ใช่ค่า 0 นั่นเป็นสัญญาณเตือนสำหรับงานนั้น (พูล) และหากถูกปฏิเสธแสดงว่าเป็นสัญญาณของการดำเนินการสำหรับภารกิจนั้น (กิจกรรม) โปรดจำไว้ว่าถ้าคุณเปลี่ยนการตั้งค่าเธรดพูลจะส่งผลกระทบต่องานอื่น ๆ (พูล) เช่นกัน
ajit blog img

3. การแลกเปลี่ยน

ตามที่กล่าวไว้ในข้อที่ 1 เราต้องจัดสรร RAM 50% ให้กับ JVM สำหรับ Elasticsearch และ Lucene ส่วนที่เหลือถูกใช้โดย Lucene บน ElasticSearch เฉพาะกล่อง แต่ระบบปฏิบัติการส่วนใหญ่เป็นหน่วยความจำที่หนักและมันจะพยายามที่จะแลกเปลี่ยนให้มากที่สุดเท่าที่แคชและเปลี่ยนหน่วยความจำแอปพลิเคชันที่ไม่ได้ใช้ ซึ่งอาจจะสลับหน้า JVM จากดิสก์
การแลกเปลี่ยนไม่ดีและนั่นเป็นเหตุผลว่ามันเป็นสิ่งสําคัญที่ต้องจับตาดู Swap ที่ใช้กับฟรี แต่คุณสามารถปิดการใช้งานการแลกเปลี่ยนเพื่อลดผลกระทบต่อ GC (Garbage Collection – เป็นบริการที่สำคัญซึ่งช่วยล้างข้อมูลบล็อกจากหน่วยความจำเพื่อให้มีที่ว่างสำหรับบล็อกย่อยของคุณ)
คุณสามารถตั้งค่า “# Sudo swapoff –a” บนกล่อง linux ซึ่งไม่ต้องรีสตาร์ท
หากต้องการปิดการใช้งานอย่างถาวรคุณจะต้องแก้ไขไฟล์ / etc / fstab และใส่เครื่องหมายความคิดเห็นในบรรทัดที่มีการสลับคำ
คุณสามารถตั้งค่าพารามิเตอร์ล็อคหน่วยความจำใน elasticsearch.yml ค่าเริ่มต้นจริง “bootstrap.memory_lock: true” คุณต้องรีสตาร์ทบริการ Elasticsearch เพื่อเปิดใช้งาน

4. ขนาดของ shards

คุณต้องใช้ shard ข้อมูลจำนวนเท่าใดสำหรับข้อมูลของคุณซึ่งจัดเก็บอยู่ในดัชนี Elasticsearch คำตอบคือขึ้นอยู่กับ shards เป็นหน่วยดัชนีที่เก็บข้อมูลจริงของคุณบนโหนดแบบกระจาย มีข้อสังเกตว่ามีชิ้นส่วนหนึ่งชิ้นที่ดีในการจัดเก็บประมาณ 30 GB – 50 GB (ต้องการให้ช่วงของข้อมูลประมาณ 20 GB – 35 GB) ของข้อมูลและคุณสามารถปรับดัชนีของคุณตามลำดับ สมมติว่าคุณมี RAM 64 GB ในแต่ละโหนดข้อมูลที่มีดิสก์ I /O ที่ดีและมี CPU เพียงพอ
การรู้ขนาดดัชนีของ Index ทำงานได้ดีขึ้นสำหรับข้อมูลคงที่ จากนั้นจะเป็นประโยชน์ในการตั้งค่าจำนวนพารามิเตอร์ของshards หากกรณีการใช้งานของคุณใช้สำหรับการวิเคราะห์ธุรกิจหรือการค้นหาระดับองค์กรซึ่งข้อมูลมาจากแหล่งข้อมูลคงที่ เช่น RDBMS ไฟล์ ฯลฯ และคุณรู้ว่าการบริโภคข้อมูลรายวัน / รายเดือน / รายปีพร้อมกับคำค้นหาของคุณนั้นเป็นเรื่องง่าย หากคุณรู้ว่าขนาดดัชนีของคุณจะเติบโตประมาณ 200 – 250 GB ต่อเดือน และทุกเดือนเป็นเอกสารสำคัญคุณสามารถตั้งค่าได้ประมาณ 5 – 6 shards ต่อดัชนี
แต่ถ้าคุณไม่แน่ใจเกี่ยวกับอัตราการบริโภคและอัตราการค้นหางานของคุณเพื่อการตั้งค่าจำนวนshard เป็นเรื่องยาก โดยเฉพาะอย่างยิ่งหากคุณมีกรณีการใช้งาน เช่น การเข้าสู่ระบบส่วนกลางสําหรับบริการที่แตกต่างกันและการตรวจสอบ การบันทึกจากส่วนกลางสำหรับบริการและแอปที่แตกต่างกันหรือการตรวจสอบข้อมูลโดยใช้ ELK และคุณกำลังใช้สิ่งที่แตกต่างกัน (เช่น metricbeat, filebeat, การเต้นของหัวใจ ฯลฯ) เมื่อดัชนีของคุณถูกสร้างขึ้นทุกวันมันเป็นเรื่องยากที่จะตั้งค่าจำนวน shard
จากประสบการณ์พบว่าหากคุณกำลังสร้างดัชนีรายวันสำหรับการสิ่งเหล่านี้ข้อมูลของคุณจะอยู่ที่ไม่กี่ GB (สูงสุด 2-4 GB) ต่อวัน/ต่อดัชนี ในกรณีนี้การตั้งค่าเริ่มต้นของคุณคือ number_of_shards: 5 คุณอาจต้องพิจารณาเปลี่ยนเป็น 1 (แทนที่จะเป็น 5) เพราะข้อมูลรายวันจะพอดีกับ 1 เศษและมันง่ายสำหรับ Elasticsearch ที่จะเขียนและอ่านข้อมูลจำนวนเล็กน้อยนี้เป็น 1 ชิ้นแทนที่จะเป็นจำนวนมาก
bootstrap.memory_lock: จริง
ในรุ่นล่าสุดของ Elasticsearch ตอนนี้ number_of_shards เริ่มต้นคือ 1
เมื่อกรณีการใช้งานเช่นการค้นหาระดับองค์กรหรือการค้นหาไซต์ที่มีจำนวนการร้องขอการค้นหาสูง (ว่ามากกว่า 500 – 1,000 การร้องขอการค้นหา/วินาที – ขึ้นอยู่กับกรณีการใช้งาน) ดังนั้นคุณอาจต้องพิจารณา shards แบบจำลองเพิ่มเติม สิ่งนี้จะช่วยในการให้บริการการอ่านข้อมูล/การร้องขอการค้นหาจากแบบจำลองการอ่านเหล่านี้
หากคุณกำลังตั้งค่าคลัสเตอร์หรือดัชนีใหม่คุณสามารถตั้งค่า number_of_replicas และ number_of_shard ที่ระดับดัชนีได้ง่าย แต่เพิ่ม number_of_shards และ number_of_replicas คุณสามารถตั้งค่านี้ในจังหวะหรือ logstash ที่คุณสร้างดัชนีหรือเพิ่มในแม่แบบดัชนี
แต่ถ้ามีดัชนีอยู่แล้วและตอนนี้กำลังเพิ่ม/ลดการจัดสรร shard จะต้องทำการคำนวณดัชนีโดยใช้
api _reindex

5. ขนาดของ Segment

ในข้อที่ 4 เราเห็นวิธีการจัดสรรจำนวน shard เพื่อปรับปรุงประสิทธิภาพการจัดทำดัชนี จากประสบการณ์โดยเฉพาะอย่างยิ่งเมื่อใช้กลุ่มขนาดใหญ่ที่มีการสร้างดัชนีรายวันฉันเห็นว่าอาจมีความเป็นไปได้ที่จะปรับปรุงประสิทธิภาพในระดับ ‘กลุ่ม’ ดัชนีเช่นกัน
“เซกเมนต์” เป็นดัชนี Lucene inverted คุณอาจสับสน คำว่า “ดัชนี” ใน Elasticsearch เป็นเหมือนฐานข้อมูล RDBMS ซึ่งเซ็กเมนต์นั้นเป็นดัชนีที่แท้จริงของคุณบนดิสก์ในแง่ของภาษา RDBMS
“เซกเมนต์” โดยทั่วไปจะเก็บสำเนาของเอกสารจริงในรูปแบบดัชนีคว่ำและมันจะทำเช่นนี้ในทุก “commit” หรือ “refresh” หรือ ” full buffer ” ช่วงเวลารีเฟรชเริ่มต้นคือ 1 วินาที
ยิ่งเซกเมนต์บนดิสก์มากเท่าไหร่ ยิ่งใช้เวลาในการค้นหานานเท่านั้น ดังนั้นเบื้องหลัง Lucene จึงทำเซกเมนต์ผสานสำหรับเซกเมนต์เหล่านั้น (จากแต่ละดัชนี) ซึ่งมีขนาดใกล้เคียงกัน ดังนั้นหากมีขนาดใกล้เคียงกัน 2 ส่วน Lucene จะรวมส่วน 2 ส่วนเหล่านี้และสร้างส่วนที่ 3 ใหม่ หลังจากกระบวนการผสานเซกเมนต์เก่าจะถูกทิ้ง กระบวนการนี้ซ้ำแล้วซ้ำอีก
เมื่อข้อมูลได้ถูกใช้/ล้างออกเป็นกลุ่ม จะสามารถค้นหาได้ ดังนั้นหากคุณใช้การตั้งค่าการรีเฟรชเริ่มต้นเช่น 1 วินาทีข้อมูลของคุณจะพร้อมใช้งานหลังจาก 1 วินาที แต่เนื่องจากมีหลายเซกเมนต์บนดิสก์และกระบวนการผสานซ้ำหลายครั้งจึงมีโอกาสที่จะทำให้ประสิทธิภาพการค้นหาลดลง หากคุณไม่ต้องการให้ข้อมูลพร้อมใช้งานสำหรับทุกๆ 1 วินาทีที่เพิ่งติดเครื่องและไม่ต้องรออีกสองสามวินาทีในการแลกเปลี่ยนเพื่อปรับปรุงประสิทธิภาพการค้นหาของคุณโดยลดจำนวนเซ็กเมนต์บนดิสก์ (และรวมน้อยกว่าทุกวินาที) ฉันอยากจะแนะนำให้ตั้งค่า index.refresh_interval เป็น 30 วินาทีแทนที่จะเป็นค่าเริ่มต้น 1 วินาทีคุณสามารถตั้งค่าพารามิเตอร์นี้ที่ระดับดัชนี
ขอแนะนำให้เปลี่ยนหน่วยความจำบัฟเฟอร์ดัชนีเพื่อเก็บข้อมูลลงในบัฟเฟอร์ดัชนีมากขึ้น ถ้าคุณเปลี่ยนช่วงเวลารีเฟรชจากค่าเริ่มต้น 10% เป็น 20% สิ่งนี้จะให้พื้นที่เพิ่มเติมสำหรับการจัดทำดัชนีในบัฟเฟอร์ คุณสามารถตั้งค่า indices.memory.index_buffer_size นี้: 20% สำหรับแต่ละระดับโหนด
ฉันยังคงเน้นเกี่ยวกับพารามิเตอร์ที่ต้องพิจารณาเพื่อปรับปรุงประสิทธิภาพโดยรวม elasticsearch คลัสเตอร์ในบทความนี้ในส่วนที่ 2 คอยติดตามบทความในหัวข้อต่อไป!
สัมมนาสดทางออนไลน์ : วิธีตรวจสอบการใช้งาน Container, Kubernetes และ OpenShift โดยใช้ Elastic Stack – การสร้างแพลตฟอร์มโดยใช้ Elastic Stack สำหรับองค์กรที่ซับซ้อน
เข้าร่วมการสัมมนาออนไลน์ของเรา: ลงทะเบียน


Go to Top