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

时间:2010-11-23 16:53:34

标签: java mysql database solr

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

  1. Solr文档ID(基本上是类名和数据库ID)
  2. 整个对象的XML表示
  3. 所以基本上它运行对Solr的搜索,下载对象的XML表示,然后从XML实例化对象,而不是使用id在数据库中查找它。

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

    当前的实现是否完美无缺,还是有数据支持这种重构成熟的想法?

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

6 个答案:

答案 0 :(得分:69)

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

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

  2. 虽然SOLR性能可以横向扩展(更多机器,更多核心等)以及垂直(更多RAM,更好的机器等),但的查询功能与成熟的RDBMS 。也就是说,有一些很好的功能,比如现场统计查询,非常方便。

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

  4. 允许高级会话管理和许多高级Web框架(Ruby,Hibernate,...)提供的有状态实体的“企业”工具必须完全抛出窗口

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

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

  7. 弹性:为了实现高可用性,SolrCloud使用下面的分布式文件系统(即HCFS)。此模型与关系数据库的模型完全不同,后者通常使用从属和主服务器或RAID等来实现弹性。因此,如果您希望它具有云可扩展性和抗拒性,那么您必须准备好提供SOLR所需的弹性基础架构。

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

    结论:即使您可以将SOLR用作RDBMS,您也可能会发现(因为我有)最终“没有免费午餐” - 以及超酷的lucene文本的成本节省 - 搜索和高性能的内存索引通常是通过较少的灵活性和采用新的数据访问工作流来支付的。

答案 1 :(得分:29)

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

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

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

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

答案 2 :(得分:2)

这可能是出于性能原因而做的,如果它不会导致任何问题我会不理会。在传统数据库和solr索引中应该有一个很大的灰色区域。我似乎人们对此做了类似的事情(通常是键值对或json而不是xml)用于UI表示,只有在需要更新/删除时才从数据库中获取真实对象。但所有的阅读都只是去Solr。

答案 3 :(得分:2)

我已经看到类似的事情,因为它允许非常快速的查找。我们将数据从我们的Lucene索引移到快速键值存储中,以遵循DRY原则并减小索引的大小。对于这类事情,没有一条严格的规则。

答案 4 :(得分:0)

除了使用@solar作为数据库的@ Jayunit100响应之外,您还以某些一致性为代价获得了可用性和分区容限。在您写的内容和何时读回它之间会有一个可配置的延迟。

答案 5 :(得分:0)

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

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

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

具体来说,我是从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)的要点是,您必须EXPECT和PLAN才能不时重新索引文档/数据,这意味着无论如何您必须将它们存储在其他位置(以前的海报暗示了这个想法),这有点违反了数据库的概念。当然,除非您的Solr核心/索引是短期的(不能持续使用多个主要版本的Solr升级),否则您绝不打算将Solr升级到一个以上的版本,否则Solr开发人员将更改此升级限制。因此,作为存储在其他位置的数据的索引(必要时可随时用于重新索引),Solr非常出色。作为数据本身的数据库,它强烈地“依赖”。