2011-09-12 29 views
3

我在使用time_uuid类型作为我的columnfamily中的键时遇到了问题。我想存储我的记录,并在插入它们时让它们排序,然后我发现time_uuid是一个好方法。这就是我建立了我的列族:pycassa中的时间UUID类型

sys.create_column_family("keyspace", "records", comparator_type=TIME_UUID_TYPE) 

当我尝试插入,我这样做:

q=pycassa.ColumnFamily(pycassa.connect("keyspace"), "records") 
myKey=pycassa.util.convert_time_to_uuid(datetime.datetime.utcnow()) 
q.insert(myKey,{'somedata':'comevalue'}) 

然而,当我插入数据,我总是得到一个错误:

v1 UUID列名或值的参数既不是UUID,也不是日期时间或数字。

如果我将comparator_type更改为UTF8_TYPE,它将起作用,但是返回时的项目顺序不符合它们的要求。我究竟做错了什么?

回答

3

列族的比较器用于排序每行内的列。你看到这个错误,因为'somedata'是有效的utf-8,但不是有效的uuid。

存储在cassandra中的行的顺序由分区器决定。最有可能你正在使用RandomPartitioner横跨集群平均分配负荷,但不允许进行有意义的范围查询(该行会以随机顺序返回。)

http://wiki.apache.org/cassandra/FAQ#range_rp

9

的问题是,在你的数据模型,你正在使用时间作为行键。虽然这是可能的,但除非您还使用ByteOrderedPartitioner,否则您将无法获得有意义的排序。

因此,大多数人使用时间插入时间排序的数据作为列名称,而不是行密钥。在这个模型中,您插入语句看起来像:

q.insert(someKey, {datetime.datetime.utcnow(): 'somevalue'}) 

其中someKey是涉及您将整个时间序列(例如,用户名)的关键。 (请注意,您不必将时间转换为UUID,pycassa会为您执行此操作。)要存储超过一个值的内容,请使用超列或组合键。

如果您确实想在行键中存储时间,则需要指定key_validation_class而不是comparator_typecomparator_type设置列名的类型,而key_validation_class设置行键的类型。

sys.create_column_family("keyspace", "records", key_validation_class=TIME_UUID_TYPE) 

请记住,除非您还使用ByteOrderedPartitioner,否则不会对行进行排序。

+0

卡桑德拉时间序列数据的优秀读取可以在这里找到:http://rubyscale.com/blog/2011/03/06/basic-time-series-with -cassandra /)和这里:[datastax.com](http://www.datastax.com/dev/blog/advanced-time-series-with-cassandra) – georg

+0

请注意,您可能需要将时间转换为UUID如果您需要**通过**'column_name'获取数据或**更新数据**,因此不希望pycassa将随机字节添加到UUID的非时间特定部分。为此,您需要设置'your_time_series_column_family.autopack_names = False'并生成'column_name',例如像这样:'pycassa.util.convert_time_to_uuid(time.time())。bytes' – georg