搜索那点事儿:Lucene 文件存储和读取技术详解

简介:

Lucene是一个高性能、可伸缩的信息搜索(IR)库。它可以为你的应用程序添加索引和搜索能力。Lucene是用Java实现的、成熟的开源项目,是著名的Apache Jakarta大家庭的一员,并且基于Apache软件许可。

Lucene的检索算法属于索引检索,即用空间来换取时间,对需要检索的文件、字符流进行全文索引,在检索的时候对索引进行快速的检索,得到检索位置,这个位置记录检索词出现的文件路径或者某个关键词。Lucene的索引是用文件存储,Lucene中的文件操作都是通过Directory来实现,下面来介绍一下Lucene有关文件存储和读取的有关技术。

1 数据存储类Directory(org.apache.lucene.store.Directory)

一个Directory对象是一系列统一的文件列表(a flat list of files)。文件可以在它们被创建的时候一次写入,一旦文件被创建,它再次打开后只能用于读取(read)或者删除(delete)操作,并且同时在读取和写入的时候允许随机访问(random access)。

在这里并不直接使用Java I/O API,但是更确切地说,所有I/O操作都是通过这个API处理的。这使得读写操作方式更统一,如基于内存的索引(RAM-based indices)的实现(即RAMDirectory)、通过JDBC存储在数据库中的索引、将一个索引存储为一个文件的实现(即FSDirectory)。

Directory的锁机制是一个LockFactory的实例实现的,可以通过调用Directory实例的setLockFactory()方法来更改。

如下图是org.apache.lucene.store.Directory类以及它的一些子类的类图:

(1) org.apache.lucene.store.FSDirectory

FSDirectory类直接实现Directory抽象类为一个包含文件的目录。目录锁的实现使用缺省的SimpleFSLockFactory,但是可以通过两种方式修改,即给getLockFactory()传入一个LockFactory实例,或者通过调用setLockFactory()方法明确制定LockFactory类。

目录将被缓存(cache)起来,对一个指定的符合规定的路径(canonical path)来说,同样的FSDirectory实例通常通过getDirectory()方法返回。这使得同步机制(synchronization)能对目录起作用。

(2) org.apache.lucene.store.RAMDirectory

RAMDirectory类是一个驻留内存的(memory-resident)Directory抽象类的实现。目录锁的实现使用缺省的SingleInstanceLockFactory,但是可以通过setLockFactory()方法修改。

(3) org.apache.lucene.store.MMapDirectory

Lucene和Solr开始在64位的Windows和Solaris系统中默认使用MMapDirectory。简单说MMapDirectory就是把Lucene的索引当作swap file来处理。mmap()系统调用让OS把整个索引文件映射到虚拟地址空间,这样Lucene就会觉得索引在内存中。然后Lucene就可以像访问一个超大的byte[]数据(在Java中这个数据被封装在ByteBuffer接口里)一样访问磁盘上的索引文件。

Lucene在访问虚拟空间中的索引时,不需要任何的系统调用,CPU里的MMU和TLB会处理所有的映射工作。如果数据还在磁盘上,那么MMU会发起一个中断,OS将会把数据加载进文件系统Cache。如果数据已经在cache里了,MMU/TLB会直接把数据映射到内存,这只需要访问内存,速度很快。

程序员不需要关心paging in/out,所有的这些都交给OS。而且,这种情况下没有并发的干扰,唯一的问题就是Java的ByteBuffer封装后的byte[]稍微慢一些,但是Java里要想用mmap就只能用这个接口。还有一个很大的优点就是所有的内存issue都由OS来负责,这样没有GC的问题。因此在64位平台上的Lucene,尽量使用MMapDirectory。

2 文件读取类 IndexInput(org.apache.lucene.store.IndexInput)

IndexInput类是一个为了从一个目录(Directory)中读取文件的抽象基类,是一个随机访问(random-access)的输入流(input stream),用于所有Lucene读取Index的操作。BufferedIndexInput是一个实现了带缓冲的IndexInput的基础实现。

3 文件写入类IndexOutput(org.apache.lucene.store.IndexOutput)

IndexOutput类是一个为了写入文件到一个目录(Directory)中的抽象基类,是一个随机访问(random-access)的输出流(output stream),用于所有Lucene写入Index的操作。BufferedIndexOutput是一个实现了带缓冲的IndexOutput的基础实现。RAMOuputStream是一个内存驻留(memory-resident)的IndexOutput的实现类。

作为一种检索系统框架,Lucene并不直接提供系统的实现,而仅仅是系统框架而已。因此,为了构建一个真正可用的全文检索系统,开发人员必须熟悉Lucene的基本框架以及API,这样才能进行高效的开发。

这一需求要求了Lucene具备一种简明、方便的构架与函数接口来方便用户(即开发人员)的使用。这体现了Lucene需要很高的易用性(usability)。 不仅如此,开源是Lucene的一个重大属性。相比Google的pagerank搜索方案,Lucene必须不断改进其算法以及各种辅助措施来使得其运行更加高效,并支持多种语言等。因此,Lucene必须具备很好的可修改性(modifiability)。



本文作者:刘光敏

来源:51CTO

相关文章
|
7月前
|
存储 大数据 Java
【云计算与大数据技术】文件存储格式行式、列式、GFS、HDFS的讲解(图文解释 超详细)
【云计算与大数据技术】文件存储格式行式、列式、GFS、HDFS的讲解(图文解释 超详细)
306 0
|
存储 文件存储 数据库
文件存储技术-数据持久化-Android
文件存储技术-数据持久化-Android
|
存储 机器学习/深度学习 缓存
阿里云文件存储低频 NAS 和生命周期管理的全面技术解读
全面解读阿里云文件存储低频 NAS 和生命周期管理的知识宝典。阿里云文件存储推出了低频 NAS 存储,价格 0.15 元/GB/月,通过配置存储生命周期管理技术实现了全面降价,最高降幅可达 92%。
562 0
|
存储 Linux 文件存储
阿里开发者招聘节 |阿里云文件存储团队诚招技术人才啦!
新一代文件存储的定义者,智能化时代的基石!阿里云文件存储团队招兵买马,逐鹿中原!
|
存储 运维 监控
阿里云的文件存储NAS使用心得
阿里云的文件存储NAS使用心得
383 0
|
存储 弹性计算 固态存储
阿里云服务器1TB存储收费标准(数据盘/对象存储OSS/文件存储NAS)
阿里云服务器1TB存储多少钱?系统盘最大可选到500GB,数据盘选到1TB价格为3655元一年。也可以选择对象存储OSS和文件存储NAS
6340 2
阿里云服务器1TB存储收费标准(数据盘/对象存储OSS/文件存储NAS)
|
存储 弹性计算 人工智能
阿里云文件存储NAS通用型、极速型和文件存储CPFS有什么区别?
阿里云文件存储NAS极速型NAS低时延,适合企业级时延敏感型核心业务;文件存储CPFS拥有高吞吐和高IOPS,适合高性能计算业务;通用型NAS大容量、高性价比、弹性扩展,支持低频介质,适合通用类文件共享业务。
1782 0
阿里云文件存储NAS通用型、极速型和文件存储CPFS有什么区别?
|
5月前
|
存储 NoSQL 文件存储
云计算问题之阿里云文件存储CPFS如何满足大模型智算场景的存储需求
云计算问题之阿里云文件存储CPFS如何满足大模型智算场景的存储需求
106 2
|
存储 弹性计算 并行计算
在高性能计算(HPC)场景下,阿里云存储的文件存储产品的实践
在高性能计算(HPC)场景下,阿里云存储的文件存储产品具有以下的应用需求和实践
453 4