lucene快速入门_为Lucene选择快速唯一标识符(UUID)

lucene快速入门

大多数使用Apache Lucene的搜索应用程序都会为每个索引文档分配一个唯一的ID(即主键)。 尽管Lucene本身不需要这样做(它可能不太在乎!),但应用程序通常需要它以后通过其外部ID替换,删除或检索该文档。 大多数在Lucene之上构建的服务器,例如Elasticsearch和Solr ,都需要一个唯一的ID,如果不提供它,则可以自动生成一个ID。

有时,您的ID值已经预先定义,例如,如果外部数据库或内容管理系统分配了ID ,或者您必须使用URI ,但是如果您可以自由分配自己的ID,那么哪种方法最适合Lucene?

一个明显的选择是Java的UUID类,该类生成版本4的通用唯一标识符 ,但事实证明,这是性能上最糟糕的选择:它比最快的速度慢4倍。 要了解原因,需要对Lucene如何找到术语有所了解。

BlockTree术语词典

术语词典的目的是存储在索引期间看到的所有唯一术语,并将每个术语映射到其元数据( docFreqtotalTermFreq等 )以及totalTermFreq (文档,偏移量,投递和有效载荷)。 当请求一个术语时,术语词典必须在磁盘索引中找到它并返回其元数据。

默认编解码器使用BlockTree术语词典 ,该词典以排序的二进制顺序存储每个字段的所有术语,并将这些术语分配到共享公共前缀的块中。 默认情况下,每个块包含25到48个词。 它使用内存中的前缀三叉戟索引结构( FST )将每个前缀快速映射到相应的磁盘块,并在查找时首先根据请求的术语的前缀检查索引,然后在-disk块并扫描以查找术语。

在某些情况下,当段中的术语具有可预测的模式时,术语索引可以知道请求的术语不能存在于磁盘上。 这种快速匹配测试可以带来可观的性能提升,尤其是当索引很冷(操作系统的IO缓存不缓存页面)时,因为它避免了昂贵的磁盘搜寻。 由于Lucene是基于段的,因此单个id查找必须访问每个段直到找到匹配项,因此快速排除一个或多个段可能是一个大胜利。 确保您的细分受众群计数尽可能低也很重要!

鉴于此,完全随机的id(例如UUID V4 )应该表现最差,因为它们击败了术语索引快速匹配测试,并且需要对每个段进行磁盘搜索。 具有可预测的每段模式的ID(例如顺序分配的值或时间戳)应发挥最佳作用,因为它们将使术语索引快速匹配测试的收益最大化。

测试性能

我创建了一个简单的性能测试器来验证这一点。 完整的源代码在这里 。 该测试首先将1亿个ID索引到具有7/7/8段结构(7个大段,7个中段,8个小段)的索引中,然后搜索200万个ID的随机子集,记录最佳时间5次运行。 我在Ubuntu 14.04上使用Java 1.7.0_55,以及3.5 GHz Ivy Bridge Core i7 3770K。

由于Lucene的术语从4.0开始是完全二进制的 ,因此存储任何值的最紧凑的方法是二进制形式,其中每个字节使用所有256个值。 然后,一个128位ID值需要16个字节。

我测试了以下标识符来源:

  • 顺序ID(0、1、2,...),采用二进制编码。
  • 零填充的顺序ID(00000000、00000001等),采用二进制编码。
  • 纳米时间,二进制编码。 但是请记住, 纳米时间是棘手的 。
  • 使用此实现从时间戳,nodeID和序列计数器派生的UUID V1 。
  • UUID V4 ,使用Java的UUID.randomUUID()随机生成。
  • 片状ID ,使用此实现 。

对于UUID和Flake ID,除了标准(16或36基)编码之外,我还测试了二进制编码。 请注意,我仅使用一个线程测试了查找速度,但是在添加线程时,结果应该线性扩展(在足够并行的硬件上)。

图表

以二进制编码的零填充顺序ID最快,比非零填充顺序ID快很多。 UUID V4(使用Java的UUID.randomUUID() )慢了约4倍。

但是对于大多数应用程序来说,顺序编号是不实际的。 第二快的是UUID V1 ,以二进制编码。 令我惊讶的是,这比Flake ID快得多,因为Flake ID使用相同的原始信息源(时间,节点ID,序列),但是以不同的方式随机排列位以保留总顺序。 我怀疑问题是在获取不同文档之间的数字之前,必须在Flake ID中遍历的通用前导数字的数目,因为64位时间戳的高位在前,而UUID V1则在低位位首先是64位时间戳。 当一个字段中的所有术语共享一个公共前缀时,术语索引也许可以优化这种情况。

