当前位置: 首页 > 面试题库 >

同步客户端-服务器数据库

夏祯
2023-03-14
问题内容

我正在寻找一些通用策略,用于将中央服务器上的数据与并不总是在线的客户端应用程序进行同步。

在我的特定情况下,我有一个带sqlite数据库的android手机应用程序和一个带MySQL数据库的PHP Web应用程序。

用户将能够在电话应用程序和Web应用程序上添加和编辑信息。我需要确保即使手机无法立即与服务器通信,在一个地方所做的更改也会在所有地方反映出来。

我不关心如何将数据从手机传输到服务器,反之亦然。我之所以仅提及我的特定技术,是因为我无法使用例如MySQL可用的复制功能。

我知道客户端-
服务器数据同步问题已经存在了很长时间,并且希望获得有关处理问题的模式的信息(文章,书籍,建议等)。我想了解处理同步以比较优点,缺点和折衷方案的一般策略。


问题答案:

您需要决定的第一件事是关于在发生冲突更改的情况下将哪一方视为“权威”的一般政策。

即:假设记录#125在1月5日晚上10点在服务器上更改,并且同一记录在1月5日晚上11点在其中一部电话(我们称为客户A)上更改了。上次同步时间是1月3日。然后,用户在1月8日重新连接。

在客户端和服务器都知道上次同步的日期的意义上,识别需要更改的内容是“容易的”,因此自上次同步以来,所有 创建或更新的内容
(请参见下文中的更多信息)都需要协调。

因此,假设唯一更改的记录是#125。您可以确定两个自动赢得其中一个,然后自动覆盖另一个,或者需要支持协调阶段,在此阶段,用户可以确定哪个版本(服务器或客户端)是正确的版本,而覆盖另一个版本。

这个决定非常重要,您必须权衡客户的“角色”。特别是如果不仅客户端与服务器之间存在潜在冲突,而且如果不同的客户端可以更改同一条记录,则尤其如此。

