No Comments

Bahasa Blog: Tips Peningkatan Kinerja di Elasticsearch, BAGIAN 1

Ajit Gadge | Senior Database Consultant, Ashnik
Singapur, 22 Aug 2019
Ajit-FImg

by , , No Comments

22-Aug-2019

Pada artikel saya sebelumnya, saya menulis tentang ukuran klaster ELK dan membawa Anda melewati bermacam faktor sebagai pertimbangan saat Anda menyiapkan gugus ELK. Hari ini, saya akan membahas bagaimana kita bisa meningkatkan kinerja Elasticsearch terutama ketika Anda sudah dalam produksi (atau berencana untuk segera meluncurkan produk). Di bawah pengaturan Elasticsearch standar, jika Anda tidak mendapat kinerja yang diinginkan, Anda perlu memperhatikan beberapa hal pada:

1:  Alokasi Memori

Kita butuh hasil pencarian yang relevan dan lebih cepat. Karenanya memori dan masuk keluarnya data dari memori sekunder memainkan peran yang sangat penting.

Disarankan punya RAM 64 GB dengan penyimpanan SSD. Tetapi dimungkinkan pula dengan kapasitas memori lebih kecil dan harddisk (memori sekunder) lebih cepat yang sebanding dengan beban kerja dan banyaknya simpul data.

Elasticsearch berjalan pada proses bahasa pemrograman Java sehingga sangat penting untuk mengatur ketepatan jumlah JVM (Java Virtual Machine) ke simpul data. Disarankan untuk mengatur sedikit kurang dari 50% RAM ke JVM heap. Contoh: Jika Anda memiliki 64 GB RAM pada kotak simpul data elasticsearch, disarankan untuk mengatur sekitar 30 GB dan tidak lebih dari 32 GB.

Anda dapat mengatur hal ini di Xms dan Xmx dalam berkas jvm.option seperti

–Xms30g

–Xmx30g

Anda juga dapat mengatur ukuran memori heap (region pada memori yang tidak dimanage secara otomatis) menjadi variabel lingkungan dengan mengatur parameter ES_JAVA_OPTS. Tetapi pastikan Anda menguraikan –Xms, -Xms di jvm.option jika Anda menetapkan variabel lingkungan.

Tetapi kita memiliki RAM 64 GB dan telah kita alokasikan sekitar 30 GB untuk Elasticsearch yang akan digunakan oleh layanan saja. Jadi mengapa kita tidak mengalokasikan seluruh 64 GB untuk Elasticsearch? Ini adalah pertanyaan yang sangat umum saya jumpai..

Selain Elasticsearch, ada pengguna lain dari heap, yakni Lucene:

Lucene dirancang untuk meningkatkan layanan sistem operasi guna mengecilkan struktur data dalam memori. Segmen Lucene disimpan dalam berkas individual (kita akan merincinya pada poin No.5). Karena segmen bersifat tetap, maka berkas-berkas tersebut tidak pernah berubah. Ini membuat mereka sangat gampang dikecilkan, dan sistem operasi akan dengan senang hati menyimpan segmen-segmen premium ini dalam memori guna akses lebih cepat. Segmen-segmen ini mencakup indeks terbalik (untuk pencarian teks lengkap) dan nilai dokumen (untuk agregasi).

Kinerja Lucene bergantung pada interaksi tersebut dengan sistem operasi. Tetapi jika Anda memberikan semua memori yang tersedia ke heap Elasticsearch, tidak akan ada yang tersisa untuk Lucene. Ini dapat berakibat fatal pada kinerja terutama kinerja pencarian Anda. Karenanya, kami menyeimbangkannya.

Cobalah untuk mengawasi penggunaan memori dengan free –m dan amati pertukaran parameter yang digunakan.

2: Fitur thread pool

Simpul Elasticsearch memiliki berbagai kumpulan thread (unit dasar dari penggunaan CPU) seperti perintah tulis (write), pencarian (search), snapshot, get dll untuk mengelola konsumsi memori yang dialokasikan bagi heap JVM. Setiap thread pool (cara kerja dengan membuat beberapa thread pada proses startup dan menempatkan mereka ke pool) akan memiliki sejumlah thread teralokasi yang pada gilirannya tersedia untuk tugas yang diberikan. Setiap pool memiliki nomor alokasi dari thread ‘UKURAN’ dan ‘ukuran antrian’nya.

