使用 Solr 搜索索引作为数据库 - 这是“错误的”吗?

Posted

技术标签:

【中文标题】使用 Solr 搜索索引作为数据库 - 这是“错误的”吗?【英文标题】:Using Solr search index as a database - is this "wrong"? 【发布时间】:2011-05-14 14:27:12 【问题描述】:

我的团队正在与使用 Solr 作为搜索索引的第三方 CMS 合作。我注意到作者似乎在使用 Solr 作为各种数据库,因为返回的每个文档都包含两个字段:

    Solr 文档 ID(基本上是类名和数据库 ID) 整个对象的 XML 表示

所以基本上它对 Solr 运行搜索,下载对象的 XML 表示,然后从 XML 实例化对象,而不是使用 id 在数据库中查找它。

我的直觉告诉我这是一种不好的做法。 Solr 是一个搜索索引,而不是数据库……所以对我来说,对 Solr 执行复杂的搜索、获取文档 ID,然后从数据库中提取相应的行更有意义。

当前的实现是否完美,或者是否有数据支持重构成熟的想法?

编辑:当我说“XML 表示”时 - 我的意思是一个存储字段,其中包含所有对象属性的 XML 字符串,而不是多个存储字段。

【问题讨论】:

只是出于好奇,它是什么 CMS? 【参考方案1】:

是的,您可以将 SOLR 用作数据库,但有一些非常严重的警告:

    SOLR 最常见的访问模式,即通过 http 对批量查询没有特别好的响应。此外,SOLR 不会流式传输数据——因此您不能一次懒惰地遍历数百万条记录。 这意味着您在使用 SOLR 设计大规模数据访问模式时必须非常周到。

    虽然 SOLR 性能可以水平(更多机器、更多内核等)以及垂直(更多 RAM、更好的机器等)扩展,但 与成熟的关系型数据库。也就是说,有一些很棒的功能,比如字段统计查询,非常方便。

    习惯使用关系数据库的开发人员在 SOLR 范例中使用相同的 DAO 设计模式时经常会遇到问题,因为 SOLR 在查询中使用过滤器的方式。 将有一个学习曲线来开发正确的方法来构建使用 SOLR 进行部分大型查询或全状态修改的应用程序

    允许许多高级 Web 框架(Ruby、Hibernate 等)提供的高级会话管理和有状态实体的“企业”工具将不得不完全抛弃强>。

    关系数据库旨在处理复杂的数据和关系 - 因此它们伴随着最先进的指标和自动分析工具。 在 SOLR 中,我发现自己编写了这样的工具并进行了很多手动压力测试,这可能会浪费时间

    加入:这是大杀手。关系数据库支持构建和优化基于简单谓词连接元组的视图和查询的方法。 在 SOLR 中,没有任何可靠的方法可以跨索引连接数据。

    弹性:为实现高可用性,SolrCloud 在底层使用分布式文件系统(即 HCFS)。这种模型与关系数据库的模型完全不同,关系数据库通常使用从属和主控或 RAID 等来实现弹性。因此,如果您希望 SOLR 具有云可扩展性和抗性,您必须准备好提供 SOLR 所需的弹性基础架构。

