在正式的了解Cassandra之前,有必要了解下Cassandra的存储模式,即Column-based存储模式。典型的
NoSql按数据存储方式主要分为三类:
当然 Key-Value,Document-based以及Column-based实际上是对NoSQL数据库的一种较为泛泛的分类。不同的数据库提供商所提供的NoSQL数据库常常具有略为不同的实现方式,并提供了不同的功能集合,进而会导致这些数据库类型之间的边界并不是那么清晰。
在存储结构上区别于行存储模式,行存储模式就是我们传统意义上使用的关系型数据库,例如Mysql、SqlServer,这类数据库是按照行来组织数据的,而列存储模式就是按照列来组织数据的(图片来源)
行式存储下一张表的数据都是放在一起的,但列式存储下都被分开保存了。那么问题来了,为什么我们要按列模式组织数据呢?这个就需要按照性能对比和需求来源来讲了。简单来说,如果我们需要读取一条记录信息,那么按照行存储模式从磁盘里找到偏移量然后进行连续读取就可以了,但是如果有一种聚合计算的场景,例如说我们想把上表中的Quantity做sum计算:
这只是个简单例子,下边举一个具体的例子来详细区分二者。
以下部分内容来源于(example来源)对于这样一组数据,我们来分别看看列存储和行存储的使用对比,突出下列存储的优势:
[
{
"author": "Alex",
"publish_time": 1508423456,
"like_num": 1024
},{
"author": "Bob",
"publish_time": 1504423069,
"like_num": 65
},{
"author": "Casey",
"publish_time": 1512523069,
"like_num": 109
}
]
如果想要完成这样一种场景,写入数据到数据库中,并计算所有人的like_num,并且假设磁盘一次读取3个方块。那么操作方式是什么呢?
首先需要把数据写入到数据库中,这个过程中Row-base模式获胜:
如果按照列模式组织的话,应该是如下方式的连续写入磁盘中的【注意,磁头不一定是连续的】
总体而言,行存储模式在写入的时候速度更快,数据完整性能得到保证。
行存储的写入是一次完成。如果这种写入建立在操作系统的文件系统上,可以保证写入过程的成功或者失败,数据的完整性因此可以确定。
列存储由于需要把一行记录拆分成单列保存,写入次数明显比行存储多(意味着磁头调度次数多,而磁头调度是需要时间的,一般在1ms~10ms),再加上磁头需要在盘片上移动和定位花费的时间,实际时间消耗会更大。所以,行存储在写入上占有很大的优势。
数据修改时:这实际也是一次写入过程。不同的是,数据修改是对磁盘上的记录做删除标记。行存储是在指定位置写入一次,列存储是将磁盘定位到多个列上分别写入,这个过程仍是行存储的列数倍。所以,数据修改也是以行存储占优。
总而言之,写入时行存储模式的关系型数据库更占优。
按照需求,需要把对应的blog数据的点赞数获取出来进行统计和聚合。
Row-based存储模式,在那么读取的时候需要连续取出所有数据,因为为了缩短处理时间,我们一般不会在磁盘里做数据过滤,而是把数据都读到内存里来。
那么行存储模式下,需要进行3次IO读取,然后对like_sum列做计算
Column-based存储模式读取的时候只需要一次IO读取即可。
总体而言,行存储模式在读取的时候速度更快,没有数据冗余、容易解析、方便压缩能得到保证。
总而言之,读取时列存储模式的关系型数据库更占优。
综合上边读取和写入的考量,可以综合确定两种模式的优缺点以及他们的适用场景:
行存储的写入是一次性完成,消耗的时间比列存储少,并且能够保证数据的完整性,缺点是数据读取过程中会产生冗余数据,如果只有少量数据,此影响可以忽略;数量大可能会影响到数据的处理效率
列存储在写入效率、保证数据完整性上都不如行存储,它的优势是在读取过程,不会产生冗余数据,这对数据完整性要求不高的大数据处理领域,比如互联网,犹为重要。
这个时候就需要看具体的使用场景了,首先明确两类系统:OLTP和OLAP,他们需要的是不同的数据库。
关于二者的区别可以参照这篇文章:
https://www.jianshu.com/p/b1d7ca178691
在OLTP中建议使用传统的关系型数据库,在OLAP中建议使用列式存储的数据仓库,例如Cassandra:
了解了需求和存储模式后下篇blog介绍Cassandra的数据结构,看看它是如何在保障列式快速读取的优势下又兼顾写数据的速度。