1. 简介
Apache Cassandra是由 Facebook 创立的高度可扩大、高性能的分布式NoSQL数据库,能够灵便的在线扩容,满足业务水平扩大的需要。具备可能解决大量数据的分布式架构。 数据搁置在具备多个复本因子的不同机器上,以取得高可用性,而无需放心单点故障。
2. 个性
分布式和去中心化
Cassandra 是分布式的,这意味着它能够运行在多台机器上,并出现给用户一个统一的整体。你能够释怀地将数据写到集群的任意一台机器上,Cassandra 都会收到数据。去中心化意味着 Cassandra 不会存在单点生效。Cassandra 集群中的所有节点的性能都齐全一样, 所以不存在一个非凡的主机作为主节点来承当协调工作。
弹性可扩大
节点间应用gossip协定通信,不须要重新启动过程,不用批改利用的查问,也无需本人手工从新平衡数据分布。在 Cassandra 里,你只有退出新的计算机,Cassandra 就会主动地发现它并让它开始工作。
可调节的一致性
CAP 定律表明,对于任意给定的零碎,只能在一致性(Consistency)、可用性(Availability)以及分区容错性(Partition Tolerance)之间抉择两个。所以 Cassandra 在设计的时候也不得不思考这些问题,因为分区容错性这个是每个分布式系统必须思考的,所以只能在一致性和可用性之间做抉择,而 Cassandra 的利用场景更多的是为了满足可用性,所以咱们只能就义一致性了。然而依据 BASE 实践,咱们其实能够通过就义强一致性取得可用性。
Cassandra 提供了可调节的一致性,容许咱们选定须要的一致性程度与可用性程度,在二者间找到平衡点。因为客户端能够管制在更新达到多少个正本之前,必须阻塞零碎。这是通过设置正本因子(replication factor)来调节与之绝对的一致性级别。
通过正本因子(replication factor),你能够决定筹备就义多少性能来换取一致性。正本因子是你要求更新在集群中流传到的节点数(留神,更新包含所有减少、删除和更新操作)。
客户端每次操作还必须设置一个一致性级别(consistency level)参数,这个参数决定了多少个正本写入胜利才能够认定写操作是胜利的,或者读取过程中读到多少个正本正确就能够认定是读胜利的。这里 Cassandra 把决定一致性水平的权力留给了客户本人。
所以,如果需要的话,你能够设定一致性级别和正本因子相等,从而达到一个较高的一致性程度,不过这样就必须付出同步阻塞操作的代价,只有所有节点都被更新实现能力胜利返回一次更新。而实际上,Cassandra 个别都不会这么来用,起因不言而喻(这样就丢失了可用性指标,影响性能,而且这不是你抉择 Cassandra 的初衷)。而如果一个客户端设置一致性级别低于正本因子的话,即便有节点宕机了,依然能够写胜利。
总体来说,Cassandra 更偏向于 CP,尽管它也能够通过调节一致性程度达到 AP;然而不举荐你这么设置。
高可用和容错
从个别架构的角度来看,零碎的可用性是由满足申请的能力来量度的。但计算机可能会有各种各样的故障,从硬件器件故障到网络中断都有可能。任何计算机都可能产生这些状况,所以它们个别都有硬件冗余,并在产生故障事件的状况下会主动响应并进行热切换。对一个须要高可用的零碎,它必须由多台联网的计算机形成,并且运行于其上的软件也必须可能在集群条件下工作,有设施可能辨认节点故障,并将产生故障的节点的性能在残余零碎上进行复原。
Cassandra 就是高可用的。你能够在不中断零碎的状况下替换故障节点,还能够把数据分布到多个数据中心里,从而提供更好的本地拜访性能,并且在某一数据中心产生火灾、洪水等不可抗劫难的时候避免零碎彻底瘫痪。
面向行
Cassandra 常常被看做是一种面向列(Column-Oriented)的数据库,这也并不算错。它的数据结构不是关系型的,而是一个多维稠密哈希表。稠密(Sparse)意味着任何一行都可能会有一列或者几列,但每行都不肯定(像关系模型那样)和其余行有一样的列。每行都有一个惟一的键值,用于进行数据拜访。所以,更确切地说,应该把 Cassandra 看做是一个有索引的、面向行的存储系统。
Cassandra 的数据存储构造根本能够看做是一个多维哈希表。这意味着你不用当时准确地决定你的具体数据结构或是你的记录应该蕴含哪些具体字段。这特地适宜处于草创阶段,还在一直减少或批改服务个性的利用。而且也特地适宜利用在麻利开发我的项目中,不用进行长达数月的事后剖析。对于应用 Cassandra 的利用,如果业务发生变化了,只须要在运行中减少或删除某些字段就行了,不会造成服务中断。
当然, 这不是说你不须要思考数据。相同,Cassandra 须要你换个角度看数据。在 RDBMS 里, 你得首先设计一个残缺的数据模型, 而后思考查问形式, 而在 Cassandra 里,你能够首先思考如何查问数据,而后提供这些数据就能够了。
灵便的模式
Cassandra 的晚期版本反对无模式(schema-free)数据模型,能够动静定义新的列。无模式数据库(如 MongoDB)在拜访大量数据时具备高度可扩展性和高性能的劣势。无模式数据库的次要毛病是难以确定数据的含意和格局,这限度了执行简单查问的能力。
为了解决这些问题,Cassandra 引入了 Cassandra Query Language(CQL),它提供了一种通过相似于结构化查询语言(SQL)的语法来定义模式。最后,CQL 是作为 Cassandra 的另一个接口,并且基于 Apache Thrift 我的项目提供无模式的接口。在这个过渡阶段,术语“模式可选”(Schema-optional)用于形容数据模型,咱们能够应用 CQL 的模式来定义。并且能够通过 Thrift API 实现动静扩大以此增加新的列。在此期间,根底数据存储模型是基于 Bigtable 的。
从 3.0 版本开始,不举荐应用基于 Thrift API 的动静列创立的 API,并且 Cassandra 底层存储曾经从新实现了,以更严密地与 CQL 保持一致。Cassandra 并没有齐全限度动静扩大架构的能力,但它的工作形式却截然不同。CQL 汇合(比方 list、set、尤其是 map)提供了在无结构化的格局外面增加内容的能力,从而能扩大现有的模式。CQL 还提供了扭转列的类型的能力,以反对 JSON 格局的文本的存储。
因而,形容 Cassandra 以后状态的最佳形式可能是它反对灵便的模式。
高性能
Cassandra 在设计之初就特地思考了要充分利用多处理器和多核计算机的性能,并思考在散布于多个数据中心的大量这类服务器上运行。它能够统一而且无缝地扩大到数百台机器,存储数 TB 的数据。Cassandra 曾经显示出了高负载下的良好体现,在一个十分一般的工作站上,Cassandra 也能够提供十分高的写吞吐量。而如果你减少更多的服务器,你还能够持续放弃 Cassandra 所有的个性而无需就义性能。
3. 利用场景
大规模部署
Cassandra 的很多精美设计都专一于高可用、可调一致性、P2P 协定、无缝扩大等,这些都是 Cassandra 的卖点。这些个性在单节点工作时都是没有意义的,更无奈实现它的全副能力。
然而,单节点关系数据库在很多状况下可能正是咱们须要的。所以你须要做一些评估,思考你的冀望的流量、吞吐需要等。对于评估没有什么硬性的指标和要求。但如果你认为有几种关系型数据库能够很好地应酬你的流量,提供不错的性能,那可能选关系型数据库更好。简略地说,这是因为 RDBMS 更易于在单机上运行,对你来说也更相熟。
然而,如果你认为须要至多几个节点能力撑持你的业务,那 Cassandra 就是个不错的抉择。如果你的利用可能须要数十个节点,那 Cassandra 可能就是个很棒的抉择了。
写密集、统计和剖析型工作
考虑一下你的利用的读写比例,Cassandra 是为优异的写吞吐量而特地优化的。
许多晚期应用 Cassandra 的产品都用于存储用户状态更新、社交网络、倡议/评估以及利用统计等。这些都是 Cassandra 很好的利用场景,因为这些利用大都是写多于读的,并且更新可能随时产生并伴有突发的峰值。事实上,撑持利用负载须要很高的多客户线程并发写性能,这正是 Cassandra 的次要个性。
异地多活
Cassandra 间接反对多地散布的数据存储,Cassandra 能够很容易配置成将数据分布到多个数据中心的存储形式。如果你有一个寰球部署的利用,那么让数据贴近用户会取得不错的性能收益,Cassandra 正适宜这种利用场合。
变动的利用
如果你正在“初创阶段”,业务会不断改进,Cassandra 这种灵便的模式的数据模型可能更适宜你。这让你的数据库能更快地跟上业务改良的步调。
4. 数据模型
Table & KeySpace
Cassandra 中的 KeySpace 概念和 RDBMS 外面的 DataBase 概念很相似,一个 KeySpace 蕴含多张表,个别将有关联的数据表放到同一个 KeySpace 上面。KeySpace 创立的时候能够指定正本策略,正本因子以及是否启用 CommitLog 机制(相似 HBase 中的 WAL)。
Cassandra 中表的概念和 RDBMS 很相似。不同的是在 Cassandra 中属于同一张表的数据在物理上是散布在不同节点上存储的,同一张表由多个 Partition 组成。
Partitions
Cassandra 个别是由多台节点组成的,每台节点负责肯定范畴的,如果应用 Murmur3hash 的时候,每个节点负责的 Token 相似于上面那样:
所以 Token 范畴为 -9223372036854775808 ~ -4611686018427387904 的数据存储在 A 节点;同理,Token 范畴为 -4611686018427387903 ~ -1 之间的数据存储在 B节点,其余相似;每个 Token 范畴由多个 Partition 形成,每个 Partition 由一行或多行数据组成。
在底层存储中,多个 Partition 组成一个 SSTable(Sorted-String Table)文件。那么同一个 SSTable 文件中的数据数据是如何组织的呢?答案是依照 Partition Key 计算失去的 Token 升序排序的。如果 Partition Key 由多个字段形成那么是将这多个字段拼在一起再计算拼成后字符串的哈希值。
Row
Partition 外面蕴含了零个或多个 Row,这些 Row 对应的 Partition Key 是一样的。
Cassandra 通过将列的信息(包含列的名称、类型、表名、keySpace等信息)保留到对应 SSTable 的 md-X-big-Statistics.db 文件中,相应的行只保留列是否存在的标记信息,这个能够节俭存储空间的占用。HBase 存储数据的时候每个 Cell 都须要保留列名称和列族名称的。
那多个 Cell 之间的程序是如何保障的呢?答案是依照列名称的字典程序升序排序的。
Cell
Cell 就是每列数据的底层实现,Cell 外面蕴含了列的定义信息,比方是否被删除、是否过期、是否设置了工夫戳等。在 Cassandra 外面,Column 有 Simple 和 Complex之分。non-frozen collection 或 UDT(用户自定义类型)的列是 ComplexColumn(Complex Cell)。
5. 应用注意事项
除了二级索引查问,其余所有查问必须指定
分区键
,即第一主键,用于决定数据存储于哪台机器。Cassandra也反对复合分区键,即多个字段作为分区键,定义时用小括号包起来。
第一主键称为分区键
Partition Key
,是用来分区的;除分区键以外的主键称为集群键Clustering Key
(从第二主键开始到最初),用于排序。硬盘中的数据是依照集群键的排列顺序存储的,所以查问时不能跳字段,必须从第二主键开始排序。
- 第一主键 只能用=号查问;第二主键往后 反对= > < >= <=; 二级索引列 只反对=号。
Cassandra反对创立二级索引,能够创立在除了第一主键(分区键:partition key)之外所有的列上;
如果查问条件里,有一个是依据索引查问,那其它非索引非主键字段,能够通过加一个ALLOW FILTERING来过滤实现;
- Cassandra 分页查问不反对跳页,每次分页必须从第一页开始,只能下一页/上一页的滚动翻页,分页无奈取到总数量和总页码。
Cassandra 想要排序功能,在建表时就要指定字段的排序程序,排序字段从第二主键开始,否则数据查问进去是乱序的。
Cassandra 排序须要从第二主键开始,第一主键无奈作为排序字段。在查问时order by 字段排序程序必须与建表时设置的字段程序统一或齐全相同。
- Cassandra查问性能较弱,适宜作为存储构造简略的大数据量宽表,做一些简略查问。
Cassandra不反对join和其余简单查问。
6. 架构
Cassandra 集群的架构相似于 redis cluster
,也是用一致性哈希算法来确定数据寄存在那台机器,且也是应用虚构节点的概念。集群节点间也是通过Gossip协定来实现无核心架构。
6.1 根本流程
点对点分布式系统,集群中各节点平等,数据分布于集群中各节点,各节点间每秒替换一次信息。
每个节点的commit log提交日志
记录写操作日志来确保数据持久性。
数据先被写入MemTable
(内存中的数据结构),待MemTable满后数据被写入SSTable
(硬盘的数据文件)。
所有的写内容被主动在集群中partition分区
并replicate复制
。
6.2 库表构造
Cassandra数据库面向行。用户可连贯至集群的任意节点,通过相似SQL的CQL查问数据。
集群中,一个利用个别蕴含一个keyspace
,一个keyspace
中蕴含多个表,keyspace
类比关系型数据库中的database
。
6.3 读写申请
客户端连贯到某一节点发动读或写申请时,该节点充当客户端利用
与领有相应数据的节点
间的 coordinator协调者
以依据集群配置确定环(ring)中的哪个节点
来解决这个申请。
对Cassandra的读操作,会依据primary key
来确定申请被路由到哪个节点下来读取数据,节点上的数据依照cluster key
排列顺序存储。
6.4 关键词阐明
关键词 | 名词解释 |
---|---|
Gossip | 点对点通信协议,用以Cassandra集群中节点间替换地位和状态信息。 |
Partitioner | 决定如何在集群中的节点间散发数据,即在哪个节点搁置数据的第一个replica。 |
Replica placement strategy | 决定在哪些节点搁置每行数据的其余replica。Cassandra在集群中的多个节点存储数据的多份拷贝(replicas)来确保牢靠和容错。 |
Snitch | 定义了复制策略用来搁置replicas和路由申请所应用的拓扑信息 |
Virtual nodes | 虚构节点, 指定数据与物理节点的所属关系 |
Token Ring | 令牌环 |
6.5 节点间通信gossip
Cassandra应用点对点通信协定gossip在集群中的节点间替换地位和状态信息。
gossip过程每秒
运行一次,与至少3个
其余节点替换信息,这样所有节点能够很快理解集群中的其余节点信息。
gossip协定的具体表现形式就是配置文件中的seeds种子节点。
一个留神点是同一个集群的所有节点的种子节点应该统一,否则如果种子节点不统一, 有时候会呈现集群决裂,即会呈现两个集群,个别先启动种子节点,尽早发现集群中的其余节点。
每个节点都和其余节点替换信息,因为随机和概率,肯定会穷举出集群的所有节点,同时每个节点都会保留集群中的所有其余节点。
这样轻易连到哪一个节点,都能晓得集群中的所有其余节点。比方cql轻易连贯集群的一个节点,都能获取集群所有节点的状态,也就是说任何一个节点对于集群中的节点信息的状态都应该是统一的!
6.6 一致性哈希
图解:key的范畴是0到2^32造成一个环,叫做hash空间环,即hash的值空间。对集群的服务器(比方ip地址)进行hash,都能确定其在环空间上的地位。
定位数据拜访到相应服务器的算法:将数据key应用雷同的函数H计算出哈希值h,而后依据h确定此数据在环上的地位,从此地位沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器。
图解:因为一致性哈希算法在服务节点太少时,容易因为节点散布不平均而造成数据歪斜问题,所以引入了虚构节点。
把每台server分成v个虚构节点,再把所有虚构节点(n*v)随机调配到一致性哈希的圆环上,这样所有的用户从本人在hash环上的地位顺时针往下取到第一个vnode就是本人所属节点。当此节点存在故障时,再顺时针取下一个作为代替节点。
图解:key通过hash会定位到hash环上的一个地位,找到下一个vnode为数据的第一份存储节点,接下来的两个vnode为另外两个正本。
6.7 hash值空间&token
下面在计算key存在哪个节点上是应用往前游走的形式找到环上的第一个节点,游走是一个计算的过程。
如果可能当时计算好集群中的节点(vnodes)在整个hash环的值空间,这样对key进行hash后,能够看它是落在哪个hash值空间上, 而值空间和节点的关系曾经晓得了,所以能够间接定位到key落在哪个节点上了。这就是token
的作用。
在Cassandra中,table的每行由惟一的primary key
标识,partitioner
分区器依据hash函数
计算出primary key的token
。Cassandra根据这个token值寻找在集群中搁置对应的行。
7. 读写流程与存储机制
7.1 写流程
当写事件产生时,首先由Commit Log
捕捉写事件并长久化,保证数据的可靠性。之后数据也会被写入到内存中,叫Memtable
,当内存满了之后写入数据文件,叫SSTable
,它是Log-Structured Storage Table的简称。 如果客户端配置了Consistency Level
是ONE,意味着只有有一个节点写入胜利,就由协调者节点(Coordinator)返回给客户端写入实现。当然这两头有可能会呈现其它节点写入失败的状况,Cassandra本人会通过Hinted Handoff或Read Repair 或者Anti-entropy Node Repair形式保证数据最终一致性。
Cassandra的存储构造相似LSM树
这种构造,不像传统数据个别都应用B+树,存储引擎以追加的形式程序写入磁盘间断存储数据,写入是能够并发写入的,不像B+树一样须要加锁,写入速度十分高。
Commit Log
记录每次写申请的残缺信息,此时并不会依据主键进行排序,而是程序写入,这样进行磁盘操作时没有随机写导致的磁盘大量寻道操作,对于晋升速度有极大的帮忙。Commit Log
会在Memtable
中的数据刷入SSTable
后被革除掉,因而它不会占用太多磁盘空间,Cassandra的配置时也能够独自设置存储区,这为应用高性能但容量小价格昂贵的SSD硬盘存储Commit Log,应用速度慢但容量大价格十分便宜的传统机械硬盘存储数据的混合布局提供了便当。
写入到Memtable
时,Cassandra可能动静地为它分配内存空间,你也能够应用工具本人调整。当达到阀值后,Memtable中的数据和索引会被放到一个队列中,而后flush到磁盘,能够应用memtableflushqueue_size
参数来指定队列的长度。当进行flush时,会进行写申请。也能够应用nodetool flush工具手动刷新 数据到磁盘,重启节点之前最好进行此操作,以缩小Commit Log回放的工夫。为了刷新数据,会依据partition key对Memtables进行重排序,而后程序写入磁盘。这个过程是十分快的,因为只蕴含Commit Log的追加和程序的磁盘写入。
这里所述的写申请不单指Insert操作,Update操作也是如此,Cassandra对Update操作的解决和传统关系数据库齐全不一样,并不立刻对原有数据进行更新,而是会减少一条新的记录,后续在进行Compaction
时将数据再进行合并。Delete操作也同样如此,要删除的数据会先标记为Tombstone
,后续进行Compaction时再真正永恒删除。
7.2 读流程
读取数据时,首先查看Bloom filter
,每一个SSTable都有一个Bloom filter用来查看partition key
是否在这个SSTable,这一步在拜访任何磁盘IO的后面都会做。Bloom filter可能误判不会漏判:判断存在,但实际上可能不存在, 判断不存在,则肯定不存在,则流程不会拜访这个SSTable。如果存在,再查看partition key cache
,而后再做如下操作:
- 如果在cache中能找到索引,到
compression offset map
中找领有这个数据的数据块,从磁盘上获得压缩数据并返回后果集。 - 如果在cache中找不到索引,搜寻
partition summary
(partition index
的样本集)确定索引在磁盘上的近似地位,而后获取索引入口,在SSTable上执行一次独自的寻道和一个程序的列读取操作,接下来也是到compression offset map
中找领有这个数据的数据块,从磁盘上获得压缩数据并返回后果集。读取数据时会合并Memtable
中缓存的数据、多个SSTable
中的数据,才返回最终的后果。比方更新用户email后,用户名、明码等还在老的SSTable中,新的email记录到新的SSTable中,返回后果时须要读取新老数据并进行合并。
2.0之后的Bloom filter
,compression offset map
,partition summary
都不放在Heap中了,只有partition key cache
还放在Heap中。Bloom filter每billion partitions增长大概1到2G。partition summary是partition index
的样本,你能够通过index_interval来配置样本频率。compression offset map每TB增长1到3G。对数据压缩越多,就会有越多个数的压缩块,和越大compression offset table。
读申请(Read Request)分两种,一种是Rirect Read Request,依据客户端配置的Consistency Level读取到数据即可返回客户端后果。一种是Background Read Repair Request,除了间接申请达到的节点外,会被发送到其它复制节点,用于修复之前写入有问题的节点,保证数据最终一致性。客户端读取时,Coordinator首先分割Consistency Level定义的节点,发送申请到最快响应的复制节点上,返回申请的数据。如果有多个节点被分割,会在内存比拟每个复制节点传过来的数据行,如果不统一选取最近的数据(依据工夫戳)返回给客户端,并在后盾更新过期的复制节点,这个过程被称作Read Repair 。
下图是Consistency Level 为ONE的读取过程,Client连贯到任意一个节点上,该节点向理论领有该数据的节点发出请求,响应最快的节点数据回到Coordinator后,就将数据返回给Client。如果其它节点数据有问题,Coordinator会将最新的数据发送有问题的节点上,进行数据的修复。
7.3 数据整顿压缩(Compaction)
更新操作不会立刻更新,这样会导致随机读写磁盘,效率不高,Cassandra会把数据程序写入到一个新的SSTable,并打上一个工夫戳以表明数据的新旧。它也不会立马做删除操作,而是用Tombstone来标记要删除的数据。Compaction时,将多个SSTable文件中的数据整合到新的SSTable文件中,当旧SSTable上的读申请一实现,会被立刻删除,空余进去的空间能够从新利用。尽管Compcation没有随机的IO拜访,但还是一个重量级的操作,个别在后盾运行,并通过限度它的吞吐量来管制,compactionthroughputmbpersec
参数能够设置,默认是16M/s。另外,如果key cache显示整顿后的数据是热点数据,操作系统会把它放入到page cache里,以晋升性能。它的合并的策略有以下两种:
- SizeTieredCompactionStrategy:每次更新不会间接更新原来的数据,这样会造成随机拜访磁盘,性能不高,而是在插入或更新间接写入下一个sstable,这样是程序写入速度十分快,适宜写敏感的操作。然而,因为数据分布在多个sstable,读取时须要屡次磁盘寻道,读取的性能不高。为了防止这样状况,会定期在后盾将类似大小的sstable进行合并,这个合并速度也会很快,默认状况是4个sstable会合并一次,合并时如果没有过期的数据要清理掉,会须要一倍的空间,因而最坏状况须要50%的闲暇磁盘。
- LeveledCompactionStrategy:创立固定大小默认是5M的sstable,最下面一级为L0上面为L1,上面一层是下面一层的10倍大小。这种整顿策略读取十分快,适宜读敏感的状况,最坏只须要10%的闲暇磁盘空间。
7.4 数据复制和散发
数据散发和复制通常是一起的,数据用表的模式来组织,用主键来辨认应该存储到哪些节点上,行的copy称作replica
。当一个集群被创立时,至多要指定如下几个配置:Virtual Nodes,Partitioner,Replication Strategy,Snitch。
数据复制策略有两种,一种是SimpleStrategy
,适宜一个数据中心的状况,第一份数据放在Partitioner确定的节点,前面的放在顺时针找到的节点上,它不思考跨数据中心和机架的复制。另外一种是NetworkTopologyStargegy
,第一份数据和前一种一样,第二份复制的数据放在不同的机架上,每个数据中心能够有不同数据的replicas。
Partitioner策略有三种,默认是Murmur3Partitioner
,应用Murmur Hash。RandomPartitioner,应用Md5 Hash。ByteOrderedPartitioner应用数据的字节进行有顺分区。Cassandra默认应用MurmurHash,这种有更高的性能。
Snitch用来确定从哪个数据中心和哪个机架上写入或读取数据,有如下几种策略:
- DynamicSnitch:监控各节点的执行状况,依据节点执行性能主动调节,大部分状况举荐应用这种配置
- SimpleSnitch:不会思考数据库和机架的状况,当应用SimpleStategy策略时思考应用这种状况
- RackInterringSnitch:思考数据库和机架
- PropertyFileSnitch:用cassandra-topology.properties文件来自定义
- GossipPropertyFileSnitch:定义一个本地的数据中心和机架,而后应用Gossip协定将这个信息流传到其它节点,对应的配置文件是cassandra-rockdc.properties
7.5 失败检测和修复
Cassandra从Gossip信息中确认某个节点是否可用,防止客户端申请路由到一个不可用的节点,或者执行比较慢的节点,这个通过dynamic snitch能够判断进去。Cassandra不是设定一个固定值来标记失败的节点,而是通过间断的计算单个节点的网络性能、工作量、以及其它条件来确定一个节点是否失败。节点失败的起因可能是硬件故障或者网络中断等,节点的中断通常是短暂的但有时也会继续比拟久的工夫。节点中断并不意味着这个节点永恒不可用了,因而不会永恒地从网络环中去除,其它节点会定期通过Gossip协定探测该节点是否恢复正常。如果想永恒的去除,能够应用nodetool手工删除。
当节点从中断中恢复过来后,它会短少最近写入的数据,这部分数据由其它复制节点暂为保留,叫做Hinted Handoff
,能够从这里进行主动复原。但如果节点中断工夫超过maxhintwindowinms(默认3小时)设定的值,这部分数据将会被抛弃,此时须要用nodetool repair在所有节点上手工执行数据修复,以保证数据的一致性。
7.6 动静扩大
Cassandra最后版本是通过一致性Hash来实现节点的动静扩大的,这样的益处是每次减少或缩小节点只会影响相邻的节点,但这个会带来一个问题就是造成数据不平均,比方新增时数据都会迁徙到这台机的机器上,缩小时这台机器上的数据又都会迁徙到相邻的机器上,而其它机器都不能分担工作,势必会造成性能问题。从1.2版本开始,Cassandra引入了虚构节点(Virtual Nodes)的概念,为每个实在节点调配多个虚构节点(默认是256),这些节点并不是按Hash值顺序排列,而是随机的,这样在新增或缩小一个节点时,会有很多实在的节点参加数据的迁徙,从而实现了负载匀衡。
8. LSM树
LSM树(Log-Structured-Merge-Tree)的名字往往会给初识者一个谬误的印象,事实上,LSM树并不像B+树、红黑树一样是一颗严格的树状数据结构,它其实是一种存储构造,目前HBase,LevelDB,RocksDB这些NoSQL存储都是采纳的LSM树。
LSM树的外围特点是利用程序写来进步写性能,但因为分层(此处分层是指的分为内存和文件两局部)的设计会略微升高读性能,然而通过就义小局部读性能换来高性能写,使得LSM树成为十分风行的存储构造。
8.1 LSM树的核心思想
如上图所示,LSM树有以下三个重要组成部分:
1) MemTable
MemTable是在内存中的数据结构,用于保留最近更新的数据,会依照Key有序地组织这些数据,LSM树对于具体如何组织有序地组织数据并没有明确的数据结构定义。
因为数据临时保留在内存中,内存并不是牢靠存储,如果断电会失落数据,因而通常会通过WAL(Write-ahead logging,预写式日志)的形式来保证数据的可靠性。
2) Immutable MemTable
当 MemTable达到肯定大小后,会转化成Immutable MemTable(不可变的MemTable)。Immutable MemTable是将转MemTable变为SSTable的一种中间状态。写操作由新的MemTable解决,在转存过程中不阻塞数据更新操作。
3) SSTable(Sorted String Table)
有序键值对汇合,是LSM树组在磁盘中的数据结构。为了放慢SSTable的读取,能够通过建设key的索引以及布隆过滤器来放慢key的查找。
这里须要关注一个重点,LSM树(Log-Structured-Merge-Tree)正如它的名字一样,LSM树会将所有的数据插入、批改、删除等操作记录(留神是操作记录)保留在内存之中,当此类操作达到肯定的数据量后,再批量地程序写入到磁盘当中。这与B+树不同,B+树数据的更新会间接在原数据所在处批改对应的值,然而LSM数的数据更新是日志式的,当一条数据更新是间接append一条更新记录实现的。这样设计的目标就是为了程序写,一直地将Immutable MemTable flush到长久化存储即可,而不必去批改之前的SSTable中的key,保障了程序写。
因而当MemTable达到肯定大小flush到长久化存储变成SSTable后,在不同的SSTable中,可能存在雷同Key的记录,当然最新的那条记录才是精确的。这样设计的尽管大大提高了写性能,但同时也会带来一些问题:
1)冗余存储,对于某个key,实际上除了最新的那条记录外,其余的记录都是冗余无用的,然而依然占用了存储空间。因而须要进行Compact操作(合并多个SSTable)来革除冗余的记录。
2)读取时须要从最新的倒着查问,直到找到某个key的记录。最坏状况须要查问完所有的SSTable,这里能够通过后面提到的索引/布隆过滤器来优化查找速度。