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快速入门

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

  1. java安卓开发 快速入门_安卓程序员如何快速入门后端开发常识

    首先,对于安卓开发人员来说,学习一下后端开发知识是有必要的,一方面可以拓展自身的知识面,另一方面也可以推动自己走向全栈程序员发展路线,在云计算时代,全栈程序员的发展空间会更大一些. 相对来说,安卓程序 ...

  2. 【笔记目录1】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 1 2 下一页  任务50:Identity MVC:DbContextSeed初始化 GASA 2019-03-02 14:09 阅读:16 ...

  3. bootstrap快速入门_在5分钟内学习Bootstrap 4-快速入门指南

    bootstrap快速入门 了解世界上最受欢迎的前端组件库的最新版本. (Get to know the newest version of the worlds most popular front ...

  4. java redis快速入门_快速入门Redis系列(3)——Redis的JavaAPI操作(附带练习)

    作为快速入门Redis系列的第三篇博客,本篇为大家带来的是Redis的JavaAPI操作. 码字不易,先赞后看! Redis的JavaAPI操作 看完了上一篇博客,相信大家对于Redis的数据类型有了 ...

  5. python的快速入门-1.1、Python快速入门(0529)

    学习来自马哥教育的视频,感谢马哥 编程语言: 用户: 问题空间 计算机:解决问题 解空间 抽象: 机器代码-->微码编程-->高级语言 (语言的高下级的是根据语言是否被人类容易理解或者更接 ...

  6. python快速编程入门教程-半小时带你快速入门Python编程,Python快速入门教程

    1,Introduction to Python (Python入门) 2,Python是什么? Python 官方网站的描述 Python is a programming language tha ...

  7. mybaitis快速生成_关于Mybatis-Plus代码生成器快速使用心得

    1.使用背景 偶然情况下,同事介绍Mybatis-Plus有一个代码生成的功能,能够通过 AutoGenerator 快速生成 Entity.Mapper.Mapper XML.Service.Con ...

  8. python快速入门教程-终于理解python快速入门教程

    跟Java语言一样,python语言也有类的概念,直接使用class关键字定义python类.在python类,定义类的方法.然后直接使用类的初始化调用自身,获取相应的属性.以下是小编为你整理的pyt ...

  9. Kylin快速入门系列(2) | Kylin的快速入门

      大家好,我是不温卜火,是一名计算机学院大数据专业大二的学生,昵称来源于成语-不温不火,本意是希望自己性情温和.作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己 ...

最新文章

  1. php fsockopen解决办法
  2. 2018-3-28 基本粒子群优化算法
  3. 什么是__pycache__?
  4. jquery选择器的一些处理
  5. no acceptable C compiler found in $PATH
  6. 让div垂直以及水平居中浏览器窗口
  7. chajian8.com谈:SyntaxHighlighter 代码高亮
  8. ubuntu下搭建车场环境(代码使用jekins构建)
  9. 功能测试的时代,结束了?
  10. 如何配置 strongSwan 客户端 -- 节选自 OpenSuSE 中文用户手册
  11. 【c4d学习笔记】OC渲染器安装问题
  12. 将字体变成红色加粗字体
  13. Flutter:bottomNavigationBar图标白色的解决办法
  14. 【专题】经典DP问题(上)
  15. CPU四核八线程和四核四线程的区别
  16. pat basic 1100 校庆
  17. Airflow2.2.5任务调度工具
  18. 大王卡40G封顶怎么解除?腾讯王卡永久解除限流方法
  19. VLOOKUP常见错误及解决办法
  20. 华为交换机网页配置vlan

热门文章

  1. nssl1231-Gift【01背包,dp】
  2. 2018NOIP普及组初赛解析
  3. GYM101933I - Intergalactic Bidding
  4. HDU5129 - Yong Zheng's Death
  5. Hadoop入门(十五)Mapreduce的数据排序程序
  6. Hadoop入门(十三)远程提交wordCout程序到hadoop集群
  7. 汇编语言(五)之数组中正数和负数分离
  8. 吃透这套架构演化图,从零搭建Web网站也不难
  9. Spring入门(二)之下载与安装
  10. 新的学期、新的开始、新的付出、新的收获!