Trik kecil dengan Elasticsearch

Catatan singkat, bukan untuk saya sendiri, tentang trik kecil untuk pemulihan data di Elasticsearch. Bagaimana cara memperbaiki indeks merah jika tidak ada cadangan, apa yang harus dilakukan jika saya menghapus dokumen, dan tidak ada salinan yang tersisa - sayangnya dalam dokumentasi resmi mereka diam tentang fitur ini.

Cadangan




Hal pertama yang harus dilakukan adalah mengatur cadangan data penting. Cara ini dilakukan dijelaskan dalam dokumentasi resmi .

Secara keseluruhan, tidak ada yang rumit. Dalam versi paling sederhana, buat bola di server lain, pasang ke semua simpul elastis dengan cara yang nyaman (nfs, smbfs, apa pun). Selanjutnya, gunakan cron, aplikasi Anda atau apa pun untuk mengirim permintaan foto berkala.

Cuplikan pertama akan panjang, yang berikutnya hanya akan berisi delta antara status indeks. Perhatikan bahwa jika Anda melakukan berkala forcemerge, delta akan menjadi waktu yang sangat besar dan, sesuai, snapshot akan jauh seperti pertama kali.

Apa yang harus dipertimbangkan:

  • Periksa status cadangan, misalnya menggunakan _cat: curl localhost:9200/_cat/snapshots/ yourbackuprepo / . Jepretan sebagian atau Gagal bukanlah milik Anda.
  • Dimulai dengan ES 6.x, elastis sangat menuntut header permintaan. Jika Anda melakukannya secara manual (bukan melalui API), periksa apakah Anda memiliki Content-Type: application/json , jika tidak semua permintaan Anda terputus dan cadangan tidak terjadi
  • Snapshot tidak dapat dikembalikan ke indeks terbuka. Itu harus ditutup atau dihapus terlebih dahulu. Namun, Anda dapat memulihkan snapshot berdampingan menggunakan rename_pattern, rename_replacement ( lihat contoh di dok ). Selain itu, ketika foto dipulihkan, pengaturannya juga dipulihkan, termasuk alias, jumlah replika, dll. Jika Anda tidak membutuhkan ini, tambahkan index_settings ( lihat dock sebagai contoh ) dengan perubahan yang diperlukan pada permintaan pengembalian.
  • Repos (bola) dengan snapshot dapat dihubungkan ke lebih dari satu cluster dan mengembalikan snapshots dari cluster mana saja ke cluster lainnya. Yang utama adalah versi elastisnya kompatibel.

Secara umum, lihat dokumentasi, ada topik ini lebih atau kurang diungkapkan.

Elasticdump




Utilitas kecil pada nodejs yang memungkinkan Anda untuk menyalin data dari satu indeks ke indeks lain, cluster, file, stdout.

Ngomong-ngomong, output ke file atau stdout dapat digunakan sebagai metode cadangan alternatif - outputnya adalah json valid reguler (sesuatu seperti sql dump), yang dapat digunakan kembali seperti yang Anda inginkan. Misalnya, Anda bisa menempelkan output dalam pipa, di mana skrip Anda entah bagaimana akan mengubah data dan mengirimkannya ke repositori lain, seperti clickhouse. Konversi js paling sederhana dapat dilakukan secara langsung dengan elasticdump itu sendiri, ada kunci yang sesuai --transformasi . Secara umum, penerbangan mewah.

Dari perangkap:

  • Sebagai metode cadangan, ini jauh lebih lambat daripada snapshot. Plus, cadangan diperpanjang dari waktu ke waktu, sehingga hasil pada indeks yang sering berubah mungkin tidak konsisten. Ingatlah selalu.
  • Jangan gunakan nodejs dari repositori debian, ada terlalu lama versi yang secara negatif mempengaruhi stabilitas alat.
  • Stabilitas dapat bervariasi, terutama jika salah satu pihak kelebihan beban. Jangan mencoba mem-backup dari satu server ke server lain dengan menjalankan alat di mesin kantor - semua lalu lintas akan mengalir melaluinya.
  • Gambar menyalin pemetaan. Jika Anda memiliki sesuatu yang rumit di sana, buatlah indeks secara manual, dan baru kemudian isikan data ke dalamnya.
  • Terkadang masuk akal untuk mengubah ukuran chunk (parameter --limit). Opsi ini secara langsung memengaruhi kecepatan penyalinan.

Untuk menggabungkan sejumlah besar indeks pada saat yang sama, ada multielasticdump dengan serangkaian opsi yang disederhanakan, tetapi semua indeks bergabung secara paralel.

Catat! Penulis utilitas mengatakan bahwa ia tidak lagi memiliki waktu untuk mendukung, sehingga program mencari pengelola baru .

Dari pengalaman pribadi: utilitas bermanfaat, diselamatkan lebih dari sekali. Kecepatan dan stabilitasnya begitu-begitu, saya ingin penggantian yang memadai, tetapi sejauh ini tidak ada yang ada di cakrawala.

Periksaindeks


Jadi, kita mulai mendekati sisi gelap. Situasi: indeks sudah merah. Dalam log - ada yang salah, cek tidak sesuai dengan jumlah, Anda mungkin mendapat memori atau disk:

org.apache.lucene.index.CorruptIndexException: checksum failed (hardware problem?)

Tentu saja, ini tidak pernah terjadi dengan admin ibu, karena mereka memiliki perangkat keras kelas atas dengan replikasi tiga kali lipat, memori superECC dengan koreksi benar-benar semua tingkat kesalahan dengan cepat, dan umumnya snapshot dikonfigurasikan setiap detik.

Tetapi kenyataan sayangnya kadang-kadang meminta opsi seperti itu, ketika cadangan relatif lama (jika Anda memiliki gigabytes per jam diindeks, apakah cadangan terlalu lama 2 jam yang lalu?), Tidak ada tempat untuk memulihkan data, replikasi tidak punya waktu dan hal-hal seperti itu.

Tentu saja, jika ada snapshot, backup atau sejenisnya. - Luar biasa, bangun dan jangan khawatir. Dan jika tidak? Untungnya, setidaknya beberapa data masih bisa disimpan.

Pertama-tama, tutup indeks dan / atau matikan elastisnya, buat salinan cadangan pecahan yang gagal.

Lucene (yaitu berfungsi sebagai backend dalam elasticsearch) memiliki metode CheckIndex yang luar biasa. Kita hanya perlu memanggilnya karena pecahannya. Lucene akan memeriksa semua segmennya dan menghapus yang rusak. Ya, data akan hilang, tetapi setidaknya tidak semuanya. Meskipun ada betapa beruntungnya itu.

Setidaknya ada 2 cara.

Metode 1: Langsung di situs


Script yang begitu sederhana akan membantu kita.

 #!/bin/bash pushd /usr/share/elasticsearch/lib java -cp lucene-core*.jar -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex "$@" popd 

Menyebutnya tanpa parameter, kami mendapatkan sesuatu seperti ini:

 ERROR: index path not specified Usage: java org.apache.lucene.index.CheckIndex pathToIndex [-exorcise] [-crossCheckTermVectors] [-segment X] [-segment Y] [-dir-impl X] -exorcise: actually write a new segments_N file, removing any problematic segments -fast: just verify file checksums, omitting logical integrity checks -crossCheckTermVectors: verifies that term vectors match postings; THIS IS VERY SLOW! -codec X: when exorcising, codec to write the new segments_N file with -verbose: print additional details -segment X: only check the specified segments. This can be specified multiple times, to check more than one segment, eg '-segment _2 -segment _a'. You can't use this with the -exorcise option -dir-impl X: use a specific FSDirectory implementation. If no package is specified the org.apache.lucene.store package will be used. **WARNING**: -exorcise *LOSES DATA*. This should only be used on an emergency basis as it will cause documents (perhaps many) to be permanently removed from the index. Always make a backup copy of your index before running this! Do not run this tool on an index that is actively being written to. You have been warned! Run without -exorcise, this tool will open the index, report version information and report any exceptions it hits and what action it would take if -exorcise were specified. With -exorcise, this tool will remove any segments that have issues and write a new segments_N file. This means all documents contained in the affected segments will be removed. This tool exits with exit code 1 if the index cannot be opened or has any corruption, else 0. 

Sebenarnya, kita bisa menjalankan tes indeks, atau membuat CheckIndex "memperbaikinya", memotong semua yang rusak.

Indeks Lucene hidup dalam kira-kira dengan cara yang sama: / var / lib / elasticsearch / node / 0 / indexes / str4ngEHashVa1uE / 0 / index /, di mana 0 dan 0 adalah nomor node pada server dan jumlah shard pada node. Nilai menakutkan di antara mereka - nama internal indeks - dapat diperoleh dari output lokal curl: 9200 / _cat / indeks.

Saya biasanya membuat salinan ke direktori lain, dan memperbaiki di tempat. Kemudian saya memulai kembali elasticsearch. Sebagai aturan, semuanya diambil, meskipun dengan kehilangan data. Terkadang indeks masih tidak ingin dibaca karena file * rusak * di folder pecahan. Pindahkan mereka ke tempat yang aman untuk sementara waktu.

Metode 2: Luke



(gambar dari Internet)

Ada utilitas bagus untuk bekerja dengan Lucene yang disebut Luke .

Masih lebih sederhana di sini. Cari tahu versi Lucene dari elasticsearch Anda:

 $ curl localhost:9200 { "name" : "node00", "cluster_name" : "main", "cluster_uuid" : "UCbEivvLTcyWSQElOipgTQ", "version" : { "number" : "6.2.4", "build_hash" : "ccec39f", "build_date" : "2018-04-12T20:37:28.497551Z", "build_snapshot" : false, "lucene_version" : "7.2.1", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" } 

Ambil versi Lukas yang sama. Kami membuka di dalamnya indeks (salinan tentu saja) dengan daw Jangan buka IndexReader (saat membuka indeks rusak) . Selanjutnya, klik Alat / Periksa Indeks. Pertama saya sarankan untuk menjalankan kering, dan hanya dalam mode perbaikan. Tindakan selanjutnya serupa - salin kembali elastis, restart / buka indeks.

Pulihkan Dokumen yang Dihapus


Situasi: Anda melakukan kueri destruktif yang menghapus banyak / semua data yang Anda butuhkan. Dan tidak ada tempat untuk mengembalikan, atau sangat mahal. Yah, tentu saja, SSZB bahwa tidak ada cadangan, tetapi ini juga terjadi.

Sayangnya atau untungnya, Lucene tidak pernah menghapus apa pun secara langsung. Filosofinya lebih dekat dengan Kontrak Karya, sehingga data yang dihapus sebenarnya tidak dihapus, tetapi hanya ditandai sebagai yang dihapus. Penghapusan itu sendiri terjadi selama optimasi indeks - data langsung dari segmen disalin ke segmen yang baru dibuat, segmen lama hanya dihapus. Secara umum, sementara status indeks yang dihapus bukan 0, ada peluang untuk mengeluarkannya.

 $ curl localhost:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open data.0 R0fgvfPnTUaoI2KKyQsgdg 5 1 7238685 1291566 45.1gb 22.6gb 

Setelah dipenjara tidak ada kesempatan.

Jadi, pertama-tama, tutup indeks, hentikan elastis, salin indeks (file) ke tempat yang aman.

Tidak mungkin mengeluarkan dokumen yang dihapus secara individu. Anda hanya dapat memulihkan semua dokumen yang dihapus di segmen yang ditentukan.

Untuk versi Lucene di bawah 4, semuanya sangat sederhana. API Lucene memiliki fungsi yang disebut undeleteAll. Anda dapat memanggilnya langsung dari Luke dari paragraf sebelumnya.

Untuk versi yang lebih baru, sayangnya, fungsionalitasnya terpotong. Tapi tetap saja masih ada jalan. Informasi tentang dokumen langsung disimpan dalam file * .liv. Namun, menghapusnya saja akan membuat indeks tidak dapat dibaca. Diperlukan untuk memperbaiki file segment_N sehingga benar-benar lupa tentang keberadaan mereka.

Buka file segment_N (N adalah bilangan bulat) di Hex editor favorit Anda. Dokumentasi resmi akan membantu kami menavigasi:
 segments_N: Header, LuceneVersion, Version, NameCounter, SegCount, MinSegmentLuceneVersion, <SegName, SegID, SegCodec, DelGen, DeletionCount, FieldInfosGen, DocValuesGen, UpdatesFiles>SegCount, CommitUserData, Footer 

Dari semua ini, kita membutuhkan nilai DelGen (Int64) dan DeletionCount (Int32). Yang pertama harus ditetapkan sama dengan -1, dan yang kedua 0.



Tidak sulit untuk menemukan mereka, mereka tepat di belakang SegCodec, yang merupakan string yang sangat mencolok seperti Lucene62. Dalam tangkapan layar ini, Anda dapat melihat bahwa DelGen memiliki nilai 3, dan DeletionCount - 184614. Kami mengganti yang pertama dengan 0xFFFFFFFFFFFFFFFFFF, dan yang kedua dengan 0x00000000. Ulangi untuk semua segmen yang diperlukan, simpan.

Namun, indeks tetap tidak akan mau memuat, mengutip kesalahan checksum. Masih lebih sederhana di sini. Ambil Luke, muat indeks dengan IndexReader yang dinonaktifkan, Alat / Periksa Indeks. Kami melakukan uji coba dan segera mengetahui bahwa segment_N rusak. Pemeriksaan ini dan itu diharapkan, tetapi ini dan itu diterima.

 Caused by: org.apache.lucene.index.CorruptIndexException: checksum failed (hardware problem?) : expected=51fbdb5c actual=6e964d17 

Omong kosong! Kami mengambil checksum yang diharapkan dan memasukkannya dalam 4 byte terakhir file.



Simpan. Kami menjalankan CheckIndex lagi untuk memastikan semuanya OK dan indeks sedang memuat.

Dan lagi!

Source: https://habr.com/ru/post/id416955/


All Articles