理解cassandra架构

本文深入探讨了Cassandra的架构,包括无损性能和高度可扩展性的设计,以及节点间的gossip通信协议。介绍了节点状态的同步、故障检测和恢复机制,以及数据分布和分区策略。此外,还涵盖了Cassandra的动态snitch、多种分区器和snitch策略。文章强调了Cassandra在处理数据分布、容错和性能优化方面的重要细节。
摘要由CSDN通过智能技术生成

本文是我在看cassandra官方文档时写的一篇翻译,由于能力有限,很多地方都翻译的不到位或者和原意有出入,希望大家可以给予指正,由于翻译的较早,而且没有全部完成,有些观点可能已经在最新的cassandra中被更新或者改变,我也会在之后的时间将这些内容补全和修复

Cassandra是一种无性能损耗的高拓展性和可用性的分布式数据库。线性的可伸缩性以及被商品级硬件设施和云基础架构验证的容错技术使它成为任务关键型数据存储的良好平台。Cassandra支持跨多个数据中心的副本备份是非常棒的,为使用者提供低延迟和即使某个区域停电也能正常运转的放心。

 

节点间通信(gossip)

Gossip是一种点对点的通信协议,按照这个协议节点间定期的交换自己和其他他们知道的节点的状态信息。Gossip进程每秒运行一次来与集群上的最多其他3个节点交换状态信息。 这些节点交换自己的信息和其他的与这些节点通信的节点信息。所以所有的节点可以快速的了解到集群上的其他节点。

为了防止gossip通信出现问题,为集群中所有的节点使用了相同列表的种子节点。这种情况在第一个节点启动时非常重要。默认情况下,一个节点在随后的重启中会记住与它通信的其他节点。种子节点的选定除了为新节点加入集群时引导gossiped过程外再无其他目的。种子节点不会有单点故障,除了引导节点外再无其他特定的目的。

在多个数据中心集群,从每个数据中心的种子列表中选取一个节点是一个好主意。建议每个数据中心指定多余一个种子节点来提高容错能力。否则,当引导一个节点时gossip不得不与另一个数据中心通信。

不建议为每个节点都创建种子节点,因为这增了加维护量同时降低了性能。Gossip的优化不是关键,但是建议使用一个有少量种子节点的列表(大约每个数据中心三个节点)

 

失败检测和恢复

