更新cassandra中的TimeUUID列

时间:2013-03-04 19:38:48

标签: cassandra pycassa timeuuid

我正在尝试将一些时间序列数据存储在以下列族中:

create column family t_data with comparator=TimeUUIDType and default_validation_class=UTF8Type and key_validation_class=UTF8Type;

我以这种方式成功插入数据:

data={datetime.datetime(2013, 3, 4, 17, 8, 57, 919671):'VALUE'}
key='row_id'
col_fam.insert(key,data)

如您所见,使用datetime对象作为列名pycassa正确转换为timeUUID对象。

[default@keyspace] get t_data[row_id];

=> (column=f36ad7be-84ed-11e2-af42-ef3ff4aa7c40, value=VALUE, timestamp=1362423749228331)

有时,应用程序需要更新某些数据。问题是,当我尝试更新该列,传递相同的日期时间对象时,pycassa会创建一个不同的UUID对象(时间部分是相同的),因此它不会更新列,而是创建另一个。

[default@keyspace] get t_data[row_id];

=> (column=f36ad7be-84ed-11e2-af42-ef3ff4aa7c40, value=VALUE, timestamp=1362423749228331)

=> (column=**f36ad7be**-84ed-11e2-b2fa-a6d3e28fea13, value=VALUE, timestamp=1362424025433209)

问题是,如何通过传递datetime对象的pycassa更新基于TimeUUID的列?或者,如果这不是正确的方法,推荐的方式是什么?

1 个答案:

答案 0 :(得分:2)

除非你做了读 - 修改 - 写,否则你不能。 UUID本质上是独一无二的。它们的存在是为了解决如何获得按时间顺序排序的唯一ID的问题,同时避免在完全相同的时间发生碰撞。

因此,要更新该列,您需要先读取它,这样您就可以找到它的列键,更改其值并再次将其写回。

这不是一个特别优雅的解决方案。你应该真的避免在Cassandra中进行读 - 修改 - 写。也许TimeUUID不是列键的正确类型?或者也许还有另一种方法可以设计你的应用程序,以避免不得不回头改变事物。

在不知道您的查询模式是什么样的情况下,我无法确切地说出您应该做什么,但这里有一些希望相关的建议:

不要更新值,只需写入新值。如果某些事情在时间T是真的,那么时间T总是如此,即使它在时间T + 1发生变化。当事情发生变化时,你会用变化的时间写一个新值并让旧值变为。当您阅读时间线时,您可以通过选择最新值来解决这些冲突 - 并且由于值将按时间顺序排序,因此最新值将始终是最后一个值。这与Cassandra内部处理的方式非常相似,而且它是一种非常强大的模式。

不要担心这会占用更多的磁盘空间,或者在读取时间序列时需要一些额外的CPU,与读取 - 修改 - 写入复杂性相比,它很可能很小,否则您将不得不实现

可能还有其他方法可以解决您的问题,如果您向我们提供更多详细信息,我们可以提出更适合您的问题。