【发布时间】:2016-12-15 01:40:44
【问题描述】:
这个问题与当大量数据写入 Cassandra 集群并导致运行将数据写入 Cassandra 的应用程序的主机上的端口耗尽有关。
问题详情如下:
在我们的应用程序中,我们不断地将数据写入由 3 个节点组成的 Cassandra 集群。应用程序是用 C# 编写的,并且是多线程的。让我们假设,打开了 100 个线程,每个线程开始使用 datastax C# 驱动程序向 Cassandra 发出写操作。根据这个文档 (4 simple rules when using datastax driver for cassandra),Session 对象是线程安全的,并且在每个线程中被重用。运行应用程序后,在几个小时内,我们观察到出现“端口耗尽”问题,并且运行应用程序的主机停止创建或接受任何其他连接。在投资了这个问题之后,我们认为每个线程向 Cassandra 驱动程序发出的写入创建了到 Cassandra 集群的单独物理连接(最多 20k 连接)。
当单个写入操作完成时,连接将关闭。但是“连接创建”和“连接关闭”的速率并不相似。连接的打开速度非常快,关闭速度相对较慢。并且当它达到大约 20k 打开连接时,主机将不会创建任何进一步的连接。
我们的问题是,与新的写入指令相比,当写入指令执行时间更长时,Cassandra 驱动程序/系统的预期行为是否会导致许多连接保持打开更长时间。
如果这是 Cassandra 驱动程序/系统的预期行为,那么可以采取哪些其他替代方案? (例如,在多台机器上运行应用程序,任务分布在节点之间,以避免端口耗尽。)
如果这不是这种情况下的预期行为,那么我们将非常感谢您指导我们寻找可能的解决方案。
运行 C# 应用程序的服务器的详细信息:-
操作系统:Windows Server 2012 R2
内存:8 GB
Datastax 企业版:4.8.3
Cassandra 版本:2.1
Cassandra C# 驱动程序版本:3.0.5
创建集群和会话的代码
string NodeIps = "127.0.0.1,127.0.0.2,127.0.0.3";
List<string> addresses = new List<string>();
addresses = NodeIps.Split(',').ToList();
cluster = Cluster.Builder()
.AddContactPoints(addresses) //node ip
.WithRetryPolicy(DowngradingConsistencyRetryPolicy.Instance)
.WithReconnectionPolicy(new FixedReconnectionPolicy(0, 5000, 2 * 60000, 60 * 60000))
.WithQueryTimeout(600000) //Timeout specified in milliseconds. //10 min = 600000
.Build();
ISession session = cluster.Connect(KeySpace);
【问题讨论】:
-
你能贴出你创建集群和会话实例的代码吗?此外,您应该启用驱动程序跟踪以查看幕后情况:datastax.github.io/csharp-driver/faq/…
-
@jorgebg 我已经用代码更新了问题。
-
您说“当单个写入操作完成时,连接将关闭。”:您不应该在写入后关闭/关闭会话。会话维护到每个节点的连接池,您应该在应用关闭时关闭集群实例。
-
@jorgebg 通过连接,我的意思是操作系统到 cassandra 集群的出站连接,我们通过在命令提示符中编写
netstat -ano | find /c ":9042"命令而不是会话对象 (ISession) 来检查这些连接。 Session 对象只有在我们的应用关闭时才会关闭,否则它还活着。
标签: c# multithreading cassandra datastax datastax-enterprise