cassandra简介
cassandra在我们公司用的还是⽐较广泛的,但是版本⽐较老,现有版本和新版本之间还是有⼀定差距,但大体架构还是没怎么变.
⽂章就cassandra的大体架构,读写删,以及cassandra 的数据一致性方法(readrepair,hintedhandoff,merkletree等机制)做一个简单的介绍,
以及对应的介绍下我们在实际运⽤中遇到的⼀些问题以及解决办法,某些部分会结合⾼低版本介绍;
这⾥先⼤体介绍下,然后后续慢慢的把各个细节介绍清楚.
架构
cassandra号称cap理论⾥面的ap做的⽐较好;一个所谓的,分布式的⾼可用的列式数据库,数据模型借鉴了bigtable;
如上图就可以认为是⼀个4个节点的cassandra集群(实际上我经常就单机eclipse跑单节点的cassandra),A,B,C,D四个节点,
如果按照⽆无vnode的情况,是每一个节点⼀个配置好的token,设叫TA,TB,TC,TD,那么各个节点负责的范围就
A(TD,TA],B(TA,TB],C(TB,TC],D(TC,TD];
若是vnode的话,集群会基于配置文件⾥面的num_tokens计算好每个节点负责的vnode的范围;这玩意⽐较轻量级,不会类似hbase那样,依赖很多东⻄.
为啥说cassandra是可用性⽐较好呢?
因为cassandra是一个去中心化的系统,每⼀个节点都是对等的,没有主从概念,每一个节点维护了⼀份集群表的migration信息,集群节点up/down信息,集群各节点状态:nornaml/joining/leaving/bootstrap等信息,集群各节点容量load信息,集群节点ip/token信息等;所以,任何一个节点挂了,整个集群⼤体的信息是可以获取的.
还有就是读写机制,3副本quoram读写,那么任何⼀个节点挂,正常情况下对集群基本读写没啥影响;甚⾄隔几个节点挂一个,都是可以.
比如上图集群2副本one读写的情况,A节点挂了,C节点挂了,整个集群挂了⼀半节点,还是可以提供正常服务;甚⾄A,B挂了,也就影响集群一半的访问,C,D不影响(但是会抛异常);
假如是主从架构的集群,主节点挂了?别说HA。。。(实际上我承认,cassandra的数据⼀致性是和hbase这种比是不是很不靠谱,主从的系统可以通过搞HA提高可用性,但是这种系统很难突破数据一致性的问题,当然了改成非cassandra有可能就突破,就比如:假如2副本,one读写,某一时刻,A写成功,B失败,下一 时刻,翻转下,写A上的数据可能就读不到,当然上述问题,我们都有fix,实际的生产环境下还会有遇到很多问题)。
读写删:
在cassandra⾥面,节点是对等的,同时每一个节点承担了2个身份:数据节点以及接入(proxy)节点;
假设当一个client连接到集群中的某⼀个节点,请求⼀个key的value,假设这个key从属的table是3个副本,这时候这个被连接节点就需要做proxy功能,需要承担这个key的decoratedkey的计算 (比如对这个key算md5);
基于计算的dk找到从属的数据节点,⽐如上图:若key连接到TA,计算 完md5得到的从属的范围是(TA,TB],且数据的摆放是simple的策略,
也就是TB,TC,TD三个节点;那么TA需要并发给TB,TC,TD发送读请求,如果是Quoram级别,那么TA上的线程会等待到⾄少2个响应回来才会可能返回,否认就是超时;这⾥TA做为一个proxy节点;那么如果key是属于(TD,TA],这⾥TA就是一个数据节点加上proxy节点;因为TA还要去本地的内存以及sstable⾥面去搂数据;
同理,写以及删除都是这样一个⼤概的流程;只不过删的话是直接打了⼀个tombstone;追加写下去即可;
hintedhandoff:
首先申明,这个机制只是合适节点挂了⽐较⼩的⼀段时间(eg :one hour),cassandra⾥面有一个system表,它是⼀个one副本的,
⾥面记录的是集群的元信息相关,通过gossip机制交换,已达到整个集群每⼀个节点的one副本一致;这个表⾥面有⼀个cf是hinted相关的;
她的作⽤是啥呢?
举个例⼦就知道了,比如上图TA,TB,TC负责了某一个range的副本数据,如下写这个range的数据, 那么是要并发写TA,TB,TC的,
那么假如⽤one级别写,TC是down的,这不影响写⼊和读取,那么down的TC不就一直写不了数据的么?
因为TC挂了,假如TC活了,我们需要有⼀些机制去把TC挂的这段期间的数据修复回来;hintedhandoff就是干这个的(当然readrepair 以及merkletree也有可能会做),
简单点说,假如TA是proxy节点,接收到 client请求,写的数据应该是落在TA,TB,TC,那么TA通过gossip模块(这里我统称)反馈的节点死活知道集群的状态,然后感知到TC黄了,那么就在TA本地记录下TC的ip以及对应需要写的key,到刚才说的system表的hinted的cf;等到TA感觉到TC又活了,那么就会把system表下,
hinted的数据读出来,写到对应的机器,然后删除这个记录;