搜索DynamoDB:Elasticsearch的索引器辅助工具

TLDR;

  • DynamoDB很棒,但是分区和搜索很困难
  • 我们建造了交流发电机和迁移服务,使生活更轻松
  • 我们开源了一个sidecar,以在Elasticsearch中索引您应该使用的DynamoDB表。 这是代码

当我们三年前开始使用Bitbucket Pipelines时,我们对使用NoSQL数据库的经验很少。 但是,当一个小型团队希望快速产生质量时,我们决定将DynamoDB作为具有良好可用性和可伸缩性特征的托管服务。 三年来,我们已经学习了很多有关如何使用DynamoDB以及如何不使用DynamoDB的知识,并且在此过程中构建了一些可能对其他团队有用或可以被不断发展的平台吸收的东西。

对NoSQL还是对NoSQL就是问题

首先,关系数据库不是狼人,而NoSQL并不是灵丹妙药。 关系数据库已经为大型应用程序服务了多年,并且它们的扩展规模远远超出了许多人的期望。 例如,Atlassian中的许多团队继续选择Postgres而不是DynamoDB,并且这样做的理由很多。 希望此博客将重点介绍选择一种技术而不是另一种技术的一些原因。 从较高的角度讲,它们包括诸如操作开销,表的预期大小,数据访问模式,数据一致性和查询要求等注意事项。

分区,分区,分区

充分了解分区的工作方式可能是DynamoDB成功的唯一最重要的事情,而且对于避免可怕的热分区问题也是必不可少的。 弄错这一点可能意味着重组数据,重新设计API,全表迁移,或者在系统达到关键阈值的将来某个时候恶化。 当然,表的分区的可见性为零-您可以根据表的吞吐量和大小来计算它们,但是它不准确,麻烦,而且我们发现,如果您按照最佳实践开发人员指南的建议设计了分布合理的键,则这在很大程度上是不必要的。 幸运的是,我们花了一些时间从一开始就了解分区,并设法避免了任何这些问题。 另外,我们现在可以利用自动扩展功能而不必担心分区边界,因为即使分区发生变化并且吞吐量在它们之间重新分配,请求仍保持均匀分布。

吞吐量,突发和节流

DynamoDB表上的读写受到表配置的吞吐量容量的限制。 吞吐量还决定了表的分区方式及其对成本的影响,因此有必要确保您不要过度配置。 DynamoDB允许在开始限制请求之前短时间内爆发超过吞吐量限制,而限制请求可能会导致应用程序操作失败,但由于DynamoDB中的默认重试配置,我们很少这样做。 适用于DynamoDB的AWS开发工具包 。 这特别令人放心,因为DynamoDB中的自动缩放会因设计而延迟,并且允许吞吐量超出容量的时间足够长,从而可能发生限制。

仅当实际工作负载在持续的几分钟内保持升高(或降低)的状态时,DynamoDB自动缩放才会修改预配置的吞吐量设置。 Application Auto Scaling目标跟踪算法将长期保持目标利用率达到或接近您选择的值。
桌子的内置突发容量可容纳突然的,短暂的活动峰值。

您仍然需要为超出吞吐量的情况设置警报,以便可以在必要时进行监视并采取相应措施(例如,对自动缩放有上限),但是我们发现突发容量,默认的SDK重试,自动缩放和自适应吞吐量非常重要有效地使得几乎不需要干预。

资源

Alternator:DynamoDB的对象-项目映射库

在Pipelines获得批准并开始对可怕的alpha代码进行重构之后,我们构建的第一件事情就是交流发电机:DynamoDB的内部对象映射库(类似于ORM)。 Alternator从应用程序中提取AWS开发工具包,并提供基于注释的,响应式(RxJava-尽管目前仍在使用掩盖式的AWS API,直到SDK的v2变得稳定为止)与DynamoDB进行交互。 它还通过Hystrix增加了电路中断,从而消除了系统早期版本中存在的许多样板代码。

