lucene详细说明文档

以下部门功能在lucene5以上版本可能有的API所有改变

目录

1.简介

2.了解索引操作

2.1倒排索引

2.2字段类型

2.3细分

2.4文件编号

2.5搜索索引

3.创建索引

4.基本索引操作

4.1核心索引类

4.2将数据添加到索引

5.文件和领域

5.1文件

5.2领域

5.3在Lucene中增强文档

1.简介

该索引是利用Lucene的任何组件的核心。就像书籍的索引一样,它组织所有数据,以便可以快速访问。索引由包含一个或多个字段的文档组成。文档和字段可以代表我们选择的任何内容,但一个常见的隐喻是:文档表示数据库表中的条目,而字段类似于表中的字段。

2.了解索引操作

让我们看一下Lucene搜索索引的图形表示。

图1

图1

简而言之,当Lucene对文档进行索引时,它会将其分解为许多术语。然后,它将术语存储在索引文件中,其中每个术语与包含该术语的文档相关联。我们可以把它当作一个哈希表。术语是使用分析器生成的,该分析器将每个单词的词根都提取出来。发出查询时,将通过用于构建索引的同一分析器对该查询进行处理,然后使用该分析器在索引中查找匹配项。这提供了与查询匹配的文档列表。

现在,让我们看一下整个Lucene搜索过程。

基本概念是索引,文档,字段和术语。

  1. 索引包含文档的集合。
  2. 文档是字段的集合。
  3. 字段是术语的集合。
  4. 术语是成对的字符串<field,term-string>。

2.1倒排索引

索引存储有关术语的统计信息,以使基于术语的搜索更加高效。Lucene的索引属于称为反向索引的索引族。这是因为它可以长期列出包含它的文档。这与文档中列出术语的自然关系相反。

2.2字段类型

在Lucene中,可以存储字段,在这种情况下,它们的文本按原样存储在索引中,并且是不可逆的。反转的字段称为索引。字段可以被存储和被索引。

可以将字段的文本标记为要索引的术语,或者可以将字段的文本从字面上用作要索引的术语。大多数字段都是标记化的,但有时对于某些标识符字段按字面意义进行索引很有用。

2.3细分

Lucene索引可以由多个子索引或段组成。每个段都是完全独立的索引,可以分别进行搜索。索引按以下方式演变:

  1. 为新添加的文档创建新的细分。
  2. 合并现有的细分。
  3. 搜索可能涉及多个段和/或多个索引,每个索引可能由一组段组成。

2.4文件编号

在内部,Lucene通过整数文档号引用文档。添加到索引的第一个文档编号为零,并且随后添加的每个文档的编号都比前一个大。

请注意,文档编号可能会更改,因此在将这些编号存储在Lucene之外时应格外小心。特别是,在以下情况下数字可能会更改:

存储在每个段中的数字仅在该段内是唯一的,并且必须进行转换才能在更大的上下文中使用它们。标准技术是根据该段中使用的数字范围为每个段分配一个值范围。要将文档编号从段转换为外部值,需要添加段的基本文档编号。要将外部值转换回特定于细分的值,可以通过外部值所在的范围来标识细分,然后减去细分的基值。例如,可以合并两个五个文档的段,以便第一个段的基值为零,第二个为五个。第二段的文档三的外部值为8。

删除文档后,在编号中会留出空白。随着索引通过合并的发展,这些最终被删除。合并段时删除已删除的文档。因此,新合并的段在编号上没有间隙。

2.5搜索索引

搜索索引由javascript函数定义。它以类似于视图的地图功能的方式运行在所有文档上,并定义了搜索可查询的字段。搜索索引是数据库的一种变体。它与RDBMS相似,因为它需要快速查找密钥,但是大部分数据驻留在辅助存储上。

3.创建索引

到目前为止,我们已经看到了Lucene索引的所有组成部分。在本节中,我们将使用Lucene索引创建文档索引。

考虑一个项目,学生在其中提交年度杂志文章。输入控制台包含学生姓名,文章标题,文章类别和文章正文的选项。我们假设该项目正在网络上运行并且可以通过它进行访问。要为这篇文章建立索引,我们需要文章本身,作者姓名,撰写日期,文章主题,文章标题以及文件所在的URL。利用这些信息,我们可以构建一个程序,该程序可以正确索引文章以使其易于查找。

让我们看一下我们类的基本框架,包括我们将需要的所有导入。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
 
