聊聊Cassandra(三)Cassandra3.9 架构分析

1.    Cassandra架构

从安装过程和机器拓展部署可以看出,Cassandra的规模化管理非常赢得人心。

1.1     概述

        Cassandra的系统架构与Dynamo类似,是基于一致性哈希的完全P2P架构,每行数据通过哈希来决定应该存在哪个或哪些节点中。

基本流程:

        点对点分布式系统,集群中各节点平等,数据分布于集群中各节点,各节点间每秒交换一次信息。每个节点的commit log提交日志捕获写操作来确保数据持久性。数据先被写入MemTable(内存中的数据结构),待MemTable满后数据被写入SSTable(硬盘的数据文件)。所有的写内容被自动在集群中partition分区并replicate复制。

库表结构: Cassandra数据库面向行。用户可连接至集群的任意节点,通过类似SQL的CQL查询数据。
集群中,一个应用一般包含一个keyspace,一个keyspace中包含多个表。

读写请求: 客户端连接到某一节点发起读或写请求时,该节点充当客户端应用与拥有相应数据的节点间的
coordinator协调者以根据集群配置确定环(ring)中的哪个节点应当获取这个请求。

CQL是客户端,Driver也是一种客户端. 使用CQL连接指定的-h节点就是协调节点。

图解: 协调节点(10)负责和客户端的交互.真正的数据在节点1,3,6上,分别表示数据的三个副本,最终只要节点1上的数据返回即可。

1.2     Dynamo

1.2.1      Gossip

点对点通信协议,用以cassandra集群中节点间交换位置和状态信息。

Gossip进程每秒运行一次与至多3个其他节点交换信息,这样所有节点可很快了解集群中的其他节点信息。

        Gossip协议的具体表现形式就是配置文件中的seeds种子节点. 一个注意点是同一个集群的所有节点的种子节点应该一致,否则如果种子节点不一致, 有时候会出现集群分裂, 即会出现两个集群. 一般先启动种子节点,尽早发现集群中的其他节点,每个节点都和其他节点交换信息, 由于随机和概率,一定会穷举出集群的所有节点.同时每个节点都会保存集群中的所有其他节点,这样随便连到哪一个节点,都能知道集群中的所有其他节点. 比如cql随便连接集群的一个节点,都能获取集群所有节点的状态,也就是说任何一个节点关于集群中的节点信息的状态都应该是一致的!

1.2.2      Failure Detection(故障检测)

        gossip可检测其他节点是否正常以避免将请求路由至不可达或者性能差的节点(后者需配置为dynamic snitch方可)。

●        可通过配置phi_convict_threshold来调整失败检测的敏感度。

●        对于失败的节点,其他节点会通过gossip定期与之联系以查看是否恢复而非简单将之移除。若需强制添加或移除集群中节点需使用nodetool工具。

●       一旦某节点被标记为失败,其错过的写操作会有其他replicas存储一段时间. (需开启hinted handoff,若节点失败的时间超过了max_hint_window_in_ms,错过的写不再被存储). Down掉的节点经过一段时间恢复后需执行repair操作,一般在所有节点运行nodetool repair以确保数据一致。

●        dynamic snitch特性: 查询请求路由到某个节点,如果这个节点宕掉或者响应慢,则应该能够查询其他节点上的副本。如配置dynamic_snitch_badness_threshold: 0.1则代表除非这个响应慢的节点比最快的主机要快10%才会继续使用它。
删除节点:

        节点失败后,仍然在集群中,通过removenode可以将节点从集群中下线.区别就是status如果不在就说明下线了. DN则仍然在集群中。
故障节点数据:

数据无法正常存储到失败的节点,所以会由其他节点暂时保存,等它恢复之后,再将错过的写补充上去。

1.2.3      Token Ring/Ranges(令牌/范围)

一致性哈希DHT:

        Cassandra 使用分布式哈希表(DHT)来确定存储某一个数据对象的节点。在 DHT 里面,负责存储的节点以及数据对象都被分配一个 token。token只能在一定的范围内取值,取值范围是 [0, 2^32]。存储节点以及对象根据 token 的大小排列成一个环,即最大的 token 后面紧跟着最小的 token,  2^32 的下一个 token 就是 0。

Cassandra 使用以下算法来分布数据: 
1. 首先,每个存储节点被分配一个随机的 token(涉及数据分区策略),该 token 代表它在 DHT 环上的位置; 
2. 然后,用户为数据对象指定一个 key(即 row-key),Cassandra 根据这个 key 计算一个哈希值作为 token,再根据 token 确定对象在 DHT 环上的位置; 
3. 最后,该数据对象由环上拥有比该对象的 token 大的最小的 token 的节点来负责存储; 
4. 根据用户在配置时指定的备份策略(涉及网络拓扑策略),将该数据对象备份到另外的 N-1 个节点上。网络中总共存在该对象的 N 个副本。

        因此,每个存储节点最起码需要负责存储在环上位于它与它的前一个存储节点之间的那些数据对象,而且这些对象都会被备份到相同的节点上。我们把 DHT 环上任何两点之间的区域称为一个 range,那么每个存储节点需要存储它与前一个存储节点之间的 range。

        因为Cassandra 以range为单位进行备份,所以每个节点需要定期检查与它保存了相同的 range 的节点,看是否有不一致的情况,这涉及到数据一致性策略。

另外,Cassandra的一个特点是写速度大于读速度,这都归功于它的存储策略。

 

1.2.4      Replication(复制)

当前有两种可用的复制策略:

