Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 频繁更新lucene索引导致性能下降_C# 4.0_Sql Server 2012_Lucene.net - Fatal编程技术网

C# 4.0 频繁更新lucene索引导致性能下降

C# 4.0 频繁更新lucene索引导致性能下降,c#-4.0,sql-server-2012,lucene.net,C# 4.0,Sql Server 2012,Lucene.net,我正在尝试将lucene.net添加到我的项目中,搜索将获得更复杂的数据。但事务(或频繁修改表,如插入新数据或修改lucene索引中使用的字段) 在这里使用lucene.net搜索好吗 如何找到已修改的字段并更新到已创建的特定lucene索引?Lucene索引包含从表中删除的文档,那么如何从Lucene索引中删除它们 正在加载时 我已删除了基于唯一字段的表中不可用的索引 如果索引不存在则插入,否则更新与表唯一字段匹配的所有索引 在加载页面时,由于我调用了删除/插入/更新索引方法,它比正常情况下花

我正在尝试将lucene.net添加到我的项目中,搜索将获得更复杂的数据。但事务(或频繁修改表,如插入新数据或修改lucene索引中使用的字段)

在这里使用lucene.net搜索好吗

如何找到已修改的字段并更新到已创建的特定lucene索引?Lucene索引包含从表中删除的文档,那么如何从Lucene索引中删除它们

正在加载时

  • 我已删除了基于唯一字段的表中不可用的索引
  • 如果索引不存在则插入,否则更新与表唯一字段匹配的所有索引
  • 在加载页面时,由于我调用了删除/插入/更新索引方法,它比正常情况下花费了更多的时间


    我怎样才能继续呢?

    你应该按照一定的时间表(定期)编制索引。最简单的方法是保留上一次索引的日期,然后查询此后的所有更改,并为新记录编制索引、更新和删除记录。为了跟踪数据库中删除的条目,您需要有一个包含删除日期的已删除记录日志。然后,您可以使用该日期查询需要从lucene中删除的内容

    现在只需每隔2分钟左右运行一次该作业


    Lucene.net说,你不太适合Web应用程序,你应该考虑使用弹性搜索、SoR或AuuRebug。基本上,服务器可以更好地处理负载和多线程。

    您应该根据一些时间表(定期)优先索引。最简单的方法是保留上一次索引的日期,然后查询此后的所有更改,并为新记录编制索引、更新和删除记录。为了跟踪数据库中删除的条目,您需要有一个包含删除日期的已删除记录日志。然后,您可以使用该日期查询需要从lucene中删除的内容

    现在只需每隔2分钟左右运行一次该作业


    Lucene.net说,你不太适合Web应用程序,你应该考虑使用弹性搜索、SoR或AuuRebug。基本上,服务器可以更好地处理负载和多线程。

    Lucene绝对适合这种类型的功能。它是完全线程安全的。。。如果你用对了

    解决方案指针

    创建单个IndexWriter并将其保存在全局可访问的单例中(可以是全局静态变量,也可以通过依赖项注入)。IWs是完全线程安全的。切勿在同一文件夹上打开多个IW

    通过此单例执行所有更新/删除。(我有一个项目每秒执行100次操作,没有任何问题,即使是在稍微糟糕的硬件上)

    根据更改频率和应用程序可接受的延迟,您可以:

    • 每次更新数据库时,向索引发送更新/删除
    • 保留一个“事务日志”或队列(可能在同一个数据库中),记录更改的行和删除(否则将跟踪)。然后通过使用日志/队列更新索引
    要搜索,请使用
    searcher=newindexsearcher(writer.GetReader())
    创建索引搜索器。这是NRT(近实时)模式的一部分。切勿在同样由IW打开的索引文件夹上创建单独的IndexReader

    根据您的使用模式,您可能希望在发生更改和这些更改对搜索“可见”之间引入一段“延迟”时间

    IS的实例也是线程安全的。因此,您还可以保留一个IS实例,通过该实例进行所有搜索。然后定期重新创建它(如使用计时器),然后使用
    Interlocked.Exchange
    交换它

    我之前创建了一个小框架,将其与应用程序隔离,并使其可重用

    警告

    话虽如此。。。在IIS中托管这个确实会引起一些问题。IIS偶尔会重新启动你的应用程序。Is也将(默认情况下)在停止现有实例之前启动新实例,然后交换它们(因此您看不到新实例的启动时间)

    因此,在短时间内,将有两个writer实例(这很糟糕!)

    您可以告诉IIS禁用“重叠”或增加重新启动之间的时间。但这将导致其他副作用

    因此,您实际上最好创建一个单独的服务来托管您的lucene位。一个简单的自托管WebAPI Windows服务非常理想而且非常简单。这还使您能够更好地控制索引文件夹的位置,并能够将其托管在不同的计算机上(这将隔离磁盘IO负载)。这意味着该服务可以从系统的其他部分访问、单独测试等

    为什么这项服务比建议的其他服务“更好”

    这是一个选择的问题。我是ElasticSearch的超级粉丝。它解决了许多关于规模和弹性的问题。它还使用了最新版本的Java Lucene,在功能和性能方面远远领先于Lucene.net。(其他两个也一样)

    但是,ES和Solr是Java(这可能是您的问题,也可能不是)。AzureSearch托管在Azure中,这也可能是个问题,也可能不是

    所有这三项都需要学习曲线,需要基础设施支持或外部第三方SaaS承诺

    如果您将服务保留在内部和c#中,它将保持简单,您可以控制功能,并且可以根据您的需要改变API的形状


    没有“正确”的答案。你必须根据自己的情况做出选择。

    Lucene绝对适合这种功能。它是完全线程安全的。。。如果你用对了

    解决方案指针

    创建一个IndexWriter并将其保存在全局可访问的sin中