java - 多节点架构中并发导致的数据库设计问题
问题描述
我会尽力解决这个问题。请让我知道是否需要任何澄清。
环境:
应用程序部署在 AWS 上,多个实例连接到单个数据存储。
数据存储由表组成,
旧表:
instance_info (id, instance_details, ...)
task_info (id, task_id, ...)
新增表:
new_table (id, instance_info_id, task_info_id, ...)
架构设计:
- id - 在所有表格中都是 PK。
- 在 new_table 列中,
- task_info_id是表 task_info 的外键,并且,
- instance_info_id是表instance_info。
- 列instance_info_id和task_info_id上存在唯一约束。
问题:
当代码执行时,它会将其操作划分(分叉)为多个独立和并行执行的线程。完成后,这些线程加入并尝试将数据插入到旧表之一 - “ task_info ”。
现在,可能会出现这样的情况,即这些多个线程(在单个节点上同时运行)将成功地将多个条目填充到表中。
要求:
如果有多个线程,并行工作,那么只有一个线程在“task_info”表中插入一条记录,而其他线程只更新它。
限制:
- 无法向task_info表添加唯一约束,因为这种方法会破坏重试机制的现有(遗留代码)功能。
- 在写操作期间不能锁定整个表,因为这最终会给我们带来性能问题。
- 一种使用“直写”机制(分布式 Memcache)的深思熟虑的方法,但是,如果我们考虑停机时间似乎存在疑问,这可能会导致数据丢失。
是否有任何可以研究的有效设计方法(对遗留代码/设计进行最小/没有更改)?
更新
实施解决方案有一些真正严格的限制(由于添加额外资源的成本),如下所示,
- 支持的数据库是 Oracle、SQL Server、MySQL 和 MariaDB。因此,锁定机构必须是可互操作的。
- 可以使用的资源有限制 - 数据库和 Memcache。
- 该系统可以部署在云端和本地。
- 无法从应用程序中创建模块,或创建/依赖新的外部服务。我真的很喜欢 Rob 提出的想法,因为它们很优雅并且让框架为我处理了大部分复杂性。但是,这增加了添加和维护资源的成本。
我猜想改变它的架构和限制,使得找到正确且具有成本效益的解决方案变得复杂。
解决方案
您正在寻找一个分布式锁管理器。对此有很多选择,但由于您已经在使用 AWS,您应该考虑他们使用 DynamoDB 作为 lock-store 构建的那个。不过,三个是很多替代方案,如果您不喜欢 AWS 构建的一个,那么 ZooKeeper 之类的东西可以帮助维护分布式锁系统。
推荐阅读
- vue.js - vue3 和 vu-cli4.x 部署 nginx 404
- mongodb - 从多个数组分组并找到总和
- json - 试图将 2 个 json 文件与地图进行比较
- mongodb - 未经授权将集合导出为 excel 文件
- android - 反应原生:反应原生地理定位
- angular - 角度等待变量变化
- javascript - Firebase 无密码重新身份验证不起作用
- c# - 具有不同文化的 DateTime.TryParse
- java - 带有特殊字符的 PDFBox 在 Windows 上运行良好,但在 Linux 中字符被其他字符替换
- javascript - 如何在 JavaScript 中过滤图像的文件类型?