導航:首頁 > 文件教程 > lucene生成索引文件有幾個

lucene生成索引文件有幾個

發布時間:2023-09-03 09:00:21

⑴ Lucene.Net建立索引 數據大概有百萬條 可是需要好久好久 請問有沒有辦法讓它變快呢

minMergeFactor還有一個這樣的參數,控制在內存緩沖的文檔數量我是建了500條數據後關閉IndexWriter.70萬的數據都可以建就是創建索引速度的問題70萬花了12小時

⑵ 搜索引擎Lucene(4):索引的創建過程

創建索引的過程如下:

索引結構如下:

IndexWriter結構:

IndexWriter通過指定存放的目錄(Directory)以及文檔分析器(Analyzer)來構建,direcotry代表索引存儲在哪裡;analyzer表示如何來分析文檔的內容;similarity用來規格化文檔,給文檔算分;IndexWriter類里還有一些SegmentInfos對象用於存儲索引片段信息,以及發生故障回滾等。

添加文檔使用addDocument()方法,刪除文檔使用deleteDocuments(Term)或者deleteDocuments(Query)方法,而且一篇文檔可以使用updateDocument()方法來更新(僅僅是先執行delete在執行add操作而已)。當完成了添加、刪除、更新文檔,應該需要調用close方法。

這些修改會緩存在內存中(buffered in memory),並且定期地(periodically)刷新到(flush)Directory中(在上述方法的調用期間)。一次flush操作會在如下時候觸發(triggered):當從上一次flush操作後有足夠多緩存的delete操作(參見setMaxBufferedDeleteTerms(int)),或者足夠多已添加的文檔(參見setMaxBufferedDocs(int)),無論哪個更快些(whichever is sooner)。對被添加的文檔來說,一次flush會在如下任何一種情況下觸發,文檔的RAM緩存使用率(setRAMBufferSizeMB)或者已添加的文檔數目,預設的RAM最高使用率是16M,為得到索引的最高效率,你需要使用更大的RAM緩存大小。需要注意的是,flush處理僅僅是將IndexWriter中內部緩存的狀態(internal buffered state)移動進索引里去,但是這些改變不會讓IndexReader見到,直到commit()和close()中的任何一個方法被調用時。一次flush可能觸發一個或更多的片斷合並(segmentmerges),這時會啟動一個後台的線程來處理,所以不會中斷addDocument的調用,請參考MergeScheler。

一個IndexReader或者IndexSearcher只會看到索引在它打開的當時的狀態。任何在索引被打開之後提交到索引中的commit信息,在它被重新打開之前都不會見到。

DocumentsWriter結構:

DocumentsWriter 是由IndexWriter 調用來負責處理多個文檔的類,它通過與Directory 類及Analyzer 類、Scorer 類等將文檔內容提取出來,並分解成一組term列表再生成一個單一的segment 所需要的數據文件,如term頻率、term 位置、term 向量等索引文件,以便SegmentMerger 將它合並到統一的segment 中去。

該類可接收多個添加的文檔,並且直接寫成一個單獨的segment 文件。這比為每一個文檔創建一個segment(使用DocumentWriter)以及對那些segments 執行合作處理更有效率。

每一個添加的文檔都被傳遞給DocConsumer類,它處理該文檔並且與索引鏈表中(indexing chain)其它的consumers相互發生作用(interacts with)。確定的consumers,就像StoredFieldWriter和TermVectorsTermsWriter,提取一個文檔的摘要(digest),並且馬上把位元組寫入「文檔存儲」文件(比如它們不為每一個文檔消耗(consume)內存RAM,除了當它們正在處理文檔的時候)。

其它的consumers,比如FreqProxTermsWriter和NormsWriter,會緩存位元組在內存中,只有當一個新的segment製造出的時候才會flush到磁碟中。

一旦使用完我們分配的RAM緩存,或者已添加的文檔數目足夠多的時候(這時候是根據添加的文檔數目而不是RAM的使用率來確定是否flush),我們將創建一個真實的segment,並將它寫入Directory中去。

索引創建的調用過程:

一個Directory對象是一系列統一的文件列表(a flat list of files)。文件可以在它們被創建的時候一次寫入,一旦文件被創建,它再次打開後只能用於讀取(read)或者刪除(delete)操作。並且同時在讀取和寫入的時候允許隨機訪問。

