Ошибка Cassandra 3.6.0: ошибка StackOverflowError, выданная HashedWheelTimer для Connection.release - PullRequest
0 голосов
/ 03 сентября 2018

При запуске некоторых вставок и обновлений в базе данных Cassandra с помощью драйвера java версии 3.6.0 я получаю следующую ошибку StackOverflowError, в которой я показываю только верхнюю часть, но последние 10 строк бесконечно повторяются. В моем коде нет ни одной строки, поэтому я не знаю, какая именно операция вызвала это.

    2018-09-03 00:19:58,294 WARN  {cluster1-timeouter-0} [c.d.s.n.u.HashedWheelTimer]  : An exception was thrown by TimerTask.
java.lang.StackOverflowError: null
        at java.util.regex.Pattern$Branch.match(Pattern.java:4604)
        at java.util.regex.Pattern$BranchConn.match(Pattern.java:4568)
        at java.util.regex.Pattern$GroupTail.match(Pattern.java:4717)
        at java.util.regex.Pattern$Curly.match0(Pattern.java:4279)
        at java.util.regex.Pattern$Curly.match(Pattern.java:4234)
        at java.util.regex.Pattern$GroupHead.match(Pattern.java:4658)
        at java.util.regex.Pattern$Branch.match(Pattern.java:4604)
        at java.util.regex.Pattern$Branch.match(Pattern.java:4602)
        at java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:3798)
        at java.util.regex.Pattern$Start.match(Pattern.java:3461)
        at java.util.regex.Matcher.search(Matcher.java:1248)
        at java.util.regex.Matcher.find(Matcher.java:664)
        at java.util.Formatter.parse(Formatter.java:2549)
        at java.util.Formatter.format(Formatter.java:2501)
        at java.util.Formatter.format(Formatter.java:2455)
        at java.lang.String.format(String.java:2940)
        at com.datastax.driver.core.exceptions.BusyConnectionException.<init>(BusyConnectionException.java:29)
        at com.datastax.driver.core.Connection$ResponseHandler.<init>(Connection.java:1538)
        at com.datastax.driver.core.Connection.write(Connection.java:711)
        at com.datastax.driver.core.RequestHandler$SpeculativeExecution.write(RequestHandler.java:451)
        at com.datastax.driver.core.RequestHandler$SpeculativeExecution.access$1600(RequestHandler.java:307)
        at com.datastax.driver.core.RequestHandler$SpeculativeExecution$1.onSuccess(RequestHandler.java:397)
        at com.datastax.driver.core.RequestHandler$SpeculativeExecution$1.onSuccess(RequestHandler.java:384)
        at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1355)
        at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:398)
        at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1024)
        at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:866)
        at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:689)
        at com.google.common.util.concurrent.SettableFuture.set(SettableFuture.java:48)
        at com.datastax.driver.core.HostConnectionPool$PendingBorrow.set(HostConnectionPool.java:755)
        at com.datastax.driver.core.HostConnectionPool.dequeue(HostConnectionPool.java:407)
        at com.datastax.driver.core.HostConnectionPool.returnConnection(HostConnectionPool.java:366)
        at com.datastax.driver.core.Connection.release(Connection.java:810)
        at com.datastax.driver.core.RequestHandler$SpeculativeExecution$1.onSuccess(RequestHandler.java:407)
        at com.datastax.driver.core.RequestHandler$SpeculativeExecution$1.onSuccess(RequestHandler.java:384)
        at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1355)
        at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:398)
        at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1024)
        at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:866)
        at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:689)
        at com.google.common.util.concurrent.SettableFuture.set(SettableFuture.java:48)
        at com.datastax.driver.core.HostConnectionPool$PendingBorrow.set(HostConnectionPool.java:755)
        at com.datastax.driver.core.HostConnectionPool.dequeue(HostConnectionPool.java:407)
        at com.datastax.driver.core.HostConnectionPool.returnConnection(HostConnectionPool.java:366)
        at com.datastax.driver.core.Connection.release(Connection.java:810)

Я не использую UDT.

Вот кодовое пространство и код создания таблицы:

session.execute(session.prepare(
          "CREATE KEYSPACE IF NOT EXISTS myspace WITH REPLICATION = {'class': 'NetworkTopologyStrategy', 'dc1': '3'}  AND DURABLE_WRITES = true;").bind());

session.execute(session.prepare("CREATE TABLE IF NOT EXISTS myspace.tasks (myId TEXT PRIMARY KEY, pointer BIGINT)").bind());

session.execute(session.prepare("CREATE TABLE IF NOT EXISTS myspace.counters (key TEXT PRIMARY KEY, cnt COUNTER)").bind());

Это подготовленное заявление, которое я использую:

PreparedStatement quickSearchTasksInsert = session.prepare("INSERT INTO myspace.tasks (myId, pointer) VALUES (:oid,:loc)"); 

Код, который воспроизводит проблему, делает следующее:

  1. Запускает метод writeTask () примерно в 10000 раз с разными значениями, такими как следующие примеры строк, которые выбираются из базы данных SQL:

    05043FA57ECEAABC3E096B281A55356B, 1678192046 5DE661E77D19C157C31EB7309494EA89, 3959390363 85D6211384E6E190299093E501169625, 3146521416 0327817F8BD59039069C13D581E8EBBE, 2907072247 D913FA0F306D6516D8DF87EB0CB1EE9B, 2507147331 DC946B409CD1E59F560A0ED75559CB16, 2810148057 2A24B1DC71D395938BA77C6CA822A5F7, 1182061065 F70705303980DA40D125CC3497174A5D, 1735385855

  2. запускает метод setLocNum () с некоторым длинным числом.

  3. Вернитесь к пункту (1) выше.

    public void writeTask(String myId, long pointer) {
        try {
          session.executeAsync(quickSearchTasksInsert.bind().setString("oid",myId).setLong("loc", pointer));
          incrementCounter("tasks_count", 1);
        } catch (OperationTimedOutException | NoHostAvailableException e) {
          // some error handling ommitted from post
        }
     }
    
    public synchronized void setLocNum(long num) {
        setCounter("loc_num", num);
    }  
    
    public void incrementCounter(String key, long incVal) {
        try {
          session.executeAsync(
              "UPDATE myspace.counters SET cnt = cnt + " + incVal + " WHERE key = '" + key.toLowerCase() + "'");
        } catch (OperationTimedOutException | NoHostAvailableException e) {
          // some error handling ommitted from post
        }
    }
    
    public void decrementCounter(String key, long decVal) {
        try {
          session.executeAsync(
              "UPDATE myspace.counters SET cnt = cnt - " + decVal + " WHERE key = '" + key.toLowerCase() + "'");
        } catch (OperationTimedOutException | NoHostAvailableException e) {
          // some error handling ommitted from post
        }
    }
    
    public synchronized void setCounter(String key, long newVal) {
        try {
          Long prevCounterValue = countersCache.get(key);
          long oldCounter = prevCounterValue == null ? readCounter(key) : prevCounterValue.longValue();
          decrementCounter(key, oldCounter);
          incrementCounter(key, newVal);
          countersCache.put(key, newVal);
        } catch (OperationTimedOutException | NoHostAvailableException e) {
          // some error handling ommitted from post
        }
    }
    
...