Java Zookeeper API странное поведение ZNode. Невозможно правильно удалить ZNode. Имеет неожиданные результаты - PullRequest
0 голосов
/ 23 апреля 2020

Я пытаюсь создать постоянный ZNode и сохранить количество строк определенного файла, который я обработал. Создание работает точно так же, как и при чтении данных с узла, но удаление не работает, если оно находится в том же коде. Я бы объяснил, что я имею в виду.

Я создал функции:

setOrCreateFileCheckpoint (fileName: String, lineNumber: Int) : - проверяет, существует ли ZNode, создает если он этого не делает, и устанавливает для сохраненного значения значение lineNumber getFileCheckpoint (fileName: String) : - возвращает значение, сохраненное в ZNode deleteFileCheckpoint (fileName: String) : - удаляет ZNode

ниже приведен код для всех трех:

/*
updates or creates a checkpoint for a file being processed
 */
def setOrCreateFileCheckpoint(fileName: String, lineNumber: Int): Unit =
    {
        val fileCheckpointPath = checkpointPoolPath + "/" +fileName
        val zk = getZookeeper
        val zkCuratorClient = getZookeeperCuratorClient

        if ( zk.exists(fileCheckpointPath, false) == null)
            {
                val node = new PersistentNode(zkCuratorClient, CreateMode.PERSISTENT, false, fileCheckpointPath, lineNumber.toString.getBytes())
                node.start()
            }
        else
            zk.setData(fileCheckpointPath, lineNumber.toString.getBytes(), -1)
    }

/*
gets checkpoint for a file
 */
def getFileCheckpoint(fileName: String): Int =
    {
        val fileCheckpointPath = checkpointPoolPath + "/" +fileName
        val zk = getZookeeper
        val zkCuratorClient = getZookeeperCuratorClient

        if ( zk.exists(fileCheckpointPath, false) != null)
            new String(zk.getData(fileCheckpointPath, false, null)).toInt

        else
            0

    }

/*
deletes the file checkpoint so that we don't keep accumulating zNodes on the zookeeper
 */
def deleteFileCheckpoint(fileName: String): Unit =
    {
        val fileCheckpointPath = checkpointPoolPath + "/" +fileName

        val zk = getZookeeper

        if ( zk.exists(fileCheckpointPath, false) == null)
        {
            throw RuntimeException("Trying to delete checkpoint that doesn't exist for file: " + fileName)
        }
        else
            {
                /*println(zk.exists(fileCheckpointPath, false).getVersion)
                zk.delete(fileCheckpointPath, zk.exists(fileCheckpointPath, false).getVersion)*/
                deleteChildren(zk, fileCheckpointPath, true)

            }
    }

Ниже приведен код, который я тестирую, и я озадачен:

        ZookeeperUtility.setOrCreateFileCheckpoint("file1", 2000) //let's call it cre1

        println(ZookeeperUtility.getFileCheckpoint("file1")) //let's call it get1

        ZookeeperUtility.deleteFileCheckpoint("file1") //let's call it del1
        println("del1")

        ZookeeperUtility.deleteFileCheckpoint("file1") //let's call in del2
        println("del2")

Выполнить 1:

Шаг 1: I Выполнить код, показанный выше

Результат: Обнаружена ошибка на del2

Шаг 2 : Закомментируйте cre1 и снова запустите код

Результат: узел получен, выдает правильное значение в качестве ошибки результата, обнаруженной на del2. Это ошеломляет. Я не могу понять почему. Предполагается, что узел будет удален.

Шаг 3: с комментарием cre1, как и в предыдущем шаге, повторите код

Результат: Узел не существует дает 0 в get1, что означает, что узел не существует. ошибка встречается в del1. Что и должно было произойти в самом шаге 2

Run2:

Шаг 1: закомментировать del2, запустить код

Результат: создает узел, выбирает правильные данные, нормально завершает работу

Шаг 2: Закомментируйте cre1, выполните код

Результат: извлекает значение 2000 из узла, который был должен быть удален. нормально завершает работу

Шаг 3: снова запустите тот же код, что и шаг 2

Результат: выборка 0, ошибка при del1.

Если I запускать код по одному шагу за раз, если я только создаю за один прогон, только извлекаю при следующем прогоне и только удаляю в прогоне после этого, все работает так, как должно. Я на грани вытаскивания волос.

PS Код написан на Scala, но я использую Java API. Scala может работать без Java классов.

Если вы посмотрите на функцию deleteFileCheckpoint , которую я закомментировал, я тоже попробовал этот подход. У него точно такой же бевайор.

1 Ответ

1 голос
/ 23 апреля 2020

Это ошеломляет. Я не могу понять почему. Узел должен быть удален.

Я не уверен, почему вы удивлены. Вы создаете PersistentNode, который существует для автоматического воссоздания узла, если он будет удален. На самом деле весь окружающий код очень озадачивает. Это дублирует то, что PersistentNode делает внутри. Вам не нужно делать все эти другие вещи. Просто используйте PersistentNode.

Далее, код вроде checkExists (), за которым следует действие, основанное на результате, почти никогда не будет работать в производстве. ZooKeeper очень параллельный и в конечном итоге последовательный. Вот почему вы всегда должны использовать рецепты Куратора вместо решений для ручного кодирования.

...