我还分别测试了10、16、36、64、256的基数,通常对于非随机ID,较高的基数更快。 我对此感到惊讶,因为我希望与BlockTree块大小(25到48)匹配的基数最好。

此测试有一些重要警告(欢迎补丁)! 一个真正的应用程序显然比简单地查找id还要做更多的工作,并且结果可能会有所不同,因为热点必须编译更多活动的代码。 在我的测试中,该索引非常热(有大量RAM可以容纳整个索引); 对于冷索引,我希望结果会更加鲜明,因为避免磁盘搜索变得非常重要。 在实际应用中,使用时间戳的id在时间上会更加分散; 我可以通过伪造更大范围的时间戳来“模拟”自己。 也许这会缩小UUID V1和Flake ID之间的差距? 我在索引编制过程中仅使用了一个线程,但是具有多个索引编制线程的实际应用程序会将ID一次分散到多个段中。

我使用了Lucene的默认TieredMergePolicy ,但是有一种更聪明的合并策略可能会支持合并ID更“相似”的段,从而可能会产生更好的结果。 该测试不会执行任何删除/更新操作,这将需要更多的查找工作,因为给定的ID(如果已更新)可能位于多个段中(只是删除了其中的一个)。

最后,我使用了Lucene的默认编解码器,但是当您愿意将RAM换成更快的查询时,我们有不错的主播查询格式已优化过,例如去年的Google夏季代码项目和MemoryPostingsFormat 。 这些可能会带来可观的性能提升!

翻译自: https://www.javacodegeeks.com/2014/05/choosing-a-fast-unique-identifier-uuid-for-lucene.html

lucene快速入门

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341259.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vim字符串替换

vi/vim 中可以使用 😒 命令来替换字符串。以前只会使用一种格式来全文替换,今天发现该命令有很多种写法(vi 真是强大啊,还有很多需要学习),记录几种在此,方便以后查询。 替换    : s/vivian/sky/ 替换当前行第一个 v…

使用网真和WAD热部署Kubernetes

在Kubernetes环境中测试企业应用程序时,更改,重新打包和重新部署应用程序的周转可能变得非常高。 网真旨在通过将本地运行的进程代理到我们的Kubernetes集群中来减轻这种情况,就像本地进程是集群的一部分一样。 如果我们将这种方法与诸如WAD之…

git clone 项目出现 Failed to connect to github.com port 443: Timed out

将命令号中的https 改为git 就可以解决这个问题的出现

使用eclipse调试ns3-配置说明

Tips: 1, 安装eclipse时注意选择C开发组件; 环境配置参考:https://www.cnblogs.com/zlcxbb/p/3852810.html 第一步,新建C工程; 第二步,在project explorer中右键属性,如下图&#…

singleton 类_在Java中对Singleton类进行双重检查锁定

singleton 类Singleton类在Java开发人员中非常常见,但是它给初级开发人员带来了许多挑战。 他们面临的主要挑战之一是如何使Singleton保持为Singleton? 也就是说,无论出于何种原因,如何防止单个实例的多个实例。 对Singleton进行双…

将 Citavi 笔记按需要导出

文章目录简要介绍导出某一条笔记导出按条件筛选的一类笔记导出某一篇 PDF 的笔记导出全部笔记简要介绍 Citavi 的笔记功能相比其他文献管理软件较为完善,对 PDF 的标注是一种双链标注,阅读论文更方便,这也是当下很多笔记软件在做的功能之一&…

反应型关系数据库事务

Spring Framework最近宣布将提供对反应式事务管理的支持 。 让我们深入研究它对R2DBC(SQL数据库访问的反应式规范)如何工作。 事务管理是一种模式,而不是特定于技术的。 从这个角度来看,它的属性和运行时行为是实现技术的功能。…

Ubuntu20.04 服务器版安装

本篇文章是实验室服务器安装系统的总结安装总结。 1 安装的前提是具有安装启动盘,下载最新的Ubuntu 20.04服务器版本系统,制作成可启动的USB驱动器。 不同品牌的电脑安装系统的启动键不同,需自行百度一下自己要装的计算机的启动键。 1 进入引…

