You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何增大Fetch Size以减少扫描Cassandra表时的网络调用次数

问题描述

我正在使用DataStax Java Driver 4.15版本,已阅读分页文档。

我的application.conf配置如下:

datastax-java-driver {   
    basic.contact-points = [ "<IP>:<PORT>"]
    basic.request {
      consistency = LOCAL_QUORUM
      page-size = 5000
    }
    advanced.prepared-statements {
      prepare-on-all-nodes = false
    }
  }

我的扫描代码如下:

ByteBuffer scan() {
  val query = "SELECT workflow_id, trace_id, message_key, created_at FROM workflow_message";
  val stmtBuilder = new SimpleStatementBuilder(query).setPageSize(5000);
  if (pagingState != null) {
      stmtBuilder.setPagingState(pagingState);
  }
   val rs = cqlSession.execute(stmtBuilder.build());
   while(rs.getAvailableWithoutFetching() > 0) {
    val row = rs.one();
    System.out.printf("\n%s, %s, %s", row.getString("workflow_id"), row.getString("trace_id"), row.getString("message_key"))
   }
   return rs.getExecutionInfo().getPagingState();
}

我发现每次仅能读取约25行数据,请问如何增大fetch size以减少与服务器的网络调用次数?


解决方案

核心问题是混淆了page size和fetch size的作用,同时代码循环逻辑只处理了驱动本地缓存的行,没有触发后续分页拉取。

1. 明确两个参数的区别

  • page size:Cassandra服务器单页返回的最大行数,你配置的5000是告诉服务器每页最多返回5000行。
  • fetch size:驱动端每次从服务器拉取并缓存的行数(默认25),缓存耗尽后才会自动请求下一页。

2. 修改代码逻辑,触发完整分页获取

当前循环while(rs.getAvailableWithoutFetching() > 0)只处理了本地缓存的25行,要获取完整的一页数据,有两种方式:

方式一:直接遍历ResultSet(推荐)

遍历过程中驱动会自动在缓存耗尽时拉取下一页:

ByteBuffer scan() {
  String query = "SELECT workflow_id, trace_id, message_key, created_at FROM workflow_message";
  SimpleStatementBuilder stmtBuilder = new SimpleStatementBuilder(query)
      .setPageSize(5000);
  if (pagingState != null) {
      stmtBuilder.setPagingState(pagingState);
  }
  ResultSet rs = cqlSession.execute(stmtBuilder.build());
  
  // 遍历所有行,驱动自动处理分页拉取
  for (Row row : rs) {
      System.out.printf("\n%s, %s, %s", row.getString("workflow_id"), row.getString("trace_id"), row.getString("message_key"));
  }
  
  return rs.getExecutionInfo().getPagingState();
}

方式二:一次性获取当前页所有行

用rs.all()触发驱动拉取完整的当前页数据(达到page size上限):

ByteBuffer scan() {
  String query = "SELECT workflow_id, trace_id, message_key, created_at FROM workflow_message";
  SimpleStatementBuilder stmtBuilder = new SimpleStatementBuilder(query)
      .setPageSize(5000);
  if (pagingState != null) {
      stmtBuilder.setPagingState(pagingState);
  }
  ResultSet rs = cqlSession.execute(stmtBuilder.build());
  
  // 一次性获取当前页全部行
  List<Row> rows = rs.all();
  for (Row row : rows) {
      System.out.printf("\n%s, %s, %s", row.getString("workflow_id"), row.getString("trace_id"), row.getString("message_key"));
  }
  
  return rs.getExecutionInfo().getPagingState();
}

3. 调整驱动fetch size(可选)

如果想减少驱动拉取次数,可以调整fetch size(不能超过page size):

  • 全局配置:在application.conf中添加:
    datastax-java-driver {
      basic.request {
        fetch-size = 1000 # 驱动每次拉取1000行缓存
      }
    }
    
  • 单语句配置:在语句构建时单独设置:
    SimpleStatementBuilder stmtBuilder = new SimpleStatementBuilder(query)
        .setPageSize(5000)
        .setFetchSize(1000);
    

内容的提问来源于stack exchange,提问作者tuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:01:03