Cassandra驱动程序不是将CQL字符串发送到Cassandra节点并等待响应的傻瓜程序

它们实际上很聪明,并且以某种方式组织的,使您易于使用,工作更开心,同时仍然尝试从Cassandra中获得最大的性能。

在本文中,我将重点介绍Java驱动程序,快速了解其体系结构及其提供的某些功能。

快速使用

3.x版本

Cluster cluster = Cluster.builder().addContactPoints(contactPoints).withPort(port).build();
session = cluster.connect();
ResultSet results = session.execute(query);
for (Row row : results) {
//TODO: access row;
}

4.x版本

session = CqlSession.builder().build();
ResultSet results = session.execute(query);
for (Row row : results) {
//TODO: access row;
}

配置application.conf,放在java进程的classpath下

datastax-java-driver {basic.contact-points = ["127.0.0.1:9042"]basic {load-balancing-policy {local-datacenter = datacenter1}}

可以看到4.x完全移除了Cluster这个类,一个会话会创建n个pool(n=node个数),一个pool就是一个连接池,拥有若干个连接,请求都是异步的,所以一个连接也是可以同时发送多个request,这种我们称之为inFlight

因为目前主流的客户端还是3.x,下面我们重点介绍3.x版本

架构

Cassandra Java驱动程序提供了一个异步API。请注意,它还提供了一个同步API,但由于它是基于异步API的,并且我不想在我的应用程序线程与Cassandra交互时夯住,因此我不准备介绍它。

让我们自底向上研究一下驱动程序各个组件

连接

最底部是与Cassandra节点的连接。Cassandra协议是完全异步的。这意味着我们可以通过同一连接发送多个请求。在发送下一个请求之前,我们不必等待单个请求完成。每个请求都由流ID标识,并且在响应中也设置了该ID,以便driver可以将响应与相应的请求进行关联。
该驱动程序依靠Netty执行异步IO操作。
一旦将请求发送到连接会话,executeAsync将返回Future,然后在接收到相应的响应(或发生超时异常)时使用Promise完成。
正在进行的请求(也称为“in-flight”请求)存储在队列中。队列已满时,您将无法再将查询发送到Cassandra。executeAsync将返回失败的future(jdk8异步作业句柄)。在版本3.1之前,调用线程处于阻塞状态,等待有可用的连接。当然,队列大小可以在poolingOptions中配置。

val poolingOptions = new PoolingOptions()
poolingOptions.setMaxRequestsPerConnection(HostDistance.LOCAL, 32768).setMaxRequestsPerConnection(HostDistance.REMOTE, 2000)val cluster = Cluster.builder().withContactPoints("127.0.0.1").withPoolingOptions(poolingOptions).build()

默认值非常低(本地连接为1024,远程连接为256)。256在生产环境很容易就用满,因此,我建议您根据需要调整这些值。
使用TCP保持活动状态或发送应用程序心跳以保持连接打开,以保持连接打开。

连接池

连接属于连接池。驱动程序为每个Cassandra节点维护一个连接池。连接池也可以通过poolingOptions进行配置。

poolingOptions.setConnectionsPerHost(HostDistance.LOCAL,  4, 10).setConnectionsPerHost(HostDistance.REMOTE, 2, 4)

主要配置是池大小。可用连接的数量可以根据负载在核心和最大数量之间变化。我们还可以为本地或远程数据中心设置不同的设置。当连接闲置时间过长时,连接将关闭,直到池大小达到其核心大小为止。

会话

连接池属于会话。

会话也是应用程序用于与Cassandra通信的对象。
该层为应用程序抽象所有连接管理。

val session = cluster.connect()

Session提供了所有与Cassandra通信的API,例如session.executeAsync,它允许应用程序向Cassandra发送请求,或者session.getState允许我们监控后端主机和进行中的查询。

cluster

群集是顶层抽象。在这里,我们可以配置所有内容,例如指定池选项,负载平衡策略,重试策略或默认一致性级别。
val cluster = Cluster.builder()

.withContactPoints("127.0.0.1")
.withPoolingOptions(poolingOptions)
.withLoadBalancingPolicy(new RoundRobinPolicy())
.withQueryOptions(new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM)
)
.build()

