一、Apache Cassandra介绍
为什么要使用Cassandra?
● 分布式的海量数据存储和处理
● 极高的性能
● 极致的可靠性(去中心化的架构 无单点故障)
● 优秀的线性可扩展能力(无上限)
● 对多地多数据中心部署的原生支持
● 运维和管理需要理解的概念简单
● 使用对开发者非常友好的类SQL语言CQL
● 强大的生态、活跃的国际社区
● 不断紧跟最新技术趋势(k8s、云原生、多模、存储计算分离)使得它持续具有强大的生命力
为什么很多企业都会使用Cassandra数据库?首先它是一个分布式的海量数据存储的数据库,我们这里说的海量不止是几十个TB,而是几万甚至几十万TB的数据库体量,这个是传统数据库非常难以企及的水平。
然后它有极高的性能,这里说的高性能指的是它每个读写操作通常都可以达到个位数毫秒级别,这跟很多其它的数据库读写操作比起来,会有数量级的性能提升,对交互式应用的终端用户体验会是很大的提高。
再就是它的去中心的架构使得它天然具有无单点故障的优势,这样也就让它有极致的可靠性。Cassandra可以做到100%在线,在美国大型商企里面有Cassandra集群,在生产环境上线三年内都是100%在线。
另一点就是Cassandra优秀的线性可扩展能力是无上限的可扩展。我们在后面会看到一个纽约证券交易所应用案例里面,对这种无限扩展的能力非常赞赏。
还有对多数据中心的原生支持,使得全球多地部署成为非常容易的事情,然后就是它的运维和管理需要理解的概念非常简单,因为在Cassandra里面它的每个节点都是对等的完全一样,所以部署1个节点,跟部署10个或者500个节点其实差别并不大。
Cassandra没有对其它系统和组件的过多依赖,只需要UNIX主机和Java运行环境,这样的话其实对容器化和云原生的部署其实非常有利。另外Cassandra提供了一种对开发者非常友好的类SQL语言:CQL。通常仅需花上半天时间就可以快速上手。
Cassandra工资前10的位置
学习Cassandra的好处?
● 著名招聘网站DICE的年度工资调查,Cassandra一直被列为IT行业十大平均薪酬水平最高的技术之一
● 对分布式系统的理解和动手能力——校招面试必备技能
● 跟社区高手学习和交流
● 提高你在职场的竞争力
Cassandra这么多年在美国是非常热门的技术,在IT行业平均薪酬仅次于人工智能和自然语言处理,学习Cassandra还可以非常容易的加深分布式系统的理解和动手能力,对于参加校招和社招来说也非常有利。Cassandra采用了非常有名的数据结构 LSM Tree,也就是Log-Structured Merge Tree。LSM Tree几乎是大厂面试必考题目,Cassandra可以算工业界把LSM Tree用的最炉火纯青的数据库。在参与Cassandra社区、或者学习,源码贡献时,会有社区高手交流和学习的机会,能够提高你在职场的竞争力。
DBEngine全世界非常权威的数据库的流行程度排名列表中,Cassandra一直在宽表数据库里面持续遥遥领先。
国际社区统计数据看到,在财富前100强企业里面90%在使用Cassandra,美国著名职场社交网站LinkedIn上已有78000 Cassandra专业人士,每年都有20%增长。根据 DataStax公司统计,有72%的公司预计今年NoSQL使用会继续增加。Cassandra在GitHub上有相关的docker镜像,在一年多以前放上之后,每年都有186%的下载量增长。目前DataStax Academy学院注册学员167,490。一些相关的大厂亚马逊、微软都相继推荐自己的Cassandra云服务。
二、架构基础和原理篇
Cassandra数据库,数据分布在多个节点上。Cassandra起配仅需单节点,吞吐量每核每秒可达到几千笔操作。生产环境通常会配置多节点,节点之间通过gossip协议进行通信,构建成一个hash token环。每个节点负责一部分token范围,这些节点之间通过gossip来互相告知谁负责哪个token范围,哪个节点是离线,哪个节点是新加入,这些都需要高效率的通信协议。有了gossip协议,每个节点都独立自主,可以自发的学习所有其它节点的状态,这也就是我们平常说的对等网络p2p概念。P2p概念对Cassandra高可靠性和线性扩展非常重要,这也是Cassandra和其它数据的关键区别。
Cassandra数据库非常吸引人的特性就是线性扩展。如果需要更多存储容量或更多数据吞吐量,只要增加节点就好。(图为当年多伦多大学全球非常有名的数据库组,做性能测评的时候,专门来检测数据库是不是确实能够做到线性增长)。另外Cassandra数据库在全球范围流行的重要原因,可以一直加节点,对数据库扩容基本上没有上限,这样的架构在云计算时代非常便利。
Cassandra扩容通过水平扩展来进行,其它数据库想增加处理能力就要加CPU或者内存、用更快的磁盘,垂直往节点上堆硬件让单节点更快更强,但Cassandra设计不仅有Scale Up垂直扩展,还有Scale Out水平扩展,使用便宜的普通硬件,在资源不够的情况下,增加节点,就可以让吞吐量实现翻倍。
数据分布前
数据分布后
Cassandra分布可以使用如上图示例,数据按照分区建(partition Key)写入到Cassandra的多个节点,同样的partition Key就会在存储到同一个节点上。数据的分布是完全自动完成,应用只需要持续写入数据,就会自动被分布到集群的各个节点上。
Cassandra环(Ring)的工作原理
Cassandra环(Ring)如何工作:想象下这里有个环,每一个圆圈都代表一个节点,总共有6个节点,每个节点都分配了所负责的token范围。我们这个例子里面把token范围取值简化,假设环的token范围加起来是0~100(实际应用中的整个token范围非常大)。
每个节点负责一段token的范围,比如说17号节点负责0~16,33号节点负责17~32,50号节点负责33~49,以此类推。我们特意用相同颜色把这个节点和它负责的范围都用相同颜色标注出来。
如果现在有数据要被写入,如token取值为59的数据。这6个节点中,将会有一个节点来负责处理这个写入请求,本例假设是83号节点。这里我们就管83号节点叫做Coordinator节点。Cassandra是无主架构,完全没有什么主节点、从节点这种角色,所有节点的地位都一样,都可以同时扮演Coordinator节点,并都能存储数据。
Coordinator节点谁当都可以,每笔操作不管是哪一个节点接受,它就成为Coordinator节点。客户端也允许每个不同的读写操作都换一个Coordinator节点来接收,这也是Coordinator可以高并发高可靠的主要原因。
当然Coordinator节点接受操作后,它会把请求转发给真正的副本存储节点,也叫Replica node。那副本节点是如何计算出来的呢?刚刚说了67号节点所负责的token范围:50~66。所以token值为59数据就会写入到67号节点了。所有节点之间它们都是通过gossip协议,可以事先就知道所有节点各自负责哪个token范围。这样的情况下,83节点(Coordinator节点)就可以把数据转发给67号节点(Replica node)。
Cassandra多副本
现在我们再来看一下存储两个副本,也就是复制因子Replication Factor为2的情况,副本节点是怎样分布的呢,看到这个图里面现在多了一层环,跟刚才比较一下的话,现在对于每一个token范围,都会有两个节点负责。比如说67号节点,它还是负责token范围为50~66,但现在83号节点,它也会负责50~66,看这个图里面第二道环所有的颜色都是往下移了一位。这个浅紫色不光是67号节点负责,83号节点也会负责它了。
数据写入前
同时落到2个节点上去
如果取值为59的数据要写入集群,假设选择了17号节点(coordinator节点)来写入。刚刚说现在67号节点和83号节点同时对token范围50~66负责,那么这个写操作都会同时落到这两个节点上,它们同时成为了副本节点(Replica node)。
以此类推,当存储三份副本,复制因子Replication Factor为3时,Cassandra环(Ring)会再多一层,又往下移了一位,写操作就会同时落到三个节点上。
多副本的配置,在生产环境中应用的是非常普遍的。因为一份数据存储多份,且分布在不同节点上的话,就为数据库平稳处理节点故障的情况打下了基础。
节点故障
如果我们有一个节点故障,这个数据库会怎么样处理呢?我们还是把复制因子设成3。现在假设83号节点出现了故障停机,如果现在还是有两个节点能访问到同样的数据,这个时候如果coordinator节点收到一个新的写操作,这个写操作还是可以被转发给两个仍然在线的节点。如果是读操作,它也可以从剩下的两个节点读出数据。
数据hence的形式缓存一笔数据
如图所示,因为83号副本节点已故障,临时不能在线。17号节点作为Coordinator节点,它会以hint的形式缓存一笔 token取值为59的数据。这样的话当83号节点重新在线的时候,会有个叫hinted handoff的过程来自动把刚才83号节点离线期间没有正确写入的数据,自动重新补齐。
数据补齐
数据修复
而且Cassandra有多副本数据时,还可以实现副本间的自动修复,它会使得Cassandra数据库在节点短期故障的情况下,数据可靠性和一致性会大大提高。
总结:Cassandra的masterless这种架构,每个节点都完全平等,既可以扮演Coordinator节点,也可以扮演副本节点这个机制,使得数据的访问性能、可靠性和一致性都大大提高。
Cassandra数据库可以有好几个数据中心,非常优秀的点就是这些数据中心是可以全球分布的。如图(左)显示我们同一个数据库,有北美数据中心,也可以有欧洲的数据中心,还可以有亚太的数据中心。比如一个跨国公司,需要为全球几大洲的终端用户提供服务,这样统一的全球数据库就非常便利。比如中国用户,可以就近访问亚太数据中心,可以大大减少延迟,提高用户体验。
比如,同一个数据库跨三个数据中心,北美、欧洲、亚太部署。在写数据的同时,只需要写到北美数据中心,Cassandra有一个很高效的复制机制,自动让数据马上复制到欧洲和亚太数据中心,Cassandra原生这种数据复制,完全不需要配置和操心,没有什么复杂的ETL,也不用远程拷贝文件,都是自动化的。
再看右图,这个是混合云和多云的部署情况,我们看到这个Cassandra不管是阿里云还是亚马逊,还是google,还是自己的私有数据中心,都可以把它构造成一个Cassandra数据库,把所有这些数据中心连成一个完整数据库。
为什么这样部署很优秀?因为可以防止数据被限制在一个云服务提供商,可以自由移动,哪家的云服务价格更有竞争力就选哪一家,哪一家的服务更好就选哪一家。迁移的时候甚至完全都不用中断数据服务,在今天公有云和私有云无处不在的时代的这样的部署方式,会让这个企业的架构会更灵活和更有竞争力。
分布式系统里面,Consistency一致性、Availability可用性,还有Partition Tolerance分区容错性三者只能选二。作为分布式数据库Partition Tolerance是必选项,分布式数据库其实就是在 Consistency和Availability这两个间选一个,Cassandra其实比较重视可用性,优点在于一致性可调。客户端的每个操作都可指定Consistency Levels,通常缩写为CL,有的CL组合比如说Quorum读和Quorum写(超过半数读写成功,则返回成功),可以做到强一致性,但是也不牺牲可用性。
有不少领域的人对Cassandra的理解是有误区,他们觉得Cassandra属于AP系统,没有强一致性。其实Cassandra只是优先保证可用性,它在可用性和一致性之间是完全可调的。
Consistency Levels 一致性级别怎样定义?在生产环境里面,大部分情况下我们都会使用RF = 3,这样能让数据库在高可用、高性能之间达到最佳平衡。
一致性级别跟复制因子紧密相关。如果我们这个复制因子为3,也就是有三份副本,当一次性级别设成1(CL等于one),则1个副本确认操作成功就给客户端返回这次操作是成功的。比如说客户端,要写入一条数据,首先把写请求发给Coordinator节点,因为复制因子为3,Coordinator节点会把记录发给三个副本节点,然后这三个副本节点都会向Coordinator节点确认写入成功,可能会有先有后。但是不管是谁最先返回写入成功,Coordinator节点只有满足了一致性级别等于1的要求,这个写操作就会返回给客户端,认为是写入成功了。
但如果一定级别设成Quorum(也就是说超过半数操作成功的意思),比如复制因子是3的话,Quorum在这里就是3÷2+1,也是2。就是说三个节点,需要两个都要确认操作成功才返回成功。注意coordinator节点,仍然会同时转发读写请求给三个副本节点,这次它会等待两个节点的成功回复,然后才返回客户端这一次的操作是成功的。
注意:如果这里不是写操作,而是读操作的话,Coordinator节点会比较副本节点返回的数据,哪个数据的时间戳更新,它就会选哪个返回。这个原则也叫做last write win(最后写入者胜出的原则)。
最后我们再来看看一致性级别设成ALL这种情况,也就是说所有副本都要成功返回。Coordinator节点还是会同时转发读写请求给三个副本节点,但它需要等待所有三个副本节点都成功返回,才能跟客户端返回这一次的操作是成功的。需要指出一点,我们一般不推荐在生产环境中使用ALL这样的一致性级别,因为用了ALL以后,基本上就放弃了高可用性。因为只要有一个副本节点故障,则读写请求就会失败。如果需要高一致性,但也不想牺牲高可用性,其实是有更好方法解决,比如使用3副本,Quorum读写一致性。
既满足强一致性Consistency,也满足高可用性。强一致性的定义是只要读的一致性级别加上写的一致性级别是大于复制因子的,这样读写操作就是强一致性的。放到图里面来说,就是读和写都使用Quorum,2+2大于3(副本数)这种情况。
如果你是三个副本写入的时候,在三个副本里面成功的已经确认了两个,现在如果读操作进来的时候,不管读到的是哪两个副本,其中必定至少有一个副本,已经成功收到了最新写入的值。
我们刚才说过last write win(最后写入胜出原则),coordinator节点读的时候,只要有一个是最新写的内容,就足以使它给客户端返回最新的数据,所以Quorum级别只要是写入成功了,Quorum级别的读一定会读到最新写入的值的。
复制因子设成3,采用Quorum读和Quorum写,可以兼顾一致性和高可用性,如果你是刚刚开始使用Cassandra,这种配置是你的首选,可以避免踩很多坑。
三、应用场景
如果你有数据库弹性扩展的需求,你的数据库和数据需要高吞吐量,有大量的这种写操作和读操作,像物联网时间序列数据库这样的应用场景,使用Cassandra是一个非常完美的选择。
如果你需要数据库这种高可用性,你的应用程序是关键任务,比如像病人监护这样的场景,绝对不能有数据丢失,必须每一秒都在线,这个也是非常适合使用Cassandra做底层的数据存储。
如果你需要有这种分布式的数据库来存储数据,你希望你的数据是全球分布、自由流动,并且自动在数据中心之间复制,同时你还有合规方面的需求,比如说像欧洲的GDPR或者是中国这种个人信息安全规范的,也就是说你需要限制其中一部分数据,只能存放在某一个国家或者某个州的数据中心,这样虽然你的数据库是跨全球的,Cassandra它本身自带这样的功能,你可以很容易配置,既能符合全球分布又能做到合规。
最后从源于云源生这个角度,如果你需要开发运行在云上的应用程序,这个程序不光要运行在公有云,也要运行在私有云,或者是需要部署在多个云服务服务商之间跨云部署,Cassandra在国外是不少大的厂商会默认选择的。
在很多不同的垂直领域,像能源、金融、服务、运输、物流、媒体、电信、零售、餐饮、科技、互联网,这全球知名的品牌大公司都在使用Cassandra。还有美国黑色星期五的零售网站最大的4个网站 里面有3个在使用Cassandra来帮助它们处理峰值。全球前15的大银行有9个在使用Cassandra来处理它的关键业务。美国4大航空公司有3个在运行Cassandra。
Cassandra在各个知名公司应用场景不一样,主要有物流和资产管理、欺诈监测和风控、库存和商品名录管理、性能监测管理、实时支付、供应链管理、客户360、数字娱乐等。
2年前苹果公司分享16万台Cassandra节点,存储超上百个PB数据,有上千个集群。
像 Facebook的Instagram使用Cassandra应用案例,比较像我们的微信朋友圈,使用Cassandra存储用户他关注的所有的人新发布的信息,是百万以上级别每秒的写入操作,当然现在肯定吞吐量是更大,读延迟的要求也比较高,可以看到它平均要在20个毫秒之内成功,因为会影响终端用户的体验。这个界面你可以看到它还使用Cassandra计数器类型,来记录点赞的次数。
纽约证券交易所,每天会发生36亿手股票交易,核心系统使用Cassandra数据库的能力。特意提出来在他们部署环境里面能够scale infinitely,也就是说可以无限扩容能力对他来说是非常重要的。
像纽约证券交易所,像这么大的这种应用场景,Cassandra都能够很好的处理他们的需求。
四、趋势展望
从DataStax角度来说,现在正在设计一个面向未来的这种数据架构,当然这个核心依然是Cassandra,但是在这个基础之上,我们希望能够让应用程序的开发人员能够解放出来,让他们使用比较熟悉的数据接口。暴露给开发人员多种接口,比如GraphQL、restful接口、甚至是文档数据库接口。