●        SimpleStrategy:用于但数据中心,允许使用replication_factor定义整数值,这决定了每一行应该包含的副本数,如果replication_factor是3,那么每行应该保存在三个不同的节点上,SimpleStrategy所有节点都相同,忽略任何配置中心,对于每一个token,它会检测节点是否添加到了一组副本,如果没有就会被添加,直到达到replication_factor所设定的值,还是通过顺时针的方式添加到后续的节点中。

●        NetworkTopologyStrategy:如果是集群多数据中心可用NetworkTopologyStrategy。可用于较复杂的多数据中心。可以指定在每个数据中心分别存储多少份replicas。

复制策略在创建keyspace时指定,如

CREATE KEYSPACE gap WITH REPLICATION = { 'class' : 'SimpleStrategy','replication_factor' : 3 };  

CREATE KEYSPACE gap WITH REPLICATION = {'class' :'NetworkTopologyStrategy', 'dc1' : 3, 'dc2' : 2};

        其中dc1、dc2这些数据中心名称要与snitch中配置的名称一致.上面的拓扑策略表示在dc1配置3个副本,在dc2配置2个副本。

1.2.5      Tunable Consistency(可调的一致性)

        Cassandra需要在每个操作上权衡一致性与可用性,从本质上来说,为了考虑操作的成功率,操作的一致性级别要指定多少副本而需要响应给协调器。下面的级别的设置:

●        ONE:只有一个副本必须响应

●        TWO:两个副本必须响应

●        THREE:三个副本必须响应

●        QUORUM:一个参数(n/2+1)的副本必须响应(Cassandra的每个keyspace可配置一行数据会写入多少个节点,设这个数为N)

●        ALL:所有的副本必须响应

●        LOCAL_QUORUM:在本地数据中心大部分的副本必须响应(不管是在数据中心的协调者)

●        EACH_QUORUM:每个数据中心大部分的副本必须响应

●        LOCAL_ONE  :只有一个副本必须响应。在多数据中心的集群,这也保证了不会将请求发送到远程数据中心。

●        ANY:一个单一的副本可能会响应,或协调员可以存储一个hint。如果一个hint被存储,协调器将稍后试图重新hint和提供的突变的副本。此一致性级别只接受写操作。

        无论什么一致性级别,写操作总是会发送到所有的副本上。一致性级别只简单地控制协调器在响应客户端之前等待多少个响应。

而对于读操作,协调器一般只会读取命令到足够的副本以满意一致性,不过也会有例外:

●        推理重试可能会发出一个多余的请求,如果其他副本没有响应在一个时间窗口上,会响应到一个额外的副本。

●        基于read_repair_chance和dclocal_read_repair_chance(表约束的一部分),为了修复潜在的不一致的数据读取请求会随机发送到所有的副本。

        Picking一致性级别是常见的读取读写一致性级别,高到足以覆盖,导致“强”一致性。这通常表示为W + R >RF,其中W是写的一致性级别(用户在读写数据时可以指定要求成功写到多少个节点才算写入成功设为W),R是读的一致性级别(成功从多少个节点读取到了数据才算成功设为R),RF是复制因子。例如,如果RF= 3,QUORUM请求将需要至少两个三个副本的响应。如果QUORUM用于读写,至少有一个副本可以保证参与读写请求,这反过来又保证了最新的写将被读取。在多数据中心环境,local_quorum可以用来提供一个较弱但仍然有用的保证:读保证看到最新的来自同一个数据中心内的写。

如果不需要这种强一致性,ONE级别可以用来提高吞吐量,延迟和可用性。

1.3     存储引擎

1.3.1      CommitLog

        与BigTable和其模仿者HBase不同,Cassandra的数据并不存储在分布式文件系统GFS或者HDFS中,而是直接存在本地。Cassandra也是日志型数据库,即把新写入的数据存储在内存的MemTables中并通过磁盘的CommitLog来做持久化,特点是写入比读取快,因为写入一条的数据是顺序计入commitlog中,需要随机读取磁盘以及搜索。

1.3.2      MemTables

        MemTables是内存结构在cassandra的缓冲区写入。一般来说,每个表中有一个活跃的Memtable。最终memtables刷新到磁盘成为SSTables,这可以通过几种方式触发:

●        该memtables内存使用超出阀值(看memtable_cleanup_threshold)。

●        Commitlog接近其最大值,为了让commitlog段被释放,强制memtable刷新。

memtables可以完全存储在on-heap或部分off-heap,这取决于memtable_allocation_type。

1.3.3      SSTables

        SSTables是不可变的数据文件,cassandra使用它来做持久化。SSTables的数据是来自memtables或者通过流来自其他节点。Cassandra触发器排列结合为一个,一旦新的SSTables已写入,那么旧的就可以被删除。

每个SSTables是由多个组件存储在单个文件中:

●        Data.db:实际的数据。

●        Index.db:来自分区key的索引,定位到data.db文件,因此在大的分区中,也会包含分区行的索引。

●        Summary.db:摘要,分区键的内容。

●        Filter.db:Bloom过滤器在SSTable的分区key。

●        CompressionInfo.db:关于偏移量和在data.db文件压缩的块长度的元数据。

●        Statistics.db:存储SSTable的元数据,包括时间戳、tombstones、集群键、压缩率、修复等还有更多的信息。

●        Digest.crc32: CRC-32算法的data.db文件。

●        TOC.txt:SSTable组件文件的简单的列表。

SSTables可以使用基于块压缩算法进行压缩数据。

转载于:https://my.oschina.net/lzhaoqiang/blog/844816

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值