也就是说 - SOLR 对于某些任务有很多明显的优势:(参见http://wiki.apache.org/solr/WhyUseSolr) - 松散的查询更容易运行并返回有意义的结果。索引是默认完成的,因此大多数任意查询都非常有效地运行(与 RDBMS 不同,您通常必须在事后进行优化和反规范化)。

结论:尽管您可以将 SOLR 用作 RDBMS,但您可能会发现(就像我一样)最终“没有免费的午餐”——以及超酷的 lucene 文本所节省的成本- 搜索和高性能的内存索引通常以较低的灵活性和采用新的数据访问工作流程为代价。

【讨论】:

批量查询:简单地并发发送多个HTTP请求。流式传输:您可以使用分页轻松地模拟这一点。会话管理/有状态实体:这仅对事务性应用程序有效。压力测试:使用 SolrMeter,无需“手动”进行。加入:大多数(所有?)NoSQL 数据库都是这样。 我不同意加入评论:例如,在 mongo 中,加入更容易,因为可以在事后对输入进行索引。 RDBMS 也一样。关于模拟流的分页,我认为您需要编写一些复杂的代码来执行此操作,并且仍然不清楚它是否会在请求之间保持一致。 感谢您的回复。我对 MongoDB 不是很熟悉,但文档说“MongoDB 不支持连接,因此有时需要一些非规范化”(mongodb.org/display/DOCS/MongoDB+Data+Modeling+and+Rails)。编写代码来模拟分页流式传输是微不足道的,至少在 .NET(~15 LoC)中是这样,尽管你是对的,它假设索引在请求之间不会改变。 是的,你是对的 mongo 查询不加入集合,但是可以使用 m/r 或编程方式以多种方式加入数据...通过事后添加索引。 更新:在 SOLR 4 中:有些不太准确。交易较少,规模更容易/更便宜,索引是分布式的。【参考方案2】:

将 Solr 用作数据库是完全合理的,具体取决于 您的 应用程序。事实上,guardian.co.uk is doing 差不多就是这样。

这本身绝对是不是不好的做法。只有当你以错误的方式使用它时才会很糟糕,就像任何级别的任何其他工具一样,甚至是 GOTO。

当您说“一种 XML 表示...”时,我假设您是在谈论存储多个 Solr 字段并使用 Solr 的 XML 格式检索它,而不仅仅是一个大的 XML 内容字段(这将是一个糟糕的用途索尔)。 Solr 使用 XML 作为默认响应格式这一事实在很大程度上无关紧要,您也可以使用 binary protocol,因此在这方面与传统的关系数据库相当。

最终,这取决于您的应用程序的需求。 Solr 主要是一个文本搜索引擎,但也可以作为许多应用程序的 NoSQL 数据库。

【讨论】:

我们有几个索引字段,但实际上只存储了两个 - 文档 ID 和文档 XML。所以是的,它实际上只是一个巨大的 XML 文本字符串,用于在应用程序端为我们所有 1,000,000 个索引对象实例化检索到的对象。 @Mike:IMO 滥用了 Solr。相反,在 Solr 模式中定义相应的字段并正确索引它们。 我正在开发一个电子商务,其中我有多个用户和每个用户的多种产品类型。当然,我需要 solr 进行搜索,但我无法决定是否必须将产品存储在与其用户相关的数据库中并将其索引到 solr,或者只是将其存储在 solr 中。我不喜欢将相同的信息存储两次的想法,但是将它放在数据库中感觉更一致。你会推荐什么? @Gonzalo 对于一般电子商务应用程序,我建议使用 RDBMS 作为您的事实来源。您将需要规范化的数据来执行各种查询/报告等。 好的,所以更好的方法是将信息存储两次并投资于更多硬件【参考方案3】:

这可能是出于性能原因,如果它不会导致任何问题,我会不理会它。传统数据库与 solr 索引之间存在很大的灰色区域。我似乎人们为 UI 呈现做了类似的事情(通常是键值对或 json 而不是 xml),并且只有在需要更新/删除时才从数据库中获取真实对象。但所有读取都只转到 Solr。

【讨论】:

问题在于性能......我们有一个 10GB 的核心只有大约 1,000,000 条记录。搜索需要 500 毫秒到 2000 毫秒(经常发生)。我认为搜索较小的核心并从数据库中提取行会更快(最高 10-50 毫秒)。 @Mike:你的索引太大了,我会考虑分片:wiki.apache.org/solr/DistributedSearch【参考方案4】:

我见过类似的事情,因为它允许非常快速的查找。我们正在将数据从 Lucene 索引中移出到快速键值存储中,以遵循 DRY 原则并减小索引的大小。这类事情没有硬性规定。

【讨论】:

【参考方案5】:

添加到@Jayunit100 响应,使用 solar 作为数据库,您可以获得可用性和分区容错性,但代价是一些一致性。在你写的东西和你可以读回来之间会有一个可配置的延迟。

【讨论】:

【参考方案6】:

我有类似的想法,在我的例子中,将一些简单的 json 数据存储在 Solr 中,使用 Solr 作为数据库。但是,让我改变主意的一个重大警告是 Solr 升级过程。

请参阅https://issues.apache.org/jira/browse/LUCENE-9127。

显然,过去(v6 之前)建议在主要版本升级后重新索引文档(不仅仅是使用 IndexUpdater),尽管您不必这样做来维护功能(我自己不能保证这一点,这是我读过的内容)。现在,在您升级了 2 个主要版本但在第一次主要版本升级后没有重新索引(实际上是完全删除文档然后索引文件本身)后,您的核心现在无法识别。

具体来说,我是从 Solr v6 开始的。升级到 v7 后,我运行了 IndexUpdater,因此索引现在为 v7。升级到 v8 后,无法加载核心。我不知道为什么——我的索引是 v7,所以满足 Solr 的 version-minus-1 兼容性声明,对吧?好吧,不——错。

我做了一个实验。我从 v6.6 开始,创建了一个核心并添加了一些文档。升级到 v7.7.3 并运行 IndexUpdater,因此该核心的索引现在为 v7.7.3。升级到 v8.6.0,之后无法加载核心。然后我重复了相同的步骤,除了在运行 IndexUpdater 之后我还重新索引了文档。同样的问题。然后我再次重复所有内容,除了我不只是重新索引,我从索引中删除了文档并删除了索引文件,然后重新索引。现在,当我到达 v8.6.0 时,我的核心就在那里,一切正常。

因此,对于 OP 或其他任何考虑这个想法的人(使用 Solr 作为 db)来说,您必须不时地预期和计划重新索引您的文档/数据,这意味着您必须将它们存储在其他地方(之前的一张海报提到了这个想法),这有点违背了数据库的概念。当然,除非您的 Solr 核心/索引是短暂的(不会持续超过一个主要版本的 Solr 升级),否则您从不打算将 Solr 升级超过 1 个版本,或者 Solr 开发人员会更改此升级限制。因此,作为存储在其他地方的数据的索引(并且在必要时可以随时重新索引),Solr 非常出色。作为数据本身的数据库,它强烈地“依赖”。

【讨论】:

以上是关于使用 Solr 搜索索引作为数据库 - 这是“错误的”吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 solrj 作为客户端从 Solr 中删除索引

使用 datastax 进行错误的 SOlr 索引。从 1 个节点扩展到 2 个 cassandra 节点和 1 个搜索节点

Solr 和网站索引以创建网站搜索

关于Solr的使用总结的心得体会

solr建索引优化

技术秀Solr搜索引擎及应用: information retrieval