使用Datastax Cassandra驱动程序进行异步操作时出现NoHostAvailable异常

时间:2015-01-08 13:45:40

标签: cassandra cassandra-2.0 datastax-java-driver

我使用Cassandra执行嵌套的异步查询。数据被连续流入并且对于每个传入数据,执行下面的cassandra操作块。它工作正常一段时间,但后来开始抛出很多NoHostAvailableException 请我帮帮我。 Cassandra会话连接代码:

我使用单独的会话进行读写。每个会话连接到不同的种子,因为我被告知这会提高性能。

final com.datastax.driver.core.Session readSession = CassandraManager.connect("10.22.1.144", "fr_repo",
                    "READ");
            final com.datastax.driver.core.Session writeSession = CassandraManager.connect("10.1.12.236", "fr_repo",
                    "WRITE");

CassandraManager.connect方法如下:

public static  Session connect(String ip, String keySpace,String type) {
           PoolingOptions poolingOpts = new PoolingOptions();
           poolingOpts.setCoreConnectionsPerHost(HostDistance.REMOTE, 2);
           poolingOpts.setMaxConnectionsPerHost(HostDistance.REMOTE, 400);
           poolingOpts.setMaxSimultaneousRequestsPerConnectionThreshold(HostDistance.REMOTE, 128);
           poolingOpts.setMinSimultaneousRequestsPerConnectionThreshold(HostDistance.REMOTE, 2);
           cluster = Cluster
             .builder()
             .withPoolingOptions( poolingOpts )
             .addContactPoint(ip)
             .withRetryPolicy( DowngradingConsistencyRetryPolicy.INSTANCE )
             .withReconnectionPolicy( new ConstantReconnectionPolicy( 100L ) ).build();
           Session s =  cluster.connect(keySpace);
           return s;
    }

数据库操作代码:

ResultSetFuture resultSetFuture = readSession.executeAsync(selectBound.bind(fr.getHashcode()));
                    Futures.addCallback(resultSetFuture, new FutureCallback<ResultSet>() {
                        public void onSuccess(com.datastax.driver.core.ResultSet resultSet) {
                            try {
                                Iterator<Row> rows = resultSet.iterator();
                                if (!rows.hasNext()) {
                                    ResultSetFuture resultSetFuture = readSession.executeAsync(selectPrimaryBound
                                            .bind(fr.getPrimaryKeyHashcode()));
                                    Futures.addCallback(resultSetFuture, new FutureCallback<ResultSet>() {
                                        public void onFailure(Throwable arg0) {

                                        }

                                        public void onSuccess(ResultSet arg0) {
                                            Iterator<Row> rows = arg0.iterator();
                                            if (!rows.hasNext()) {
                                                writeSession.executeAsync(insertBound.bind(fr.getHashcode(), fr,
                                                        System.currentTimeMillis()));
                                                    writeSession.executeAsync(insertPrimaryBound.bind(
                                                            fr.getHashcode(),
                                                            fr.getCombinedPrimaryKeys(), System.currentTimeMillis()));
                                                produceintoQueue(new Gson().toJson(frCompleteMap));

                                            } else {
                                                writeSession.executeAsync(updateBound.bind(fr,
                                                        System.currentTimeMillis(), fr.getHashcode()));
                                                produceintoQueue(new Gson().toJson(frCompleteMap));
                                            }
                                        }

                                    });

                                } else {
                                    writeSession.executeAsync(updateLastSeenBound.bind(System.currentTimeMillis(),
                                        fr.getHashcode()));

                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }

1 个答案:

答案 0 :(得分:4)

听起来您发送的请求多于池/群集可以处理的请求。当您从未真正等待结果时,这很容易做到,就像代码中的情况一样。您实际上只是将尽可能多的请求投入到管道中而没有阻塞,并且如果池或群集得到备份,则没有自然的背压来减慢应用程序的速度。因此,如果您的请求量过高,最终所有主机都将忙于备份的工作队列。您可以使用nodetool tpstats查看请求队列在每个节点上的外观。