cloudant_多租户服务的Cloudant最佳做法

本文探讨了在多租户服务中使用Cloudant的最佳实践,包括文档和数据库组织、文档查询和删除,以及性能优化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IBM于2014年2月收购了Cloudant,从那时起,它已被证明是一个有用的基于文档的存储系统。 Cloudant提供了直观的仪表板,其中包含管理大数据所需的许多工具,并且各种客户端库使在自己的应用程序中轻松利用Cloudant变得容易。 但是,与任何出色的工具一样,应该遵循最佳实践,而应该避免的陷阱。

本文为Cloudant提供了有关组织文档/数据库,查询和删除文档以及性能优化的最佳实践。 我们分享了使用Cloudant将配置数据存储在多租户云服务中的经验教训。 我们不会将自己描述为Cloudant专家,但是我们已经与Cloudant合作了一年多。 我们通过反复试验学到了很多东西,并且由于找不到关于使用Cloudant在现场构建多租户企业系统的许多真实故事,因此我们认为与其他架构师分享经验可能很有用和开发人员。

我们做了什么

我们使用Cloudant存储了大约1,000个租户的配置数据。 这些租户大多数依赖少量的配置数据(每个使用大约200个文档),而少数租户依赖大量的配置数据(每个使用大约500,000-250万个文档)。 通过提供在Node.js中实现的REST API,我们封装了Cloudant中存储的数据。 最终用户没有直接访问Cloudant的权限。 REST API作为一组可伸缩的微服务托管在IBM Cloud上。

本文为Cloudant提供了有关文档/数据库组织,文档查询和删除以及性能优化的最佳实践。

我们学到了什么,以及如何使用本文

有很多很棒的文章可以教您CouchDB和Cloudant的基础知识。 本文的目的不是覆盖这些基础知识,而是为在多租户环境中使用Cloudant提供一些指导。 如果您还不熟悉基础知识,请查看本教程末尾的“相关主题”部分,以获取有用文章的链接。 我们建议您先阅读这些内容,然后再继续此处。

在学习了基础知识之后,我们不太确定如何构造数据或设计搜索索引。 我们将分享我们在下面学到的东西,这些知识是一些松散的最佳实践。 如果后面的部分引起您的更多兴趣,请随时跳过某些部分。 希望我们学到的一些经验教训对您的下一个项目有帮助!

整理文件

将文档组织为大量的小型数据库,而不是少量的大型数据库是一个好主意。 对于我们的项目,我们最初为每个租户创建了一个Cloudant数据库。 与该租户有关的所有文档都存储在其特定于租户的数据库中。 随着租户数据库规模的增长,我们遇到了一些索引性能问题。 后来,我们通过为每个租户的每种文档类型创建一个数据库来重组了文档。 结果,我们能够获得更好的性能。 (我们将在下面的“ 优化索引性能 ”部分中讨论我们的经验教训。)

当使用各种文档类型时,请将每种文档类型分成一个单独的数据库。 许多视图和索引仅适用于特定类型的文档。 将较小的数据库与相似的文档一起使用可使索引更小,并且较小的索引会减少重新建立索引时Cloudant集群执行的总体工作。 例如,计算平均“物品”价格的视图可能不会检查“地址”文件,因此,最好为物品创建一个数据库,为地址创建另一个数据库。

删除文件

当您在Cloudant中删除文档时,Cloudant实际上不会从存储中删除整个文档。 取而代之的是,它为墓碑提供了有关文档的非常基本的信息。 墓碑包含字段_deleted (布尔标志), _id ,并_rev 。 尝试避免删除大量文档的模式,因为只要数据库存在,逻辑删除就会继续消耗存储空间。 如果必须频繁删除大量文档,则还应定期删除包含那些逻辑删除文件的数据库。

例如,考虑一个在Cloudant中存储大量数据的应用程序,该数据只需要存在一个月即可。 如果仅在不再需要文档时将其删除,那么随着时间的推移,逻辑删除的数量很容易超过实时文档的数量。 相反,您应该为每个月的数据创建一个新数据库,并在数据到期后删除整个数据库。

查询文件

Cloudant提供了用于查询和检索文档的多个选项。 如您所料,每种选择都有其优点和缺点,因此针对特定用例的最佳选择取决于您的使用场景。 在本节中,我们将讨论查询选项以及每个选项对我们来说更好的方案。

主索引(按文档ID搜索)