FSDirectory類直接實現Directory抽象類為一個包含文件的目錄。目錄鎖的實現使用預設的SimpleFSLockFactory,但是可以通過兩種方式修改,即給getLockFactory()傳入一個LockFactory實例,或者通過調用setLockFactory()方法明確制定LockFactory類。

目錄將被緩存(cache)起來,對一個指定的符合規定的路徑(canonical path)來說,同樣的FSDirectory實例通常通過getDirectory()方法返回。這使得同步機制(synchronization)能對目錄起作用。

RAMDirectory類是一個駐留內存的(memory-resident)Directory抽象類的實現。目錄鎖的實現使用預設的SingleInstanceLockFactory,但是可以通過setLockFactory()方法修改。

IndexInput類是一個為了從一個目錄(Directory)中讀取文件的抽象基類,是一個隨機訪問(random-access)的輸入流(input stream),用於所有Lucene讀取Index的操作。BufferedIndexInput是一個實現了帶緩沖的IndexInput的基礎實現。

IndexOutput類是一個為了寫入文件到一個目錄(Directory)中的抽象基類,是一個隨機訪問(random-access)的輸出流(output stream),用於所有Lucene寫入Index的操作。BufferedIndexOutput是一個實現了帶緩沖的IndexOutput的基礎實現。RAMOuputStream是一個內存駐留(memory-resident)的IndexOutput的實現類。

域索引選項通過倒排索引來控制文本是否可被搜索。

當lucene建立起倒排索引後,默認情況下它會保存所有必要的信息以實施Vector Space Model。該Model需要計算文檔中出現的Term數,以及它們出現的文職(這是必要的,比如通過片語搜索時用到)。但有時候這些域只是在布爾搜索時用到,他們並不為相關評分做貢獻,一個常見的例子是,域只是被用作過濾,如許可權過濾和日期過濾。在這種情況下,可以通過調用Field.setOmitTermFreqAndPositions(true)方法讓lucene跳過對改選項的出現頻率和出現位置的索引。該方法可以節省一些索引在磁碟上的儲存空間,還可以加速搜索和過濾過程,但會悄悄阻止需要位置信息的搜索,如阻止PhraseQuery和SpanQuery類的運行。

域存儲選項是用來確定是否需要存儲域的真實值,以便後續搜索時能回復這個值。

lucene支持想一個域中寫入多個不同的值。

這種處理方式是完全可以接受並鼓勵使用的,因為這是邏輯上具有多個域值的域的自然表示方式。在lucene內部,只要文檔中出現同名的多域值,倒排索引和項向量都會在邏輯上將這些語匯單元附加進去,具體順序由添加該域的順序決定。

文檔和域的加權操作可以在索引期間完成。而搜索期間的加權操作會更加動態化,因為每次搜索都可以根據不同的加權因子獨立選擇加權或不加權,但這個策略也可能多消耗一些CPU效率。搜索期間的動態加權可以更靈活控制。

默認情況下,所有文檔的加權因子都是1.0,通過改變文檔的加權因子,就可以影響文檔在索引中的重要程度。調整加權操作的API為:setBoost(float);

同文檔加權一樣,可以對進行加權操作。文檔加權時,lucene內部會採用同一加權因子來對該文檔中的域進行加權。域加權API:Field.setBoost(fliat)。

Analyzer類構建用於分析文本的TokenStream對象,因此(thus)它表示(represent)用於從文本中分解(extract)出組成索引的terms的一個規則器(policy)。典型的(typical)實現首先創建一個Tokenizer,它將那些從Reader對象中讀取字元流(stream of characters)打碎為(break into)原始的Tokens(raw Tokens)。然後一個或更多的TokenFilters可以應用在這個Tokenizer的輸出上。警告:你必須在你的子類(subclass)中覆寫(override)定義在這個類中的其中一個方法,否則的話Analyzer將會進入一個無限循環(infinite loop)中。

StandardAnalyzer:

StandardAnalyzer類是使用一個English的stop words列表來進行tokenize分解出文本中word,使用StandardTokenizer類分解詞,再加上StandardFilter以及LowerCaseFilter以及StopFilter這些過濾器進行處理的這樣一個Analyzer類的實現。

⑶ 突破性能瓶頸!ElasticSearch百億級數據檢索優化案例

本文中的數據平台已迭代三個版本,從頭開始遇到很多常見的難題,終於有片段時間整理一些已完善的文檔,在此分享以供所需朋友的。實現參考,少走些彎路,在此篇幅中偏重於ES的優化,目前生產已存儲百億數據,性能良好,關於HBase,Hadoop的設計優化估計有很多文章可以參考,不再贅述。

