基於lucene的案例開發:實現實時索引基本原理
個人的部落格小站也搭建成功,網址:www.llwjy.com ,歡迎大家來吐槽~
基本原理
在前面的部落格中也說過,程式初始話索引檔案是十分消耗系統資源的,因此要想實現實時索引就不能實時的去修改索引檔案、重新載入索引檔案,就必須考慮如何使用記憶體來實現這實時索引;在Lucene4.3.1版本(之前的版本也有,但是在後面的版本中就將NRT*相關的類刪除了)中NRT*相關類就提供了建立實時索引(偽實時索引)的相關方法,將IndexWrite的相關操作委託給TrackingIndexWriter來處理,實現了記憶體索引和硬碟索引的結合,通過NRTManager為外部提供可用的索引,當然,在執行commit(之前
在系統剛啟動時候,存在兩個索引:記憶體索引、硬碟索引,當然此時記憶體索引中是沒有任何資料的,結構如下圖所示:
在系統執行過程中,一旦有索引的增加、刪除、修改等操作,這些操作都是操作記憶體索引,而不是硬碟索引,如下圖所示:
當程式主動執行commit操作時,這是會將記憶體索引複製一份,我們稱之為合併索引,同時將記憶體索引清空,用於之後的索引操作,此時系統中就存在記憶體索引、合併索引、硬碟索引,在想外提供服務的同時,也會將合併索引中的資料寫入硬碟,如下圖所示:
當合並索引中的資料已經全部寫入硬碟之後,程式會對硬碟索引重讀,形成新的IndexReader,在新的硬碟IndexReader替換舊的硬碟IndexReader時,刪除合併索引的IndexReader,這樣系統又重新回到最初的狀態(當然此時記憶體索引中可能會有資料),如下圖所示:
如此反覆,一個實時索引的系統也就算完成了,當然這裡也會有一定的風險,就是在宕機時可能會丟失一部分的資料。關於這個問題,如果資料準確度要求不是太高的話可以忽略,畢竟這種情況發生的概率太小了;如果對資料的準確度要求特別高的話,可以通過新增輸出日誌來完成。
ps:Lucene內部的實現邏輯比上面複雜的多,這裡只是簡單的介紹一下實現原理,如要深入瞭解,還請詳細閱讀相關書籍、原始碼。
配置類
在這篇部落格中就先把這個系列的實時索引的配置類介紹以下,後面就不再介紹了。
ConfigBean
ConfigBean類中,定義了一些索引的基本屬性,如:索引名、硬碟儲存位置、採用的分詞器、commit操作執行頻率、記憶體索引重讀頻率等,具體程式碼如下:
/**
*@Description: 索引基礎配置屬性
*/
package com.lulei.lucene.index.model;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.util.Version;
public class ConfigBean {
// 分詞器
private Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);
// 索引地址
private String indexPath = "/index/";
private double indexReopenMaxStaleSec = 10;
private double indexReopenMinStaleSec = 0.025;
// 索引commit時間
private int indexCommitSeconds = 60;
// 索引名稱
private String indexName = "index";
//commit時是否輸出相關資訊
private boolean bprint = true;
public Analyzer getAnalyzer() {
return analyzer;
}
public void setAnalyzer(Analyzer analyzer) {
this.analyzer = analyzer;
}
public String getIndexPath() {
return indexPath;
}
public void setIndexPath(String indexPath) {
if (!(indexPath.endsWith("\\") || indexPath.endsWith("/"))) {
indexPath += "/";
}
this.indexPath = indexPath;
}
public double getIndexReopenMaxStaleSec() {
return indexReopenMaxStaleSec;
}
public void setIndexReopenMaxStaleSec(double indexReopenMaxStaleSec) {
this.indexReopenMaxStaleSec = indexReopenMaxStaleSec;
}
public double getIndexReopenMinStaleSec() {
return indexReopenMinStaleSec;
}
public void setIndexReopenMinStaleSec(double indexReopenMinStaleSec) {
this.indexReopenMinStaleSec = indexReopenMinStaleSec;
}
public int getIndexCommitSeconds() {
return indexCommitSeconds;
}
public void setIndexCommitSeconds(int indexCommitSeconds) {
this.indexCommitSeconds = indexCommitSeconds;
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public boolean isBprint() {
return bprint;
}
public void setBprint(boolean bprint) {
this.bprint = bprint;
}
}
IndexConfig
在一個系統中並不一定只存在一個索引,也可能會是多個,所以又添加了一個IndexConfig類,具體程式碼如下:
/**
*@Description: 索引的相關配置引數
*/
package com.lulei.lucene.index.model;
import java.util.HashSet;
public class IndexConfig {
//配置引數
private static HashSet<ConfigBean> configBean = null;
//預設的配置
private static class LazyLoadIndexConfig {
private static final HashSet<ConfigBean> configBeanDefault = new HashSet<ConfigBean>();
static {
ConfigBean configBean = new ConfigBean();
configBeanDefault.add(configBean);
}
}
public static HashSet<ConfigBean> getConfigBean() {
//如果未對IndexConfig初始化,則使用預設配置
if (configBean == null) {
configBean = LazyLoadIndexConfig.configBeanDefault;
}
return configBean;
}
public static void setConfigBean(HashSet<ConfigBean> configBean) {
IndexConfig.configBean = configBean;
}
}
ps:最近發現其他網站可能會對部落格轉載,上面並沒有源連結,如想檢視更多關於 基於lucene的案例開發 請點選這裡。或訪問網址http://blog.csdn.net/xiaojimanman/article/category/2841877 或 http://www.llwjy.com/
相關推薦
基於lucene的案例開發:實現實時索引基本原理
個人的部落格小站也搭建成功,網址:www.llwjy.com ,歡迎大家來吐槽~ 基本原理 在前面的部落格中也說過,程式初始話索引檔案是十分消耗系統資源的,因此要想實現實時索引就不能實時的去修改索引檔案、重新載入索引檔案,就必須考慮如何使用記憶
基於lucene的案例開發:建立索引
從這篇部落格開始,不論是API介紹還是後面的案例開發,都是基於 lucene4.3.1 這個版本,Lucene4.3.1 下載請點選這裡, Lucene其他版本下載請點選這裡,Lucene4.3.1官方API文件請點選這裡。 建立索引demo 在
基於lucene的案例開發:IndexSearcher中檢索方法
轉載請註明出處:http://blog.csdn.net/xiaojimanman/article/details/43052829 前面我們介紹了Analyzer和Query,這篇我們就開始該系列最後一個類IndexSearcher的搜尋API介紹,Lucen
基於lucene的案例開發:分詞器介紹
在lucene建立索引的過程中,資料資訊的處理是一個十分重要的過程,在這一過程中,主要的部分就是這一篇部落格的主題:分詞器。在下面簡單的demo中,介紹了7中比較常見的分詞技術,即:CJKAnalyzer、KeywordAnalyzer、SimpleAnaly
基於gin的golang web開發:實現使用者登入
前文分別介紹過了[Resty][1]和[gin-jwt][2]兩個包,```Resty```是一個HTTP和REST客戶端,```gin-jwt```是一個實現了JWT的Gin中介軟體。本文將使用這兩個包來實現一個簡單的使用者登入功能。 ### 環境準備 實現登入功能之前要提前準備一個用於查詢使用者是否存
基於Jquery插件Uploadify實現實時顯示進度條上傳圖片
準備 深入學習 pla 回調 true bar put and 分割 網址:http://www.jb51.net/article/83811.htm 這篇文章主要介紹了基於Jquery插件Uploadify實現實時顯示進度條上傳圖片的相關資料,感興趣的小夥伴們可
[.NET] 簡單接入微信公眾號開發:實現自動回復
ring echo AC tin 處理過程 文本消息 n) () token 簡單接入微信公眾號開發:實現自動回復 一、前提 先申請微信公眾號的授權,找到或配置幾個關鍵的信息(開發者ID、開發者密碼、IP白名單、令牌和消息加解密密鑰等)。 二、基本配置信
JQuery案例一:實現表格隔行換色
body ble () ++ doc cti seo head 姓名 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t
JQuery案例二:實現全選、全不選和反選
lap lsp enter scrip ttr on() class cells span <!DOCTYPE html> <html> <head> <meta charset="UTF-8">
案例六:實現1+2+3+...+100的求和計算
color 圖片 author sum png main col 求和 bsp package project_06; /** * 2018年9月7日22:45:05 * @author Suaron XiaMen * */ public class Summa
音樂網站開發:實現點選按鈕切換頁面背景圖的功能
最近這一星期在做一個簡單小型的音樂播放器網站,目前各種功能基本都已經實現,包括切換上一曲下一曲,播放與暫停,隨機播放單曲迴圈順序播放模式切換,一首播放完畢自動按模式切換至下一曲,載入單句歌詞及所有歌詞等功能。另外就是本篇部落格要介紹的功能了,點
基於Lucene 7.1.0 實現搜尋引擎
引入lucene 7.1.0 所使用的jar包 <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId>
Modbus協議棧開發筆記之一:實現功能的基本設計
Modbus作為開放式的工業通訊協議,在各種工業裝置中應用極其廣泛。本人也使用Modbus通訊很多年了,或者用現成的,或者針對具體應用開發,一直以來都想要開發一個比較通用的協議棧能在後續的專案中複用,而不必每次都寫一遍。現在利用專案研發的機會,開發一個自己的Modbus協議棧。 Modbus
Android開發:實現分享給微信好友以及出現閃退的問題
轉載煩請註明本文出處~ 1.申請微信APPID 要實現分享到微信的功能,首先要到微信開放平臺申請一個APPID。但在申請APPID的時候需要填寫一個應用簽名和應用包名。需要注意的是包名必須與開發應用時的包名一致,應用簽名也必須去掉冒號而且字母為小寫。 2.應
Android開發:實現系統自帶截圖功能 需要獲取System許可權
在一個service介面上,點選一個button按鈕,可以截圖 貼上程式碼: mButton.setOnClickListener(new OnClickListener(){ public void onClick(View arg0) {
基於 Flume+Kafka+Spark Streaming 實現實時監控輸出日誌的報警系統
運用場景:我們機器上每天或者定期都要跑很多工,很多時候任務出現錯誤不能及時發現,導致發現的時候任務已經掛了很久了。 解決方法:基於 Flume+Kafka+Spark Streaming 的框架對這些任務的輸出日誌進行實時監控,當檢測到日誌出現Error的資訊就傳送郵件給
Android二維碼掃描開發:實現思路與原理
現在二維碼已經非常普及了,那麼二維碼的掃描與處理也成為了Android開發中的一個必要技能。網上有很多關於Android中二維碼處理的帖子,大都是在講開源框架zxing用法,然後貼貼程式碼就完了,並沒有一個系統的分析和原理解析。其中涉及到的Camera的操作和YUV影
iOS開發:實現圖片的打碼效果
馬賽克(mosaic)作為人類進步路上的一大絆腳石,被人們所深惡痛絕。作為阻止人類進步小能手,我今天就給大家普及一下關於如何在iOS平臺實現圖片打碼效果的。 圖1、效果圖 本文主要介紹的是使用iOS平臺自身的API去實現圖片打碼效果的,沒有使用openCV。
Android 開發:Paint畫筆的基本使用方法
1.setStyle(Paint.Style style) 設定畫筆樣式,取值有 Paint.Style.FILL :填充內部 Paint.Style.FILL_AND_STROKE :填充內部和描邊 Paint.Style.STROKE :僅描邊、 注意STROKE、F
Lucene學習總結之一:全文檢索的基本原理
一、總論 Lucene是一個高效的,基於Java的全文檢索庫。 所以在瞭解Lucene之前要費一番工夫瞭解一下全文檢索。 那麼什麼叫做全文檢索呢?這要從我們生活中的資料說起。 我們生活中的資料總體分為兩種:結構化資料和非結構化資料。 結構化資料:指具