Pengaturan standar dari thread pool nyaris sempurna untuk banyak tipe beban kerja dan Anda dapat melihat kinerja thread pool ini di kueri dalam tampilan di bawah. Tetapi jika Anda ingin mengubahnya (ini adalah pengaturan lanjut dan tidak disarankan), Anda dapat melihat antrian dan kolom yang ditolak dalam kueri di bawah ini. Jika sebagian thread pool menampilkan antrian nilai bukan 0 maka itu adalah tanda peringatan untuk tugas tersebut dan jika ditolak maka itu adalah tanda bahwa ada tindakan yang diambil untuk aktivitas tersebut. Ingat, jika Anda mengubah pengaturan thread pool, maka akan memengaruhi tugas-tugas lainnya pula.

3: Swapping

Seperti ditulis dalam poin No.1, kita perlu mengalokasikan 50% RAM untuk JVM bagi Elasticsearch dan sisanya digunakan oleh Lucene pada dedicated box (terpisah dan berdiri sendiri) dari Elasticsearch. Namun mayoritas sistem operasi itu rakus memori dan akan mencoba untuk menukar sebanyak mungkin memori di cache dan memori aplikasi yang tidak digunakan. Mungkin pula telah menukar halaman JVM sebagaimana juga dari memori sekunder.
Swapping (atau bertukar) itu hal buruk dan sebab itu dianggap penting untuk mengawasi Swap yang digunakan dengan free -m. Tetapi Anda dapat menon-aktifkan swapping guna mengurangi dampak pada GC (Garbage Collection alias Pengumpulan Sampah – ini adalah layanan penting yang membantu membersihkan blok memori guna memberikan ruang bagi blok baru Anda).

Anda bisa mengatur:

# Sudo swapoff –a

di kotak linux yang tidak memerlukan restart.

Untuk menonaktifkannya secara permanen, Anda perlu mengedit berkas etc/fstab dan mengomentari setiap baris yang mengandung kata swap.

Anda dapat menetapkan parameter kunci memori di elasticsearch.yml. Nilai default-nya true.

bootstrap.memory_lock: true

Anda harus restart layanan Elasticsearch untuk mengaktifkannya.

4: Besaran Shard

Berapa banyak shard (kontainer data yang merupakan instance dari Apache Lucene) yang Anda butuhkan untuk data Anda yang disimpan dalam indeks Elasticsearch? Jawaban: tergantung! Shard merupakan unit dari indeks yang menyimpan data aktual Anda pada titik terdistribusi. Diamati bahwa satu shard bagus untuk menyimpan sekitar 30 GB – 50 GB (saya cenderung lebih suka di kisaran sekitar 20 GB – 35 GB) data dan karenanya Anda dapat mengukur kesesuaian indeks Anda. Dengan asumsi Anda memiliki 64 GB RAM pada setiap titik data dengan disk I/O yang baik dan CPU yang memadai.

Mengetahui ukuran indeks Anda bakal bermanfaat lebih bagus untuk data permanen, dan sangat membantu guna menetapkan parameter number_of_shard. Jika kasus penggunaan Anda untuk analisis bisnis atau pencarian perusahaan, di mana data berasal dari sumber permanen semacam RDBMS, berkas, dll. dan Anda mengetahui konsumsi data harian/bulanan/tahunan bersama dengan permintaan pencarian Anda, maka gampanglah untuk mengatur shard. Jika Anda tahu bahwa ukuran indeks Anda akan tumbuh sekitar 200-250 GB per bulan dan setiap bulan ada pengarsipan, maka Anda dapat menetapkan sekitar 5 – 6 shard per indeks.

Tetapi jika Anda tidak yakin tentang tingkat konsumsi dan pencarian Anda, maka tugas Anda bakal sulit untuk mengatur jumlah shard. Terutama jika Anda menggunakan kasus-kasus seperti log-in terpusat untuk berbagai layanan dan aplikasi atau pemantauan infra menggunakan ELK (Elasticsearch, Logstash, dan Kibana) dan Anda menggunakan beat berbeda (seperti metricbeat, filebeat, heartbeat dsb). Ketika indeks Anda dibuat setiap hari, maka bakal sulit untuk mengatur jumlah shard.

Berdasarkan pengalaman, saya telah mengamati bahwa jika Anda membuat indeks harian untuk beat tersebut, maka data Anda besarnya sekitar beberapa GB (2-4 GB maks) per hari / per indeks. Dalam hal ini, pengaturan standar number_of_shards: 5 tidak akan berfungsi. Anda mungkin perlu mempertimbangkan untuk mengubah ke 1 (bukan 5). Karena data harian akan lebih mudah masuk ke dalam 1 shard dan gampang bagi Elasticsearch untuk menulis dan membaca sejumlah kecil data ini menjadi 1 shard, bukan banyak.