import java.util.Date;
 
public class ArticleIndexer {
 
}

我们需要添加的第一件事是将文章转换为Document对象的方法。

为此,我们将使用一种方法createDocument()

01
02
03
04
05
06
07
08
09
10
11
12
13
private Document createDocument(String article, String author,
                                    String title, String topic,
                                    String url, Date dateWritten) {
 
        Document document = new Document();
        document.add(Field.Text("author", author));
        document.add(Field.Text("title", title));
        document.add(Field.Text("topic", topic));
        document.add(Field.UnIndexed("url", url));
        document.add(Field.Keyword("date", dateWritten));
        document.add(Field.UnStored("article", article));
        return document;
    }

首先,我们创建一个新Document对象。我们需要做的下一步是将文章的不同部分添加到中Document。我们为每个部分指定的名称完全是任意的,并且像。中的键一样工作HashMap。使用的名称必须是String。Document的add方法将使用一个Field对象,该对象使用Field类中提供的静态方法之一构建。提供了四种将Field对象添加到文档的方法。

Field.Keyword–数据已存储并建立索引,但未标记。这对于应保留不变的数据(例如日期)最有用。实际上,Field.Keyword可以将Date对象作为输入。

Field.Text–数据被存储,索引和标记化。Field.Text字段不应用于诸如文章本身之类的大量数据,因为索引将变得非常大,因为它将包含文章的完整副本以及标记化的版本。

Field.UnStored–数据不存储,但被索引和标记。大量数据(例如文章的文本)应放置在未存储的索引中。

Field.UnIndexed–数据已存储,但未编制索引或标记。它与要与搜索结果一起返回的数据一起使用,但实际上不会在该数据上进行搜索。在我们的示例中,由于我们不允许搜索URL,因此没有理由对其进行索引,但是我们希望在找到搜索结果后将其返回给我们。

现在我们有了一个Document对象,我们需要将其IndexWriter写入Document索引。

1个
2
3
4
5
6
7
8
9
String indexDirectory = "lucene-index";
 
    private void indexDocument(Document document) throws Exception {
        Analyzer analyzer  = new StandardAnalyzer();
        IndexWriter writer = new IndexWriter(indexDirectory, analyzer, false);
        writer.addDocument(document);
        writer.optimize();
        writer.close();
    }

我们首先创建一个StandardAnalyzer,然后IndexWriter使用分析器创建一个。在构造函数中,我们必须指定索引将驻留的目录。构造函数末尾的布尔值告诉IndexWriter它是应该创建新索引还是将其添加到现有索引。在将新文档添加到现有索引时,我们将指定false。然后,将添加Document到索引。最后,我们优化然后关闭索引。如果要添加多个Document对象,则应始终进行优化,然后在将所有Document对象都添加到索引之后关闭索引。

现在,我们只需要添加一种将各个部分组合在一起的方法即可。

为了驱动索引​​操作,我们将编写一个带有indexArticle()一些参数的方法。

1个
2
3
4
5
6
7
8
9
public void indexArticle(String article, String author,
                             String title, String topic,
                             String url, Date dateWritten)
                             throws Exception {
        Document document = createDocument(article, author,
                                           title, topic,
                                           url, dateWritten);
        indexDocument(document);
    }

对文章运行该文章会将其添加到索引中。将IndexWriter构造函数中的布尔值更改为true会创建一个索引,因此我们应该在第一次创建索引以及每次要从头开始重建索引时使用它。现在我们已经构建了索引,我们需要在索引中搜索文章。

索引存储为单个目录中的一组文件。

索引由任意数量的独立段组成,这些段存储有关已索引文档子集的信息。每个段都有自己的术语词典,术语词典索引和文档存储(存储的字段值)。所有段数据都存储在_xxxxx.cfs文件中,其中xxxxx是段名称。

创建索引段文件后,将无法对其进行更新。新文档将添加到新段中。删除的文档仅在可选的.del文件中标记为已删除。

4.基本索引操作

索引数据

Lucene让我们可以索引文本格式的任何可用数据。Lucene几乎可以用于任何数据源,只要可以从中提取文本信息即可。我们可以使用Lucene对存​​储在HTML文档,Microsoft Word文档,PDF文件等中的数据进行索引和搜索。索引数据的第一步是使其以简单文本格式可用。可以使用自定义解析器和数据转换器。

索引过程

