点对点架构在 Cassandra 中如何工作?
How does peer to peer architecture work in Cassandra?
点对点 Cassandra 架构的真正工作原理是什么?我的意思是:
当请求到达集群时,它必须根据 IP 到达某台机器,对吗?
那么它会先命中哪台机器呢? : 节点之一,或者集群中负责平衡请求并将请求重定向到正确节点的某个节点?
你能描述一下它是什么吗?这与 Master/Folowers 架构有何不同?
您似乎在问 Cassandra 是如何具体选择哪个节点被数据击中而哪个节点没有被击中的。
这有两个方面:客户端和服务器
在客户端
建立 CQL 连接时,客户端(如果在客户端库中实现并配置)通常还会从集群中检索 Topology。拓扑是有关环内令牌所有权的信息以及有关仲裁等的信息。
因此,由于 Cassandra 中主键的 Consistent Hashing,客户端本身已经可以决定下一次请求联系哪个节点以获得一定数量的信息。客户知道谁是联系 Node 的正确选择。
但客户端仍然可以选择不使用此信息,只将信息发送到环中的任何节点 - 然后节点会将请求转发给适当的令牌所有者 -> 请参阅下一节。
集群中
这同样适用于节点本身。如果客户端向节点发送请求,它将简单地在其拓扑 table 中查找所有者节点,并将请求转发到确实拥有此令牌的节点。
它会始终将其转发给所有这些人,以便数据在整个集群中保持一致。根据复制因子,如果集群确认所需的复制,它将 return 对客户端的成功响应(例如,LOCAL_QUORUM
RF=3 将 return 成功响应,当 2节点确认收到,而第三个节点仍在等待中)。
如果检测到某个节点已关闭或无法访问,则本应发送到该节点的命令将保存在本地 hints
table - 一个缓冲区,用于保存所有未成功发送到其他节点的操作。
您可以在 Hints in the Cassandra Docs
上阅读更多内容
与 Leader/Follower 架构相比,Cassandra 模型实际上更简单并且主要依赖于所有相关节点通过令牌看到发生在它们“拥有”的数据上的所有突变命令。
它基于您用于连接到 Cassandra™ 集群的驱动程序。同样,数据中心中的所有节点都是同一个节点。它将连接到您根据接触点配置在驱动程序配置中提供的 localdatacenter
的任何节点(即 Java 驱动程序中的 datastax-java-driver.basic.contact-points
)。
例如,Java 驱动程序(大多数驱动程序逻辑相同)使用 system.peers.rpc-address
连接到新发现的节点。对于特殊的网络拓扑,可以插入一个地址转换组件。
advanced.address-translator
在配置中。
默认为 - none。也可用:特定于 EC2(用于跨多个区域的部署),或编写您自己的。
Cassandra 集群中的每个节点都由一个 IP 地址唯一标识,驱动程序将使用该地址建立连接。
对于接触点,这些是作为配置 CqlSession
对象的一部分提供的;
对于其他节点,地址将被动态发现,通过检查 system.peers
已经连接的节点,或者通过八卦发现新节点时在控制连接上收到的推送通知。
可以找到更多信息 here。
使用 Cassandra 时,我们必须记住两个非常重要的事情:数据被分区(分成块)和数据被复制 (每个块都存储在几个不同的服务器上)。出于可扩展性目的需要分区,而复制服务于高可用性。鉴于 Cassandra 设计用于在巨大压力下处理 PB 级数据(每秒数千万次查询),并且没有单个服务器能够处理这样的负载,因此每个集群服务器仅负责一定范围的数据,而不负责整个数据集。存储特定查询所需数据的节点称为“副本节点”。请注意,那里的不同查询将具有不同的副本节点。
总的来说,它带来了一些启示:
- 我们必须在单个查询期间到达多个服务器,以确保数据一致(读取)/将数据写入所有负责的服务器(写入)。
- 我们如何知道哪个节点适合该特定查询?如果查询命中“错误”节点会怎样?我们如何配置应用程序以便它向副本节点发送查询?
有趣的是,作为开发人员,您只需做一件事:理解分区和分区键,然后 Cassandra 将处理所有潜在问题。就那么简单。当您设计 table 时,您必须声明分区键,数据放置将基于此 - 自动进行。接下来,您必须在查询时始终指定分区键。就这样,你的工作完成了,去喝杯咖啡吧!
与此同时,Cassandra 开始了她的工作。 Cassandra 节点很聪明,它们知道数据放置,它们知道哪些服务器负责您正在写入的数据,并且它们知道分区 - 在 Cassandra 语言中称为 token-aware。 并不重要哪个服务器将接收查询,因为字面意思是每个服务器都能够回答它。任何收到请求的节点(它被称为查询协调器,因为它协调查询操作)将根据分区的位置找到副本节点。这样,查询协调器将执行查询,对副本进行适当的调用——协调器知道要询问哪些节点,因为你完成了你的部分工作,并在查询中指定了用于路由的分区键值。
简而言之,您可以请求任何集群节点 write/read 您的数据,Cassandra 是去中心化的,您会搞定的。但是我们如何让它变得更好并直接进入副本以避免打扰不存储我们数据的节点?[=13=]
So which machine it will hit first ?
请求的传输比我们想象的要早得多 - 当您的应用程序启动时,Cassandra driver 连接到集群并读取有关数据放置的信息:哪个分区存储在哪个节点上,这意味着 driver 知道对于不同的查询必须联系哪个节点。你没看错,driver 也是 token-aware!
Token-aware drivers 了解数据放置并将查询路由到适当的副本节点。回答问题:在正常情况下,你的查询会首先命中其中一个副本节点,这个节点会得到答案或者将数据写入其他副本节点,就这样,我们很好。在极少数情况下,您的查询可能会命中“错误的”non-replica 服务器,但这并不重要,因为它也能完成工作,只是稍有延迟——例如,如果您的复制因子 = 3 (您有三个副本),并且您的查询到达了一个“错误”的节点,它将不得不询问所有三个副本,同时命中“正确的一个”仍然需要 2 个网络操作。这没什么大不了的,因为所有操作都是并行完成的。
how this differ from the Master/Folowers architecture
使用 leader/follower 架构,您可以从任何服务器读取,但只能写入领导服务器,这会带来两个问题:
- 你的应用需要知道谁是领导者(或者你需要有一个特殊的代理)
- 单点故障 (SPoF) - 如果 leader 宕机,你根本无法写入 DB
使用 Cassandra 的 peer-to-peer 架构,您可以写入 任何 集群节点,即使它们有数千个。当然,没有SPoF。
P.S。 Cassandra 是一项非常强大的技术,但强大的力量伴随着巨大的责任,它也相当复杂。如果您打算使用它,您最好花一些时间来学习如何正确使用它。我确实建议在 academy.datastax.com (it's free!) or at least watch DataStax "Intro to Cassandra" workshop
上选择开发人员路径
出于回答的目的,我将以 the Java driver 为例,因为它最受欢迎。
当您使用其中一个驱动程序连接到集群时,您需要使用集群的详细信息对其进行配置,包括:
- 联系点 - 集群的入口点,它是集群中某些节点的 comma-separated 列表 IPs/hostnames。
- 登录凭据 - 用户名和密码(如果您的集群启用了身份验证)。
- SSL/TLS 证书和凭据 - 如果您的集群启用了加密。
当您的应用程序启动时,a control connection is established with the first available node 在 联系点列表中 。驱动程序将此控制连接用于管理任务,例如:
- 获取有关集群的拓扑信息,包括节点 IP、机架布置、network/DC 信息等
- 获取模式信息,例如键空间和表
- 订阅元数据更改,包括拓扑和架构更新
当您使用 load-balancing policy (LBP) 配置驱动程序时,该策略将确定驱动程序将选择哪个节点作为每个查询的协调器。默认情况下,Java 驱动程序使用负载平衡策略来选择本地数据中心的节点。如果您不指定哪个DC是应用程序的本地DC,驱动程序会将本地DC设置为第一个接触点的DC。
驱动程序每次执行查询时,都会生成一个查询计划或要联系的节点列表。此节点列表具有以下特征:
- 每个查询的查询计划都不同,以平衡集群中各节点的负载。
- 查询计划仅列出可用节点,不包括已关闭或暂时不可用的节点。
- 首先列出本地 DC 中的节点,如果 load-balancing 策略允许,则最后包括远程节点。
驱动程序尝试按照列出的顺序联系查询计划中的每个节点。如果第一个节点可用,则驱动程序将其用作协调器。如果第一个节点没有响应(无论出于何种原因),驱动程序会尝试查询计划中的下一个节点,依此类推。
最后,Cassandra 中的所有节点都是平等的。没有 active-passive,没有 leader-follower,没有 primary-secondary,这使得 Cassandra 成为真正的高可用性 (HA) 集群,没有单个 point-of-failure。任何节点都可以完成任何其他节点的工作,并且负载按设计平均分配给所有节点。
如果您是 Cassandra 的新手,我建议您看看 datastax.com/dev which has lots of free hands-on interactive learning resources. In particular, the Cassandra Fundamentals 学习系列,让您快速了解基本概念。
对于它的价值,您还可以使用 Stargate.io data platform. It allows you to connect to a Cassandra cluster using APIs you're already familiar with. It is fully open-source so it's free to use. Here are links to the Stargate tutorials on datastax.com/dev: REST API, Document API, GraphQL API, and more recently gRPC API。干杯!
点对点 Cassandra 架构的真正工作原理是什么?我的意思是:
当请求到达集群时,它必须根据 IP 到达某台机器,对吗?
那么它会先命中哪台机器呢? : 节点之一,或者集群中负责平衡请求并将请求重定向到正确节点的某个节点?
你能描述一下它是什么吗?这与 Master/Folowers 架构有何不同?
您似乎在问 Cassandra 是如何具体选择哪个节点被数据击中而哪个节点没有被击中的。
这有两个方面:客户端和服务器
在客户端
建立 CQL 连接时,客户端(如果在客户端库中实现并配置)通常还会从集群中检索 Topology。拓扑是有关环内令牌所有权的信息以及有关仲裁等的信息。
因此,由于 Cassandra 中主键的 Consistent Hashing,客户端本身已经可以决定下一次请求联系哪个节点以获得一定数量的信息。客户知道谁是联系 Node 的正确选择。
但客户端仍然可以选择不使用此信息,只将信息发送到环中的任何节点 - 然后节点会将请求转发给适当的令牌所有者 -> 请参阅下一节。
集群中
这同样适用于节点本身。如果客户端向节点发送请求,它将简单地在其拓扑 table 中查找所有者节点,并将请求转发到确实拥有此令牌的节点。
它会始终将其转发给所有这些人,以便数据在整个集群中保持一致。根据复制因子,如果集群确认所需的复制,它将 return 对客户端的成功响应(例如,LOCAL_QUORUM
RF=3 将 return 成功响应,当 2节点确认收到,而第三个节点仍在等待中)。
如果检测到某个节点已关闭或无法访问,则本应发送到该节点的命令将保存在本地 hints
table - 一个缓冲区,用于保存所有未成功发送到其他节点的操作。
您可以在 Hints in the Cassandra Docs
上阅读更多内容与 Leader/Follower 架构相比,Cassandra 模型实际上更简单并且主要依赖于所有相关节点通过令牌看到发生在它们“拥有”的数据上的所有突变命令。
它基于您用于连接到 Cassandra™ 集群的驱动程序。同样,数据中心中的所有节点都是同一个节点。它将连接到您根据接触点配置在驱动程序配置中提供的 localdatacenter
的任何节点(即 Java 驱动程序中的 datastax-java-driver.basic.contact-points
)。
例如,Java 驱动程序(大多数驱动程序逻辑相同)使用 system.peers.rpc-address
连接到新发现的节点。对于特殊的网络拓扑,可以插入一个地址转换组件。
advanced.address-translator
在配置中。
默认为 - none。也可用:特定于 EC2(用于跨多个区域的部署),或编写您自己的。
Cassandra 集群中的每个节点都由一个 IP 地址唯一标识,驱动程序将使用该地址建立连接。
对于接触点,这些是作为配置 CqlSession
对象的一部分提供的;
对于其他节点,地址将被动态发现,通过检查 system.peers
已经连接的节点,或者通过八卦发现新节点时在控制连接上收到的推送通知。
可以找到更多信息 here。
使用 Cassandra 时,我们必须记住两个非常重要的事情:数据被分区(分成块)和数据被复制 (每个块都存储在几个不同的服务器上)。出于可扩展性目的需要分区,而复制服务于高可用性。鉴于 Cassandra 设计用于在巨大压力下处理 PB 级数据(每秒数千万次查询),并且没有单个服务器能够处理这样的负载,因此每个集群服务器仅负责一定范围的数据,而不负责整个数据集。存储特定查询所需数据的节点称为“副本节点”。请注意,那里的不同查询将具有不同的副本节点。
总的来说,它带来了一些启示:
- 我们必须在单个查询期间到达多个服务器,以确保数据一致(读取)/将数据写入所有负责的服务器(写入)。
- 我们如何知道哪个节点适合该特定查询?如果查询命中“错误”节点会怎样?我们如何配置应用程序以便它向副本节点发送查询?
有趣的是,作为开发人员,您只需做一件事:理解分区和分区键,然后 Cassandra 将处理所有潜在问题。就那么简单。当您设计 table 时,您必须声明分区键,数据放置将基于此 - 自动进行。接下来,您必须在查询时始终指定分区键。就这样,你的工作完成了,去喝杯咖啡吧!
与此同时,Cassandra 开始了她的工作。 Cassandra 节点很聪明,它们知道数据放置,它们知道哪些服务器负责您正在写入的数据,并且它们知道分区 - 在 Cassandra 语言中称为 token-aware。 并不重要哪个服务器将接收查询,因为字面意思是每个服务器都能够回答它。任何收到请求的节点(它被称为查询协调器,因为它协调查询操作)将根据分区的位置找到副本节点。这样,查询协调器将执行查询,对副本进行适当的调用——协调器知道要询问哪些节点,因为你完成了你的部分工作,并在查询中指定了用于路由的分区键值。
简而言之,您可以请求任何集群节点 write/read 您的数据,Cassandra 是去中心化的,您会搞定的。但是我们如何让它变得更好并直接进入副本以避免打扰不存储我们数据的节点?[=13=]
So which machine it will hit first ?
请求的传输比我们想象的要早得多 - 当您的应用程序启动时,Cassandra driver 连接到集群并读取有关数据放置的信息:哪个分区存储在哪个节点上,这意味着 driver 知道对于不同的查询必须联系哪个节点。你没看错,driver 也是 token-aware!
Token-aware drivers 了解数据放置并将查询路由到适当的副本节点。回答问题:在正常情况下,你的查询会首先命中其中一个副本节点,这个节点会得到答案或者将数据写入其他副本节点,就这样,我们很好。在极少数情况下,您的查询可能会命中“错误的”non-replica 服务器,但这并不重要,因为它也能完成工作,只是稍有延迟——例如,如果您的复制因子 = 3 (您有三个副本),并且您的查询到达了一个“错误”的节点,它将不得不询问所有三个副本,同时命中“正确的一个”仍然需要 2 个网络操作。这没什么大不了的,因为所有操作都是并行完成的。
how this differ from the Master/Folowers architecture
使用 leader/follower 架构,您可以从任何服务器读取,但只能写入领导服务器,这会带来两个问题:
- 你的应用需要知道谁是领导者(或者你需要有一个特殊的代理)
- 单点故障 (SPoF) - 如果 leader 宕机,你根本无法写入 DB
使用 Cassandra 的 peer-to-peer 架构,您可以写入 任何 集群节点,即使它们有数千个。当然,没有SPoF。
P.S。 Cassandra 是一项非常强大的技术,但强大的力量伴随着巨大的责任,它也相当复杂。如果您打算使用它,您最好花一些时间来学习如何正确使用它。我确实建议在 academy.datastax.com (it's free!) or at least watch DataStax "Intro to Cassandra" workshop
上选择开发人员路径出于回答的目的,我将以 the Java driver 为例,因为它最受欢迎。
当您使用其中一个驱动程序连接到集群时,您需要使用集群的详细信息对其进行配置,包括:
- 联系点 - 集群的入口点,它是集群中某些节点的 comma-separated 列表 IPs/hostnames。
- 登录凭据 - 用户名和密码(如果您的集群启用了身份验证)。
- SSL/TLS 证书和凭据 - 如果您的集群启用了加密。
当您的应用程序启动时,a control connection is established with the first available node 在 联系点列表中 。驱动程序将此控制连接用于管理任务,例如:
- 获取有关集群的拓扑信息,包括节点 IP、机架布置、network/DC 信息等
- 获取模式信息,例如键空间和表
- 订阅元数据更改,包括拓扑和架构更新
当您使用 load-balancing policy (LBP) 配置驱动程序时,该策略将确定驱动程序将选择哪个节点作为每个查询的协调器。默认情况下,Java 驱动程序使用负载平衡策略来选择本地数据中心的节点。如果您不指定哪个DC是应用程序的本地DC,驱动程序会将本地DC设置为第一个接触点的DC。
驱动程序每次执行查询时,都会生成一个查询计划或要联系的节点列表。此节点列表具有以下特征:
- 每个查询的查询计划都不同,以平衡集群中各节点的负载。
- 查询计划仅列出可用节点,不包括已关闭或暂时不可用的节点。
- 首先列出本地 DC 中的节点,如果 load-balancing 策略允许,则最后包括远程节点。
驱动程序尝试按照列出的顺序联系查询计划中的每个节点。如果第一个节点可用,则驱动程序将其用作协调器。如果第一个节点没有响应(无论出于何种原因),驱动程序会尝试查询计划中的下一个节点,依此类推。
最后,Cassandra 中的所有节点都是平等的。没有 active-passive,没有 leader-follower,没有 primary-secondary,这使得 Cassandra 成为真正的高可用性 (HA) 集群,没有单个 point-of-failure。任何节点都可以完成任何其他节点的工作,并且负载按设计平均分配给所有节点。
如果您是 Cassandra 的新手,我建议您看看 datastax.com/dev which has lots of free hands-on interactive learning resources. In particular, the Cassandra Fundamentals 学习系列,让您快速了解基本概念。
对于它的价值,您还可以使用 Stargate.io data platform. It allows you to connect to a Cassandra cluster using APIs you're already familiar with. It is fully open-source so it's free to use. Here are links to the Stargate tutorials on datastax.com/dev: REST API, Document API, GraphQL API, and more recently gRPC API。干杯!