@Table( name = “pipeline”, primaryKey = @PrimaryKey(hash = @HashKey(name = “uuid”)) ) @ItemConverter(PipelineItemConverter.class) public interface PipelineDao { @PutOperation(conditionExpression = “attribute_not_exists(#uuid)”) Single<Pipeline> create(@Item Pipeline pipeline); } @ItemConverter(PipelineItemConverter.class) public interface PipelineDao { @PutOperation(conditionExpression = “attribute_not_exists(#uuid)”) Single<Pipeline> create(@Item Pipeline pipeline); }

迁移服务

DynamoDB表当然不需要架构,但这并不意味着您不需要执行迁移。 除了用于在表中添加或更改属性的典型数据迁移之外,还有许多功能只能在首次创建表时配置,例如本地二级索引,这些功能可用于查询和排序除表中的其他属性外首要的关键。

Pipelines的前几次迁移涉及编写定制代码,以将大量数据移动到新表中,并使之与应用程序中通常很复杂的更改同步,以支持旧表和新表,以避免停机。 我们很早就了解到,制定迁移策略可以消除很多摩擦,因此迁移服务诞生了。

迁移服务是我们开发的内部服务,用于迁移DynamoDB表中的数据。 它支持两种类型的迁移:

  1. 同一表迁移,用于添加或修改现有表中的数据。
  2. 表到表的迁移,用于将数据移动到新表。

迁移的工作方式是扫描源表中的所有数据,将它们传递给转换器(特定于正在进行的迁移),然后将其写入目标表。 它使用并行扫描来做到这一点,以在表分区之间平均分配负载,并在整个过程中最大化负载以在尽可能短的时间内完成迁移。

表到表的迁移然后附加到源表的流,以使目标表保持同步,直到您决定切换到使用它为止。 这允许应用程序直接切换为使用新表,而在迁移期间不必同时支持新表和新表。

DynamoDB中的查询:心痛和痛苦的故事

DynamoDB通过本地和全局二级索引提供有限的查询和排序功能。 表限于五个本地二级索引,每个索引与表的主键共享相同的分区键,并且一次只能对一个索引执行查询操作。 这意味着在按电子邮件地址划分的“用户”表上,只能在电子邮件地址和另一个值的上下文中执行查询操作。

全局二级索引以支付第二批吞吐量为代价消除了分区键的要求,并且仅支持最终的一致读取。 两种类型的索引对于许多用例都是有用且足够的,并且管道继续广泛使用它们,但它们不能满足某些应用程序更复杂的查询要求。 在管道中,这一需求主要来自我们的REST API,该API通常允许客户端同时对多个属性进行过滤和排序。

资源

我们的解决方案

解决这个问题的第一个尝试是MultiQuery,它内置于交流发电机中。 使用这种方法,我们查询了多个本地二级索引(LSI),并将结果汇​​总到内存中,从而使我们可以在单个API请求中对多达五个值(LSI的最大数量)执行过滤和排序。 虽然这在当时很有效,但随着我们的表的大小和指数的增长,它开始遭受严重的性能下降,因此您要过滤的值越多。 在替换多查询之前,我们的端到端测试存储库(其中一个拥有大量管道)上的管道列表页面需要花费数十秒的时间进行响应,并且在分支上进行筛选时始终超时。

搜索DynamoDB内容的常见模式是在搜索引擎中对其进行索引。 方便的是,AWS提供了一个logstash插件来为Elasticsearch中的Dynamo表建立索引,因此我们着手使用此插件创建索引服务,结果令人鼓舞。 查询性能得到了极大的改善,但logstash插件花了将近11个小时才能索引700,000个文档,这有很多不足之处。

对logstash插件的一些分析以及我们已经在迁移服务中构建了实质上是高性能索引器的认识,导致我们用自定义索引器实现替换了logstash插件。 我们的索引器主要基于与迁移服务相同的扫描/流语义,并利用Elasticsearch的批量索引API,在27分钟内成功浏览了近700万份文档。

分度器边车

此后,自定义索引器已重新打包为sidecar,从而允许任何服务应用程序在Elasticsearch中无缝索引DynamoDB表。 最初的扫描阶段和正在进行的流阶段都可以通过租用/检查点机制(针对扫描而定制,针对流的标准运动客户端)来实现高可用性和可恢复性。

我们目前使用由Bitbucket代码搜索团队构建的出色的Elasticsearch客户端来查询索引,并已开始在内部库中工作,该库以与交流发电机相同的方式添加了RxJava和Hystrix。

这是带有代码和自述文件的仓库

最后的想法

如果您以前从未使用过NoSQL,则肯定需要改变思维方式,但是总体而言,我们在DynamoDB方面的经验是积极的。 在过去的三年中,该平台已被证明是非常可靠的(我不记得它引起的单个重大事件),而最大的挑战来自于查询需求。 也许有人会说这是足够的理由,所以首先选择了一个关系数据库,我不会强烈反对他们。 但是我们已经设法通过解决方案解决了这个问题,该解决方案在很大程度上是从日常运营中抽象出来的。 从好的方面来说,我们不必一直在运行解释查询,也不必处理格式不正确的SQL,复杂的表联接或缺少索引的情况,而且我们也不急于返回。

该帖子由Sam Tannous撰写。 Sam是Atlassian的高级软件工程师,并且是将CI / CD Pipelines引入Bitbucket云的团队的成员。 凭借超过15年的行业经验,他与他人合着了3项专利,维护了1个开源项目,并具有向最终用户成功交付大规模基于云的应用程序的记录。 linkedin 上与他联系

最初于 2019年3月28日 发布在 bitbucket.org 上。

From: https://hackernoon.com/searching-dynamodb-an-indexer-sidecar-for-elasticsearch-6e70f2abf676

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值