在 Cassandra 中存储加权图时间序列
Posted
技术标签:
【中文标题】在 Cassandra 中存储加权图时间序列【英文标题】:Storing Weighted Graph Time Series in Cassandra 【发布时间】:2013-07-02 21:58:50 【问题描述】:我是 Cassandra 的新手,我想集思广益,在 Cassandra 中存储加权图的时间序列,其中边权重每次都会增加,但也会随着时间而更新。例如,
w_ij(t+1) = w_ij(t)*exp(-dt/tau) + 1
我的第一个镜头涉及两个 CQL v3 表:
首先,我通过连接图形的 id 和特定边上的两个节点来创建一个分区键,例如G-V1-V2。我这样做是为了能够在下面描述的复合键的第二个组件(即时间戳类型)上使用“ORDER BY”指令。将此字符串称为 EID,用于“edge id”。
表格1 - 边缘更新的时间序列 - 主键:EID、时间、重量 表 2 - “最后更新时间”和“最后重量”的值 - 主键:开斋节 - 列:时间,重量每次滴答时,我都会获取并更新存储在表 2 中的时间和权重值。我使用这些值来计算时间增量和新权重。然后我将这些值插入表 1。
此策略是否存在严重的低效率问题? 应该怎么做?我已经知道表 2 的更新过程不是幂等的,可能会导致不一致,但我暂时可以接受。
编辑:我可能会做的一件事是将两个表合并为一个时间序列表。
【问题讨论】:
【参考方案1】:当涉及到 Cassandra(以及任何其他您无法对写入执行比较和交换操作的数据库)时,您应该避免任何类型的 read-before-write。
【讨论】:
【参考方案2】:首先:您的应用程序有哪些查询和查询模式? 此外,我会对计算和存储每条边的新权重的频率感兴趣。每一秒、每一小时、每一天?
是否可以在内存中保存每条边的最后权重?所以你可以避免在写作之前阅读?这个值的某种延迟加载机制可能是可行的。
如果您的查询允许使用此数据模型,我会尝试使用单列族构建解决方案。
【讨论】:
【参考方案3】:我会避免在写 Cassandra 之前先阅读,因为它确实不太适合。读取是昂贵的,比写入要贵得多,为了维持性能,您需要大量节点来处理相对少量的查询。您的建议并不适合 Cassandra,因为似乎没有任何方法可以避免在您写作之前阅读。即使您使用单个表,您仍然需要获取最后一个更新条目来执行您的写入。虽然它当然可以完成,但我认为有更好的工具来完成这项工作。话虽如此,如果您可以将表 2 中的所有数据保存在内存中,并可能利用行缓存,这将是完全可行的。只要表 2 不是太大以至于它可以容纳内存中的大多数行,您的读取将明显更快,这可能会弥补每次写入执行读取的需要。然而,这将是一个相当大的挑战,您需要确保仅将每行的“最后更新时间”保存在内存中,并且很少需要触及磁盘。
无论如何,您可能想要查看的另一种设计是一种实现,您不仅使用 Cassandra,而且还使用 Cassandra 前面的缓存来存储上次更新时间。这可以与 Cassandra 一起运行,也可以在单独的节点上运行,但可能只是最后一次更新时间的内存存储,当您需要更新一行时,您可以查询缓存,并将整行写入 Cassandra(您甚至可以编写上次更新时间(如果您愿意)。您可以使用 Redis 之类的工具来执行此功能,这样您就无需担心墓碑或强制将所有内容存储在内存中等等。
【讨论】:
以上是关于在 Cassandra 中存储加权图时间序列的主要内容,如果未能解决你的问题,请参考以下文章