在ruby中更新SolrCloud的配置(附代码示例)

63 阅读7分钟

我们有一个使用Solr的应用程序。我们目前在传统的 "非云 "模式下运行一个Solr。我们的Solr配置目录在Solr服务器的磁盘上,由我们的流程来获取我们想要的Solr配置,并在它改变时进行更新。

我们正在向 "SolrCloud模式"的Solr转移,可能通过SearchStax管理的Solr服务。我们的Solr "云 "可能只有一个节点,但是 "SolrCloud模式 "让我们可以访问额外的API来管理你的Solr配置,而不是直接将其写入磁盘(在SolrCloud模式下可能根本不可能?而且肯定不是使用管理的SearchStax)。

也就是SolrConfigSets API,尽管你可能也想使用集合管理API的一些部分,将配置集与Solr集合联系起来。

基本上,你是把你想要的Solr配置目录,压缩起来,然后作为一个有特定名称的 "配置集"[或 "configset"]上传到Solr。然后你可以使用这个配置集创建集合,或者重新分配现有集合所使用的命名的配置集。

我没能找到任何现有的Ruby gems来与这些Solr API进行交互。RSolr是一个 "与Solr交互的Ruby客户端",但它是在Solr的这些管理API存在之前编写的,而且似乎没有更新以处理这些API(除非我错过了),RSolr似乎主要/仅是关于查询Solr,以及一些有限的索引。

不过不用担心,用一些Ruby来包装我想使用的特定API并不是太难。对我来说,这确实比每次写具体的HTTP请求要好得多(并确保你能处理错误等!)。 是的,我会与你分享代码)。

我决定我想要一个对象,在一个特定的solr实例中绑定到一个特定的solr集合;并且由一个特定的本地目录和solr配置支持。这对我的用例很有效,我最终得到了一个看起来像这样的API:

updater = SolrConfigsetUpdater.new(
  solr_url: "https://example.com/solr",
  conf_dir: "./solr/conf",
  collection_name: "myCollection"
)

# will zip up ./solr/conf and upload it as named MyConfigset:
updater.upload("myConfigset")

updater.list #=> ["myConfigSet"]
updater.config_name # what configset name is MyCollection currently configured to use?
# => "oldConfigSet"

# what if we try to delete the one it's using?
updater.delete("oldConfigSet")
# => raises SolrConfigsetUpdater::SolrError with message:
# "Can not delete ConfigSet as it is currently being used by collection [myConfigset]"

# okay let's change it to use the new one and delete the old one

updater.update_config_name("myConfigset")
# now MyCollection uses this new configset, although we possibly
# need to reload the collection to make that so
updater.reload
# now let's delete the one we're not using
updater.delete("oldConfigSet")

好的,很好。这里面有一些技巧,试图抓住Solr报告不同类型错误的明显的多种方式,以确保Solr报告的错误最好变成带有良好错误信息的异常。

现在,除了最初为你正在创建使用的集合上传配置集之外,我的主要用例是希望将配置更新到现有集合的新值上。当然,这往往需要事后重新索引。

如果你有最近发布的Solr 8.7,它可以让你覆盖一个现有的配置集,所以这可以很容易地完成:

updater.upload(updater.config_name, overwrite: true)
updater.reload

但是在Solr 8.7之前,你不能覆盖一个现有的配置集。而SearchStax还没有Solr 8.7。因此,无论如何,我们需要做一个动作,在新的名字下上传配置集,然后切换集合来使用它。

有了这个可以让我们轻松执行相关Solr API的更新器对象,我们就可以轻松尝试不同的逻辑流程。例如,在一个Solr listerv线程中,Alex Halovnic建议了一个有点复杂的8步流程的解决方法,我们可以这样实现它:

current_name = updater.config_name
temp_name = "#{current_name}_temp"

