Использование клиента Datastax Cassandra для одновременного создания таблицы

1

После очистки моего ключа через:

drop keyspace simplex

Я выполняю следующие команды через клиент datastax java Cassandra (из кода scala):

  val songsTable = (
    "CREATE TABLE IF NOT EXISTS simplex.songs ("
    + "id uuid PRIMARY KEY,"
    + "title text,"
    + "album text,"
    + "artist text,"
    + "tags set<text>,"
    + "data blob"
    + ");")

  val listsTable = (
    "CREATE TABLE IF NOT EXISTS simplex.playlists ("
    + "id bigint,"
    + "title text,"
    + "album text, "
    + "artist text,"
    + "song_id uuid,"
    + "PRIMARY KEY (id, title, album, artist)"
    + ");")

  val songs = (
    "INSERT INTO simplex.songs "
    + "(id, title, album, artist, tags) "
    + "VALUES ("
    + "756716f7-2e54-4715-9f00-91dcbea6cf50,"
    + "'La Petite Tonkinoise',"
    + "'Bye Bye Blackbird',"
    + "'Joséphine Baker',"
    + "{'jazz', '2013'}"
    + ");")
  ...
  ...
  ...
  val rsf = session.executeAsync(command) // in parallel
  rsf.addListener(() => p.success(rsf.get), exec)

Это приводит к созданию только созданной таблицы списка воспроизведения, и обратный вызов для команд "create songs table" и "insert song" никогда не будет выполнен.

Я понял, что клиент datastax java Cassandra безопасен для использования одновременно. Разве это не так? В чем проблема с моими предположениями?

  • 1
    Что такое command ? (это объединение этих заявлений?)
  • 0
    Нет, каждый выполняется параллельно (т. s.executeAsync(cmd1); s.executeAsync(cmd2); s.executeAsync(cmd3) ).
Показать ещё 2 комментария
Теги:
cassandra

1 ответ

0

Когда вы создаете таблицы или области ключей - общие для интеграционных тестов - вам нужно закрыть экземпляры Session и Cluster потому что метаданные Cluster устарели. Хотя я вижу сообщение в журнале, в котором говорится, что драйвер пытается обновить метаданные, которые, как представляется, никогда не возвращаются своевременно, - что делает закрытие и повторное открытие экземпляров Cluster и Session достаточно для тестов интеграции.

Поскольку Cluster.connect(keyspaceName) существует, и я не могу получить Cluster.connect(keyspaceName) к USE keyspace; правильно работать в качестве выполненной команды (неважно, что это значит для совместного использования сеанса в приложении, где любой клиент может просто использовать другое пространство ключей произвольно). В итоге я написал следующее:

(Здесь _cluster - это параметр Option[Cluster] который инициализируется во время preStart для моего CassandraSessionActor и preStart keyspace - это параметр Option[String] который определяют разработчики. CassandraSessionActor возвращает Session запросу, но запускает getSession один раз во время preStart чтобы он мог делиться сеансом через приложение, согласно Простым Правилам Datastax 4).

trait AutoCreateKeyspace extends CassandraSessionActor {
  override def getSession = {
    keyspace match {
      case None => _cluster.get.connect()
      case Some(ks) =>
        _cluster.map { cluster =>
          if (cluster.getMetadata.getKeyspace(ks) == null &&
            cluster.getMetadata.getKeyspace(ks.toLowerCase) == null) {
            val temporarySession = cluster.connect()
            log.debug(s"creating keyspace $ks")
            temporarySession.execute(s"""CREATE KEYSPACE $ks
                                       |with replication = {
                                       |'class':                'SimpleStrategy',
                                       |'replication_factor':    2 }""".stripMargin)
            temporarySession.close()
            cluster.close()
          }
        }
        _cluster = Some(Cassandra.createNewCluster())
        _cluster.get.connect(ks)
    }

  }
}

private object Cassandra extends LazyLogging {

  def conf = ConfigFactory.load()

  val hosts = conf.getStringList("cassandra.hosts")

  logger.info(s"cassandra.hosts specified: $hosts")


  def createNewCluster(): Cluster = {
    Cluster.builder()
      .addContactPoints(hosts: _*)
      .build()
  }

}

Ещё вопросы

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