对于以下情况,最佳的Cassandra数据模型和查询是什么?
我们的系统负责为我们的烤面包机分配唯一的序列号,每次都是在我们的工厂里创建的。
所需业绩:
我们的数据集现在大约有1000万个序列号,每年增长约100万。
我们目前正在使用Cassandra 2.0.x,不久将迁移到2.1.x。
发布于 2015-04-16 14:57:46
好吧,我对这件事作了一些思考。在这种情况下,有几件事是很棘手的:
我假设您想知道哪些序列号与哪种型号联系在一起,哪些型号有哪些序列号。为此,我将使用两个查找表:
CREATE TABLE serialNumbersByUPC (
modelUPC uuid,
insertTime timeuuid,
serialNumber text,
PRIMARY KEY (modelUPC,insertTime))
WITH CLUSTERING ORDER BY (insertTime DESC);
CREATE TABLE UPCsBySerialNumbers (
modelUPC uuid
insertTime timeuuid,
serialNumber text,
PRIMARY KEY (serialNumber));请注意,您也可以使用serialNumbersByUPC作为集群键(而不是insertTime)来对serialNumber进行键设置。但是timeuuids是唯一的(因此在serialNumbers上不会发生冲突),通过insertTime进行集群还有一个好处,允许您按日期/时间进行排序。当然,在为UPC分配序列号时,您需要确保插入到这两个表中。
对于未分配的序列号,最好使用像HornetQ或RabbitMQ这样的排队系统。这样,您就可以从队列中取出新的序列号,并根据需要分配它们。我提出这个建议的原因是,使用Cassandra来排队的瞬态数据已经被确认为反模式。
当然,您可以决定不注意上述警告,并坚持使用Cassandra作为该功能。如果是这样的话,那么我将用Cassandra存储未分配的序列号:
CREATE TABLE unassignedSerialNumbers (
dateBucket bigint,
serialNumber text,
insertTime timeuuid,
PRIMARY KEY ((dateBucket),insertTime))
WITH compaction = {'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy'}
AND gc_grace_seconds = 86400;关于这个解决方案的一些事情:
datebucket上进行分区,因为我不知道您分配每天进来的2800序列号的速度有多快。您可能只想查询今天或昨天输入的数字。我创建它是作为一个bigint,但您可以使用任何大小的桶(例如:"20150416“将隔断序列号的到来,2015年4月16日)。datebucket进行分区,那么我就不会担心那个表会变得足够大,从而影响查询性能。当然,您的删除将创建墓碑,您的查询将不得不面对,但这应该有助于我的最后两点。insertTime上进行聚类的原因与在serialNumbersByUPC表中的原因相同。DateTieredCompactionStrategy。此策略将将同时写入的行保存在相同的SSTABLE文件中。在删除和写入新数据时,这对性能非常重要。gc_grace_seconds被设置为1天而不是10天,这将迫使被刻在墓碑上的行每天被垃圾收集。此设置的缺点是,如果有一个节点下降,则需要在其下线后1天内将其带回来,以获取删除内容。如果你不这样做,你将需要运行一个完整的修复或冒险删除的序列号“从死后回来”。您还需要在DateTieredCompactionStrategy上阅读。可能还有一些其他的选择,可能对你来说是有意义的。
如果你有什么问题,或者我遗漏了什么,请告诉我。
发布于 2015-04-15 17:37:45
这个怎么样:
有一个包含未分配序列号的表,称之为“未分配”。当你被提供新的序列号时,它们会插入到“未分配”中。UPC编号是分区键,序列号可以是群集列。
然后有另一个表名为“指定”。在构建烤面包机时,可以从未分配的表中随机获取序列号,并尝试使用insert上的“如果不存在”子句将其插入指定的表中。这确保一个序列号只分配一次,以防您运行多个进程。
如果插入成功,则进程将返回并从未分配的表中删除序列号。如果插入由于已经存在的数字而失败,则随机选择不同的数字并尝试该数字,直到得到成功的数字为止。
要获取一个序列号来尝试插入,您可以从限制为100的适当未分配的UPC分区中进行选择,然后随机选择您返回的序列号之一(这样,如果您有多个进程,它们就不会在insert尝试中都尝试相同的编号)。并且在一个分区内限制100将非常快。
现在,要获得未分配数字的计数,可以为未分配表中的每个UPC分区执行选择计数(*),但是如果有太多行,则可能会超时。因此,您可以有第三个表的计数器列和只是增量和减少,因为序列号被添加和使用。
https://stackoverflow.com/questions/29615391
复制相似问题