Window10:不能建立到远程计算机的连接。你可能需要更改此连接的网络设置。

解决步骤: 第一步:在桌面找到此电脑,鼠标右键点击,选择管理 第二步:进入计算机管理界面 第三步:点击设备管理器-再点击网络适配器 第四步:卸载WAN MIniport(ip) 重启电脑。重新拨号&…

java默认代码地址_Java 8默认方法可能会破坏您的(用户)代码

java默认代码地址乍一看, 默认方法为Java虚拟机的指令集带来了一个很棒的新功能。 最后,库开发人员能够开发已建立的API,而不会对其用户代码造成不兼容性。 使用默认方法,当将新方法引入该接口时,任何实现库接口的用户…

C盘爆红的解决方法

C盘爆红的原因 1. 系统存在的过多功能 2. 安装的软件占用 3. 聊天软件文件占用 4. 临时文件占用 5. 软件缓存占用 针对不同的原因进行处理 一.关闭不用的系统功能 1. 从1903版本开始,win10 C盘就有~7G的保留空间占用; 提供dism命令关闭方法,命令…

Apache Camel 3 –骆驼核心vs骆驼核心引擎(较小的核心)

Camel团队目前正在忙于Apache Camel 3的开发。已经完成了许多工作,到目前为止,我们已经发布了3个里程碑版本。 下一个里程碑版本4具有一些出色的创新功能,这些功能我将在接下来的几个月中发布。 该博客的主题是我们在将骆驼核拆分成较小的模…

OneNote使用说明

Microsoft OneNote,是一套用于自由形式的信息获取以及多用户协作工具。OneNote最常用于笔记本电脑或台式电脑,但这套软件更适合用于支持手写笔操作的平板电脑,在这类设备上可使用触笔、声音或视频创建笔记。 感觉onenote就像纸质的笔记本&…

雷柏MT750S鼠标使用总结(驱动|连接|模式|续航)

【什么值得买 摘要频道】下列精选内容摘自于《无线办公好帮手 雷柏MT750S无线蓝牙鼠标体验》的片段: 驱动 雷柏MT750S的驱动软件界面比较简单,因为没有灯光的原因,软件主要是鼠标按键功能的设置,在左侧显示了各种功能&#xff0c…

1.0jpa 2.0_JPA 2.1实体图–第1部分:命名实体图

1.0jpa 2.0延迟加载通常是JPA 2.0的问题。 如果要使用FetchType.LAZY(默认)或FetchType.EAGER来加载关系,则必须在实体上进行定义,并且始终使用此模式。 仅当我们要始终加载关系时才使用FetchType.EAGER。 在几乎所有情况下都使用…

Notion,程序员最后一款笔记软件

市面上笔记软件五花八门,都各有特色。wolai、语雀、飞书、印象笔记、石墨、幕布、为知笔记.....等等,数不胜数,但我最终选择了notion,因为它实在太好用了!!!如果你之前没使用过,赶紧…

通过Main的Checkpoint Restore加快Java启动速度

Java虚拟机为已编译为字节码 (但不一定是用Java编写)的应用程序提供了托管运行时环境。 与为特定平台静态编译的代码相比,这为应用程序开发人员提供了许多好处,并且通常可以提高性能。 JVM通过垃圾回收器 (GC&#xff…

notion常用快捷键

由于我自己的电脑是window10系统,我也就只整理window系统的快捷键。notion官网上有全部快捷键的教程,链接如下: https://www.notion.so/Learn-the-shortcuts-66e28cec810548c3a4061513126766b0 这篇博客来自于我的CSDN账号,里面…

“操作无法完成因为其中的文件夹或文件已在另一个程序中打开”解决办法

在windows系统中,我们经常会遇到这样一个问题:删除某一个文件或者文件夹,被提醒:操作无法完成,因为其中的文件夹或文件已在另一个程序中打开。 这个时候我们一般会先检查是否真的有程序或者文件打开了没有关闭&#xf…

带有AngularJS资源的Spring Rest Controller

Angularjs ngResource是用于与基于REST的服务进行交互的angularjs模块。 我最近在Spring MVC的一个小型项目中使用了它,并希望记录一个对我来说很好的配置。 该控制器在工厂中运行,它支持在Hotel实体上进行CRUD操作,并支持以下方法&#xff…