我不知道这是不是问我问题的好地方,但就在这里。
受firebase的启发,我决定编写一个小框架来同步客户端之间的数据。这将简化诸如聊天、论坛等web应用程序的开发。
假设有一个或多个服务器。客户端可以连接到一个服务器并访问特定的集合(例如,聊天消息列表)。如果客户机修改集合,则这些修改将发送到请求访问同一集合的其他客户机。
我希望我的解决方案迅速而全面。修改的传播应该非常快,并且集合应该保存在数据库上。
集合可能非常大,但客户端可能只请求集合的视图(例如,最近20分钟的聊天消息)。
可能的解决方案
我们有n个服务器,1个节点有一个快速内存数据库(redis),还有一个集群有一个nosql db。
群集将包含完整的集合。
当客户机连接到服务器并首次被授予访问集合的权限时,将直接从集群中读取集合的请求部分。
当客户端修改集合C时,修改将写入内存中的数据库,其中将包含以下内容:
123添加了“消息…”
124删除ID235
125修改ID143“新消息…”
其中123、124和125是集合的版本。
在这种情况下,集群包含整个集合c及其版本号122。
当客户机第一次连接到服务器并访问集合c时,服务器从集群读取集合的请求部分,然后从内存db读取更新,以便将集合从版本122更新到版本125。
当客户端修改集合C时,
修改的描述被插入到存储器db中;
其他服务器被告知有新版本的c可用;
向客户端发送更新。
当然,其他服务器一旦得到通知,也会将更新发送给它们的客户机。
后台的另一个进程将按以下方式更新群集:
while(内存数据库包含的集合c更新少于k个)
从内存数据库中读取下一个更新u;
使用u原子地更新集群中的集合c及其版本号。
更新必须是可线性化的,也就是说,任何服务器都不能看到集合C处于在上一次更新之前应用了更新的状态。
当集群完全一致时,我们从内存数据库中从最低版本到最高版本删除更新。
问题
我的解决方案需要一个支持事务(acid?)并具有很强的一致性。例如,我不能使用MongoDB。
问题
你能想出一个更简单的解决办法吗?
或
如果我的解决方案是可以接受的,那么您建议集群使用什么数据库?
谢谢你的耐心。
最佳答案
如果为集合的每个元素分配了唯一的id,并且内存数据库中的更新包含这些id,则集群中的集合不需要版本号,因此不需要事务。
其思想是可以使用id来决定是否需要更新。例如,如果更新显示
version=123 action=add id=05276 msg=“消息”
而且群集中的集合已包含id=05276的文档,则此更新是旧的,并且已应用于群集中的集合。
我们只需要注意这一点:在从内存数据库中删除一些更新之前,我们必须确保这些更新已应用于集群中的集合,并且集群与该集合完全一致。
当客户端请求访问集合时,其连接的服务器需要:
从内存数据库中读取所有更新并将其保存在内存中
从集群中读取(集合的相关部分)
用保存在内存中的更新更新读集合
首先从内存数据库中读取所有更新是很重要的,以避免出现争用情况。考虑这个场景:
我们从集群中读取了集合的旧版本
集合已更新
集群变得完全一致
一些更新从内存数据库中删除
我们用新的更新更新了read集合
问题是,在第5点我们会错过一些更新。
关于mongodb - 客户端之间的数据同步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24844229/