database - 保持本地缓存在分布式系统中看到相同的 "version"数据的策略

标签 database architecture distributed distributed-computing distributed-system

我正在尝试构建一个分布式系统来运行一些性能密集型计算。一个计算可以在多个工作节点上并行完成。问题是,由于数据源不断实时变化,我们希望每个工作节点(在单个计算期间)对相同“版本”的数据进行操作,即数据库的时间点快照。这是为了避免不一致的结果。

另一个问题是,每次计算的整个输入数据集可能非常大,所以目前我们在每个工作节点上保留一个本地缓存,它通过向数据源询问“差异”来定期刷新内容,因为当前本地缓存版本并将差异应用到本地缓存。

有哪些设计策略可以实现每个工作节点看到相同“版本”的数据(同时仍然有相当新鲜的数据)的要求?我考虑过以下解决方案,但想看看这是否是已解决的常见模式:

  • 构建一个“版本控制”服务,定期查询数据源的差异并将每个差异存储为数据“版本”。工作节点的缓存与版本控制服务同步,并将其缓存数据保存在多个版本中。对于一个计算,我们确保工作节点使用相同版本的输入数据以实现一致性。此版本控制服务还应保留整个数据集的最新副本,供工作节点最初加载其缓存,并在工作节点出现故障并重新启动时恢复本地缓存内容。

系统的一些预估参数:

  • worker 人数:10

  • 平均工作持续时间:显然我们希望它尽可能快,但假设它应该少于 2 分钟

  • 作业的输入数据(所有工作人员的总和):~100GB

  • 数据库大小:~1TB

最佳答案

如果您不依赖 MySQL 并且可以使用 Oracle,那么有一个简单的解决方案适合您:

Oracle Flashback

(我还没有发现 MySQL 闪回,如果你知道这方面的一些知识,请发表评论。)你不必创建手动快照等。你可以将它与单个数据库服务器一起使用,并且你的所有进程都可以读取在要求的时间内表示的数据。这个解决方案非常干净和强大,但需要许可证。

如果我是你,我会尝试退后一步,尝试进一步简化问题。如果不同的工作人员可以并行运行,则应适用以下内容:

  • 没有一个 worker 使用其他 worker 的输出
  • 他们都没有改变原始数据

如果这两个要求都有效,您可以使用单个数据库来存储计算等。您唯一需要关心的是交易应该仔细计划。

另一方面,在一个类似的项目中,我们使用了一个小技巧来实现这一点(作为闪回解决方案):插入时间也存储在数据库中。 (更新实际上是插入新的时间戳。)所有的计算等都是通过在查询中添加

give me the last version of this kind of row before x timestamp

通过这个解决方案,我们避免了许可成本和快照维护。唯一的问题是,如果您不需要整个历史记录,它会很快占用您的数据库空间。为了解决这个问题,我们做了一个 cron 作业,根据时间戳清除未使用的记录。

如果你想得到更多,有一种叫做影子表的东西。有一篇关于此主题的不错的 MySQL 博客文章: http://arnab.org/blog/shadow-tables-using-mysql-triggers

关于database - 保持本地缓存在分布式系统中看到相同的 "version"数据的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38666043/

相关文章:

apache-spark - spark上的tensorflow与默认的分布式tensorflow 1.0有什么区别?

redis - 哨兵的数量应该是奇数吗?

sql - 如何使表不在phpmyadmin中的非空集字段中取空值?

javascript - Bookshelf.js 预加载第三个表

architecture - System.Transactions 中避免事务升级的策略

c++ - 与我的 Qt 应用程序一起工作的轻量级跨平台数据库引擎

php - 用户 'admin' @'localhost' 的 MySQL 访问被拒绝(使用密码 : YES)

php - 将 str_replace() 与从 SQL 数据库导入的字符串结合使用

php - 寻找存储/缓存计数的推荐方法

javascript - Jmeter Chromedriver 错误 : unknown error: DevToolsActivePort file doesn't exist when executed from remote master machine