索引编制是将文本数据转换为便于快速搜索的格式的过程。一个简单的类比是您在书末找到的索引:该索引将您指向书中出现的主题的位置。

Lucene将输入数据存储在称为反向索引的数据结构中,该数据结构作为一组索引文件存储在文件系统或内存中。大多数Web搜索引擎使用反向索引。它使用户可以执行快速的关键字查找,并找到与给定查询匹配的文档。在将文本数据添加到索引之前,分析器会对其进行处理(使用分析过程)。

分析

分析将文本数据转换为基本搜索单位,称为术语。在分析过程中,文本数据会经历多种操作:提取单词,删除常用单词,忽略标点符号,将单词简化为词根形式,将单词更改为小写字母等。分析仅在建立索引和查询解析之前进行。分析将文本数据转换为标记,并将这些标记作为术语添加到Lucene索引中。

Lucene的带有各种内置的分析,比如SimpleAnalyzerStandardAnalyzerStopAnalyzerSnowballAnalyzer,等等。它们在标记文本和应用过滤器的方式上有所不同。由于分析会在索引编制之前删除单词,因此会减小索引大小,但会对查询处理的精度产生负面影响。通过使用Lucene提供的基本构建块创建自定义分析器,可以对分析过程进行更多控制。表1显示了一些内置分析仪及其处理数据的方式。

4.1核心索引类

目录

代表索引文件存储位置的抽象类。通常主要使用两个子类:

FSDirectory—将目录存储在实际文件系统中的Directory的实现。这对于大索引很有用。

RAMDirectory—一种将所有索引存储在内存中的实现。这适用于较小的索引,这些索引可以完全加载到内存中,并在应用程序终止时销毁。由于索引保存在内存中,因此速度相对较快。

分析仪

如所讨论的,分析器负责预处理文本数据并将其转换为存储在索引中的令牌。IndexWriter接受用于索引数据之前对数据进行标记的分析器。为了正确地为文本建立索引,您应该使用适合需要被索引的文本语言的分析器。

默认分析器适用于英语。Lucene沙箱中还有其他一些分析器,包括中文,日文和韩文的分析器。

IndexDeletionPolicy

用于实现自定义从索引目录中删除过时提交的策略的接口。默认的删除策略是KeepOnlyLastCommitDeletionPolicy,它仅保留最近的提交,并在完成新提交后立即删除所有先前的提交。

IndexWriter

创建或维护索引的类。它的构造函数接受一个布尔值,该布尔值确定是创建新索引还是打开现有索引。它提供了添加,删除或更新索引中文档的方法。

对索引所做的更改最初会在内存中进行缓冲,并定期刷新到索引目录。IndexWriter公开了几个字段,这些字段控制如何在内存中缓冲索引并将其写入磁盘的方式。IndexReader除非IndexWriter调用的commit或close方法,否则看不到对索引所做的更改。IndexWriter为目录创建一个锁定文件,以防止索引同时更新导致索引损坏。IndexWriter允许用户指定可选的索引删除策略。

4.2将数据添加到索引

将文本数据添加到索引涉及两个类。

字段表示在搜索中查询或检索的一条数据。Field类封装一个字段名称及其值。Lucene提供了一些选项来指定是否需要对字段进行索引或分析以及是否需要存储其值。在创建字段实例时可以传递这些选项。下表显示了字段元数据选项的详细信息。

选项描述
Field.Store.Yes用于存储字段的值。适用于显示搜索结果的字段,例如文件路径和URL。
Field.Store.No字段值未存储-例如,电子邮件正文。
Field.Index.No适用于未搜索的字段-通常与存储的字段(例如文件路径)一起使用。
Field.Index.ANALYZED用于索引但未分析的字段。它完整​​地保留了字段的原始值,例如日期和个人名称。
Field.Index.NOT_ANALYZED用于索引但未分析的字段。它完整​​地保留了字段的原始值,例如日期和个人名称。

字段元数据选项的详细信息

而文档是字段的集合。Lucene还支持增强文档和字段,如果要重视某些索引数据,这是一个有用的功能。为文本文件建立索引包括将文本数据包装在字段中,创建文档,在字段中填充文档,以及使用将文档添加到索引中IndexWriter

5.文件和领域

如您先前所见,文档是索引和搜索过程的单元。

5.1文件

文档是一组字段。每个字段都有一个名称和一个文本值。字段可以与文档一起存储,在这种情况下,它会随文档的搜索命中一起返回。因此,每个文档通常应包含一个或多个唯一标识它的存储字段。

