\\关键点
\
- 了解关于Cassandra NoSQL数据库3.0版的功能; \
- 如何安装和配置Cassandra数据库,包括集群管理; \
- Cassandra数据库的数据模型(概念、逻辑和物理方面); \
- Cassandra提供的数据分区和复制策略; \
- 如何实现认证安全、授权和加密;
由Jeff Carpenter和Eben Hewitt合著的《Cassandra权威指南》第二版,讲述了Cassandra NoSQL数据库3.0版的内容。\
作者们讨论了与这款流行数据库相关的几个重要话题,包括数据建模(概念、逻辑和物理模型)以及Cassandra架构细节,还有一致性级别、分区器和复制策略等。文中也分析了跨数据中心的Cassandra数据库集群高可用问题。读者们可以了解如何安装并配置Cassandra,包括如何创建一个Cassandra集群。作者们还用专门的章节讨论了监控和运维方面的内容,这些将在Cassandra数据库程序部署到生产环境之后发挥关键作用。\
InfoQ就本书的第二版,以及Cassandra数据库当前的功能和未来的规划等问题采访了Jeff Carpenter。\
InfoQ:您为什么决定写这个版本呢?自从这本书的第一版完成之后,现在已经过去6年了。\
\\Jeff Carpenter:Eben Hewitt在2010年写的第一版是关于Cassandra的第一本书。因为它主要是针对0.7版的,因此许多后续的功能,比如Cassandra Query Language(CQL)等都压根没有提及。这本书现在仍然享有非常好的口碑,因为它对核心的理念和架构讲得非常好,但它已经和最新的技术脱节太久了,里面包括着许多过时的词汇(列簇、超列簇等)和实现细节(比如Thrift接口)。因为这本书的核心理念还是讲得非常好的,所以我的任务基本上就是保留第一版的优点,同时把变化了的东西更新。
InfoQ:大家有时候会有困惑,Cassandra该属于哪种NoSQL数据库类型呢?键值型、列存储或是表格型?您能试着讲讲Cassandra该属于哪种类型吗?\
\\Jeff Carpenter:这个问题在Apache的Cassandra社区里每隔一段时间就会讨论一遍。渐渐地比较为大家所接受的是一个组合词:分区型行存储。这表明Cassandra是按行保存数据的,并且会把数据映射到不同的分区中。这些分区按照一定的复制策略分布在多个不同节点之上,而且分区也决定了每个节点上存储的数据的主键范围。对每行数据的存储是分散的,也就是说只有那些保存着数据值的Cell才会被保存。
InfoQ:Cassandra 3.0版与以前版本相比,有什么有趣的新功能吗?\
\\Jeff Carpenter:Cassandra 3.0版与之前版本相比,有一个大飞跃。主要的新功能包括物化视图,以及被称为第二附加存储索引(Secondary Attached Storage Index,SASI)的新索引实现。特别是物化视图的功能非常棒,它可以让Cassandra节点维护非标准化的视图,而在此之前,这样的功能要靠客户端程序去做。\
在以前,Cassandra用户对数据模型的设计比较赞成查询为先。要用这种方法的话,就要先整理出所有要用到的查询操作,然后为每种查询操作创建一张表。比如说,我创建了一张根据确认号来存储酒店预订信息的表。然后不久,我又想通过宾馆名和日期来查询预订信息。在3.0之前,我就要为了支持这个查询操作而再单独创建一张表,用一个不同的分区键。这么做工作量很大:需要把数据迁移到新的表中,还要改持久化程序来保证这些表之间的数据是同步的。而且最重要的是,项目所需要的存储空间会翻倍。\
有了Cassandra 3.0,现在我可以在我的表“reservations_by_confirmation_number”上创建一个物化视图,来支持这种新的访问模式。Cassandra通过底层的表来保证视图数据的更新,而且做这事的效率也远比外部程序更高。\
为支持物化视图的实现,这个版本的底层也做了许多关键改变。Cassandra的底层存储引擎和SSTable文件格式全都重新改写了,这样才能更方便地通过SQL来展示数据,同时还带来了许多其它好处,比如更好的读写性能和更少的存储空间等。\
我对SASI索引的功能非常满意。从0.7版之后Cassandra就支持第二索引功能了,但要使用这功能有很大的性能问题,因为通过第二索引查询数据通常要涉及集群内的所有节点,然后才能通过索引定位到相关的数据项。SASI索引是一套新实现,它的性能比原有的第二索引实现性能好得多,因为索引数据是存储在每个SSTable文件里面的,而不是像旧的实现一样存储在独立的“隐藏”表里。更重要的是,SASI索引支持LIKE关键字,可以用它来做部份文本匹配查询操作。但要做全功能的搜索,还是要借助于SOLR之类的引擎,不过现在已经是向前迈了一大步了。
InfoQ:您能谈谈Cassandra提供的分区和复制功能吗?以及与其它的NoSQL数据库相比,它们有什么不同?\
\\Carpenter:选定的分区和复制策略会决定你的数据存储在哪些节点上,所以一定要注意每个选项的功能和影响。\
分区器实际上就是基于分区键字段的哈希函数,由此生成名为令牌的值。可能的令牌值的集合组成一个环,Cassandra会把可能的令牌值分配到集群里的不同节点上。分区器生成的令牌值是用来标识存储相应数据的主节点的。默认的分区器是Murmur3Partitioner,这是个随机分区器。另外还有有序分区器。有序分区器的目的是为了能把存储相似主键的分区尽可能地分配到相同节点上,以此来提升范围查询的性能。但在实践中,这个好处抵不过数据在集群内分布不均衡的缺点,因为在某些节点上存储的数据记录数可能会远超其它节点。因为这个原因,而分区器又是整个集群范围内的设置,所以大多数情况下大家还是会用默认的分区器。\
分区器生成的令牌会决定每个相应的分区存储的主节点,同时我们还要决定要保存哪些额外的数据副本。这就是存在复制策略的原因。用得最多的策略就是SimpleStrategy和NetworkTopologyStrategy。SimpleStrategy主要用于单个数据中心的部署,用户提供一个值,名为复制因子,意思是数据需要保存多少份(多少个副本),剩下的事交给Cassandra就好了。NetworkTopologyStrategy主要用于多个数据中心的部署,采用这个策略时,需要为每个数据中心都指定一个复制因子。\
与MongoDB之类的其他NoSQL数据库的主要不同在于,Cassandra的每份数据副本都是被平等对待的,而不是有主和备。平台的可伸缩性也非常重要。Cassandra的开发者们为此做了很多努力,为分区器和复制策略提供了可插拔式API,以及许多其它核心算法,从而可以让社区来扩展并改进这个平台。
InfoQ:Cassandra支持可调节的一致性功能。您能把这一点与强一致、以及最终一致性模型等比较一下吗?\
\\Carpenter:可调节的一致性功能是个特别强大的功能,所以大家一般并不是非常了解。比如,是完全可以在Cassandra里实现强一致性的,主要是看您对读和写使用怎样的一致性级别。公式“R + W \u0026gt; N”常用于描述这个是怎么实现的。在这个公式里,R和W分别是由所用的一致性级别决定的要读和写的节点数。N是复制因子。实现强一致性的最常见的办法就是对读和写使用QUORUM一致性级别,QUORUM常被定义成一个大于半数节点的数字(有3个节点就把QUORUM设成2,有4个节点就设成3,5个节点就设成3,等等)。\
如果能允许最终一致性,那也可以用相对宽松的一致性级别,以此来获得更高的读或写速度。在使用较低的一致性级别时,就有可能在刚完成写入之后数据还没有复制到其它副本之上,因此在一定时间间隔内你读不到最新的数据。比如,要在一个物联网应用程序中尽可能快地写入传感器数据,你就要使用ONE甚至ANY的一致性级别,这样只要有任何节点在它的提交日志中记下了这个写操作,就可以立即返回。这种情况是可以接受的,特别是在你的程序并不需要实时地从Cassandra中读取传感器数据时。\
因为每次Cassandra调用都可以使用自己的一致性级别,所以你有很高的灵活性。比如,如果我用Cassandra来跟踪某类库存,我可能会在货物快要卖光时提高我的查询的一致性级别,这样来保证不会超卖。
InfoQ:Cassandra可以在数据库中保存图片文件吗?开发项目时如果要在Cassandra中保存图片和其它二进制类型数据,有什么要考虑的吗?\
\\Carpenter:保存二进制数据当然是Cassandra支持的用例。比如,巴西的Globo TV公司提供了Globo Play服务,这是一套有类似DVR功能的流视频系统,曾在2014年为FIFA世界杯,以及许多次国家大选提供服务。GLobo的工程师们曾就他们基于Cassandra构建的系统分享过几篇文章和讲座,我在这里简单总结一下。\
成功保存二进制数据的关键在于保证文件尺寸不能过大。对此的推荐作法是把大二进制对象拆成多块,因此可以保存到不同的分区中。使用固定的块大小可以保证每个分区中的数据大小相同,因而保证集群的平衡。\
这种方法能不能用在你的项目中,取决于你要支持的访问模型。在Globo的用例中,他们的客户端程序所要支持的DVR功能,比如可以暂停视频、回头恢复到之前看过的位置、或者直接跳到想看的位置,等等,都非常适合使用这样的解决方案。\
当然,如果不需要有灵活性可以快速访问二进制内容的分片,一个更简单的设计方法就是把二进制数据保存在外部文件存储中,比如亚马逊S3。然后,用Cassandra来保存和获取每个二进制文件的元数据就可以了。
InfoQ:Cassandra在安全和监控方面提供了哪些功能?\
\\Carpenter:Cassandra通过JMX(Java Management Extensions)来提供了非常丰富的指标和控制方法,可以通过JConsole等标准JMX客户端访问。Nodetool是Cassandra的标准命令行工具,它也通过JMX提供了针对单个节点的监控和维护功能。\
在集群级别支持监控功能也有很多办法。如果你用的是DataStax Enterprise(DSE)分支,OpsCenter提供了对集群状态和指标的非常好的可视化功能,以及修复和备份等关键操作的自动化。如果你用的是Apache Cassandra分支,我建议通过JMX来从Cassandra节点中获取指标,并输入KairosDB(基于Cassandra构建)之类的指标数据库,然后就可以用Grafana之类的工具来构建仪表盘了。我们用这种方法有着很多成功案例,因为在我们的环境中可伸缩性是识别关键指标的关键所在。\
缺乏安全功能是许多早期NoSQL数据库的弱点之一,包括Cassandra。不过,经过最近几年的发展,情况已经大为改观。现在Cassandra在“客户端-节点”以及“节点-节点”之间的通信中支持认证和加密了。另外,也可以在主键空间以及表级支持基于角色的访问控制。Apache Cassandra的文件级加密功能还在开发中,因为要处理的文件类型很多(SSTables、提交日志、提示和索引等),这是个由DSE提供的功能。
InfoQ:你能谈谈跨多个数据中心的Cassandra集群吗?Cassandra集群有什么好处和不足?\
\\Carpenter:Cassandra集群的主要优势之一在于,数据跨多个数据中心分布是它的核心设计之一,而其它数据库要依赖的后台复制机制都是后面才加上去的。也就是说,像修复之类的操作就需要详细的计划和调节。跨多个数据中心构建集群时,要注意考虑数据中心之间的网络状况,配置超时时间。如果预算允许,我建议使用数据中心间的专用高速连接。还要考虑应用程序访问数据时,本地和集群范围内的一致性级别之间的权衡,即LOCAL_QUORUM和QUORUM。
InfoQ:哪些开发工具可以让开发者开发基于Cassandra的应用程序时提高生产率?\
\\Carpenter:开发者应该熟悉几个工具来做数据建模、程序开发和测试。\
依我的经验,许多至关重要的决定都是连一行代码都还没写,就依据数据模型做出来了。这就是为什么一定要对Cassandra的数据建模原理有深刻理解的原因所在。也正是由于这个原因,我们在O'Reilly的网站上将书中的数据建模这一章免费发布出来了。\
就用不同方法来做数据建模和实验来说,我推荐DataStax DevCenter。DevCenter是个免费工具,可以让你在运行中的集群上设计模式并执行查询。它是基于Eclipsse IDE平台构建的,所以它的布局和语法高亮规则等对众多开发者来说应该是非常熟悉的。Cassandra的CQL Shell(cqlsh)提供了非常棒的交互式体验,我发现它的语法高亮和保存常用命令的能力可以极大地提高工作效率。它默认也会跟踪所有查询语句,并提供不错的表格式报告来帮你分析日志。这些对于帮助开发者学习Cassandra在底层是怎么工作的,以及避免会导至性能差的跨分区查询等反模式行为非常重要。\
这也有助于让你在还没有对一个特别的设计付出过多代价时,就了解你的数据模型在上了规模时会表现如何。我建议使用Cassandra自带的压力测试工具,来生成模拟的读写压力。但这个工具的不足在于对比如UDT(User Defined Types)之类的比较复杂的CQL元素支持不够,但你还是可以用它来获得一些不错的结论。\
就写应用程序代码来说,你也会想要有好用的库。以前有许多用不同语言写成的Cassandra客户端库,是由不同的人写成的,各自带有不同的功能集。最近几年,DataStarx的开源客户端库开发进行得非常活跃,对Apache Cassandra和DSE分支提供了对许多常用语言的支持。\
对于测试,用Python实现的Cassandra Cluster Manager(CCM)是个非常不错的工具,可以在你的本地服务器上运行起最小配置的集群。这对于单元测试和尝试不同的参数设置是非常有用的。
InfoQ:你能谈谈Cassandra与Spark、ElasticSearch和Solr等技术的整合吗?\
\\Carpenter:因为有多种语言的存在,我们现在可以不断地看到技术朝着更复杂的架构方向发展的趋势,也就是说,会根据不同种类的数据需求来使用不同的数据库去构建系统。因为Spark可以从Cassandra以及其它多种数据源整合数据,所以现在很吸引大家眼球。Datastax Enterprise(DSE)就提供了与Spark、Hadoop和SOLR等的整合功能,你也可以自己做类似的事。\
我最近在做的一个挺不错的案例,就是在Cassandra、Elasticsearch和Kairos DB的基础之上使用Spark。我们可以实现一些有趣的实时分析任务来把运营数据与日志和指标数据结合在一起,了解系统行为。这只是通过整合多种大数据技术来实现的一个实时分析类案例而已,当然还可以实现更多。
InfoQ:您觉得把Cassandra NoSQL数据库与其它的新兴技术,比如微服务、还有Docker之类的容器技术一起使用怎么样?\
\\Carpenter:微服务架构有个基本原则,就是一个服务只做一件事。由此可以推理出每个服务都会对自己的数据拥有独占权。有许多不同的方法来加强这种独占权。比如在有可能上规模时,像Netflix之类的大公司会为每个服务建立专门的集群。我们大多数人都不会构建那么大的系统,而让多种微服务共享集群是更现实、经济的方案。如果你也是这样,我建议你为每种服务使用独立的Keyspace,用Cassandra的基于角色的权限控制机制来保证,每个服务都只访问它自己的Keyspace(管理员访问除外)。如果你要处理涉及多种数据类型的操作,你可以创建另外的微服务来将管理那些数据类型的微服务组合起来,或者用异步架构来完成这些操作。\
关于容器化部署,我觉得还有些网络上的难题要处理,但已经有所进展。当你需要快速上线或下线集群时,也许里面还需要有些数据,我觉得容器化的Cassandra比较适合。如果你希望容器化集群中的数据能保留下来,我建议你把提交日志和数据文件都保存在外部存储。
InfoQ:Cassandra还有什么现在没有,但你希望将来会有的功能?\
\\Carpenter:我对现有的功能集已经非常满意了,而且我也刚开始用上3.0的功能。我们的确有的时候会发现有些SQL支持的语句在CQL中不支持,但也有很多办法可以解决。\
我觉得配置和管理Cassandra的学习曲线才是个大问题。最近ThoughtWorks Technology Radar发表了一篇挺有趣的简短声明。他们说因为Cassandra运维复杂,所以建议大家远离Cassandra,除非你有的确需要用上上百个节点乃至更多的集群。我虽然不会按声明所说的做,但我也的确对大家用Cassandra的过程中碰到的挫折而表示遗憾,这里面还有很大空间可以改进。比如,假如有些手册可以指导大家配置、监控和调节集群的过程就好了。默认的配置已经很好用了,但可能我们还要再开发些配置模板,这样可以方便大家使用更多的部署模式。\
我在社区中发现有许多不错的项目,在开发一些开源工具来将这些复杂的运维工作自动化。比如,修复是Cassandra维护数据一致性的重要功能。修复任务在节点上做为后台任务运行,有许多选项可用,这些对于新用户来说很困惑。Cassandra Reaper是一个可以将修复任务自动化的工具。原始版是Spotify,还有一个派生版。我希望将来类似这样的工具可以被整合到Apache的分支中。\
现在还有种趋势来减轻Cassandra的运维复杂度,就是出现了一些供应商,他们开始将Cassandra做为一种服务提供给大家。像Instaclustr和DataScale(最近被DataStax收购了)这些公司都为基于云、自建或混合型的部署提供了许多不同的部署和管理方法。让别人把管理集群的任务承担起来,这看起来太有诱惑性了,特别是对于那些小型或初创公司来说,这样他们可以专注于实现核心业务价值。
Jeff也谈到了社区对Cassandra数据库的支持情况。\
Cassandra一直都是Apache最活跃的项目之一,而且开发者社区也非常热心。最近几个月最令人备受鼓舞的变化之一,就是DataStax在加大了对Apache项目的管理和实现工作的参与度之后,社区也给予了积极的响应,包括The Last Pickle这样的小咨询公司,以及Apple和Netflix这样的行业巨头。由开源社区和商业公司这两方面可以看到贡献者的多样性,这也可以不断地证明Cassandra的重要性和繁荣发展。\
Jeff Carpenter是一位软件和系统架构师,对于服务业和国防工业有着丰富经验。Jeff在Service-Oriented Architecture(SOA)时代的早期就已经开始担任架构师,经历的项目从苛刻网络环境中复杂的战斗规划系统,到基于云的酒店预订系统,领域非常广泛。Jeff非常热衷于那些可以改变整个行业的技术,并且愿意帮助受困的项目找到解决方案,以及教授其他的架构师和开发者等。
\阅读英文原文:Cassandra: The Definitive Guide, 2nd Edition Book Review and Interview