項目背景:在一業務系統中,部分表每天的數據量過億,已按天分表,但業務上受限於按天查詢,並且DB中只能保留3個月的數據(硬體高配),分庫代價較高。

改進版本目標:

談到優化必須能了解組件的基本原理,才容易找到瓶頸所在,以免走多種彎路,先從ES的基礎結構說起(如下圖):

一些基本概念:

ES依賴一個重要的組件Lucene,關於數據結構的優化通常來說是對Lucene的優化,它是集群的一個存儲於檢索工作單元,結構如下圖:

在Lucene中,分為索引(錄入)與檢索(查詢)兩部分,索引部分包含 分詞器、過濾器、字元映射器 等,檢索部分包含 查詢解析器 等。一個Lucene索引包含多個segments,一個segment包含多個文檔,每個文檔包含多個欄位,每個欄位經過分詞後形成一個或多個term。

通過Luke工具查看ES的lucene文件如下,主要增加了_id 和 _source欄位:

Lucene 索引文件結構主要的分為:詞典、倒排表、正向文件、DocValues等,如下圖:

Lucene 隨機三次磁碟讀取比較耗時。其中.fdt文件保存數據值損耗空間大,.tim和.doc則需要SSD存儲提高隨機讀寫性能。
另外一個比較消耗性能的是打分流程,不需要則可屏蔽。

關於DocValues:

倒排索引解決從詞快速檢索到相應文檔ID, 但如果需要對結果進行排序、分組、聚合等操作的時候則需要根據文檔ID快速找到對應的值。

通過倒排索引代價缺很高:需迭代索引里的每個詞項並收集文檔的列裡面 token。這很慢而且難以擴展:隨著詞項和文檔的數量增加,執行時間也會增加。Solr docs對此的解釋如下:

在lucene 4.0版本前通過FieldCache,原理是通過按列逆轉倒排表將(field value ->doc)映射變成(doc -> field value)映射,問題為逐步構建時間長並且消耗大量內存,容易造成OOM。

DocValues是一種列存儲結構,能快速通過文檔ID找到相關需要排序的欄位。在ES中,默認開啟所有(除了標記需analyzed的字元串欄位)欄位的doc values,如果不需要對此欄位做任何排序等工作,則可關閉以減少資源消耗。

ES中一個索引由一個或多個lucene索引構成,一個lucene索引由一個或多個segment構成,其中segment是最小的檢索域。

數據具體被存儲到哪個分片上:shard = hash(routing) % number_of_primary_shards

默認情況下 routing參數是文檔ID (murmurhash3),可通過 URL中的 _routing 參數指定數據分布在同一個分片中,index和search的時候都需要一致才能找到數據,如果能明確根據_routing進行數據分區,則可減少分片的檢索工作,以提高性能。

在我們的案例中,查詢欄位都是固定的,不提供全文檢索功能,這也是幾十億數據能秒級返回的一個大前提:

1、ES僅提供欄位的檢索,僅存儲HBase的Rowkey不存儲實際數據。
2、實際數據存儲在HBase中,通過Rowkey查詢,如下圖。
3、提高索引與檢索的性能建議,可參考官方文檔(如 https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html )。

一些細節優化項官方與其他的一些文章都有描述,在此文章中僅提出一些本案例的重點優化項。

1、批量寫入,看每條數據量的大小,一般都是幾百到幾千。

2、多線程寫入,寫入線程數一般和機器數相當,可以配多種情況,在測試環境通過Kibana觀察性能曲線。

3、增加segments的刷新時間,通過上面的原理知道,segment作為一個最小的檢索單元,比如segment有50個,目的需要查10條數據,但需要從50個segment,分別查詢10條,共500條記錄,再進行排序或者分數比較後,截取最前面的10條,丟棄490條。在我們的案例中將此 "refresh_interval": "-1" ,程序批量寫入完成後進行手工刷新(調用相應的API即可)。

4、內存分配方面,很多文章已經提到,給系統50%的內存給Lucene做文件緩存,它任務很繁重,所以ES節點的內存需要比較多(比如每個節點能配置64G以上最好)。

5、磁碟方面配置SSD,機械盤做陣列RAID5 RAID10雖然看上去很快,但是隨機IO還是SSD好。

6、 使用自動生成的ID,在我們的案例中使用自定義的KEY,也就是與HBase的ROW KEY,是為了能根據rowkey刪除和更新數據,性能下降不是很明顯。

