读过本文才算真正了解Cassandra数据库

作者介绍
宇文湛泉,现任金融行业核心业务系统DBA,主要涉及Oracle、DB2、Cassandra等数据库开发工作 。
Cassandra数据库,值得介绍的技术细节其实挺多的 。因为它很多实现思路和关系型数据库或者其他的NoSQL数据库,是有一些不同的 。这种不同是在数据库设计实现思路上也是根源上的 。所以衍生开来的诸多特点,在介绍起来就不太容易和其他数据库去类比 。那么Cassandra有这么大量的内容,本文只能选讲其中的一部分,这部分内容是如何挑选的呢?
在《Cassandra The Definitive Guide》这本书里,有一段概括性的描述,即用50个word描述Cassandra 。它归纳了Cassandra的几大特性,依次为:开源、分布式、去中心化、可扩展性、高可用、容错性、可配置的一致性、行存储 。
我把这几大特性分为四类:

  • 第一类开源,这个不需要讨论 。其余的三类7个特性,就是选讲的核心提纲 。
  • 第二类是高可用、容错性、可配置的一致性,这是围绕着多节点冗余数据的特性,换句话说,如果Cassandra的数据,每一行数据只有一份而没有副本,那么第二类特点就是不存在的 。
  • 第三类是分布式、去中心化、可扩展性,这三个特点围绕的是数据库的可拆分性,且各节点可以独立运行的能力 。若只装一个单机的Cassandra,那这一类特点就不存在 。
  • 第四类是行存储,是描述数据库底层存放数据的最基本的存储结构特征,也是我切入的第一个特征 。
行存储结构
任何数据库设计和优化始终围绕一个核心事情——查询优化 。查询永远是使用数据的核心需求 。为什么要INSERT?为了以后这个数据要查询 。为什么要DELETE?因为不再查询,并且让其他的数据更快的查询 。为什么要UPDATE,因为要实时的查询使用 。无论是数据库的存储结构,像ORACLE的段、区、块的设计,还是辅助的存储结构,像索引这种,归根结底,为了更快速的查询出需要数据 。Cassandra也不例外,了解它的存储结构,就更加能够理解它是如何在这个存储体系下提高查询性能的,即便它是一个号称更擅长于INSERT的数据库 。
在早期的Cassandra中,数据库表一直被称之为ColumnFamily(列族),我也有很长的时间将其理解为列的集合的意思 。所以,我有一段时间认为Cassandra是一个列存储的数据库 。那为什么Cassandra的数据模型,可以认为是行存储(ROW-ORIENTED)的,但又会在早期表被称之ColumnFamily呢?因为从根本上来讲,Cassandra不能算一个严格的行存储,当然它更不是列存储,它的数据是存储在一个稀疏矩阵中的 。可能这个解释略微抽象 。那么我先来说下它为什么不是行存储 。
任何传统的行存储数据库,一旦DDL定义了数据表有多少个列 。那么这一行数据一定存储了所有的列值 。即使出现了这一列没有值的情况,那么也一定存储了一个值,或者是由应用程序存储一个空格或0来表示没有值 。这一列对应的存储空间一定是存在的,当然数据库中的varchar或者压缩算法会使得这个存储空间尽可能小 。
但是,Cassandra允许对于任何给定的行,你可以只包含其中几列,而并非一行数据要有所有的列,当然KEY列是要有的 。这种在列值存储上的动态性,是传统的行存储数据库根本不具备的 。我猜这也可能早期为何有ColumnFamily概念的根源 。
前文提到了,我有一段时间认为Cassandra是一个列存储的数据库 。但是,我从来都认为它是一个不彻底的列存储数据库,而是一个受限的列存储数据库 。不彻底在哪里?大部分的列存储数据库,都是为了OLAP而生的,它的优势在于,在某一列上做聚合的性能无语伦比 。
比如我一个表有100列,我要对某一列求个SUM 。列存储数据库可以完美绕过多余的99列,只把需要的这一列一个不差的拿出来做SUM 。但是,用过Cassandra数据库的人都知道,在任何一列上做全列级的聚合,那简直是灾难性的 。就凭Cassandra会将不同的KEY部署在不同的数据库节点/分区PARTITION(注意这里和传统数据库分区不同),任何列级的操作,都会需要在多个数据库上打转 。更何况,CQL语句到来的时候,还要搞清楚,这个聚合列在这行数据上有没有 。所以,Cassandra是不具备列存储数据库的特质的 。
读过本文才算真正了解Cassandra数据库

文章插图
为什么,最后Cassandra还是被描述为是一个ROW-ORIENTED呢?
首先,它的存储是紧紧围绕着Key的 。Key,它是一行数据的唯一标识符号 。一行数据围绕着Partition Key存在一起,并且围绕着Clusterting Key局部有序 。可见它ROW-ORIENTED的特点还是很鲜明的 。什么样的存储结构,就决定一个数据库擅长做什么 。按主键排序的行存储DB2数据库最擅长的是什么?是在OLTP系统里,通过主键做单条记录的快速查询(Select by Key),这也正是Cassandra最为常见的CQL形态 。什么样的存储结构,也决定了什么样的操作会有限制 。


推荐阅读