【问题标题】:Cassandra - IN or TOKEN query for querying an entire partition?Cassandra - 用于查询整个分区的 IN 或 TOKEN 查询?
【发布时间】:2017-02-18 23:32:35
【问题描述】:

我想查询我的表的完整分区。 我的复合分区键由(id, date, hour_of_timestamp) 组成。 iddate 是字符串,hour_of_timestamp 是整数。

由于在摄取数据时出现热点,我需要将 hour_of_timestamp 字段添加到我的分区键中。

现在我想知道查询数据的完整分区最有效的方法是什么? 根据this blog 的说法,使用SELECT * from mytable WHERE id = 'x' AND date = '10-10-2016' AND hour_of_timestamp IN (0,1,...23); 会在协调节点上造成大量开销。

使用TOKEN 函数并使用两个令牌查询分区是否更好?如SELECT * from mytable WHERE TOKEN(id,date,hour_of_timestamp) >= TOKEN('x','10-10-2016',0) AND TOKEN(id,date,hour_of_timestamp) <= TOKEN('x','10-10-2016',23);

所以我的问题是: 我应该使用INTOKEN 查询来查询我的数据的整个分区吗?或者我应该使用 23 个查询(hour_of_timestamp 的每个值一个)并让驱动程序完成其余的工作?

我正在使用 Cassandra 3.0.8 和最新的 Datastax Java 驱动程序连接到 6 节点集群。

【问题讨论】:

  • 你能发布你的整个 PRIMARY KEY 定义吗?
  • @Aaron PRIMARY KEY ((log_creator, date, hour), ts, log_id) 是实际定义。我已将问题中的字段名称调整为更“通用”...tstimestamp 类型,log_id 是另一个字符串。

标签: cassandra cql cql3 datastax-java-driver


【解决方案1】:

你说:

现在我想知道查询完整的最有效方法是什么 我的数据分区?根据这个博客,使用 SELECT * from mytable WHERE id = 'x' AND date = '10-10-2016' AND hour_of_timestamp 在 (0,1,...23);在协调节点上造成大量开销。

但实际上您会查询 24 个分区。

您可能的意思是,您的设计中单个分区现在由 24 个分区组成,因为您添加了小时以避免数据摄取期间的热点。请注意,在这两种模型(旧模型和新模型)中,数据仍然按时间戳排序,您有两种选择:

  1. 一次运行 1 个查询。
  2. 第一次运行 2 个查询,然后一次运行一个以“预取”结果。
  3. 并行运行 24 个查询。

案例 1

如果您按顺序处理数据,第一个选择是运行第 0 小时的查询,处理数据,完成后,运行第 1 小时的查询,依此类推......这是一个简单的实现,并且我认为它不应该得到更多。

案例 2

如果您的查询花费的时间比数据处理时间长,您可以“预取”一些数据。因此,第一次可以并行运行 2 个查询,同时获取 0 小时和 1 小时的数据,并开始处理 0 小时的数据。与此同时,1 小时的数据到达,所以当您完成处理数据时小时 0 您可以预取第 2 小时的数据并开始处理第 1 小时的数据。依此类推....这样可以加快数据处理速度。当然,根据您的时间(数据处理和查询时间),您应该优化“预取”查询的数量。

还请注意,Java 驱动程序会自动为您分页,并且根据检索到的分区的大小,您可能希望禁用该功能以避免阻塞数据处理,或者可能希望使用类似的东西抢先获取更多数据this:

ResultSet rs = session.execute("your query");
for (Row row : rs) {
    if (rs.getAvailableWithoutFetching() == 100 && !rs.isFullyFetched())
        rs.fetchMoreResults(); // this is asynchronous
    // Process the row ...
}

您可以在哪里调整 rs.getAvailableWithoutFetching() == 100 以更好地满足您的预取要求。

您可能还想在第一次预取多个分区,以确保您的处理不会等待任何数据提取部分。

案例 3

如果您需要同时处理来自不同分区的数据,例如您需要第 3 小时和第 6 小时的数据,那么您可以尝试按“依赖关系”对数据进行分组(例如同时查询第 3 小时和第 6 小时)。

如果您需要所有这些,则应该并行运行 24 个查询,然后在应用程序级别加入它们(您已经知道为什么应该避免多个分区的 IN)。请记住,您的数据已经有序,因此您的应用程序级别的工作将非常小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-08
    • 2015-02-01
    • 1970-01-01
    • 2020-08-18
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多