使用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
謝謝!我會更新我的答案。 –
在我研究之前,你的結果集有多大? (每行的列數,每個查詢的行數)? –