lucene索引_在崩溃或断电后测试Lucene的索引耐久性
lucene索引
Lucene有用的事務功能之一是索引持久性 ,它可以確保一旦成功調用IndexWriter.commit ,即使操作系統或JVM崩潰或斷電,或者您殺死-KILL JVM進程,重啟后索引也將保持完整(未損壞),并將反映崩潰前的最后一次成功提交。
當然,這僅在硬件運行狀況良好且IO設備正確實現fsync(在操作系統要求時刷新其寫緩存)的情況下才有效。 如果您遇到數據丟失的問題,例如內存,IO或CPU路徑中的靜默位翻轉器,則得益于Lucene 4.8.0和Lucene中提供的新的端到端校驗和功能 ( LUCENE-2446 )現在在索引或CheckIndex期間也將檢測到該CheckIndex 。 這類似于ZFS文件系統的塊級校驗和,但并不是每個人都使用ZFS(呵呵),因此Lucene現在在文件系統之上進行自己的校驗和驗證。
確保通過調用IndexWriterConfig.setCheckIntegrityAtMerge啟用合并期間的校驗和驗證。 將來,我們希望刪除該選項,并始終在合并時驗證校驗和,并且我們已經對LUCENE-5580中的默認存儲字段格式和LUCENE-5602中的 (很快)術語向量格式以及設置低級IO API,以便其他編解碼器組件也可以使用LUCENE-5583 (適用于Lucene 4.8.0)做到這一點。
FileDescriptor.sync和fsync
在后臺,當您調用IndexWriter.commit ,Lucene將收集自上次提交以來所有新寫入的文件名,并在每個文件名上調用FileDescriptor.sync以確保所有更改都移至穩定的存儲中。
從本質上講 , fsync是一項復雜的操作,因為操作系統必須從其IO緩沖區高速緩存中清除與指定文件關聯的所有臟頁,并與基礎IO設備一起使用,以確保也清除了它們的寫高速緩存,并且還可以正常工作文件系統以確保其完整性得以保留。 您可以單獨同步文件的字節或元數據,也可以同步包含文件的目錄。
這篇博客文章很好地說明了挑戰。
最近,我們一直在仔細研究Lucene的這些部分,所有這些注意都發現了一些令人興奮的問題!
在LUCENE-5570 (將在Lucene 4.7.2中修復)中,我們發現FSDirectory實現中的fsync實現能夠引入新的0字節文件。 通常,這本身并不是問題,因為IndexWriter不應同步未創建的文件。 但是,當使用Lucene的IndexWriter或應用程序中存在錯誤時(例如,直接刪除不應刪除的索引文件),則會加劇調試。 在這些情況下,這么長時間后才發現這些0字節的文件會令人困惑,而不是在IndexWriter嘗試對它們進行同步時命中FileNotFoundException 。
在LUCENE-5588 (要在Lucene 4.8.0中修復)中,我們意識到我們還必須同步包含索引的目錄,否則在操作系統崩潰或斷電時,該目錄可能不會鏈接到新創建的文件,或者您將無法通過文件名查找文件。 這顯然很重要,因為Lucene會列出目錄以查找所有提交點( segments_N文件),并且當然還會按文件名打開文件。
由于Lucene不依賴文件元數據(例如訪問時間和修改時間),因此很容易使用fdatasync (或Java中的FileChannel.force(false) )來僅同步文件的字節。 但是,這是一種優化,目前我們專注于錯誤。 此外,這可能不會更快,因為如果文件長度已更改,則元數據仍必須由fdatasync進行同步,這在Lucene中通常是這樣,因為我們僅在寫入時才附加到文件(我們刪除了Indexoutput.seek在LUCENE-4399中 )。
在LUCENE-5574 (從Lucene 4.7.2開始修復)中,我們發現關閉時接近實時的讀取器可以刪除文件,即使從中打開的寫入器已經關閉。 通常,這本身就不是問題,因為只要使用Lucene的API并且不自己修改索引文件,Lucene就會一次寫入(一次不會多次寫入同一個文件名)。 但是,如果通過將文件復制到索引中來實現自己的索引復制,并且如果您不先關閉近實時讀取器,則關閉它們可能會刪除剛復制的文件。
在任何給定的索引編制會話期間,Lucene都會寫入并關閉許多文件,合并后會刪除許多文件, IndexWriter.commit ,直到以后,當應用程序最終調用IndexWriter.commit , IndexWriter才會按順序重新打開新創建的文件。獲取FileDescriptor,以便我們對其進行fsync 。
這種方法(關閉原始文件,然后再打開以進行同步),而不是從不關閉原始文件并同步您用于寫入的相同文件句柄,這種方法可能是冒險的: FileDescriptor.sync的javadocs有點模糊關于這種方法是否安全。 但是,當我們查看Unix / Posix上的fsync和Windows上的FlushFileBuffers的文檔時,他們清楚地表明這種做法很好,因為打開文件描述符實際上僅是確定要同步哪個文件的緩沖區所必需的。 很難想象會有一個操作系統單獨跟蹤哪個打開的文件描述符對文件進行了哪些更改。 但是,出于偏執狂或謹慎起見,我們還在探索LUCENE-3237上可能的補丁程序,以僅同步最初打開的文件。
測試fsync確實有效
在應用程序對IndexWriter.commit的調用與物理定律之間的所有這些復雜層之間,確保了很少的磁體被翻轉或少數電子被移動到NAND單元中的微小浮動柵中 ,我們如何才能可靠地測試整個序列抽象實際上在起作用嗎?
在Lucene的隨機測試框架中,我們有一個稱為MockDirectoryWrapper的不錯的Directory實現。 它可以做各種令人討厭的事情,例如引發隨機異常,有時會減慢某些文件的打開,關閉和寫入速度,拒絕刪除仍在打開的文件(例如Windows),在仍然有打開的文件時拒絕關閉等。隨著時間的推移,它幫助我們發現了各種有趣的錯誤。
它關閉時要做的另一件事是通過隨機破壞任何未壓縮的文件來模擬操作系統崩潰或斷電,然后確認索引沒有破壞。 這對于捕獲Lucene錯誤很有用,因為我們本應在適當的時候調用fsync失敗,但不會捕獲FSDirectory類中的sync實現中的錯誤,例如令人沮喪的LUCENE-3418 (最初出現在Lucene 3.1中,最后出現在在Lucene 3.4中修復)。
因此,為了捕獲此類錯誤,我創建了一個基本的測試設置,使用了一個簡單的Insteon 開/關設備以及我很久以前創建的與Insteon設備進行交互的自定義??Python綁定。 我已經在家中各處使用這些設備來控制燈光和電器,因此將其用于Lucene也是我兩個熱情的完美結合!
該腳本將永遠循環,首先更新源代碼,進行編譯,檢查索引是否損壞,然后在設置中進行一些隨機化后開始索引運行,最后等待幾分鐘,然后切斷電源。 然后,它恢復電源,等待機器再次響應,然后再次啟動。
到目前為止,已經完成了80個電源循環,而且還沒有損壞。 好消息!
為了“測試測試人員”,我嘗試臨時更改fsync使其不執行任何操作,實際上,經過幾次迭代,索引已損壞。 因此確實,測試設置似乎“有效”。
目前,該測試在帶有ext4文件系統的旋轉磁鐵硬盤上使用Linux。 這僅僅是一個開始,但是總比沒有對Lucene的fsync進行適當的測試要好。 隨著時間的流逝,我希望測試操作系統,文件系統,IO硬件等的不同組合。
翻譯自: https://www.javacodegeeks.com/2014/04/testing-lucenes-index-durability-after-crash-or-power-loss.html
lucene索引
總結
以上是生活随笔為你收集整理的lucene索引_在崩溃或断电后测试Lucene的索引耐久性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为平板全球发货量超1亿台 余承东:感谢
- 下一篇: 苹果升级专业视频格式 2.2.7 ,添加