我同时运行超过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
"默认值是无限的">
我的猜测是,您通过创建太多连接来压倒您的操作系统。 每个 Cassandra 集群只应创建 1 个集群实例。 群集创建会话,会话管理自己的连接池。 群集和会话都是线程安全的,因此您可以在线程之间共享它们。
使用驱动程序进行编码的四个简单规则可以很好地提炼出这些概念:
编写使用驱动程序的代码时,应遵循四个简单的规则,这些规则也将使您的代码高效:
每个(
- 物理(集群(每个应用程序生存期(使用一个集群实例
每个密钥空间- 最多使用一个会话实例,或者使用单个会话并在查询中显式指定密钥空间...
集群实例允许配置连接和查询处理方式的不同重要方面。在此级别,你可以配置所有内容,包括联系点 (在驱动程序执行节点发现之前最初要联系的节点的地址(、请求路由策略、重试和重新连接策略等。通常,此类设置在应用程序级别设置一次。
虽然会话实例以查询执行为中心,但会话它还管理每个节点的连接池。会话实例是一个长期存在的对象,不应以请求-响应的短期方式使用它。代码应在整个应用程序中共享相同的集群和会话实例。