您将文档添加到索引,并且在执行搜索之后,您将获得结果列表,它们是文档。文档只是字段的非结构化集合。

5.2领域

字段是Lucene.net的实际内容所有者:它们基本上是一个哈希表,具有名称和值。如果我们拥有无限的磁盘空间和无限的处理能力,那就是我们所需要知道的。但是不幸的是,磁盘空间和处理能力受到限制,因此您不能仅分析所有内容并将其存储到索引中。但是Lucene.net提供了将字段添加到索引的不同方法。

Lucene的提供四种不同的类型从一个开发者可以选择字段:KeywordUnIndexedUnStored,和Text。您应该使用哪种字段类型取决于您要如何使用该字段及其值。

关键字字段未标记,但被逐字索引并存储在索引中。此字段适用于原始值应完整保留的字段,例如URL,日期,个人姓名,社会保险号,电话号码等。

未索引字段既没有标记也没有索引,但它们的值存储在逐字索引中。该字段适用于需要与搜索结果一起显示但绝不会直接搜索其值的字段。由于未对这种类型的字段建立索引,因此对其进行搜索很慢。由于此类型的字段的原始值存储在索引中,因此如果存在索引大小的问题,则此类型不适合存储具有非常大值的字段。

未存储字段与未索引字段相反。此类型的字段已标记并建立索引,但未存储在索引中。此字段适用于索引大量不需要以其原始形式检索的文本,例如网页正文或任何其他类型的文本文档。

文本字段被标记,索引并存储在索引中。这意味着可以搜索此类型的字段,但请注意存储为“文本”字段的字段的大小。

如果您回顾一下LuceneIndexExample该类,将会看到我使用了一个Text字段:

1个
document.add(Field.Text("fieldname", text));

如果要更改字段的类型,fieldname我们将调用Field类的其他方法之一:

1个
document.add(Field.Keyword("fieldname", text));

要么

1个
document.add(Field.UnIndexed("fieldname", text));

要么

1个
document.add(Field.UnStored("fieldname", text));

虽然Field.TextField.KeywordField.UnIndexed,和Field.UnStored电话可以先看看来电来样构造,他们真的只是为了不同的Field类方法的调用。表1总结了不同的字段类型。

现场方法/类型代币化索引已储存
Field.Keyword(String, String)没有
Field.UnIndexed(String, String)没有没有
Field.UnStored(String, String)没有
Field.Text(String, String)
Field.Text(String, Reader)没有

表1:不同字段类型的概述。

5.3在Lucene中增强文档

在“信息检索”中,文档与搜索的相关性通过与查询的相似程度来衡量。Lucene中实现了几种相似性模型,您可以通过扩展相似性类并使用Lucene保存的索引统计信息来实现自己的相似性模型。还可以为文档分配静态分数,以表示它们在整个语料库中的重要性,而与正在执行的查询无关,例如其受欢迎程度,评分或PageRank。

在Lucene 4.0之前,您可以通过调用为文档分配静态分数document.setBoost。在内部,通过将字段的提升因子乘以文档的提升因子,将提升应用于文档的每个字段。但是,这永远无法正常工作,并且取决于所执行查询的类型,可能根本不会影响文档的排名。

通过在lucene中添加DocValues,增强文档就像在中添加a NumericDocValuesField并在中使用它一样容易CustomScoreQuery,它将计算出的分数乘以“ boost”字段的值。下面的代码示例说明了如何实现此目的:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
// add two documents to the index
Document doc = new Document();
doc.add(new TextField("f", "test document", Store.NO));
doc.add(new NumericDocValuesField("boost", 1L));
writer.addDocument(doc);
 
doc = new Document();
doc.add(new TextField("f", "test document", Store.NO));
doc.add(new NumericDocValuesField("boost", 2L));
writer.addDocument(doc);
 
// search for 'test' while boosting by field 'boost'
Query baseQuery = new TermQuery(new Term("f", "test"));
Query boostQuery = new FunctionQuery(new LongFieldSource("boost"));
Query q = new CustomScoreQuery(baseQuery, boostQuery);
searcher.search(q, 10);

通过编写一个简单的公式,新的Expressions模块也可以用于增强文档,如下所示。尽管比使用verbose更冗长CustomScoreQuery,但它通过计算更复杂的公式(例如sqrt(_score)+ ln(boost))变得微不足道。

