基于lucene的案例开发:实现实时索引基本原理

Posted 中软IT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于lucene的案例开发:实现实时索引基本原理相关的知识,希望对你有一定的参考价值。

基本原理


在前面的博客中也说过,程序初始化索引文件是十分消耗系统资源的,因此要想实现实时索引就不能实时的去修改索引文件、重新加载索引文件,就必须考虑如何使用内存来实现这实时索引;在Lucene4.3.1版本(之前的版本也有,但是在后面的版本中就将NRT*相关的类删除了)中NRT*相关类就提供了创建实时索引(伪实时索引)的相关方法,将IndexWrite的相关操作委托给TrackingIndexWriter来处理,实现了内存索引和硬盘索引的结合,通过NRTManager为外部提供可用的索引,当然,在执行commit(之前创建索引中有相关介绍)操作之前,操作的数据都是存在内存中,一旦宕机或者服务重,这些数据都将丢失,因此就需要自己添加一个守护线程去不断的执行commit操作(commit操作十分消耗系统资源,索引不可能每一次修改都去执行该操作)。下面就通过几个简单的图来介绍一下实时索引的实现原理:


在系统刚启动时候,存在两个索引:内存索引、硬盘索引,当然此时内存索引中是没有任何数据的,结构如下图所示:


基于lucene的案例开发:实现实时索引基本原理


在系统运行过程中,一旦有索引的增加、删除、修改等操作,这些操作都是操作内存索引,而不是硬盘索引,如下图所示:


基于lucene的案例开发:实现实时索引基本原理


当程序主动执行commit操作时,这是会将内存索引复制一份,我们称之为合并索引,同时将内存索引清空,用于之后的索引操作,此时系统中就存在内存索引、合并索引、硬盘索引,在向外提供服务的同时,也会将合并索引中的数据写入硬盘,如下图所示:


基于lucene的案例开发:实现实时索引基本原理


当合并索引中的数据已经全部写入硬盘之后,程序会对硬盘索引重读,形成新的IndexReader,在新的硬盘IndexReader替换旧的硬盘IndexReader时,删除合并索引的IndexReader,这样系统又重新回到最初的状态(当然此时内存索引中可能会有数据),如下图所示:


基于lucene的案例开发:实现实时索引基本原理


如此反复,一个实时索引的系统也就算完成了,当然这里也会有一定的风险,就是在宕机时可能会丢失一部分的数据。关于这个问题,如果数据准确度要求不是太高的话可以忽略,毕竟这种情况发生的概率太小了;如果对数据的准确度要求特别高的话,可以通过添加输出日志来完成。


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;

}

}

来自:小鸡慢慢的个人博客

链接:http://blog.csdn.net/xiaojimanman/article/details/43982653

来源:网络。若涉及版权问题,烦请原作者联系我们,我们会在24小时内删除处理,谢谢!

基于lucene的案例开发:实现实时索引基本原理

中软高科

以上是关于基于lucene的案例开发:实现实时索引基本原理的主要内容,如果未能解决你的问题,请参考以下文章

Solr全文检索基本原理及评分机制

Elaticsearch基本概念及架构原理

Elasticsearch-基础介绍及索引原理分析

Lucene 原理和实现机制

ES近实时搜索原理

索引 - ElasticSearch基本使用