Bootstrapping

当驱动程序首次连接到种子节点之一时,它会建立一个控制连接,用于发现群集拓扑。基本上,它查询Cassandra中的系统表。
引导启动时,从种子节点列表中随机选择种子节点,以避免在初始群集拓扑中始终使用相同的节点。

负载均衡

负载平衡负责建立与整个Cassandra集群(不仅在一个节点上)的连接,并维护与集群中每个主机的连接池。
它具有将某些请求发送到某些节点的逻辑。与哪些主机建立连接以及向哪些主机发送请求由负载平衡策略确定。
实际上,对每个请求都会算出一个查询计划。查询计划确定向哪个主机发送请求以及以哪个顺序发送(取决于推测执行策略和重试策略)。
负载平衡还确定主机是本地主机还是远程主机(跟客户端DCAware配置有关)。
如果默认策略不够用,可以编写自定义负载平衡策略。

驱动程序从请求中提取partitionKey,并使用正确的哈希算法路由到持有该分区的Cassandra节点。

默认策略是DatacenterAwareLoadBalancingPolicy。拥有如下两特性

  • 数据中心感知:确定哪些节点属于本地数据中心,哪些节点属于远程数据中心。然后,驱动程序仅将请求发送到本地数据中心,并将远程数据中心用作备用。
  • 令牌感知:查找请求的分区键,并使用与群集相同的算法对其进行哈希处理。然后,它将请求发送到负责令牌的节点(在该分区的副本中随机选择)。
    使用DDCAwareRoundRobinPolicy时可以指定本地数据中心:
Cluster cluster = Cluster.builder().addContactPoint("127.0.0.1").withLoadBalancingPolicy(DCAwareRoundRobinPolicy.builder().withLocalDc("myLocalDC").withUsedHostsPerRemoteDc(2).allowRemoteDCsForLocalConsistencyLevel().build())).build()

容错能力

错误主要有3种:

  • 无效的请求:错误直接返回应用上层,因为驱动程序无法知道如何处理此类请求
  • 服务器错误:驱动程序可以根据负载平衡策略尝试下一个节点
  • 网络超时:如果请求被标记为幂等,则驱动程序可以重试该请求。默认情况下,请求不被认为是幂等的,因此在可能的情况下将请求尽量标记是一个好习惯。
    对于幂等请求,如果在一定的延迟内没有来自第一节点的响应,则驱动程序可以将请求发送到第二节点。这称为“推测重试”,用SpeculativeExecutionPolicy进行配置。