1个
2
3
4
5
6
Expression expr = JavascriptCompiler.compile("_score * boost");
SimpleBindings bindings = new SimpleBindings();
bindings.add(new SortField("_score", SortField.Type.SCORE));
bindings.add(new SortField("boost", SortField.Type.LONG));
Sort sort = new Sort(expr.getSortField(bindings, true));
searcher.search(baseQuery, null, 10, sort);

既然Lucene允许NumericDocValuesField在不重新索引文档的情况下更新,您就可以将频繁变化的字段(受欢迎程度,评分,价格,最后修改时间…)纳入提升因素,而无需每次对文档进行任何索引时都重新为其编制索引。

 

文章来源:https://www.javacodegeeks.com/2015/09/building-a-search-index-with-lucene.html#boostingdocumentsinlucene

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

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

相关文章

分布式集群架构场景解决方案学习笔记

课程学习 一致性哈希算法集群时钟同步问题分布式ID解决方案分布式任务调度问题session共享(一致性)问题 一致性哈希算法 一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的&#xff0c;设计目标是为了解决因特网中的热点(Hot spot)问题&#xff0c…

分布式学习-总结

文章目录分布式理论分布式系统定义以及面临的问题分布式系统定义分布式面临的问题通信异常网络分区三态节点故障分布式理论&#xff1a;一致性概念分布式一致性的提出强一致性弱一致性最终一致性分布式事务CAP定理什么是CAP理论&#xff1f;为什么只能3选2能不能解决3选2的问题…

什么叫死锁?死锁案例?死锁必须满足哪些条件?如何定位死锁问题?有哪些解决死锁策略?哲学家问题?

1.死锁是什么&#xff1f; 死锁一定发生在并发环境中&#xff0c;死锁是一种状态&#xff0c;当两个(或者多个线程)相互持有对方所需要的资源&#xff0c;却又都不主动释放手中持有的资源&#xff0c;导致大家都获取不到自己想要的资源&#xff0c;所有相关的线程无法继续执行…

dubbo启动服务启动报错.UnsatisfiedDependencyException: Error creating bean with name '***': Un

报错信息&#xff1a; 今天部署开发环境的时候这个问题弄了一下午&#xff0c;由于我本地启动是好的&#xff0c;然后部署到服务器老是启动不了&#xff0c;报如上错&#xff0c;后来经过排查发现是provider.xml和consumer.xml中的如下代码version属性版本信息不一致。 <du…

【转载保存】dubbo学习笔记

Dubbo Dubbo简介 首先&#xff0c;我理解的Dubbo&#xff0c;从大的方向来看是单体应用到分布式应用过度期的一个产物&#xff0c;具体来说应该是分布式应用从早期的SOA到微服务过度的一个产物。 在编写分布式场景下高并发、高扩展的系统对技能的要求很高&#xff0c;因为这…

mysql搭建手册

mysql搭建手册 主从搭建 搭建mysql 关闭防火墙&#xff1a;systemctl stop firewalld 如果失败先安装 yum install iptables-services 配置数据库 /etc/my.cnf&#xff0c;配置同步数据库等 主库配置信息 [mysqld] datadir/usr/local/mysql/data log-error/usr/local/mysql/…

MongoDb安装配置

Mongodb学习 Mongodb安装 1.下载社区版 MongoDB 4.1.3 去官网下载对应的MongoDB 然后上传到Linux虚拟机 2.将压缩包解压即可 tar -zxvf MongoDB-linux-x86_64-4.1.3.tgz3.启动 mkdir -p /data/db./bin/mongod4.指定配置文件方式的启动 配置文件样例: dbpath/data/mongo…

FastDFS学习笔记

FastDFS课程内容 第一部分&#xff1a;FastDFS基础回顾 为什么要有分布式文件系统、分布式文件系统对比、FastDFS特性、linux安装、java访问FastDFS 第二部分&#xff1a;FastDFS系统架构和功能原理 架构详解、架构设计的概念、设计理念、功能原理(上传、下载、文件同步、删…

redis主从搭建和分片集群搭建

文章目录redis主从搭建搭建一主一从&#xff1a;下载安装redis&#xff1a;两台机器都需要操作权限认证理解主从复制原理、同步数据集全量同步三个阶段&#xff1a;增量同步&#xff1a;心跳检测redis哨兵模式部署方案搭建配置哨兵模式原理建立连接获取主服务器信息获取从服务器…