updater.create(from: current_name, to: temp_name)
updater.change_config_name(temp_name)
updater.reload
updater.delete(current_name)
updater.upload(configset_name: current_name)
updater.change_config_name(current_name)
updater.reload
updater.delete(temp_name)

这很有效,但在与宾夕法尼亚州立大学的Dann Bohn交谈时,他分享了一种不同的算法,其内容如下:

  • 对整个solr目录做一个加密摘要哈希值,我们要在configset名称中使用这个哈希值。
  • 检查集合是否已经在使用一个名为`name_digest` 的配置集,如果已经是,你就完成了,不需要改变。
  • 否则,上传带有基于指纹的名称的配置集,切换集合使用它,重新加载,删除集合原来使用的配置集。

起初,这对我来说似乎是多余的,但在思考和实验之后,我喜欢它!它真的可以快速地制作一个挖掘机。对少量的文件进行摘要确实很快,这不是什么大问题。(我使用十六进制SHA256的前7个字符)。即使我们有Solr 8.7,我也喜欢我们可以避免在Solr上做任何操作,如果没有变化的话--我真的想使用这个操作,就像Rails的db:migrate ,在每次部署时运行它,以确保Solr模式与该部署的repo中的模式一致。

Dann还与我分享了他的 源代码,这对我了解如何制作摘要、如何在ruby中制作Zip文件等很有帮助。 谢谢 Dann!

分享我的代码

所以我也写了一些方法来实现那些变体更新stragies,Dann的,和Alex Halovnic的从列表等。

想过把这一切包装成一个宝石,但我真的没有时间让它真的好到那个程度。我的API有点古怪,我没有花额外的时间把它想得很好,以减少将来向后兼容的需要,就像我把它变成一个宝石那样。我也想不出一个很好的方法来编写我认为特别有用的自动化测试;所以在我的代码库中,它实际上目前还没有被测试过(嘘),但在一个宝石中,我想以某种方式解决这个问题。

但我确实尝试了写出通用/灵活的代码,以便其他人可以在他们的使用案例中使用它;我尝试以我的最高标准记录它;我把它全部放在一个文件中,这实际上可能不是最好的OO抽象/设计,但使你更容易复制和粘贴单个文件供你自己使用。)

所以你可以在这里找到我的代码;它是经过apache许可的;欢迎你复制和粘贴它,做你想做的事情,包括如果你想的话,自己做一个 gem。也许我将来会自己把它做成一个 gem,我不知道,如果有兴趣,我很好奇。

SearchStax专有的API's

SearchStax有它自己的API,我认为可以用于更新配置和设置集合使用某些配置等。当我开始探索他们时,他们不是我见过的最差的供应商API,但我确实发现他们工作起来有点麻烦。认证系统涉及很多步骤(为什么你不能直接从SearchStax Web GUI中创建一个API Key?)

总的来说,我发现它们比标准的Solr Cloud API更难使用,Solr Cloud API在SearchStax部署中运行良好,而且还有一个额外的好处,那就是可以转移到任何SolrCloud部署,而不是专门针对SearchStax。 虽然SearchStax的文档和支持试图将你引向SearchStax特定的API,我不认为这真的有任何好的理由。(也许定制的SearchStax API是很久以前写的,当时Solr的API还不那么完整?)

SearchStax支持建议,SearchStax APIs在某种程度上更安全;但是我的SearchStax Solr API's在HTTP基本认证后面受到保护,如果我已经创建了基本认证凭证(或IP地址允许列表),这些API's将对任何有认证的人可用,以访问Solr,无论我是否使用它们支持人员还建议,SearchStax API的使用会被记录下来,而我直接使用Solr API则不会被记录下来,这似乎是真的,至少在默认设置中是这样,我可能可以以不同的方式配置Solr日志,但它对我的这些特殊功能来说并不那么重要。

因此,在对SearchStax API进行了一些初步探索后,我意识到SolrCloud API(我以前从未使用过)可以做我需要的一切,而且使用起来更加直接和可转移,我对我的决定感到满意。