개발
[cassandra] Detected a synchronous call on an I/O thread
eun2ce
2022. 8. 9. 23:12
보통 casandra 는 scalable 하지만 multi query pattern 을 수용하기에 적합하지 않기때문에 inverted index 로 es(elastic search) 를 많이 채택하여 사용하고 있습니다.
어쩌다보니 카산드라로부터 대량의 목록 조회를 하게 되었는데 그 과정에서 아래와 같은 이슈가 발생했습니다.
Detected a synchronous call on an I/O thread, this can cause deadlocks or unpredictable behavior. This generally happens when a Future callback calls a synchronous Session method (execute() or prepare()), or iterates a result set past the fetch size (causing an internal synchronous fetch of the next page of results). Avoid this in your callbacks, or schedule them on a different executor.
com.datastax.driver.core.AbstractSession.checkNotInEventLoop(AbstractSession.java:206)
com.datastax.driver.core.ArrayBackedResultSet$MultiPage.prepareNextRow(ArrayBackedResultSet.java:310)
com.datastax.driver.core.ArrayBackedResultSet$MultiPage.isExhausted(ArrayBackedResultSet.java:269)
com.datastax.driver.core.ArrayBackedResultSet$1.hasNext(ArrayBackedResultSet.java:143)
com.datastax.driver.mapping.Result$1.hasNext(Result.java:102...
원인은
다수의 row 를 가져오는 쿼리를 날릴 경우, datastax driver 가 paging 하게 되는데 이 때, 한 번에 가져올 수 있는 크기보다 실제 쿼리 양이 더 많을 경우 위와 같은 문제가 발생하는 것이었습니다.
참고
- cassandra resultset 의 paging 관련하여 정리가 잘 된 문서
해결방법
cassandra 의 fetch size 를 조정하여 한 번에 가져올 수 있는 크기를 설정할 수 있습니다.
statement 를 bind 하는 과정에서 아래와 같이 작성해주면 됩니다.
Statement statement = new SimpleStatement("your query");
statement.setFetchSize(2000);
참고
- datastax fetch size
DataStax Java Driver - Paging
docs.datastax.com