为Lucene选择快速唯一标识符(UUID)

大多数使用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,序列),但是以不同的方式对位进行混洗以保留总体顺序。 我怀疑问题在于,在获取不同文档之间的数字之前,必须在片状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已被更新(除其中一个以外的所有其他ID),则该ID可能位于多个段中。

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

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

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

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

相关文章

ubuntu16.04设置静态ip

最近在课堂上,有很多同学反映在搭建环境的时候,虚拟机ip经常变,那么我们配置好的web服务可能就不能用了。下面讲一下如何在ubuntu上面设置静态ip 1:首先我们确认一下ubuntu的版本 cat /etc/issue 或者sudo lsb_release -a或者unam…

css布局:块级元素的居中

一.定宽&#xff1a; 1.定位居中(absolute) 方法一&#xff1a; html:<div class"main"></main>css:.main{width:400px;height:200px;background:#eee;position:absolute;left:50%;top:50%;margin-left:-200px;margin-top:-100px;} 方法二&#xff1a;…

精准客户数据服务

详情请点击&#xff1a;http://www.rulingtech.com 客户数据&#xff08;名录&#xff09;是市场营销活动不可或缺的重要资料。目前企业采用的客户名录数据主要通过订购黄页、购买第三方名录、自行搜集等途径。这些方式面临的问题是&#xff1a;数据重复度高、有效性差、准确率…

Maven常用的构建命令

Maven常用命令&#xff1a; Maven库&#xff1a; http://repo2.maven.org/maven2/ Maven依赖查询&#xff1a; http://mvnrepository.com/ 一&#xff0c;Maven常用命令&#xff1a; 1. 创建Maven的普通Java项目&#xff1a; mvn archetype:create-DgroupIdpackageName-Dartifa…

JPA 2.1实体图–第1部分:命名实体图

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

课时85.层叠性(掌握)

1.什么是层叠性&#xff1f; 层叠性就是CSS处理冲突的一种能力。 这个字体最终会变为红色 注意点&#xff1a; 层叠性只有在多个选择器选中“同一个标签”,然后又设置了“相同的属性”&#xff0c;才会发生层叠性。 CSS全称&#xff1a;Cascading StyleSheet 层叠样式表&am…

ABZ职业规划

关于职业规划&#xff0c;LinkedIn&#xff08;领英&#xff09;创始人里德霍夫曼&#xff08;Reid Hoffman&#xff09;提出著名的“ABZ理论”&#xff0c;教我们应对变化莫测的职场人生。 德霍父曼建议每个职场人应有A计划&#xff0c;B计划&#xff0c;C计划。 A计划&#x…

SetProcessWorkingSetSize减少内存占用

系统启动起来以后&#xff0c;内存占用越来越大&#xff0c;使用析构函数、GC.Collect什么的也不见效果&#xff0c;后来查了好久&#xff0c;找到了个办法&#xff0c;就是使用 SetProcessWorkingSetSize函数。这个函数是Windows API 函数。下面是使用的方法&#xff1a;[Syst…

Spring Boot 与消息 (JMS、AMQP、RabbitMQ)

RabbitMQ教程 - 鸟哥的专栏 - CSDN博客 一、概述 大多应用中&#xff0c;可通过消息服务中间件来提升系统异步通信、扩展解耦能力消息服务中两个重要概念&#xff1a;消息代理&#xff08;message broker)和目的地&#xff08;destination) 当消息发送者发送消息以后&#xff0…

使用Apache Camel通过soap添加WS-Security

WS-Security&#xff08;Web服务安全性&#xff09;是一种协议&#xff0c;可让您保护自己的soap Web服务。 发出Soap请求的客户端必须在Soap标头中提供登录名和密码。 服务器接收到肥皂请求&#xff0c;检查凭据并验证请求是否正确。 使用Apache Camel&#xff0c;可以很容易…

课时3.浏览器访问网页原理(理解)

浏览器访问网页原理&#xff08;理解&#xff09; 第一次打开IE6&#xff0c;发现系统自动生成了一个文件夹&#xff0c;所以我们可以得出这个文件夹必然和IE6有一定的关系先删除Internet Cache下的所有文件夹&#xff0c;然后通过IE6打开百度的首页&#xff0c;打开百度首页以…

matlab 图像平移操作

目标&#xff1a;对原图I进行[80,50]的偏移操作得到图B。 首先读入图像&#xff0c;以matlab自带的pout.tif为例. strel是创建形态学结构元素的. translate函数在原结构上进行[80,50]的偏移. I imread(cameraman.tif); se translate(strel(1),[80,50]); B imdilate(I,se);转…

爬虫之基于线程池异步抓取

from multiprocessing.dummy import Pool #线程池模块#必须只可以有一个参数 def my_requests(url):return requests.get(urlurl,headersheaders).textstart time.time() urls [http://127.0.0.1:5000/bobo,http://127.0.0.1:5000/jay,http://127.0.0.1:5000/tom, ]pool Poo…

使用xjc一秒钟生成您的JAXB类

由于JAXB是JDK的一部分&#xff0c;因此它是处理XML文档最常用的框架之一。 它提供了一种从XML文档检索数据并将其存储到Java类的简便方法。 因为几乎每个Java开发人员都已经使用过JAXB&#xff0c;所以我不会解释不同的JAXB批注。 相反&#xff0c;我将专注于一个名为xjc的命令…

课时27.base(掌握)

base标签就是专门用来统一的指定当前网页中所有的超链接&#xff08;a标签&#xff09;需要如何打开格式 <base target"_blank"> <a href"https://www.baidu.com">百度</a> 注意点&#xff1a; base标签必须写在head标签的开始标签和…

async await详解

async await本身就是promise generator的语法糖。 本文主要讲述以下内容 async awiat 实质async await 主要特性async await 实质 下面使用 promise generate 实现 async await // 转换目标 async1// async function async1() {// console.log(async1 start);// await …

JavaOne 2014 –有关提交的一些初步分析

这些天时间不多了。 并行发生的事情如此之多&#xff0c;当然&#xff0c;最重要的Java会议就是一切。 JavaOne 2014已经关闭了CfP门&#xff0c;投票正在进行中。 程序委员会几乎没有什么可以谈论的&#xff0c;但是去年跳过了这种分析之后&#xff0c;现在是我该寻求许可的时…

【搜索】$P1092$虫食算

【搜索】\(P1092\)虫食算 题目链接 首先&#xff0c;我们只考虑加法的虫食算。这里的加法是N进制加法&#xff0c;算式中三个数都有N位&#xff0c;允许有前导的0。 其次&#xff0c;虫子把所有的数都啃光了&#xff0c;我们只知道哪些数字是相同的&#xff0c;我们将相同的数字…

【译】XNA Shader 程序设计(二)

XNA Shader 程序设计 教程2 - 漫反射 大家好&#xff0c;今天我们将在教程一的基础上继续学习&#xff0c;在光照算式中加上漫反射光。 漫反射光 环境光计算等式为&#xff1a; I Aintensity * Acolor 漫反射基于这个等式&#xff0c;添加了一道有方向的光线&#xff1a; I A…

Jquery基础之DOM操作

Dom是Document Object Model的缩写&#xff0c;意思是文档对象模型。DOM是一种与浏览器、平台、语言无关的接口&#xff0c;使用该接口可以轻松访问页面中所有的标准组件。DOM操作可以分为三个方面即DOM Core(核心)、HTM-DOM和CSS-DOM。 JQuery中的DOM操作主要对包括&#xff…