Scala - Cassandra: сбой чтения кластера с ошибкой «Не удается использовать этот экземпляр кластера, поскольку он был ранее закрыт»

1

Я получаю эту ошибку при чтении из таблицы в кластере из 5 узлов с использованием драйверов datastax.

2015-02-19 03: 24: 09,908 ОШИБКА [akka.actor.default-dispatcher-9] OneForOneStrategy akka://user/HealthServiceChecker-49e686b9-e189-48e3-9aeb-a574c875a8ab Невозможно использовать этот экземпляр кластера, поскольку он был ранее закрытое java.lang.IllegalStateException: не может использовать этот экземпляр кластера, поскольку он был ранее закрыт на com.datastax.driver.core.Cluster $ Manager.init(Cluster.java:1128) ~ [cassandra-driver-core-2.0.4.jar: na] at com.datastax.driver.core.Cluster.init(Cluster.java:149) ~ [cassandra-driver-core-2.0.4.jar: na] at com.datastax.driver.core.Cluster.connect(Cluster.java:225) ~ [cassandra-driver-core-2.0.4.jar: na] в com.datastax.driver.core.Cluster.connect(Cluster.java:258) ~ [cassandra- водитель-жильный-2.0.4.jar: на]

Я могу подключиться с помощью cqlsh и выполнить операции чтения.

Есть ли какая-нибудь подсказка, что может быть проблемой здесь?

настройки:

  • Уровень согласованности: ОДИН
  • Стратегия репликации ключевого пространства: 'класс': 'NetworkTopologyStrategy', 'DC2': '1', 'DC1': '1'

  • версия cassandra: 2.0.6

Коды, управляющие сеансами cassandra, являются центральными, и это так;

trait ConfigCassandraCluster
  extends CassandraCluster
{
  def cassandraConf: CassandraConfig
  lazy val port = cassandraConf.port
  lazy val host = cassandraConf.host
  lazy val cluster: Cluster =
    Cluster.builder()
      .addContactPoints(host)
      .withReconnectionPolicy(new ExponentialReconnectionPolicy(100, 30000))
      .withPort(port)
      .withSocketOptions(new SocketOptions().setKeepAlive(true))
      .build()

  lazy val keyspace = cassandraConf.keyspace
  private lazy val casSession = cluster.connect(keyspace)
  val session = new SessionProvider(casSession)
}

class SessionProvider(casSession: => Session) extends Logging {
  var lastSuccessful: Long = 0
  var firstSuccessful: Long = -1
  def apply[T](fn: Session => T): T = {
    val result = retry(fn, 15)
    if(firstSuccessful < 0)
      firstSuccessful = System.currentTimeMillis()
    lastSuccessful = System.currentTimeMillis()
    result
  }

  private def retry[T](fn: Session => T, remainingAttempts: Int): T = {
    //retry logic
}
  • 0
    В вашем коде есть некоторые проблемы ... мы не можем волшебным образом узнать причину, не увидев код. Вы где-то закрываете соединение кластера ... и пытаетесь выполнить запрос из закрытого соединения.
  • 1
    Спасибо за ответ. Я забыл упоминание, что код работает в другом месте, кроме этой конфигурации Cassandra. Я могу подтвердить, что код не имеет закрывающей логики, а сеансы управляются централизованно, включая повторные попытки в случае сбоев. (код выше)
Теги:
cassandra
datastax

2 ответа

4

Проблема в том, что cluster.connect(keyspace) закроет сам кластер, если он испытывает NoHostAvailableException. Из-за этого во время логики повтора вы сталкиваетесь с IllegalStateException.

Посмотрите на метод Cluster init() и вы поймете больше.

Решение для вашей проблемы было бы в логике повторения сделать Cluster.builder.addContactPoint(node).build.connect(keyspace). Это позволит включить новый объект кластера во время повторной попытки.

1

Найдите свой код для session.close().

Вы закрываете свое соединение где-то, как указано в комментариях. Как только сеанс закрыт, его нельзя использовать снова. Вместо того, чтобы закрывать соединения, объедините их, чтобы разрешить повторное использование.

  • 1
    Похоже, что только в интересах этого потока проблема связана с проблемой сети в этой конкретной среде. Как упоминалось ранее, мы проверили это в нескольких средах и, кажется, работали довольно хорошо, за исключением этого. Пока мы не нашли точную причину, между ними есть межсетевой экран, и есть небольшие различия в конфигах кассандры. Я опубликую дальше, если мы приберем это к точной причине.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню