0

我正在同时运行超过 50 个线程的 ExecutorService。每个线程都打开与 Cassandra 的连接并使用springframework.data.cassandra. 问题是当我一次打开超过 50 个连接时,我收到以下错误。

Caused by: org.jboss.netty.channel.ChannelException: Failed to create a selector.
    at org.jboss.netty.channel.socket.nio.AbstractNioSelector.openSelector(AbstractNioSelector.java:343)
    at org.jboss.netty.channel.socket.nio.AbstractNioSelector.<init>(AbstractNioSelector.java:100)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.<init>(AbstractNioWorker.java:52)
    at org.jboss.netty.channel.socket.nio.NioWorker.<init>(NioWorker.java:45)
    at org.jboss.netty.channel.socket.nio.NioWorkerPool.createWorker(NioWorkerPool.java:45)
    at org.jboss.netty.channel.socket.nio.NioWorkerPool.createWorker(NioWorkerPool.java:28)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.newWorker(AbstractNioWorkerPool.java:143)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.init(AbstractNioWorkerPool.java:81)
    at org.jboss.netty.channel.socket.nio.NioWorkerPool.<init>(NioWorkerPool.java:39)
    at org.jboss.netty.channel.socket.nio.NioWorkerPool.<init>(NioWorkerPool.java:33)
    at org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory.<init>(NioClientSocketChannelFactory.java:151)
    at org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory.<init>(NioClientSocketChannelFactory.java:116)
    at com.datastax.driver.core.Connection$Factory.<init>(Connection.java:532)
    at com.datastax.driver.core.Cluster$Manager.<init>(Cluster.java:1201)
    at com.datastax.driver.core.Cluster$Manager.<init>(Cluster.java:1144)
    at com.datastax.driver.core.Cluster.<init>(Cluster.java:121)
    at com.datastax.driver.core.Cluster.<init>(Cluster.java:108)
    at com.datastax.driver.core.Cluster.buildFrom(Cluster.java:177)
    at com.datastax.driver.core.Cluster$Builder.build(Cluster.java:1109)

如果我正好打开 50 个线程(或更少),它工作正常。有没有办法配置它,所以我可以允许更多?在我的 cassandra.yaml 文件中,rpc_max_threads根据默认注释“默认为无限制”

4

1 回答 1

1

我的猜测是您通过创建太多连接来压倒您的操作系统。您应该只为每个 Cassandra 集群创建 1 个集群实例。集群创建会话,会话管理自己的连接池。Cluster 和 Session 都是线程安全的,所以你可以在线程之间共享它们。

使用驱动程序进行编码的四个简单规则很好地提炼了这些概念:

在编写使用驱动程序的代码时,您应该遵循四个简单的规则,这也会使您的代码高效:

  1. 每个(物理)集群(每个应用程序生命周期)使用一个集群实例
  2. 每个键空间最多使用一个会话实例,或者使用单个会话并在查询中明确指定键空间...

集群实例允许配置处理连接和查询方式的不同重要方面。在此级别,您可以配置所有内容,包括联系点(在驱动程序执行节点发现之前最初要联系的节点的地址)、请求路由策略、重试和重新连接策略等。通常,此类设置在应用程序级别设置一次。

虽然会话实例以查询执行为中心,但它还管理每个节点的连接池。会话实例是一个长期存在的对象,它不应该以请求-响应、短期的方式使用。代码应该在您的应用程序中共享相同的集群和会话实例。

于 2016-01-29T20:06:26.740 回答