13

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

我有 1.0 版的文档。它说:

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

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

比如有这个参数:

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

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

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

2013:12:06 12:05:50 DEBUG Cluster:742 - 使用接触点启动新集群

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

2013:12:06 12:05:50 调试 ControlConnection:219 - [控制连接] 刷新模式

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

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

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

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

4

3 回答 3

15

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

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

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

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

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

ACluster代表整个Cassandra 环

一个环由多个节点(主机)组成,环可以支持一个或多个密钥空间。您可以查询有关集群(环)级别属性的集群对象。

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

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

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

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

A在SessionStatement内执行

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

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

于 2017-04-07T22:22:22.833 回答
8

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

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

编辑(2017 年 4 月 10 日):我在@William Price one 之后精确地回答了这个问题。请注意,这个答案已有 4 年历史,而 Cassandra 在此期间发生了相当大的变化!

于 2013-12-06T12:26:48.763 回答
4

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

private static Cluster cluster;

cluster.getConfiguration().getPoolingOptions().setMaxConnectionsPerHost(HostDistance.LOCAL,100);
于 2015-02-17T05:30:40.517 回答