Проблема с Hector API и базой данных Cassandra: недокументированное исключение
Всякий раз, когда я использую любую функцию Hector API для доступа к своей базе данных Cassandra, я получаю исключение:
me.prettyprint.hector.api.exceptions.HectorException: все пулы хостов размечены. Повторите бремя вытеснено клиенту.
На моем сервере база данных Cassandra работает в фоновом режиме.
Я прочитал об исключении, и оно фактически недокументировано. Похоже, что исключение связано с проблемами подключения.
Как мне это исправить?
3 ответа
Вы получите эту ошибку, если клиент Гектора не сможет подключиться к Cassandra. Для этого может быть несколько причин и попыток:
- Убедитесь, что свойства соединения в вашем коде (ip/host/port) настроены правильно.
- Убедитесь, что вы можете подключиться к нему с помощью cassandra-cli удаленно - это может быть проблема с сетью.
- Попробуйте опубликовать здесь свой код подключения - возможно, там есть проблема.
Я получал ту же ошибку с cassandra-unit 2.0.2.1, но снижение версии до 2.0.2.0 решило проблему. Это странно, но я использовал 2.0.2.0 сейчас с некоторыми дополнительными зависимостями sbt
"com.datastax.cassandra" % "cassandra-driver-core" % "2.0.1",
"org.cassandraunit" % "cassandra-unit" % "2.0.2.0" withSources() withJavadoc()
Я получаю эту ошибку случайно из-за проблем с сетевым подключением, но повторная попытка несколько раз обычно исправляет ее. Вот код, который я использую, чтобы повторить функции Hector API:
/** An interface where inside the execute() method I call Hector */
public interface Retriable<T> {
T execute();
}
/**
* Executes operation and retries N times in case of an exception
* @param retriable
* @param maxRetries
* @param <T>
* @return
*/
public static <T> T executeWithRetry(Retriable<T> retriable, int maxRetries) {
T result;
int retries = 0;
long sleepSec = 1;
// retry in case of an exception:
while (true) {
try {
result = retriable.execute();
break;
} catch (Exception e) {
if (retries == maxRetries) {
LOG.error("Exception occurred. Reached max retries.", e);
throw e;
}
retries++;
LOG.error(String.format("Exception occurred. Retrying in %d seconds - #%d", sleepSec, retries), e);
try {
Thread.sleep(sleepSec * 1000);
// increase sleepSec exponentially:
sleepSec *= 2;
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
return result;
}
И пример того, как его использовать:
ColumnFamilyResult<String, String> columns = executeWithRetry(new Retriable<ColumnFamilyResult<String, String>>() {
@Override
public ColumnFamilyResult<String, String> execute() {
return template.queryColumns(row.getKey());
}
});