Cassandra Datastax驱动程序 - 连接池

时间:2013-12-06 10:35:30

标签: java cassandra datastax-java-driver

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

我有1.0版本的文档。它说:

  

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

他们通过连接了解什么?连接到群集时,我们有:构建器,群集和会话。其中哪一个是连接?

例如,有以下参数:

  

maxSimultaneousRequestsPerConnection - 所有连接上的同时请求数   到主机之后创建了更多连接。

因此,在连接池的情况下,这些连接会自动创建(这是我所期望的)。但究竟是什么联系?集群对象?会话?

我正在尝试决定在我的网络服务中保留“静态”的内容。目前,我决定保持Builder静态,因此对于每次调用,我都会创建一个新的Cluster和一个新的Session。这个可以吗?如果群集是连接,那么它应该没问题。但是吗?现在,记录器说,每次通话:

  

2013:12:06 12:05:50 DEBUG Cluster:742 - 启动带有接触点的新集群

     

2013:12:06 12:05:50 DEBUG ControlConnection:216 - [控制连接]刷新节点列表和令牌映射

     

2013:12:06 12:05:50 DEBUG ControlConnection:219 - [控制连接]刷新架构

     

2013:12:06 12:05:50 DEBUG ControlConnection:147 - [控制连接]已成功连接到...

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

那么,连接实际上是会话?如果是这种情况,我应该保持群集静态,而不是构建器。

我应该调用哪种方法,以确保尽可能重用连接?

3 个答案:

答案 0 :(得分:11)

accepted answer (在撰写本文时) 正在提供正确的建议:

  

只要您使用相同的Session对象,您[将]重用连接。

但是,有些部分原本过于简单。我希望以下内容能够深入了解每种对象类型的范围及其各自的用途。

构建器≠集群≠会话≠连接≠语句

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

Cluster代表整个 Cassandra戒指

环由多个节点(主机)组成,环可以支持一个或多个键空间。您可以查询有关cluster-(ring)-level属性的 Cluster 对象。

我还将它视为代表调用应用程序到环的对象。您将应用程序的需求(例如加密,压缩等)传达给构建器,但此对象 首先实现/与实际C *环通信。如果您的应用程序为不同的用户/目的使用多个身份验证凭据,即使它们连接到同一个环,您也可能有不同的群集对象。

Session 本身不是连接,但它管理它们

会话可能需要与环中的所有节点通信,除了在仅包含一(1)个节点的环的特殊情况之外,这不能通过单个TCP连接完成。 会话管理connection pool,该池通常至少有一个连接,用于环中的每个节点这就是为什么你应该尽可能多地重用 Session 对象。应用程序不直接管理或访问连接。

Cluster 对象访问会话;它通常一次“绑定”到单个键空间,这将成为从该会话执行的语句的默认键空间。语句可以使用完全限定的表名(例如keyspacename.tablename)来访问其他键空间中的表,因此不需要使用多个会话来跨键空间访问数据。使用多个会话相同的环进行通信会增加所需的TCP连接总数。

A Statement会话

内执行

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

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

答案 1 :(得分:7)

你是对的,连接实际上是在Session中,Session是你应该给DAO写入Cassandra的对象。

只要您使用相同的Session对象,就应该重用连接(您可以将Session视为连接池)。

编辑(2017/4/10):我在@William Price之后准备了这个答案。 请注意,这个答案是4岁,而Cassandra在此期间已经改变了一点!

答案 2 :(得分:3)

只是社区的更新。您可以按以下方式设置连接池

private static Cluster cluster;

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