每天都会有一组新的数据需要写入和更新到数据库中。这组数据可以包含8-10百万条记录。
这个新的数据集来自Service A,它直接写入Service B使用的数据库。我不维护Service A,但我维护Service B。
问题是,每当Service A不得不对数据库进行如此大的负载时,它就会消耗掉所有的IOPS并陷入数据库的泥潭,这反过来又会影响到Service B。因为有这么多的记录,完成这个过程需要超过10-15个小时。这意味着数据库的负载在这个小时内仍然很高!
我正在考虑为Service A提供一个端点来发送它的新数据,我将以一种更“优雅”的方式写入数据库,这样它就不会影响Service B。
但是,我不知道应该如何做到这一点,即使是使用端点,也不需要继续深入数据库,这样Service就不必直接写到数据库了。我在想,即使我为Service A提供了一个端点,以便将数据写入我的数据库,我仍然需要以某种方式处理同样数量的负载,即服务B直接写入数据库并导致相同的负载问题。
我目前正在使用AWS Postgres RDS作为我们的数据库。我们所有的服务都托管在AWS上,我们有一个“微服务”架构。
在这样的场景中,我应该如何设计我的端点,或者我应该使用什么AWS服务,这样我才能更优雅地处理大量的数据?
发布于 2019-10-11 11:46:08
在注释线程中,您澄清了数据库属于服务B,由您管理。
这使您有权控制对数据库的访问。这确实意味着您必须公开一个端点,并通过您的服务路由这个流量,但它也给了您在您认为合适的情况下控制请求的权限。
如果您以每秒X请求的速度绘制界限(您可以根据数据库在服务B保持可用时可以处理的内容来确定这一点),那么只需在该秒期间拒绝来自该源的任何附加请求。如果这是一个服务开发人员的问题,那么这是一个服务开发人员必须解决的问题。
您目前正在让某人DDOS您的数据库,似乎认为您没有其他的响应,除了默认和让数据库被拖拽。这不是正确的反应。
为它们打开端点,拒绝服务A对数据库的直接访问(撤消服务凭据,或者如果A和B共享相同的凭据,更改密码,不给它们新密码),强迫它们使用您的服务,通知他们您已经实现的节流。他们有责任遵守你的服务。
当服务devs抱怨节流时,另一种解决方案是接近管理,并证明升级服务B需要适当的资源来处理工作负载。管理层可以决定什么更重要,降低成本,或者确保服务A能以最快的速度工作。
在这样的场景中,我应该如何设计我的端点,以便更优雅地处理大量的数据?
这一切归结为你拥有什么所有权。你,我指的是服务B。
如果数据库被认为是服务B的数据库,那么所有对数据库的访问都应该通过服务B。不要让其他人直接访问,因为您不能对他们执行的数据操作执行任何质量控制。
如果数据库不是特定服务所拥有的共享数据库,那么它就不是您的问题(如果您只是一个服务B)。这个问题需要由维护数据库的人来解决(例如,强制请求节流),或者服务needs (修复他们自己的服务)。
我正在考虑为服务A提供一个端点来发送它的新数据,我将以一种更“优雅”的方式写入数据库,这样它就不会影响服务B。
如果它是服务B的数据库,那么您应该从一开始就这样做(不管性能问题)。如果它不是服务B的数据库,那么这是一个“不是我的马戏团,不是我的猴子”(从服务B的角度来看,也就是)。
假设您确实在A和db之间扮演了一个合理的中间角色,而忽略了实现细节。那么,如果明天创建的Service将导入不同的(但大小相同的数据),会发生什么?你现在也打算加入服务C吗?服务D呢?E?F?
试图掩盖其他错误的机制只会导致更多的努力和劣质的解决方案。你把水弄混了,A和B是分开的,是有原因的。
您要做的类似于防止您自己的数据库服务器(服务A)受到DDOS攻击。如果是您自己的托管服务器,我建议与数据库服务器的it支持人员一起处理这个问题。DDOS攻击不是由程序员(有效)阻止的,而是由服务器/网络管理员进行的。
由于这是与AWS相关的,我不太确定如何做到这一点,但是这种方法的原理是相同的。
与其试图修复错误的参与者(服务A),不如修复数据库服务器。即使你修复了服务A,你也必须修复每个演员的不当行为。但是,如果您通过对每个参与者强制执行请求节流来修复数据库服务器,那么您将防止任何未来的服务发生同样的错误,并再次将整个系统拖垮。
发布于 2019-10-11 12:44:38
解决大多数大容量负载问题的架构解决方案是消除大容量负载。回到事件的源头,并在流中使用它们。
然而。如果这是不可能的,您需要一个战术解决方案,而遵循关于服务B拥有自己的DB的严格规则可能对您没有帮助。
亚马逊对大宗进口有一些指导。
https://aws.amazon.com/premiumsupport/knowledge-center/rds-import-data/
但您可以看到,这并不是为了成为一个常规的业务流程。建议您关闭备份等。
如果您处于数据级别,您被迫使用这些“一次性”方法来在合理的时间内完成工作,那么我将考虑为每个导入建立新的数据库,并让服务B知道多个RDS实例。
这样您就可以让Service创建一个全新的DB,然后添加数据,然后消息服务B:“一个新的DB已经为您准备好了”
云中的所有内容都有助于这一点,因为您可以使用AWS api来拆分和访问服务,而不必担心物理硬件。
https://softwareengineering.stackexchange.com/questions/399585
复制相似问题