主索引是从数据库检索数据的最快方法。 它随每个Cloudant数据库一起提供,这意味着您无需编写任何代码即可使用它。 主索引(通常称为_all_docs为数据库中的每个文档返回一个ID,一个键和一个值。 ID和密钥是相同的(Cloudant使索引以doc ID作为密钥),而值是文档的_rev_all_docs还报告文档总数以及用于查询索引的所有偏移量。 如果知道要查询的文档的ID,则使用它来检索文档总是更有效的。

优点:

  • 最快的查询选项
  • 无需额外的存储开销-密钥自动索引
  • 可以在一个请求中一次查询任意数量的文档

缺点:

  • 最不灵活的查询选项-只能按ID查询

二级索引(MapReduce视图)

二级索引是一种用于处理数据库中文档内容的机制。 它可以有选择地筛选文档,加快内容搜索速度,并在将结果返回给客户端之前对其进行预处理。 与索引视图相关的性能成本,我们将在“ 优化索引性能 ”部分中详细讨论。

优点:

  • 可以在一个请求中检索任意数量文档的结果
  • 可以减少服务器上的查询结果以提高性能并减少通过HTTP传输的数据

缺点:

  • 自定义JavaScript的reduce函数并不总是能够很好地扩展,因此请不要使用自定义函数。 尽可能使用内置的reduce函数以获得更好的性能。
  • 存储开销-由映射功能发出的键存储在数据库中的每个文档中。

Cloudant搜索(按文档中的特定字段搜索)

设计文档中定义的搜索索引允许使用Lucene Query Parser语法查询数据库。 搜索索引由索引函数定义,类似于MapReduce视图中的地图函数。 索引功能决定要索引哪些数据并将其存储在索引中。

优点:

  • 比Map Reduce View更加灵活-任何索引字段都可以自己搜索,也可以与其他索引字段一起搜索,因此您无需做任何前瞻性的工作即可使搜索索引适应未来的搜索需求。

缺点:

  • 一次最多只能检索200个文档-当搜索产生200多个结果时,必须使用书签来在后续的HTTP查询中检索下一页结果。
  • 存储开销-为数据库中的每个文档索引字段。

下图显示了Cloudant中可用的不同查询选项之间的关系。 主索引以最小的灵活性提供最佳的性能,而Cloudant Search以性能为代价提供最大的灵活性。

Cloudant查询选项
Cloudant查询选项

该简短视频简要介绍了主索引,二级索引和Cloudant搜索以及其他搜索选项。

优化查询性能

您应该完全依赖内置的reduce函数。 我们发现自定义JavaScript精简功能在处理大量文档时效果不佳。 如果您需要通过单个操作查询200多个文档,请使用二级索引而不是Cloudant搜索。 只要有可能,请对可以使用稍微过时的数据的查询使用stale选项。 如果要浏览大量视图结果,请使用startkey / startkey_docid选项而不是skip选项,如CouchDb Wiki中所述

skip选项只能用于较小的值,因为以这种方式跳过大范围的文档效率不高(它会从startkey扫描索引,然后跳过N个元素,但是仍然需要读取所有索引值)。 为了有效地分页,您需要使用startkey和limit。 如果您希望多个文档发出相同的密钥,则除了startkey之外,还需要使用startkey_docid才能正确分页。 原因是单独使用startkey将不再足以唯一标识一行。

优化索引性能

每当您创建或更新设计文档时,Cloudant都会为该文档中的每个视图填充索引。 这些索引很重要,因为它们可以帮助您更快地运行查询。 但是,了解索引编制过程的工作方式也很重要,因为索引包含大量文档或复杂视图的数据库可能会导致意外的副作用。

例如,索引编制是一项锁定操作,因此在建立索引时将无法使用它(除非使用“ 优化查询性能 ”部分中讨论的stale选项)。 此外,在繁重的索引编制期间,整个Cloudant群集可能会变得无响应或不稳定,因此您需要密切注意索引编制代码的性能。

当Cloudant为特定视图为数据库建立索引时,它将为数据库中的每个文档运行map函数,并存储map函数发出的键以供将来参考。 具有大量文档的数据库需要很长时间才能建立索引,因为必须为数据库中的每个文档运行map函数,而不管为每个文档发出的键数如何。 具有非常复杂的映射功能的视图也需要很长时间才能建立索引,因为必须为每个文档一遍又一遍地执行这种复杂的逻辑。

索引编制过程在后台运行,在完成索引编制之前,您提交的用于创建或更新设计文档的HTTP命令将返回。 可以通过Cloudant UI或监视API来监视索引编制进度,但是无法估计完成100%准确度的特定索引编制任务将花费多少时间。

根据我们的经验,以下做法降低了索引数据库的性能成本。

  • 最小化每个数据库中的视图/索引数。
  • 每个设计文档严格定义一个视图或索引。 这种做法使您可以更新特定的视图/索引,而无需为所有未更改的视图/索引重新索引数据库中的所有文档。
    • 案例1 — 1个具有50个视图的设计文档。 如果需要更新一个视图,则需要在Cloudant中更新整个设计文档。 此更新使Cloudant为所有50个视图重新索引数据库中的所有文档。
    • 案例2 — 50个设计文档,每个文档有1个视图。 如果您需要更新一个视图,则只需在Cloudant中更新一个设计文档。 此更新使Cloudant重新为更改后的视图编制索引,但是不需要为所有未更改的视图重新编制索引。
  • 视图和索引应应用于其相应数据库中的所有(或大多数)文档。 如果您的视图/索引并不适用于数据库中的所有文档,那么您应该对视图/索引进行概括以适用于数据库中的所有文档,或者将不相关的文档移至单独的数据库中。 这种做法通过仅在适当的文档上运行索引来减少建立索引的时间(这可能是一组较小的文档,具体取决于您构造数据库的方式)。
  • 对于具有大量文档的数据库,您应该一次更新一个设计文档。 换句话说,如果您有100个租户,每个租户都有250万个文档, 则不要同时在每个数据库中创建或更新同一设计文档。 取而代之的是,为一个数据库创建或更新设计文档,监视Cloudant集群,然后等到索引完成为止,然后为下一个数据库重复。 通过一次不给群集增加重新索引任务的负担,这将使群集保持响应状态。
  • 切勿更新设计文档。 而是,创建一个新的设计文档,然后再删除旧的文档。 许多生产系统必须在没有任何停机时间的情况下运行,并且通常这些系统只会提升新代码,而旧代码仍在同时运行。 这种做法允许旧代码与旧视图一起使用,而新代码同时与新视图一起使用。
  • 与为同一文档定义多个视图/索引相比,为同一文档发出许多不同的键要好。 例如,如果您的数据库中充满了“人员”文档,则不要定义一个为姓氏发出密钥的视图(例如“ findPeopleByFirstName”),以及另一个为姓氏产生密钥的视图(“ findPeopleByLastName”)。 而是定义一个视图,该视图为要查询的每个属性(“ findPeople”)发出键。 这种做法减少了索引编制时间,因为每次文档更新都必须运行较少数量的视图/索引,但是由于查询所依据的键数较大,因此可能会增加查询时间。

优化客户端性能

对Cloudant的所有请求都必须通过HTTP,并且每个HTTP请求都会带来性能成本。 Cloudant支持封装HTTP详细信息的各种客户端库,并允许您调用抽象操作,例如运行视图或创建文档。 对于大多数客户端来说,在处理低请求量时,基本HTTP请求的性能成本几乎是不明显的。 但是,由于通常与多租户应用程序相关联的请求量很高,因此花费在HTTP请求上的时间可能会削弱应用程序的性能。

  • 微调您的HTTP客户端,以有效处理大量请求。 具体设置会因您选择的客户端技术而异。 我们使用了“ nodejs-cloudant”库,并通过使用HTTP Agent设置[KeepAlive = true]重用现有的HTTP连接,发现了显着的性能改进。 其他语言(例如Java)的HTTP客户端实现将此概念称为HTTP连接池。
  • 批量更新文档,而不是一次创建或更新文档。 请记住,单个JSON文档的每个创建,更新和删除操作也是单个HTTP请求。 如果您的应用程序每隔几天仅创建或更新一个文档,则单个HTTP请求的成本非常低,并且几乎不需要进行任何优化。 但是,如果您的应用程序每秒创建或更新数百个文档,则对每个文档批量使用所有文档,使用每个文档单独的HTTP请求的效率远远低于使用单个HTTP请求。 Cloudant批量操作可以处理单个HTTP请求中任意数量的文档的创建,更新和删除操作,因此您可以通过对所有三个操作重新使用相同的代码来简化应用程序逻辑。 最好仅在支持批量操作的情况下实现应用程序代码,因为您可以轻松地将单个文档功能实现为批量操作请求的特例。 汇总单个文档的更新请求也是一个好主意。 例如,如果您的应用程序的100个用户在同一秒内发送了更新100个不同文档的请求,那么最好将单个HTTP请求发送给Cloudant,而不是100个HTTP请求。
  • 使用limit选项limit查询可以返回的记录数。 结果太大可能会导致客户端内存不足的问题。

结论

在本教程中,我们讨论了针对多租户服务提高Cloudant可靠性和可伸缩性的最佳实践。 这包括组织文档和数据库,查询和删除文档以及性能注意事项。 组织文档和数据库是实现可伸缩性的关键因素,而优化性能是保持可靠性的最重要因素之一。 我们还提供了最佳实践,以改善客户端性能并减少服务负载。


翻译自: https://www.ibm.com/developerworks/cloud/library/cl-cloudant-best-practices-multi-tenant-service-trs/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值