bootstrap.memory_lock: true

Dalam versi terbaru dari Elasticsearch, sekarang standar number_of_shards adalah 1.

Ketika Anda menggunakan kasus seperti pencarian perusahaan atau situs di mana jumlah permintaan pencarian tinggi (saya akan mengatakan lebih dari 500 – 1000 permintaan pencarian/detik – tergantung dari kasus penggunaan) maka Anda mungkin perlu mempertimbangkan lebih banyak jumlah replika shard. Ini bakal membantu untuk melayani permintaan baca data / permintaan pencarian dari replika baca ini.

Jika Anda mengatur klaster atau indeks baru, maka mudah untuk mengatur number_of_replicas dan number_of_shard pada tingkat indeks dengan menambahkan number_of_shards dan number_of_replicas. Anda dapat mengatur ini dalam beat atau logstash di mana Anda membuat indeks atau menambahkannya di templat indeks.

Tetapi jika Anda sudah memiliki indeks dan sekarang meningkatkan / mengurangi alokasi shard Anda, maka Anda perlu melakukan pengindeksan ulang using_reindex API.

.
5: Ukuran segmen

Di poin no. 4, kita melihat bagaimana mengalokasikan jumlah shard untuk meningkatkan kinerja pengindeksan. Sesuai pengalaman, terutama dalam implementasi klaster besar dengan peyusunan indeks harian, saya telah melihat juga adanya kemungkinan untuk meningkatkan lebih banyak kinerja di tingkat indeks ‘segment’.

‘Segment’ merupakan indeks J terbalik pada Lucene. Anda mungkin bingung, saya paham. Istilah “Index” di Elasticsearch itu laksana basis data RDBMS di mana segmen tersebut adalah indeks aktual Anda pada memori sekunder dalam hal bahasa RDBMS.

“Segment” pada dasarnya menyimpan salinan dokumen nyata dalam wujud indeks terbalik dan melakukan ini di setiap “commit” atau “refresh interval” atau “full buffer”. Nilai standar “refresh interval” adalah 1s (1 detik).

Semakin banyak segmen pada memori sekunder, semakin lama pula setiap pencarian. Di belakang layar, Lucene melakukan proses penggabungan segmen untuk segmen (dari setiap indeks) dengan ukuran yang sama. Jadi jika ada 2 segmen dengan ukuran yang sama, Lucene menggabungkan 2 segmen ini dan menciptakan segmen ke-3 yang baru. Setelah proses penggabungan, segmen lama dibuang. Proses ini berulang.

Setelah data menjadi segmen, maka ia tersedia untuk pencarian. Jadi, jika Anda berada di standar pengaturan 1s maka data Anda akan tersedia setelah 1s. Tetapi karena banyaknya segmen pada memori sekunder dan berulangnya proses penggabungan, mungkin saja terjadi pengurangan kinerja pencarian Anda. Jika Anda tidak menghendaki datanya tersedia setiap 1 detik maka relakan menunggu beberapa detik guna ditukar dengan peningkatan kinerja pencarian, yaitu dengan mereduksi jumlah segmen di memori sekunder (dan mengurangi penggabungan setiap detiknya), maka saya rekomendasi Anda guna mengatur index.refresh_interval menjadi 30s, menggantikan standar 1s. Anda dapat mengatur parameter ini pada level indeks.

Saya juga merekomendasikan untuk mengubah indeks di memori buffer untuk menahan lebih banyak data ke dalam buffer indeks jika Anda mengubah refresh-interval dari standar 10% menjadi 20%. Ini akan memberi lebih banyak ruang untuk pengindeksan dalam buffer. Anda dapat mengatur hal ini pada setiap tingkat simpul indexes.memory.index_buffer_size: 20%.

Saya juga akan menyoroti parameter yang harus dipertimbangkan untuk meningkatkan kinerja keseluruhan klaster Elasticsearch, pada bagian 2 artikel ini. Nantikan edisi berikutnya!

0
0

  • Ajit brings over 16 years of solid experience in solution architecting and implementation. He has successfully delivered solutions on various database technologies including PostgreSQL, MySQL, SQLServer. His derives his strength from his passion for database technologies and love of pre-sales engagement with customers. Ajit has successfully engaged with customers from across the globe including South East Asia, USA and India. His commitment and ability to find solutions has earned him great respect from customers. Prior to Ashnik he has worked with EnterpriseDB for 7 years and helped it grow in South East Asia and India

More From Ajit Gadge | Senior Database Consultant, Ashnik :
22-Aug-2019