目前考虑的分布式数据系统架构主要是cassandra以及由阿里开发的基于mysql的mycat。我们先来比较cassandra与mycat两种数据库集群技术的特点。
Cassandra是由一些平等的数据存储结点组成的集群,而mycat是普通主从mysql集群的扩充,形成了多个主从的架构。
数据分布
Cassandra:
数据实际由key-value对组成,key分为两部分,分区key以及聚集key,分区key根据某种函数运算,将不同的数据映射到集群中的不同结点,而每个结点中的数据是按棸集key来排序的。
Mycat:
根据某一列的值将数据映射到不同的主从集群中。
数据模型
Cassandra:
1.根据key来查询数据
2.根据二级索引来查询数据,如果结果数据过多,二级索引可能会跨多个不同结点,性能会有问题,二级索引不应该作为常规方法来使用。
或者在加上主键索引的条件下再使用二级索引是没有什么问题的,这只会在一个结点上进行操作
3.只能根据聚集key进行排序
4. 支持有序集合,无序列表,map等数据结构,但这些数据结构能存储的数据量有一个很小的限制(64K),不能作为常规方法使用。
5. 能灵活的增加列而不影响线上操作
6. limit语句不支持offset,这对分页来说很不方便
Cassandra底层采用sstable数据结构实现,所能进行的操作也是极为有限的,一个cassandra表结构往往只能满足一种查询模式,多个查询模式需要多个不同的表,进行一定数据冗余。
Mycat:
由于mycat底层由mysql来实现,所以能实现mysql所能进行的大部分操作,但因为分布式集群的原因,有些操作需要mycat进行合并处理,跨结点的操作是有性能问题的,所以mycat可以说退化为和cassandra一样,每种表结构或者分区方式只能很好的满足一种查询模式,所以mycat在这方面对于cassandra来说并没有什么特别大的优势。
集群管理
Cassandra :
1. 各结点根据划分规则平分数据,结点间没有主从之分,完全平等。
2. 数据有备份(数据复制),也可以设定备份的因子以决定有多少个备份
3. 结点故障检测及恢复
4. 数据分区采用一致性hash,在结点减少与添加时可以最少程度减少数据的移动,另外通过添加虚似结点,可以在扩充集群里不移动数据。
5. 集群性能随集群结点的增加而线性提高,结点间的数据会重新平衡
6. 集群可以跨数据中心
Mycat:
也可以检测到机器的失败并进行主从切换,但整个集群管理的方便性及可扩展性是不如cassandra的。
性能
Cassandra:
Cassandra底层采用sstable实现,读数据时对磁盘上的数据有索引,所以读取很快,而写数据时是先写入内存然后周期性将内存中的数据持久化到磁盘上,写性能也很高。
Mycat:
基于mysql,是针对磁盘的读与写,所以性能从理论上讲会比cassandra会差很多。
事务及数据一致性
Cassandra:
1. 不支持事务
2. 数据一致性是可以调整的,比如调整成强一致性。写数据的时候,在写完主结点后,对备份结点可以采用同步或异步的方式进行同步,同步的个数是可以调整的,但同步也会影响写性能。 读数据时可以调整从多少个结点中读取数据并选择一个最新的数据。
3. 利用commit log保证集群结点重启后数据不丢失
Mycat :
支持事务,但是最终一致性,不可以调整
cassandra的CQL虽然跟sql有点类似,但所能进行的操作是极为有限的,以网站评论功能为例:
评论的主要操作:
1. 添加评论
2. 分页查询评论
3. 删除评论
4. 举报评论
5. 为评论点赞
可以抽象为三大类操作:
1. 添加一条新评论数据
2. 根据文章id查询某一页的评论数据并按时间排序
3. 对单条评论进行查询或者处理
根据操作我们假设创建如下的表结构:
CREATE TABLE POST(
post_id timeuuid, //评论id
thread_id uuid, // 主题id
status int // 评论状态,作说明用
create_time int // 创建时间
.... //其它字段
PRIMARY KEY (thread_id, post_id )
);
CREATE INDEX ON POST(status);
我们以thread_id作为分区key,post_id作为聚集key,只能按如下CQL进行查询:
select * from post where thread_id= xxx order by post_id desc limit xxx.
CQL并不支持如下按status筛选后排序,即使在status上加上了二级索引,如下所示:
select * from post where thread_id= xxx and status = xxx order by post_id desc limit xxx.
会报告如下错误:
InvalidRequest: code=2200 [Invalid query] message="ORDER BY with 2ndary indexes is not supported."
所以基本上cassandra还是只能作为key-value存储来用,不能进行复杂的关系运算来替换掉mysql。