如何利用redis实现秒杀系统

文章目录题记利用Watch实现Redis乐观锁题记 在线思维导图总结&#xff1a;redis大纲 利用Watch实现Redis乐观锁 乐观锁基于CAS&#xff08;Compare And Swap&#xff09;思想&#xff08;比较并替换&#xff09;&#xff0c;是不具有互斥性&#xff0c;不会产生锁等待而消 耗…

教你如何使用redis分布式锁

文章目录一、redis客户端实现应用1.利用set nx命令实现分布式锁2.利用分布式锁命令 setnx问题1.为什么不直接调用jedis.del(key)方法而采用redislua实现&#xff1f;2.上述两种方式存在的问题&#xff1f;3.根本原因分析二、分布式场景Redission分布式锁的使用1.分布式锁的特性…

本地缓存之Guava简单使用

文章目录使用场景Guava Cache 的优势Guava Cache使用CacheLoaderCallable删除主动删除过期删除基于容量删除引用删除高级用法并发设置更新锁定GuavaCache高级实战之疑难问题GuavaCache会oom&#xff08;内存溢出&#xff09;吗GuavaCache缓存到期就会立即清除吗GuavaCache如何找…

java中强引用、弱引用、软引用、虚引用学习

文章目录强引用弱引用软引用虚引用将引用之前首先让我们一起回顾一下java对象的生命周期强引用 在实际开发场景中&#xff0c;我们一般使用的都是强引用&#xff0c;只要强引用存在&#xff0c;垃圾回收即使OOM也不会回收&#xff0c;知道强引用释放以后&#xff0c;对象才会被…

mysql left join、right join、inner join、union、union all使用以及图解

左外连接&#xff1a;left join sql语法&#xff1a;LEFT JOIN LEFT OUTER JOIN 首先需要创建两张表做测试&#xff0c;表数据如下所示 table 1 表&#xff1a; table2 表&#xff1a; 查询sql&#xff1a; select * from table1 a LEFT JOIN table2 b on a.idb.id 总结&a…

第十八章 Swing程序设计

Swing用于开发桌面窗体程序&#xff0c;是JDK的第二代GUI框架&#xff0c;其功能比JDK第一代GUI框架AWT更为强大、性能更加优良。但因为Swing技术推出时间太早&#xff0c;其性能、开发效率等不及一些其他流行技术&#xff0c;所以目前市场上大多数桌面窗体程序都不是由Java开发…

redis stream学习总结

文章目录streamStream基本概念消息id消息内容增删查改消息生产添加消息 xadd查看消息长度 xlen限制stream最大长度1.xadd 中添加**maxlen**:2.xtrim查询消息 xrange正向排序&#xff1a;消费id从小到大排反向查询&#xff1a;消费id从大到小排删除消息消息消费独立消费 xread消…

常用的限流算法学习

常用的限流算法有漏桶算法和令牌桶算法&#xff0c;guava的RateLimiter使用的是令牌桶算法&#xff0c;也就是以固定的频率向桶中放入令牌&#xff0c;例如一秒钟10枚令牌&#xff0c;实际业务在每次响应请求之前都从桶中获取令牌&#xff0c;只有取到令牌的请求才会被成功响应…

基于rocketMq秒杀系统demo

基于RocketMQ设计秒杀。 要求&#xff1a; 1. 秒杀商品LagouPhone&#xff0c;数量100个。 2. 秒杀商品不能超卖。 3. 抢购链接隐藏 4. NginxRedisRocketMQTomcatMySQL 实现 接口说明&#xff1a;https://www.liuchengtu.com/swdt/#R9f978d0d00ef9be99f0…

基于Curator实现dubbo服务自动注册发现

文章目录概念基于ServiceDiscovery实现服务自动注册和发现Service:服务基本信息InstanceDetails:封装实例用过来保存到zk中ServiceProvider&#xff1a;服务提供者ServiceConsumer&#xff1a;服务消费者运行基于ServiceDiscovery、ServiceCache实现服务自动注册和发现Registry…

jdk、cglib动态代理代码示例

文章目录jdk动态代理实现步骤代码示例新建一个接口新建一个接口的实现类新建一个代理类调用测试cglib动态代理实现实现步骤创建一个实现类新建一个代理类调用测试jdk动态代理 实现步骤 新建一个接口新建一个接口的实现类新建一个代理类&#xff0c;实现InvocationHandler接口…