首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >支持不同时间点的任意更新的随时间变化的维护设计

支持不同时间点的任意更新的随时间变化的维护设计
EN

Software Engineering用户
提问于 2021-04-24 21:25:34
回答 1查看 77关注 0票数 -1

我有一个文档集合,其中包含一个主题id、一个时间戳和一个值。例如:

代码语言:javascript
运行
复制
{ sid: 1, t: 3, v: "A" }    
{ sid: 1, t: 5, v: "B" }

这意味着subject#1的值在t=3被度量为值A,而在t=5,值被更改为"B“。只有当值被更改时,才会插入新文档。

我的目标是保存更改的历史记录,并允许查询。

  • 对于多个主题ID(或此处未提及的其他字段),可以获得完整的历史记录或
  • 一个主题和一个“当时的价值”的时间戳。

我定期地收到另一组包含不同时间的主题和值的文档(t)。然后我需要将这些新信息合并到现有的数据中。假设我收到:

代码语言:javascript
运行
复制
{ sid: 1, t: 2, v: "A" }
{ sid: 1, t: 6, v: "B" }    
{ sid: 2, t: 5, v: "C" }

并不是这套新的文件都能给我提供有用的信息。解释:

  1. 第一个是有用的,因为它让我知道一个变化发生得比我想象的要早,所以我应该使用它。我正试图尽早发现变化:
  2. 第二种方法并不有用,因为我已经知道在t=5发生的从"A“到"B”的值变化早于新的信息。
  3. 第三种方法很有用,因为我以前没有任何关于subject#2的信息。

因此,合并后的结果应该是:

代码语言:javascript
运行
复制
{ sid: 1, t: 2, v: "A" }
{ sid: 1, t: 5, v: "B" }    
{ sid: 2, t: 5, v: "C" }

新的信息以流的形式到达,约为2-3k文档/秒。我可以将它作为一个流处理,或者分批处理,15分钟宽=250万个文档。现有的更改--数据收集有数亿个文档。

新到达的数据没有及时排序,它可以包含比现有数据更早或更晚的时间戳。

最简单的方法是查询每个传入文档的现有集合,并查看是否发生了有用的更改,但这意味着每秒对数据存储(Solr)的查询将达到数千次。

另一种方法是以某种方式检测哪些文档可能会受到新数据的影响,并一次性加载、修改并一次性将其写回。我不知道如何才能确定这些文件。**

我试图独立于任何特定技术来问这个问题,因为我认为这个设计问题也与技术栈无关,但是变更数据将存储在Solr中,我可以在Spark中运行聚合。如果能解决这个问题,另一个技术栈建议也是受欢迎的。

如果可以帮助解决这个问题,我还可以更改模式和数据在现有数据和传入数据中的表示方式。

你对这个问题有设计上的建议吗?还是回答我的问题?

EN

回答 1

Software Engineering用户

发布于 2021-04-24 22:27:21

我想我要指出的是,这里有一些潜在的错误推理。所以,你说如果你有:

代码语言:javascript
运行
复制
{ sid: 1, t: 3, v: "A" }    
{ sid: 1, t: 5, v: "B" }

那么{ sid: 1, t: 6, v: "B" }是多余的。可能是真的。

但是,让我们研究一个例子,当将不更改视为冗余时将是一个错误:

假设我们得到的改变不是在t:6,而是在t:7{ sid: 1, t: 7, v: "B" }。然后,我们得到了{ sid: 1, t: 6, v: "C" }

将这两个示例更改添加到我们的两个原始更改(按时间戳排序):

代码语言:javascript
运行
复制
{ sid: 1, t: 3, v: "A" }    
{ sid: 1, t: 5, v: "B" }
{ sid: 1, t: 6, v: "C" }
{ sid: 1, t: 7, v: "B" }
// at t:8 sid:1 is B. This is correct

再次添加这两个更改,但这一次,当它们出现时,让我们删除未更改:

代码语言:javascript
运行
复制
{ sid: 1, t: 3, v: "A" }    
{ sid: 1, t: 5, v: "B" }
{ sid: 1, t: 6, v: "C" }
<deleted before event at t:6 was known because it was a non-change from t:5>
// at t:8, sid:1 is C. Whoops. That's wrong.

在当时,t:7可能看起来是一个多余的不改变,但一旦知道t:6就变得重要了。如果我们抛弃了t:7t:6就会愚弄我们,以为sid:1的最终价值是C

如果有一个新的变化可以适应的差距,我们就不能对不完整数据的实际冗余做出一个好的决定。

事实上,问题不只是与差距有关。如果您正在接收来自某个源的数据,您不能百分之百地相信它是一致的,您也有一个问题。假设第一个人得到了{ sid: 1, t: 6, v: "C" },然后一个人得到了{ sid: 1, t: 6, v: "D" }。如果第一个被丢弃为“多余”,那么当第二个进入时,就不可能检测到发生了什么奇怪的事情。

你可能已经注意到这是我考虑过的事情。我使用postgresql“时态表”编写了一些代码,类似地配置为不持久化非更新。有意义的代码的一个重要部分是确保严格按照顺序处理事件。

因此,可能只有在查询中或在您维护和更新的读取模型中删除“冗余”数据才有可能从您的更改存储中删除。但这是一个不同的问题,我不知道你的技术或用例如何有效或大规模地做到这一点。

票数 5
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/425761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档