2016-06-17 4 views
2

У нас есть кластер 3 узлов с РФ 3.Cassandra 3 узлов кластера метания NoHostAvailableException как только один узел вниз

Как только мы стечь один узел из кластера мы видим много:

All host(s) tried for query failed (no host was tried) 
com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (no host was tried) 
     at com.datastax.driver.core.exceptions.NoHostAvailableException.copy(NoHostAvailableException.java:84) 
     at com.datastax.driver.core.DriverThrowables.propagateCause(DriverThrowables.java:37) 
     at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:214) 
     at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:52) 

Все наши записи и чтения имеют уровень согласованности QUORUM или ONE, поэтому с одним узлом все должно работать отлично. Но пока узел опущен, исключаются исключения.

Мы используем Cassandra 2.2.4 + Java Cassandra Driver 2.1.10.2

Вот как мы создаем наш кластер:

new Cluster.Builder() 
    .addContactPoints(CONTACT_POINTS) 
    .withCredentials(USERNAME, PASSWORD) 
    .withRetryPolicy(new LoggingRetryPolicy(DefaultRetryPolicy.INSTANCE)) 
    .withReconnectionPolicy(new ExponentialReconnectionPolicy(10, 10000)) 
    .withLoadBalancingPolicy(new TokenAwarePolicy(new RoundRobinPolicy())) 
    .withSocketOptions(new SocketOptions().setReadTimeoutMillis(12_000)) 
    .build(); 

CONTACT_POINTS является массив строк из 3 публичных изобр из узлов.

Несколько месяцев назад, кластер работает нормально с временно только 2 узлов, но по неизвестной причине это больше не так, и я бегу из идей :(

Спасибо большое за помощь!

+0

Пробовали ли вы остановить различных узлов или вы всегда остановить тот же один? – aalku

+0

Я перезагрузил все 3 узла 30 минут appart, и для всех 3 ту же волну Исключений. – Etienne

ответ

0

проблема решена.

Более подробный анализ показал, что вопрос исходил от проблемы IP. Наши сервера Cassandra используют частный локальный IP-адрес (10.0.), чтобы общаться друг с другом в то время как наши сервера приложений имеют свой публичный IP-адрес в их конфигурации.

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

Решение было добавить IPTranslater в кластере строитель:

.withAddressTranslater(new ToPublicIpAddressTranslater()) 

следующим кодом:

private static class ToPublicIpAddressTranslater implements AddressTranslater { 

    private Map<String, String> internalToPublicIpMap = new HashMap<>(); 

    public ToPublicIpAddressTranslater() { 
     for (int i = 0; i < CONTACT_POINT_PRIVATE_IPS.length; i++) { 
      internalToPublicIpMap.put(CONTACT_POINT_PRIVATE_IPS[i], CONTACT_POINTS[i]); 
     } 
    } 

    @Override 
    public InetSocketAddress translate(InetSocketAddress address) { 
     String publicIp = internalToPublicIpMap.get(address.getHostString()); 
     if (publicIp != null) { 
      return new InetSocketAddress(publicIp, address.getPort()); 
     } 
     return address; 
    } 
}