7、關於段合並,合並在後台定期執行,比較大的segment需要很長時間才能完成,為了減少對其他操作的影響(如檢索),elasticsearch進行閾值限制,默認是20MB/s,

可配置的參數:"indices.store.throttle.max_bytes_per_sec" : "200mb" (根據磁碟性能調整)

合並線程數默認是:Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2)),如果是機械磁碟,可以考慮設置為1:index.merge.scheler.max_thread_count: 1,

在我們的案例中使用SSD,配置了6個合並線程。

1、關閉不需要欄位的doc values。

2、盡量使用keyword替代一些long或者int之類,term查詢總比range查詢好 (參考lucene說明 http://lucene.apache.org/core/7_4_0/core/org/apache/lucene/index/PointValues.html )。

3、關閉不需要查詢欄位的 _ source 功能,不將此存儲僅ES中,以節省磁碟空間。

4、評分消耗資源,如果不需要可使用filter過濾來達到關閉評分功能,score則為0,如果使用constantScoreQuery則score為1。

5、關於分頁:

(1)from + size:
每分片檢索結果數最大為 from + size,假設from = 20, size = 20,則每個分片需要獲取 20 x 20 = 400條數據,多個分片的結果在協調節點合並(假設請求的分配數為5,則結果數最大為 400 * 5 = 2000條) 再在內存中排序後然後20條給用戶。這種機制導致越往後分頁獲取的代價越高,達到50000條將面臨沉重的代價,默認from + size默認如下: index.max_result_window:10000

(2) search_after: 使用前一個分頁記錄的最後一條來檢索下一個分頁記錄,在我們的案例中,首先使用from+size,檢索出結果後再使用search_after,在頁面上我們限制了用戶只能跳5頁,不能跳到最後一頁。

(3) scroll 用於大結果集查詢,缺陷是需要維護scroll_id

6、關於排序:我們增加一個long欄位,它用於存儲時間和ID的組合(通過移位即可),正排與倒排性能相差不明顯。

7、關於CPU消耗,檢索時如果需要做排序則需要欄位對比,消耗CPU比較大,如果有可能盡量分配16cores以上的CPU,具體看業務壓力。

8、關於合並被標記刪除的記錄,我們設置為0表示在合並的時候一定刪除被標記的記錄,默認應該是大於10%才刪除: "merge.policy.expunge_deletes_allowed": "0"。

優化效果評估基於基準測試,如果沒有基準測試無法了解是否有性能提升,在這所有的變動前做一次測試會比較好。在我們的案例中:

1、單節點5千萬到一億的數據量測試,檢查單點承受能力。

2、集群測試1億-30億的數量,磁碟IO/內存/CPU/網路IO消耗如何。

3、隨機不同組合條件的檢索,在各個數據量情況下表現如何。

4、另外SSD與機械盤在測試中性能差距如何。

性能的測試組合有很多,通常也很花時間,不過作為評測標准時間上的投入有必要,否則生產出現性能問題很難定位或不好改善。對於ES的性能研究花了不少時間,最多的關注點就是lucene的優化,能深入了解lucene原理對優化有很大的幫助。

目前平台穩定運行,百億的數據查詢100條都在3秒內返回,前後翻頁很快,如果後續有性能瓶頸,可通過擴展節點分擔數據壓力。

閱讀全文

與lucene生成索引文件有幾個相關的資料

熱點內容
word2010怎麼從任意頁設置頁碼 瀏覽:622
cass怎麼校正數據 瀏覽:612
linux查看所有管理員 瀏覽:2
u盤文件解壓縮失敗如何修復 瀏覽:566
黑蘋果怎麼顯卡才4m 瀏覽:270
方程式0day圖形化工具 瀏覽:961
電腦裝文件很慢 瀏覽:958
網路標號怎麼用 瀏覽:352
會議上文件讀好後要說什麼 瀏覽:783
安裝壓縮文件office 瀏覽:417
2014年網路營銷大事件 瀏覽:186
首頁全屏安裝代碼 瀏覽:39
黨規黨紀指的哪些文件 瀏覽:995
windows編程圖形界面用什麼設置 瀏覽:266
deb文件安裝路徑 瀏覽:540
飛鴿傳送提示文件名太長 瀏覽:486
日服文件名 瀏覽:648
宏程序和編程哪個好學 瀏覽:965
怎麼打開微信中的文件怎麼打開方式打開方式 瀏覽:98
wordpressgbk版本 瀏覽:328

友情鏈接