如果另一个节点挂掉了或者正在恢复中,失败检测方法用于本地确定gossip的状态和历史。Cassandra使用这个信息避免客户端请求被路由到不可到达的节点。(Cassandra也可以避免请求被路由到活着的但是效率低下的节点,请参考dynamic snitch

 

Gossip进程使用直接方式(节点的gossiping直接导向他)和间接方式(节点的信息被传达2手,三手,等等)跟踪节点的状态。Cassandra不是使用固定的阈值来标记失败的节点,而是使用一个责权检测机制来计算考虑了账户网路性能,工作量和历史条件的每个节点的阈值。在gossip交换期间,每个节点维护一个与集群中的其他节点的关于gossip信息的上次到达时间的滑动窗口。通过配置phi_convict_threshold 属性来调整错误检测器的灵敏程度。较低的值增加了无反应节点被标记为down的可能性,而较高的值减少了瞬时错误引起的节点故障的可能性。大多数情况使用默认值即可,但是为亚马逊EC2将其增加到10-12(由于经常遇到的网络拥堵)。在不稳定的网络环境(例如有时候EC2就是这样),提高值为10或12有利于防止虚假故障,不建议使用值高于12和低于5。

节点失败可能由各种原因引起,如硬件失败和网络中断。节点中断往往瞬变,但可以持续很长时间。因为节点中断很少意味着它将从集群中永久的离开,这不会自动导致永久从环中移除节点。其他节点将定期与失败节点尝试建立连接查看他们是否备份。要在集群上永久改变节点的资格,管理员必须从cassandra环上使用 nodetool utility.工具精准的添加或者移除节点。当一个节点在宕机后重新联机时,或许它已经遗失了它所维护的对于副本数据的写操作。存在一个修复机制以恢复遗失的数据,例如hinted handoffs和使用nodetool手动修复。宕机时间的长短将决定哪种修复机制被用于保持数据一致性。

 

一致性hash允许数据分布跨越一个集群,以减少增加或减少节点时进行的重组操作。一致性hash基于partition key为数据分区,关于partition key和主见的介绍,请参考

 Data modeling example

 

例如,你有如下数据

 

Cassandra是一种无性能损耗的高拓展性和可用性的分布式数据库。线性的可伸缩性以及被商品级硬件设施和云基础架构验证的容错技术使它成为任务关键型数据存储的良好平台。Cassandra支持跨多个数据中心的副本备份是非常棒的,为使用者提供低延迟和即使某个区域停电也能正常运转的放心。

 

节点间通信(gossip)

Gossip是一种点对点的通信协议,按照这个协议节点间定期的交换自己和其他他们知道的节点的状态信息。Gossip进程每秒运行一次来与集群上的最多其他3个节点交换状态信息。 这些节点交换自己的信息和其他的与这些节点通信的节点信息。所以所有的节点可以快速的了解到集群上的其他节点。

为了防止gossip通信出现问题,为集群中所有的节点使用了相同列表的种子节点。这种情况在第一个节点启动时非常重要。默认情况下,一个节点在随后的重启中会记住与它通信的其他节点。种子节点的选定除了为新节点加入集群时引导gossiped过程外再无其他目的。种子节点不会有单点故障,除了引导节点外再无其他特定的目的。

在多个数据中心集群,从每个数据中心的种子列表中选取一个节点是一个好主意。建议每个数据中心指定多余一个种子节点来提高容错能力。否则,当引导一个节点时gossip不得不与另一个数据中心通信。

不建议为每个节点都创建种子节点,因为这增了加维护量同时降低了性能。Gossip的优化不是关键,但是建议使用一个有少量种子节点的列表(大约每个数据中心三个节点)

 

失败检测和恢复

如果另一个节点挂掉了或者正在恢复中,失败检测方法用于本地确定gossip的状态和历史。Cassandra使用这个信息避免客户端请求被路由到不可到达的节点。(Cassandra也可以避免请求被路由到活着的但是效率低下的节点,请参考dynamic snitch

 

Gossip进程使用直接方式(节点的gossiping直接导向他)和间接方式(节点的信息被传达2手,三手,等等)跟踪节点的状态。Cassandra不是使用固定的阈值来标记失败的节点,而是使用一个责权检测机制来计算考虑了账户网路性能,工作量和历史条件的每个节点的阈值。在gossip交换期间,每个节点维护一个与集群中的其他节点的关于gossip信息的上次到达时间的滑动窗口。通过配置phi_convict_threshold 属性来调整错误检测器的灵敏程度。较低的值增加了无反应节点被标记为down的可能性,而较高的值减少了瞬时错误引起的节点故障的可能性。大多数情况使用默认值即可,但是为亚马逊EC2将其增加到10-12(由于经常遇到的网络拥堵)。在不稳定的网络环境(例如有时候EC2就是这样),提高值为10或12有利于防止虚假故障,不建议使用值高于12和低于5。

节点失败可能由各种原因引起,如硬件失败和网络中断。节点中断往往瞬变,但可以持续很长时间。因为节点中断很少意味着它将从集群中永久的离开,这不会自动导致永久从环中移除节点。其他节点将定期与失败节点尝试建立连接查看他们是否备份。要在集群上永久改变节点的资格,管理员必须从cassandra环上使用 nodetool utility.工具精准的添加或者移除节点。当一个节点在宕机后重新联机时,或许它已经遗失了它所维护的对于副本数据的写操作。存在一个修复机制以恢复遗失的数据,例如hinted handoffs和使用nodetool手动修复。宕机时间的长短将决定哪种修复机制被用于保持数据一致性。

 

一致性hash允许数据分布跨越一个集群,以减少增加或减少节点时进行的重组操作。一致性hash基于partition key为数据分区,关于partition key和主见的介绍,请参考

 Data modeling example

 

例如,你有如下数据

 

name

age

car

gender

jim

36

camaro

M

carol

37

bmw

F

johnny

12

 

M

suzy

10

 

F

Cassandra assigns a hash value to each partition key:

Partition key

Murmur3 hash value

jim

-2245462676723223822

carol

7723358927203680754

johnny

-6723372854036780875

suzy

1168604627387940318

 

集群中的每个节点对基于hash值得一段数据负责。在集群中四个节点的hash值

 

cassandra基于partition key的值和每个节点所负责的值得范围来为每个节点分配数据。例如,在一个4个节点的集群 中,数据如下分布

Node

Start range

End range

Partition key

Hash value

A

-9223372036854775808

-4611686018427387904

johnny

-6723372854036780875

B

-4611686018427387903

-1

jim

-2245462676723223822

C

0

4611686018427387903

suzy

1168604627387940318

D

4611686018427387904

9223372036854775807

carol

7723358927203680754

 

 

Virtual nodes

 

虚拟节点,称为Vnodes,以更新的力度跨节点分布数据,如果使用计算token的话这很容易实现。Vnodes简化了cassadra中的许多任务。

 

 

更多信息,请参考cassandora1.2 中关于虚拟节点的主题。

Virtual nodes in Cassandra 1.2

 

将一个存在的节点转换为虚拟节点,参考

Enabling virtual nodes on an existing production cluster.

 

How data is distributed across a cluster (using virtual nodes)

 

虚拟节点使用一致性hash来分配数据,不需要生成和分配新的token

 

Partitioners

 

一个partitioner决定数据分布式的存储在集群中的节点上(包括副本)。基本上,分区程序使用hash函数从partition key中派生出一个token,该token代表了一行数据。每行的数据之后按token的值跨集群分布。

Murmur3Partitioner 和RandomPartitioner 使用token来为每个节点分配相同比例的数据,表格中的数据均等的分布在整个环上,或是其他组上如秘钥空间。即使表使用不同的分区键如username或者timestamps也是按这种情况来做。而且在此基础上,对于集群的读写操作也被均匀的分布,负载均衡被简化因为hash range的每个部分获取到row的数量是均等的。更多细节参考

Consistent hashing.

 

这两个分区算法的区别是如何生成token的hash值,RandomPartitioner 使用一个加密hash,他生成hash的时间要比Murmur3Partitioner 长,Cassoandra不需要加密hash,所以使用Murmur3Partitioner 在3-5分钟内产生完hash值可以改进效率。

 

Cassandra支持如下的分区程序,可以在cassandra.yaml文件中设置他们。

Murmur3Partitioner (默认)基于MurmurHash  hash值跨集群均匀分布节点。

RandomPartitioner 基于MD5  hash值跨集群均匀分布节点。

ByteOrderedPartition 按照数据的秘钥字节字典顺序有序分布。

Murmur3Partitioner 作为默认的分区策略应用于cassandra1.2以后,在部分情况下作为生成新集群的首选。

然而,分区程序间并不兼容, 使用一种分区程序后很难再转换为另一种分区程序。

如果使用虚拟节点(vnodes),你不必计算tokens。如果不使用vnodes,你必须计算tokens的数量然后为cassandra.yaml文件中的initial_token参数赋值。请参见

Generating tokens  同时使用某种分区程序的对应方法。

 

Murmur3Partitioner是默认分区程序,Murmur3Partitioner比RandomPartitioner更快更有效率,Murmur3Partitioner 可以使用vnodes,然而,如果你不使用vnodes,你必须计算token的数量,正如

Generating tokens中描述的那样。

为新的集群使用Murmur3Partitioner。你无法将已经存在的集群的分区程序改变为另一种分区程序。Murmur3Partitioner使用

MurmurHash 函数。该 哈希函数创建一个64-bithash值作为分区键,可能的hash值得范围从

 -263 to +263-1

当使用Murmur3Partitioner时,

你可以通过使用token功能在一个CQL语句中查询所有行。

 

RandomPartitioner 是cassandra1.2之前的默认分区程序,它包含向后的兼容性。RandomPartitioner 可以和vnodes一起使用。然而,如果你不使用vnodes,你必须计算tokens,如Generating tokens中描述的那样。RandomPartitioner 使用MD5 hash值作为行的键值来跨多个节点均匀的分布数据。可能的hash值范围从0-2127-1

 

casssandra为顺序分区提供ByteOrderedPartition方式。他提供向后兼容性。分区程序使用秘钥字节的词法顺序来排序行。通过查看你的分区秘钥数据的实际值并且使用秘钥中前导字符的十六进制表示形式来计算tokens的值。例如,如果你想按照行的字母顺序分区,你可以使用16进制表示形式41带指定A token.

使用顺序分区允许基于主键 的顺序查找。这意味着你可以进行扫描就好像你通过传统的索引移动光标一样。例如,如果你的应用使用用户名作为分区主键,你可以检索用户名落在jakejoe之间的行,这种检索形式使用RandomPartitioner 关键字是不可能实现的,因为键是以MD5 hash值来存储的(非顺序的)。

虽然有能力在行上做范围查询听起来是顺序分区的一个可取特点,但是通过使用表索引可以实现相同的功能。

以下情况

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值