val cluster = Cluster.builder().addContactPoint("127.0.0.1").withSpeculativeExecutionPolicy(new ConstantSpeculativeExecutionPolicy(500, // delay before a new execution is launched2    // maximum number of executions)).build()

结论

感谢datastax为我们提供了这么强大的客户端,Java驱动程序值得花一些时间来了解其体系结构以及如何正确配置它(每个连接的最大请求尤为重要,因为我发现默认值不是很合适–配置本地数据中心也很重要,否则驱动程序可能会连接到远程数据中心)。

在系统启动时至少有一个服务或驱动程序产生错误_Cassandra Java驱动程序相关推荐

  1. win2003服务器服务正在运行,win2003提示“在系统启动时至少有一个服务或驱动程序产生错误”Windows服务器操作系统 -电脑资料...

    经常遇到新安装的windows 2003服务器/vps启动的时候弹出"在系统启动时至少有一个服务或驱动程序产生错误"的错误对话框, 首先可以看到它提示使用事件查看器查看事件日志.我 ...

  2. java cassandra连接池_Cassandra Java驱动程序的最佳设置只能写入本地数据中心

    我最近开始为我们的Cassandra用例使用Datastax Java驱动程序-我们将使用Datastax Java驱动程序读取/写入Cassandra - 我成功地可以使用Datastax Java ...

  3. 在系统启动时至少一个服务或驱动程序产生错误 hwinfo32

    http://blog.chinaunix.net/uid-26930741-id-3241327.html 原因: 该系统安装过驱动精灵,卸载驱动精灵后注册表有残余服务键值. 解决办法: 1.打开注 ...

  4. 【系统】windows2003 至少有一个服务或驱动程序无法加载或错误

    不知道怎么搞的,电脑上装的 windows 2003 每次安装了程序卸载后,开机时总会提示 "至少有一个服务或驱动程序无法加载或错误",弄的我很郁闷.在网上找了很多解决的办法.感觉 ...

  5. android 提供服务,GitHub - FamliarMan/AndroidServiceProvider: 为模块化提供的一个服务发现库...

    AndroidServiceProvider是为了解决模块化过程中各模块服务统一获取的难题而产生的,具体情况请参照这篇文章 Android模块化中的服务发现机制 注意混淆 这里特别强调,所有注册的类都 ...

  6. 我是如何把微服务的这个模式落地的:一个服务一个数据库模式(中)

    从我接触微服务以来,迄今也得有五六年了.断断续续要么从零开始,要么中途接手,也经历了 5 套微服务项目了. 从这些项目中的经验以及和同行交流来看,根据业务切分微服务的方法总的来说思路不复杂,但是落地总 ...

  7. python写一个服务_写一个Python的windows服务

    1. 安装pywin32和pyinstaller pip install pywin32 pip install pyinstaller 2.写一个服务Demo # -*- coding: utf-8 ...

  8. c++socket多个客户端通过不同端口与一个服务端通信_手写RPC,深入底层理解整个RPC通信...

    一.前言 RPC,远程过程调用,调用远程方法像调用本地方法一样.RPC交互分为客户端和服务端,客户端调用服务端方法,服务端接收数据并打印到控制台,并response响应给客户端. RPC和HTTP的联 ...

  9. 老王有两个孩子,已知至少有一个孩子是在星期二出生的男孩。问:两个孩子都是男孩的概率是多大?

    这个问题其实不难,只是很多时候,尤其在没有任何提示的时候,容易想错.条件概率的题目一定要看清楚条件信息. 问题描述:老王有两个孩子,已知至少有一个孩子是在星期二出生的男孩.问:两个孩子都是男孩的概率是 ...

最新文章

  1. APMServ下Xdebug安装与使用
  2. LeetCode374 猜数字大小 (二分法)
  3. 搭建“双11”大型网站架构必须掌握的 5 个核心知识
  4. 【网络安全】一次应急实战经验思路分享
  5. Unit05: window 常用子对象-2 、 event 对象 、 Cookie
  6. 现实世界中的Windows Azure:ADMIXER特别版、Autocosmos.com、IT WORKS和News360!
  7. struts2学习笔记(2)
  8. C# 计算程序运行耗时的方法
  9. 变分模态分解(VMD)-Python代码
  10. 终端天线—7.UWB天线仿真
  11. ubuntu20.04系统安装谷歌浏览器
  12. 【刷题-每天一算法】赛马
  13. Apache Geronimo监控
  14. [转]Typora中使用Latex符号——基本操作
  15. win10系统 开启蓝牙服务器,win10系统蓝牙在哪开启?
  16. google map api key申请
  17. JavaScript 各种参数 详解
  18. 计算机网络校园网服务器搭建,计算机网络校园网服务器搭建课程设计(绝对等级).doc...
  19. 出租车和家用轿车的信息描述(java 作业)
  20. 使用sklear.metrics计算precision等指标

热门文章

  1. Maven : maven工程libraries没有maven dependencies
  2. Spark之hive的UDF自定义函数
  3. kylin: NoClassDefFoundError: org/apache/hadoop/hive/conf/HiveConf
  4. 【Logstash】windows下logstash报错config files contains non-ascii characters but are not UTF-8 encoded
  5. hadoop环境准备
  6. 云计算实战系列二(Linux-用户管理)
  7. JVM第一讲:为什么需要 JVM?它处在什么位置?
  8. 客户端连接故障检查流程手段
  9. signature=348a7ccbb9abe65fb90d6a0f44514435,Built-in self test for memory interconnect testing
  10. github语音识别对对_语音识别尝试方向