我读了这个问题,但它并没有真正的帮助。
首先也是最重要的事情:时间性能是我正在开发的应用程序中的重点
我们有一个客户端/服务器模型(如果我们愿意,甚至可以是分布式或云)和一个托管在服务器上的数据结构D
。每个客户端请求包括:
- 阅读
D
的内容 -
最终在
D
上写点东西 -
最终删除
D
上的某些内容
我们可以说,在此应用程序中,接收的操作数量之间的关系可以描述为delete<<write<<read
。另外:
- 读取操作不能绝对等待:必须立即处理它们
- 写入和删除可以等待一段时间,但越快越好。
从上面的描述来看,任何锁定机制都是不可接受的:这意味着读取操作可以等待,这是不可接受的(对不起,如果我如此强调它,但这确实是一个关键点)。
一致性不是必需的:如果已经执行了写入/删除操作,然后读取操作看不到写入/删除效果,这没什么大不了的。它会更好,但这不是必需的。
解决方案应该是独立于数据结构的,所以我们写在矢量、列表、地图还是唐纳德·特朗普的脸上并不重要。
数据结构可能会占用大量内存。
到目前为止,我的解决方案:
我们使用两台服务器:第一台服务器(称为f
)有Df
,第二台服务器(称为s
)Ds
更新。
f
使用Df
应答客户端请求,并向s
发送写入/删除操作。然后s
按顺序Ds
应用写入/删除操作。
在某个时候,所有将来的客户端请求都将重定向到s
。同时,f
副本s
更新Ds
到其Df
中。
现在,f
和s
角色互换:s
将使用Ds
回答客户端请求,f
将保留Ds
的更新版本。交换过程会定期重复。
请注意,为了简单起见,我故意省略了很多细节(例如,一旦交换完成,f
必须完成所有挂起的客户端请求,然后才能应用同时从s
收到的写入/删除操作)。
为什么我们需要两台服务器?因为数据结构可能太大,无法放入一个内存中。
现在,我的问题是:文学中有一些类似的方法?我在 10 分钟内想出了这个协议,我觉得奇怪的是没有提出与此类似的(更好的)解决方案!
PS:我可能忘记了一些应用程序规格,请随时要求任何澄清!
您拥有的方案有效。我认为它没有任何特别的问题。这基本上就像许多数据库运行其 HA 解决方案一样。它们将写入日志应用于副本。此模型在副本的形成、访问和维护方式方面提供了极大的灵活性。故障转移也很容易。
另一种技术是使用持久数据结构。每次写入都会返回一个新的独立数据版本。所有版本都可以以稳定和无锁的方式读取。版本可以随意保留或丢弃。版本尽可能多地共享基础状态。
通常,树是这种持久数据结构的基础,因为很容易更新树的一小部分并重用大部分旧树。
您可能没有找到更复杂的方法的一个原因是您的问题非常普遍:您希望它适用于任何数据结构,并且数据可能很大。
SQL Server Hekaton 使用相当复杂的数据结构来实现任何数据库内容的无锁、可读时间点快照。也许值得看看他们是如何做到的(他们发表了一篇描述系统每个细节的论文)。它们还允许 ACID 事务、可序列化性和并发写入。全部无锁。
同时,f 将更新后的 Ds 复制到其 Df 中。
此副本将花费很长时间,因为数据很大。它会阻止读者。更好的方法是在接受新写入之前将写入日志应用于可写副本。这样就可以连续接受读取。
切换也是一个较短的时间段,读取的延迟可能略高于正常情况。