使用datastax cassandra驱动程序(3.0)可以看到一个奇怪的行为。我创建了一个新的集群,然后我使用同一个集群对象启动了一组线程。如果我保持线程为1或2,我会看到5ms的平均提取时间,但是如果我将线程数增加到60,则提取时间会增加到200ms(每个线程)。奇怪的是,如果我让60个线程应用程序运行,并且我在同一台机器上启动另一个只有1个线程的进程,那么该单线程应用程序的提取时间又是5ms。所以这似乎与客户有关。我多次重复相同的测试以避免缓存冷启动问题。 这里是集群对象是如何配置:Cassandra java驱动程序 - 使用多线程提取数据时的高延迟
PoolingOptions poolingOptions = new PoolingOptions();
poolingOptions
.setConnectionsPerHost(HostDistance.LOCAL, parallelism, parallelism+20)
.setConnectionsPerHost(HostDistance.REMOTE, parallelism, parallelism+20)
.setMaxRequestsPerConnection(HostDistance.LOCAL, 32768)
.setMaxRequestsPerConnection(HostDistance.REMOTE, 2000);
this.cluster = Cluster.builder()
.addContactPoints(nodes)
.withRetryPolicy(DowngradingConsistencyRetryPolicy.INSTANCE)
.withReconnectionPolicy(new ConstantReconnectionPolicy(100L))
.withLoadBalancingPolicy(new TokenAwarePolicy(DCAwareRoundRobinPolicy.builder().build()))
.withCompression(Compression.LZ4)
.withPoolingOptions(poolingOptions)
.withProtocolVersion(ProtocolVersion.V4)
.build();
有谁经历过同样的问题吗?这似乎是一个客户端配置问题。也许Netty有一些额外的缺失配置?
更新1 什么应用程序在做使用查询等提取数据的块:
select * from table where id=? and ts>=? and ts<?
所以我有60个线程并行提取这些数据。 id是分区键。每个查询由线程执行如下:
//Prepare statement
PreparedStatement stmt = ... get the prepared statment cached
BoundStatement bstmt = stmt.bind(...)
//Execute query
long te1 = System.nanoTime();
ResultSet rs = this.session.execute(bstmt);
long te2 = System.nanoTime();
//Fetch...
Iterator<Row> iterator = rs.iterator();
while (!rs.isExhausted() && iterator.hasNext()) { .... }
会话是一个并共享交叉所有线程。我测量的是session.execute()方法调用的平均时间。
谢谢!
更新2 下面是schema定义
CREATE TABLE d_t (
id bigint,
xid bigint,
ts timestamp,
avg double,
ce double,
cg double,
p double,
w double,
c double,
sum double,
last double,
max double,
min double,
p75 double,
p90 double,
p95 double,
squad double,
sumq double,
wavg double,
weight double,
PRIMARY KEY ((id), xid, ts)
) WITH CLUSTERING ORDER BY (xid DESC, ts DESC)
and compaction = {'class': 'SizeTieredCompactionStrategy'}
and gc_grace_seconds=86400
and caching = { 'keys' : 'ALL', 'rows_per_partition':'36000' }
and min_index_interval = 2
and max_index_interval = 20;
更新3 也试图与
.setMaxRequestsPerConnection(HostDistance.LOCAL, 1)
.setMaxRequestsPerConnection(HostDistance.REMOTE, 1)
没有变化
谢谢!我用一个应用程序正在做的例子更新了这个问题。问候 – RJtokenring
谢谢!我会更新我的答案。 –
在我研究之前,你的结果集有多大? (每行的列数,每个查询的行数)? –