0

我在 Cassandra 有一个 Column 家族,我将在其中存储这样的东西-

BundleName    |     Version
----------------------------
FrameworkBundle    1.0.0
BundleA            1.0.0
BundleB            1.0.0
BundleC            1.0.0
BundleD            1.0.0

我正在使用 Astyanax 客户端从 Cassandra 数据库中检索数据。我将有一些方法可以从 Cassandra 中检索数据-

public Map<String, String> getFromDatabase() {

    // 1) For the first time, return me everything in the map
    // 2) Second time, it should return me only the the change if there is any bundle version change

}

现在这个方法应该把所有东西都作为地图返回给我,就像这样 -

Key as FrameworkBundle and Value as 1.0.0
Key as BundleA and Value as 1.0.0
Key as BundleB and Value as 1.0.0
....
And for other Bundles like above

现在我需要的是——

  1. 当我第一次运行我的应用程序时,它应该像上面一样返回地图中的所有内容。
  2. 而且我有一个后台线程,它将每 15 分钟检查一次 Cassandra 数据库,以查看是否有新版本的捆绑包。如果任何捆绑包有任何新版本,那么只需将捆绑包名称及其新版本返回给我,如果任何版本都没有更改,则不要第二次给我返回任何东西。然后,同样的过程将每 15 分钟发生一次。

仅意味着第一次,否则我想返回所有内容,除非捆绑版本有任何更改,否则我不想返回任何内容。

我不确定 Cassandra 是否可以直接提供这方面的信息,而无需编写某种逻辑来获取我需要的信息。

在 Cassandra 中做这件事的最好和最有效的方法是什么?我不想每 15 分钟从 Cassandra 数据库中检索所有数据,然后执行某种逻辑来找出更改了哪个捆绑版本。

4

1 回答 1

1

好吧,cassandra 有点像键/值存储,所以为了实现这一点,您需要一个合理的行键。提交(列范围)查询时,您始终需要行键。捆绑名称和版本都不是很好的行键,因为您需要提前知道它们。您是否有某种应用程序分类或其他可用于分区的功能?

例如,如果您将应用程序类型 ID(商业、开源、私有...)作为另一个字段,您可以轻松创建一个表,其中您的集群/列键是时间戳。您的行键可能是您的应用程序类型 ID。每当有新版本时,将版本号插入应用程序/时间戳。然后,使用时间戳进行范围查询。

  CREATE TABLE Bundles (
    bundle varchar,
    type varchar,
    ts timeuuid,
    version varchar,
    PRIMARY KEY (type, ts)
   );

如果您是第一次运行并想了解所有新版本,请运行:

cqlsh:test> SELECT * FROM Bundles WHERE 
    ...        type = 'OSS' and
    ...        ts < maxTimeuuid('2013-08-27 09:00:00');

(empty resultset)

因为到目前为止还没有插入。

然后,您(或其他一些进程)插入一个新版本。 假设您有几个软件类别,名为“类型”,类型是“框架”或“开源”或任何适合您的用例,您可以插入如下数据:

cqlsh:test> INSERT INTO Bundles (bundle, type, ts, version) 
 VALUES ('SomeFramwork', 'OSS', now(), '0.1.0a');

这会在分区 1 中存储一个新列(在 now() 的列键值下)(对于类型,我们的分片键)。

十五分钟后,如果您想知道过去 15 分钟内的所有新版本,请运行:

    cqlsh:test> SELECT type, dateOf(ts), bundle, version FROM Bundles WHERE
     type = 'OSS' and
     ts > minTimeuuid('2013-08-27 09:00:00')
     and ts < maxTimeuuid('2013-08-27 09:15:00');

     type | dateOf(ts)               | bundle       | version
    ------+--------------------------+--------------+---------
      OSS | 2013-08-27 09:14:27+0200 | SomeFramwork |  0.1.0a

您需要对每种类型进行查询。TimeUUD 类型将保证插入保持无冲突。

如果您担心行变得太长(> 20 亿),您可以使用存储桶来限制行长度。

要使用 cql3 查询插入 Astyanax,您可以使用

    keyspace.prepareQuery(CF_BUNDLES).withCql(cql).execute();

其中 cql 是您的 cql 查询,CF_BUNDLES 是 ColumnFamily 的一个实例。

要使用上面在 Astyanax 中定义的 cql 查询获取数据,您可以使用

    CqlResult<String, String> result = keyspace
    .prepareQuery(CF_BUNDLES).withCql(cql).execute()
    .getResult();

这使您能够迭代结果。

于 2013-08-26T12:02:02.883 回答