ClickHouse / clickhouse-java

Java client and JDBC driver for ClickHouse
https://clickhouse.com
Apache License 2.0
1.42k stars 523 forks source link

Read timed out after 30000 ms, server ClickHouseNode #1622

Open ats1999 opened 4 months ago

ats1999 commented 4 months ago

I am using clickhouse docker on local machine. just testing out things, nothing else is connected with clickhouse. I have even tried starting and restarting the clickhouse, but didn’t work.

Java Code

    ClickHouseNode node =
        ClickHouseNode.builder()
            .host("localhost")
            .port(ClickHouseProtocol.HTTP, 8123)
            .database("test")
            .build();

    ClickHouseClient client =
        ClickHouseClient.builder()
            .nodeSelector(ClickHouseNodeSelector.of(ClickHouseProtocol.HTTP))
            .option(ClickHouseClientOption.COMPRESS_ALGORITHM, ClickHouseCompression.ZSTD)
            .option(ClickHouseClientOption.COMPRESS_LEVEL, 1)
            .option(ClickHouseClientOption.MAX_THREADS_PER_CLIENT, 4)
            .build();

    ClickHouseRequest.Mutation req =
        client.write(node).table("user").format(ClickHouseFormat.RowBinary);
    ClickHouseConfig config = req.getConfig();

    ClickHousePipedOutputStream stream =
        ClickHouseDataStreamFactory.getInstance().createPipedOutputStream(config, (Runnable) null);

    CompletableFuture<ClickHouseResponse> f = req.data(stream.getInputStream()).execute();
    BinaryStreamUtils.writeString(stream, "Rahul Kumar");
    BinaryStreamUtils.writeUnsignedInt32(stream, 25);
    f.get();

Error

Exception in thread "main" java.util.concurrent.ExecutionException: com.clickhouse.client.ClickHouseException: Read timed out after 30000 ms, server ClickHouseNode [uri=http://localhost:8123/test]@-1844990477
    at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396)
    at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073)
    at com.watchman.etl.ClkDemo.main(ClkDemo.java:44)
Caused by: com.clickhouse.client.ClickHouseException: Read timed out after 30000 ms, server ClickHouseNode [uri=http://localhost:8123/test]@-1844990477
    at com.clickhouse.client.ClickHouseException.of(ClickHouseException.java:168)
    at com.clickhouse.client.AbstractClient.lambda$execute$0(AbstractClient.java:275)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.io.IOException: Read timed out after 30000 ms
    at com.clickhouse.data.stream.NonBlockingInputStream.updateBuffer(NonBlockingInputStream.java:31)
    at com.clickhouse.data.stream.AbstractByteBufferInputStream.available(AbstractByteBufferInputStream.java:74)
    at com.clickhouse.client.http.ClickHouseHttpConnection.postData(ClickHouseHttpConnection.java:338)
    at com.clickhouse.client.http.ClickHouseHttpEntity.writeTo(ClickHouseHttpEntity.java:57)
    at org.apache.hc.client5.http.impl.classic.RequestEntityProxy.writeTo(RequestEntityProxy.java:106)
    at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:253)
    at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:141)
    at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:218)
    at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:717)
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.execute(InternalExecRuntime.java:216)
    at org.apache.hc.client5.http.impl.classic.MainClientExec.execute(MainClientExec.java:116)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:188)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:192)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:113)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:116)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:170)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:123)
    at com.clickhouse.client.http.ApacheHttpConnectionImpl.post(ApacheHttpConnectionImpl.java:241)
    at com.clickhouse.client.http.ClickHouseHttpClient.send(ClickHouseHttpClient.java:118)
    at com.clickhouse.client.AbstractClient.sendAsync(AbstractClient.java:161)
    at com.clickhouse.client.AbstractClient.lambda$execute$0(AbstractClient.java:273)
    ... 4 more

Although, below code is working fine.

            client
                .write(node)
                .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
                .query("insert into user (name,age) values ('Deepa Kumari',25)")
                .executeAndWait()
                .records()
                .forEach(
                    r -> {
                      System.out.println("This is the record-");
                    });
### Tasks
chernser commented 3 months ago

Good day, @ats1999 ! I think, I know where problem is.

You are using ClickHousePipedOutputStream that internally has queue of buffers and current buffer. The last one is not submitted to the queue until full or stream is closed. The exception is a bit confusing but stack trace tell that procedure that sends bytes to server have not got anything from provided input stream for 30seconds.

Please, add stream.close(); (to close output buffer where you are writing data) before f.get(). It will push buffer to the queue and further to server. Please let me know if you have questions.

chernser commented 2 months ago

@ats1999 did it help to add stream.close(); ?