我们目前正在重写我们的点对点服务总线目录(Zebus)。
我们有一个Cassandra / Thrift实现,必须对其进行改进以满足一些新的加载要求,因此使用CQL重写它似乎是正确的做法。
我们有两个CF,一个用于存储Peers,一个用于存储Subscriptions,后者是最棘手的。
我们需要为每种消息类型存储路由密钥(绑定)列表,以及每个对等体的消息类型列表。我们还需要能够单独更新每个消息类型的路由列表(我们使用Cassandra的时间戳来处理潜在的竞争条件,因为我们有多个目录)。最后,当有人请求Peers状态时,我们需要能够列出所有这些订阅。
最后一点是一个问题,因为它意味着运行SELECT * FROM "Subscriptions"
,这意味着列出来自多个节点的行(BTW如何让CQL允许您列出底层的Cassandra行?)并且恰好很慢。 / p>
因此,我们最终为CF提供了以下模式,将所有内容连续存储在同一个Cassandra行的磁盘上并具有良好的读取性能(我们意识到这在平衡节点之间的数据方面非常糟糕)。
CREATE TABLE IF NOT EXISTS "DynamicSubscriptions" (
"UselessKey" boolean,
"PeerId" text,
"MessageTypeId" text,
"SubscriptionBindings" blob,
PRIMARY KEY("UselessKey", "PeerId", "MessageTypeId")
);
这很丑陋但是诀窍,每个人都在同一个“Thrift行”上,导致闪电般快速读取。
所以我的问题如下:如果我希望在无约束的SELECT期间我的数据能够快速查询,是否有漂亮方法来设计使用CQL的CF?
(或者,如果您认为我们的设计存在完全缺陷,请随时说出来。)
答案 0 :(得分:0)
所以,据我所知,你应该创建这样的表:
CREATE TABLE IF NOT EXISTS dynamic_subscriptions (
peer_id text,
message_type text,
bindings blob,
PRIMARY KEY (peer_id, message_type)
);
它与您的非常相似,但主要区别在于主键定义。
主键的第一列是分区键,这意味着具有相同分区键的所有数据将存储在同一物理列族行中。其余主键组件是群集列,用于区分单个分区键中的数据并对其进行排序。
换句话说,这种模式的优点是:
我希望这会对你有所帮助。
答案 1 :(得分:0)
通常会有一种方法来限制由用户交互驱动的要被阅读的信息。这也将推动您的数据模型设计。
我可以考虑限制您列出订阅的对等方数量的一种方法是基于时间段。请注意,这需要与您查询以获取每个对等方信息的CF分开。黄金法则是一个CF驱动一个查询。
假设您可以按时间限制向用户显示的对等方数量,下一个要解决的问题是将数据分布在多个分区(Thrift行)中。您可以使用MessageType和时间组件(如日期)的组合作为分区键。当您向用户显示此数据时,您将拥有自然的分页机制。
总结一下,你需要Jacek L提到的CF.此外,为了显示多个同伴的信息,您可以使用类似这样的内容
CREATE TABLE IF NOT EXISTS peer_subscriptions (
message_type text,
connection_date text,
peer_id text,
bindings blob,
PRIMARY KEY ((message_type,connection_date),peer_id)
);