Cassandra Datastax驱动程序 - 连接池

14

我正在尝试理解Datastax Cassandra Driver中的连接池,以便更好地在我的Web服务中使用它。

我有文档版本1.0。文档中写道:

Java驱动程序异步使用连接,因此可以在同一连接上同时提交多个请求。

他们对连接的理解是什么?连接到集群时,我们有:Builder、Cluster和Session。它们中的哪一个是连接?

例如,有这个参数:

maxSimultaneousRequestsPerConnection——所有连接到主机的并发请求数量,超过该数量后会创建更多连接。

所以,在连接池的情况下,这些连接是自动创建的(这是我期望的)。但是这些连接到底是什么?Cluster对象?Sessions?

我正在尝试决定在我的Web服务中什么应该保持“静态”。目前,我决定将Builder保持静态,因此每次调用时我都会创建一个新的Cluster和一个新的Session。这样做可以吗?如果Cluster就是连接,那应该可以。但是呢?现在,日志器在每次调用时都显示:

2013:12:06 12:05:50 DEBUG Cluster:742 - Starting new cluster with contact points

2013:12:06 12:05:50 DEBUG ControlConnection:216 - [Control connection] Refreshing node list and token map

2013:12:06 12:05:50 DEBUG ControlConnection:219 - [Control connection] Refreshing schema

2013:12:06 12:05:50 DEBUG ControlConnection:147 - [Control connection] Successfully connected to...

那么,它每次都连接到Cluster吗?这不是我想要的,我想重用连接。

所以,连接实际上就是Session吗?如果是这样的话,我应该将Cluster保持静态,而不是Builder。

我应该调用哪个方法,以确保在可能的情况下重用连接?

3个回答

15

在撰写本文时,接受的答案给出了正确的建议:

只要使用相同的会话对象,您就可以重复使用连接。

然而,有些部分最初过于简化。我希望以下内容能够阐明每个对象类型的范围和它们各自的目的。

Builder ≠ Cluster ≠ Session ≠ Connection ≠ Statement

Cluster.Builder 用于配置和创建集群

Cluster 表示整个Cassandra环

一个环包含多个节点(主机),并且该环可以支持一个或多个keyspace。您可以向集群对象查询与集群(环)级别属性相关的信息。

我认为它是代表调用应用程序的对象。通过与构建器进行通信,您向其传达了应用程序的需求(例如加密、压缩等),但是正是这个对象首先实现/与实际的C*环通信。如果您的应用程序针对不同用户/用途使用多个身份验证凭据,则即使它们连接到同一个环,您可能也有不同的Cluster对象。

Session本身不是连接,而是管理连接的对象

一个会话可能需要与环中的所有节点进行通信,除非包含恰好一个(1)节点的特殊情况下,否则无法通过单个TCP连接完成。 会话 管理 连接池 ,该池通常会为环中的每个节点至少提供一个连接。 这就是为什么您应尽可能重复使用 会话 对象的原因。应用程序不直接管理或访问连接。

一个SessionCluster对象中访问;通常它会"绑定"到一个单独的keyspace,成为从该会话执行的statements的默认keyspace。语句可以使用完全限定的表名(例如keyspacename.tablename)来访问其他keyspaces中的表,因此不需要使用多个会话来跨keyspaces访问数据。使用多个sessions与同一ring交谈会增加所需的TCP连接总数。

Statement

Session内执行
语句可以是准备的或未准备的,每个语句都会改变数据或查询数据(在某些情况下,两者兼而有之)。最快、最有效的语句需要与至多一个节点通信,来自拓扑感知的集群Session应该仅联系该节点(或其对等节点)上的单个TCP连接。最不高效的语句必须涉及所有副本(大多数节点),但这将由环上的协调器节点处理,因此即使对于这些语句,Session也只会从应用程序中使用单个连接。

此外,驱动程序使用的Cassandra 二进制协议的2和3版本在连接上使用多路复用。因此,虽然单个语句至少需要一个TCP连接,但该单个连接可以同时为128个或32k+异步请求提供服务,具体取决于协议版本。


2
谢谢,我更新了我的答案(目前被接受的答案),至少反映了一点你的写作 :-) - C4stor

8
你说得对,连接实际上在会话(Session)中,而会话(Session)是你应该提供给DAO以写入Cassandra的对象。
只要使用相同的会话(Session)对象,你应该重用连接(你可以将会话(Session)视为连接池)。
编辑(2017/4/10):我根据@William Price的回答进行了澄清。 请注意,这个回答已经有4年了,在此期间Cassandra发生了很多变化!

谢谢您的回答。那么,连接池逻辑是在会话层面还是在查询执行层面保留的?我本来以为它会在集群对象中,在会话创建层面保留。 - Anakin001
池化策略是通过构建器传递的,并由Session对象用于选择要查询的节点。 - C4stor
我只是希望当多个客户端同时使用相同的会话时,它们实际上会使用不同的物理连接。 - Anakin001
像@Anakin001所说的那样,@C4stor希望当多个客户端同时使用相同的会话时,它们实际上会使用不同的物理连接。这是真的吗? - Prakash P
1
@PrakashPandey - 实际上不是这样的。在C*本地协议v2和v3中,物理TCP连接是多路复用的。在这些协议中,一个“单个TCP连接”可以分别支持最多128个和32k+个同时进行的异步请求。 - William Price

4

给社区的最新消息。您可以按照以下方式设置连接池:

private static Cluster cluster;

cluster.getConfiguration().getPoolingOptions().setMaxConnectionsPerHost(HostDistance.LOCAL,100);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接