如何有效地从Cassandra中批量选择数据?

pan*_*ang 3 cql cassandra

我知道 Cassandra 不支持批量查询,也不建议使用IN,因为它会降低性能。但我必须通过id获取数据,例如:

select * from visit where id in ([visit_id array])
Run Code Online (Sandbox Code Playgroud)

说明表:

CREATE TABLE visit (
    enterprise_id int,
    id text,
    ........
    PRIMARY KEY (enterprise_id, id)
Run Code Online (Sandbox Code Playgroud)

该数组可能有数千个元素。有什么办法可以有效做到吗?

xma*_*s79 6

我发出此类查询的首选方法是展开部件IN。这仅仅意味着您需要并行发出多个查询,因为token-o-matic(又名令牌感知)驱动程序会将每个查询视为单个独立查询,然后将它们分布在不同的节点之间,从而使每个单个节点负责每个查询的协调员。

您应该最多运行X 个查询,并等待至少其中一个查询完成(我使用 Java):

final int X = 1000;
ArrayList<ResultSetFuture> futures = new ArrayList<>();
ArrayList<ResultSet> results = new ArrayList<>();
for (int i = 0; i < allTheRowsINeedToFetch; i++) {
    futures.add(session.executeAsync(myBeautifulPreparedStatement.bind(xxx,yyy,zzz)));
    while (futures.size() >= X || (futures.size() > 0 && futures.get(0).isDone())) {
        ResultSetFuture rsf = futures.remove(0);
        results.add(rsf.getUninterruptibly());
    }
}

while (futures.size() > 0) {
    ResultSetFuture rsf = futures.remove(0);
    results.add(rsf.getUninterruptibly());
}

// Now use the results
Run Code Online (Sandbox Code Playgroud)

这称为背压,用于将压力从集群转移到客户端

此方法的优点在于,您可以实现真正的并行 ( X = allTheRowsINeedToFetch ),也可以实现真正的串行 ( X = 1 ),并且两者之间的所有内容仅取决于您的集群硬件。X值较低意味着您没有充分使用集群功能,而值较高则意味着您会遇到麻烦,因为您将开始看到超时。所以,你确实需要调整它。