【问题标题】:Keeping partly-offline sqlite db in sync with postgresql保持部分离线的 sqlite db 与 postgresql 同步
【发布时间】:2016-12-21 18:13:36
【问题描述】:

这个问题更多的是关于架构和库,而不是实现。

我目前在项目中工作,该项目需要客户端的本地长期缓存存储(每天更新一次)与服务器上的远程数据库保持同步。对于客户端,选择 sqlite 作为轻量级方法,选择 postgresql 作为服务器端功能丰富的数据库。 postgres 的本机复制机制是不可选择的,因为我需要保持客户端真正轻量级,并且不依赖数据库服务器等外部组件。

实现语言是 Python。现在我正在研究像 SQLAlchemy 这样的 ORM,但以前没有使用过。

  • SQLAlchemy 是否有任何工具可以使 sqlite 和 postgres 数据库保持同步?
  • 如果没有,是否还有其他具有此类工具的 Python 库?
  • 如果必须“手动”解决任务,您对架构应该是什么样子有任何想法?

添加: 这就像遥测,因为客户端每天只能连接大约 20 分钟的互联网

所以,主要问题是关于这样一个系统的架构

【问题讨论】:

  • 这个问题太宽泛了。
  • 附注。如果您的餐桌上有权衡的地方,您可以查看 CouchDB,它宣传为离线优先数据库(虽然是文档,但不是关系数据库)。或者至少在他们的文档中寻找关于eventual consistency 的想法(并可能通过关系数据库实现它)。根据我的经验,它过于限制和不方便,但您的里程可能会有所不同。
  • 这是单向复制还是双向复制?即客户端上的数据库是只读的吗?如果只是在客户端更新数据库,那就简单多了。没有碰撞。如果是客户端和服务器都对数据库进行修改,您可以对每个客户端的数据进行分区吗?我问这个的原因是看看是否有办法避免冲突,其中 2 个客户端离线更新同一行然后都上传 - 你将如何协调
  • @YounElan 是的,复制是双向的,因此可能发生冲突。现在我正在考虑通过将我的数据库设计为一个包含所有事务列表和物化视图的表来解决这个问题

标签: python database sqlite architecture sqlalchemy


【解决方案1】:

在数据库之间同步数据通常不属于 ORM 的任务,因此您可能必须自己实现它。鉴于您选择的数据库,我不知道有任何解决方案可以为您处理同步。

有几个重要的设计选择需要考虑:

  • 您如何确定哪些数据已更改(即插入、更新或删除)
  • 打包变更日志最有效的方法是什么
  • 您必须处理冲突吗?以及你将如何做到这一点。

找出变化的最有效方法是让数据库直接告诉您。 Bottled water 可以在这方面提供一些启发。这个想法是利用 postgres 用于复制的事件日志。您将需要像 Kafka 这样的东西来跟踪您的每个客户已经知道的内容。这将允许您优化服务器的写入,因为您不会让客户端查询试图找出自上次在线以来发生的变化。 使用event callbacks 在 sqlight 端也可以实现相同的效果,您只需在客户端上交换一些存储空间即可保留要发送到服务器的更改。如果这听起来对您的需求来说基础设施太多了,那么您也可以使用 SQL 和池轻松实现它,但我仍然会将它视为事件日志,并考虑它是如何实现的细节 - 可能允许更多高效的实施起泡。

构建和打包更改日志的最佳方式取决于您的应用程序要求、可用的带宽等。您可以使用标准格式,例如 json,如果需要,可以压缩和加密。

这样设计您的应用程序会更简单,以避免冲突,并可能在单个方向上流动数据,或对您的数据进行分区,使其始终在特定分区的单个方向上流动。

最后一个教训是,使用这样的架构,您将获得增量更新,其中一些可能由于计划外的原因(系统故障、错误、丢失的消息等)而丢失。您可以使用一些内置的启发式方法来检查您的数据是否匹配,例如至少检查每一侧的记录数,通过某种方式来恢复此类故障,至少可以手动从权威机构重新获取数据来源,即如果服务器是权威的,客户端应该能够丢弃它的数据并重新获取它。在重新安装客户端等情况下,您可能仍然需要这种机制。

【讨论】:

    猜你喜欢
    • 2013-07-10
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 2018-07-11
    • 2013-11-14
    • 2017-01-06
    相关资源
    最近更新 更多