[假设#125可以由第二个客户端(客户端B)修改,则尚未同步的客户端B可能会提供同一记录的另一个版本,从而使先前的冲突解决方法无济于事]

关于上面的“ 创建或更新的
”要点…如果记录起源于一个客户端,那么如何正确识别记录(假设这在您的问题域中有意义)?假设您的应用管理一个业务联系人列表。如果客户A说您必须添加一个新创建的John
Smith,并且服务器上有一个昨天由客户D创建的John Smith …您是否创建两个记录,因为不能确定它们不是不同的人?您还会要求用户调解此冲突吗?

客户是否拥有数据子集的“所有权”?即,如果将客户B设置为区域#5的数据的“权威”,则客户A是否可以修改/创建区域5的记录?(这将使某些冲突解决方案更容易,但可能对您的情况不可行)。

概括起来,主要问题是:

  • 考虑到分离的客户端在创建新记录之前可能尚未访问服务器,如何定义“身份”。
  • 以前的情况,无论解决方案多么复杂,都可能导致数据重复,因此您必须预见到如何定期解决这些问题,以及如何通知客户端他们认为“记录#675”的内容实际上已被合并/取代。记录#543
  • 决定是否通过 法令 来解决冲突(例如,“如果服务器版本自上次同步以来已更新,则服务器版本总是胜过客户端的版本”)或通过手动干预来解决
  • 如果是 法定命令 ,尤其是如果您决定让客户端优先,则还必须注意如何处理可能会带来更多变化的其他尚未同步的客户端。
  • 前面的内容没有考虑数据的粒度(为了使描述更简单)。只需说一下,而不是像我的示例那样在“记录”级别进行推理,您可能会发现更适合在字段级别记录更改。或者一次处理一组记录(例如,人记录+地址记录+联系人记录),将它们的汇总视为“元记录”。

参考书目:

  • 当然,有关更多信息,请参见Wikipedia。

  • Vdirsyncer的作者提出的一种简单的同步算法

  • OBJC关于数据同步的文章

  • SyncML®:同步和管理您的移动数据(在O’Reilly Safari上预订)

  • 无冲突的复制数据类型

  • 乐观复制YASUSHI SAITO(惠普实验室)和MARC SHAPIRO(微软研究有限公司)-ACM 计算调查,第一卷。 V,第N号,2005年3月。

  • 亚历山大·特劳德(Alexander Traud),尤尔根·纳格勒·伊莱因(Juergen Nagler-Ihlein),弗兰克·卡格(Frank Kargl)和迈克尔·韦伯(Michael Weber)。2008。通过重用SyncML进行循环数据同步。在第九届国际移动数据管理国际会议论文集(MDM ‘08)中。IEEE计算机协会,华盛顿特区,美国,​​165-172。DOI = 10.1109 / MDM.2008.10 http://dx.doi.org/10.1109/MDM.2008.10

  • Lam,F.,Lam,N.和Wong,R.2002。移动XML数据的高效同步。在第十一届国际信息和知识管理国际会议论文集(2002年11月4日至9日,美国弗吉尼亚州麦克莱恩)上。CIKM ‘02。ACM,纽约,纽约,153-160。DOI = http://doi.acm.org/10.1145/584792.584820

  • 公关库(Cunha)和麦博姆(TS)1981。抽象数据类型+同步-面向消息的编程方法-。在第五届软件工程国际会议论文集(1981年3月9日至12日,美国加利福尼亚州圣地亚哥)上。国际软件工程大会。IEEE Press,Piscataway,NJ,263-272。

(最后三个来自ACM数字图书馆,不知道您是会员还是可以通过其他渠道获得)。

从Dr.Dobbs网站:

  • 使用SQL Server CE和SQL RDA创建应用程序,作者Bill Wagner,2004年5月19日(为台式机和移动PC设计应用程序的最佳做法-Windows / .NET)

来自arxiv.org:

  • 无冲突的复制JSON数据类型-本文描述了JSON CRDT的实现(无冲突的复制数据类型-CRDT-是支持并发修改并保证此类并发更新的收敛性的数据结构家族)。


 类似资料:
  • 问题内容: 我已经使用sqlite3在xcode中创建了一个应用程序。我想创建一个名为sync的按钮以与服务器中的mysql数据库进行同步。关于同步过程有什么建议吗?请告诉我。 问题答案: 在服务器上使用Web服务返回架构版本号和上次更新的时间戳记。如果客户端已过时,它将再次调用以获取更新的架构和/或新数据。

  • 问题内容: 我正在制作客户端服务器MMO风格的游戏。到目前为止,我已经建立了框架,以便服务器和客户端相互交互以提供状态更新。服务器维护游戏状态并定期计算下一个状态,然后每隔一段时间(每n毫秒)将其发送给所有客户端。用户可以在客户端查看此新状态并做出反应。然后,将这些操作发送回服务器进行处理,并发送给下一次更新。 明显的问题是这些更新在服务器和客户端之间传播需要花费时间。如果客户端采取行动攻击敌人,

  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 异步Mysql客户端 AsyncMysql::query($sql, $usePool = true) 第二个参数设为false将不会使用连接池中的资源,默认都会从连接池中取,配置连接池数量 => config/database.php 具体使用 use AsyncMysql; //设置超时时间 AsyncMysql::setTimeout(2); $res = (

  • 异步Redis客户端 连接池(连接池默认开启) use AsyncRedis; //关闭连接池 AsyncRedis::enablePool(false); //开启连接池 AsyncRedis::enablePool(true); 使用AsyncRedis use AsyncRedis; //设置超时时间 AsyncRedis::s

  • 异步Http客户端 Get方式 1.使用域名形式 use AsyncHttp; //直接使用域名, get方式 $http = new AsyncHttp('http://groupco.com'); //设置2s超时 $http->setTimeout(2); //$http->setCookies(['token' => 'xxxx']);