首页 文章

几百次插入后,DataStax Cassandra java驱动程序与NoHostAvailableException崩溃

提问于
浏览
1

我想编写一个将5个字符串(与文件资产相关)写入Cassandra的应用程序 . 我将代码基于DataStax文档中的教程 . 几百次插入可以工作约30秒,但崩溃时会出现错误:

Caused by: 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:65)
    at com.datastax.driver.core.DefaultResultSetFuture.extractCauseFromExecutionException(DefaultResultSetFuture.java:256)
    at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:172)
    at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:52)
...
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:744)
Caused by: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (no host was tried)
    at com.datastax.driver.core.RequestHandler.sendRequest(RequestHandler.java:103)
    at com.datastax.driver.core.SessionManager.execute(SessionManager.java:368)
    at com.datastax.driver.core.SessionManager.executeQuery(SessionManager.java:404)
    at com.datastax.driver.core.SessionManager.executeAsync(SessionManager.java:85)
    ... 8 more

该过程仍在运行,我可以使用相同的结果重新运行单元测试:几百次插入然后出现此错误 . 服务器没有显示遇险或错误的迹象 .

我正在使用驱动程序:

<dependency>
        <groupId>com.datastax.cassandra</groupId>
        <artifactId>cassandra-driver-core</artifactId>
        <version>2.0.3</version>
    </dependency>

这是我的客户端代码:

private static final String BOUND_STATEMENT = "INSERT INTO myschema.files(file_name, md5, last_modified, size, hash_date) "
        + "VALUES (?, ?, ?, ?, ?);";
@Override
public void persist(FileEntry entry) {
    Session session = cluster.connect();
    //prepare statement, if it doesn't exist.
    if (persistPs == null) {
        persistPs = session.prepare(BOUND_STATEMENT);
    }
    BoundStatement boundStatement = new BoundStatement(persistPs);
    session.execute(boundStatement.bind(entry.getFileName(), entry.getMd5(), entry.getLastModified(),
            entry.getSize(), entry.getHashDate()));
    session.close();
    System.out.print(".");
}

我在我的本地主机上运行Cassandra 2.0.9(OSX带有固态硬盘和最近的macbook) .

任何关于如何使这不崩溃的线索?如果这只是DataStax驱动程序的一个问题,我很乐意使用任何其他驱动程序 .

我没有产生太严重的负载,并且服务器进程没有抛出任何可能出错的异常或提示 . 我听说其他组织在Cassandra上取得了成功,所以我认为这与我的客户端代码有关 .

谢谢!

1 回答

  • 3

    BryceAtNetwork23是对的 . 通过将会话对象从调用传递给调用来解决问题 .

    public final void persist(final FileEntry entry, final Session session) {
        prepareInsertStatement(session);
        final BoundStatement boundStatement = new BoundStatement(persistPs);
        //bind values from our bean to our insert query
        session.execute(boundStatement.bind(entry.getFileName(), entry.getMd5(), entry.getLastModified(),
                entry.getSize(), entry.getHashDate()));
    }
    
    private final synchronized void prepareInsertStatement(final Session session) {
        // prepare statement, if it doesn't exist.
        if (persistPs == null) {
            persistPs = session.prepare(BOUND_STATEMENT);
        }
    }
    

    我不知道这是否是Cassandra引擎或DataStax驱动程序的可扩展性的问题,但通常情况下,我必须比平台工作更难以使用它的膝盖 . 无论如何,我对他们的文档感到沮丧 . 我从未在平台上遇到这么多麻烦,让它在没有崩溃的情况下运行 . 他们的示例在1000次插入之后崩溃单个节点 . 如果我们正在评估Cassandra,我们可能希望插入超过1000行 .

    也就是说,一旦我从调用到调用通过会话,代码运行得非常快,并且运行良好 . 我有一些矛盾,但我很高兴一切都有效 . 谢谢大家的帮助 .

相关问题