在Cassandra中存储加权图时间序列

时间:2013-07-04 20:59:20

标签: graph cassandra time-series data-modeling cql

我是Cassandra的新手,我想在Cassandra中集思广益存储加权图的时间序列,其中边缘权重每次都会增加,但也会随着时间的推移而更新。例如,

w_ij(t+1) = w_ij(t)*exp(-dt/tau) + 1

我的第一个镜头涉及两个CQL v3表:

首先,我通过连接图形的id和特定边缘上的两个节点来创建分区键,例如: G-V1-V2。我这样做是为了能够在下面描述的复合键的第二个组件上使用“ORDER BY”指令,这是类型时间戳。将此字符串称为EID,用于“edge id”。

TABLE 1
- a time series of edge updates
- PRIMARY KEY: EID, time, weight


TABLE 2
- values of "last update time" and "last weight"
- PRIMARY KEY: EID
- COLUMNS: time, weight

每次勾选时,我都会获取并更新表2中存储的时间和权重值。我使用这些值来计算时间增量和新权重。然后,我将这些值插入表1中。

这种策略是否有任何可怕的低效率? 应如何完成?我已经知道表2的更新过程不是幂等的,可能会导致不一致,但我暂时可以接受。

编辑:我可能做的一件事是将两个表合并为一个时间序列表。

3 个答案:

答案 0 :(得分:0)

当涉及到Cassandra(以及任何其他无法对写入进行比较和交换操作的数据库)时,应该避免任何类型的read-before-write。

答案 1 :(得分:0)

首先:您的应用程序有哪些查询和查询模式? 此外,我会感兴趣的是,每个边缘的新权重将被计算和存储的频率。每一秒,一小时,一天?

是否可以将每条边的最后一个重量保存在内存中?所以你可以在写作前避免阅读?可能这种值的某种延迟加载机制是可行的。

如果您的查询将允许此数据模型,我会尝试使用单列系列构建解决方案。

答案 2 :(得分:0)

在Cassandra写作之前我会避免阅读,因为它真的不太适合。读取是昂贵的,远远超过写入,并且为了维持性能,您需要大量节点来进行相对少量的查询。你所建议的并不能真正适合Cassandra,因为在你写作之前似乎没有任何方法可以避免阅读。即使您使用单个表,仍然需要获取最后一个更新条目以执行写入。虽然它当然可以做到,但我认为有更好的工具可以完成这项工作。话虽如此,如果您可以将表2中的所有数据保存在内存中,并且可能利用行缓存,这将是完全可行的。只要表2不是那么大,它可以适合内存中的大多数行,您的读取将显着更快,这可以弥补每次写入执行读取的需要。然而,这将是一个相当大的挑战,您需要确保每行的“最后更新时间”仅保留在内存中,并且很少需要触摸磁盘。

无论如何,您可能想要看到的另一个设计是一个实现,您不仅可以使用Cassandra,还可以使用Cassandra前面的缓存来存储上次更新的时间。这可以与Cassandra一起运行,也可以在单独的节点上运行,但可能只是最后一次更新时间的内存存储,当你需要更新一行时,你会查询缓存,然后把你的整行写到Cassandra(你甚至可以写如果你愿意的最后更新时间)。您可以使用Redis之类的功能来执行此功能,这样您就不必担心墓碑或强制将所有内容存储在内存中等等。