最近对Cassandra产生了兴趣,觉得这以后应该是个趋势,决定从今天开始翻译一些Cassandra的资料,和大家分享。
今天这篇文章的原文在:http://wiki.apache.org/cassandra/DataModel
简介
Cassandra的数据模型可以非常简单的看成是一个四维或者五维的散列表。
一些基本的概念:
- Cluster: 一个Cassandra实例里的所有机器(节点)。一个Cluster可以含有多个keyspace.
- Keyspace: ColumnFamilies的名字空间,一般来说每个应用里面有一个Keyspace.
-
ColumnFamilies: Columnfamilies包括多个column, 每个column包括一个name,一个value,一个timestamp,每个column都被一个key引用。
-
SuperColumn: SuperColumn可以看成一个可以有自己子column的column.
我们将从底向上,从Cassandra数据模型的叶子节点(column)到根节点(cluster)给大家一一介绍。
Column
Column是数据模型上的叶子节点,最底层的数据,每个column是个triplet包括name, value和timestamp. 下面是Column的Trift定义:
struct Column {
1: binary name,
2: binary value,
3: i64 timestamp,
}
下面是一个json风格的column实例:
{
"name": "emailAddress",
"value": "foo@bar.com",
"timestamp": 123456789
}
所有的数值(name, value, timestamp)都由客户端提供,这意味着所有的客户端的时钟必须同步,因为timestamp要用来进行冲突检测。在许多情况下,客户端并不使用timestamp字段,所以为了方便起见,我们可以把column看成name/value对子。在这篇文章的其余部分,为了可读性的考虑,我们将省略timestamp。值得一提的是,name和value的类型是binary, 虽然在许多应用里面他们是UTF-8编码的字符串。
ColumnFamilies
ColumnFalimies是一个Column的容器,和关系型数据库里面的table对应。你可以在你的storage-conf.xml里面定义ColumnFamilies,并且不能修改或者添加新的ColumnFamilies,除非重启Cassandra进程。一个ColumnFamily包含一个排序的column列表,你可以column的名字得到这些column。
ColumnFamily里面一个row里面的column的顺序是可以配置的,而这个顺序会影响Thrift API里面get_slice的行为。现在支持以下几种排序方式:ASCII, UTF-8, Long, and UUID (lexical or time).
Rows
在Cassandra里面,每个ColumnFamily保存在一个单独的文件里面,而这些文件里面内容的存贮顺序是以每个column的key来进行排序的。那些你要同时访问的,相关的column,最好放在同一个ColumnFamily里面。
每一行的key决定了对应的数据。所以,对于每个key,可以在多个ColumnFamily里面都有对应的数据。
然而,这里有一些逻辑上的不同,这也是Thrift API为什么被设计成每次只读取一个ColumnFamily.
下面是一个key -> column families -> column的JSON表示的结构:
{
"mccv":{
"Users":{
"emailAddress":{"name":"emailAddress", "value":"foo@bar.com"},
"webSite":{"name":"webSite", "value":"http://bar.com"}
},
"Stats":{
"visits":{"name":"visits", "value":"243"}
}
},
"user2":{
"Users":{
"emailAddress":{"name":"emailAddress", "value":"user2@bar.com"},
"twitter":{"name":"twitter", "value":"user2"}
}
}
}
注意,key: mccv在两个ColumnFamily里面有数据: Users和Stats,这并不表明这两个ColumnFamily里面的数据有关系, 到底有没有关系,是什么关系由具体的应用决定。再要注意的是在同一个ColumnFamily Users里面mccv, user2有不同column,这是Cassandra所允许的. 实际上可能有无限个可能的column名字列表 -- 这个特性可以使我们在运行时在决定column的名字列表。这个和通常的存贮系统,特别是关系型数据库是很不同的。
Keyspaces
Keyspace是Cassandra数据模型散列表里面的第一维,是ColumnFamily的容器。简单的说,Keyspace和关系型数据库里面的Database是同一个粒度。我们通过Keyspace来对ColumnFamily进行配置和管理,Batch insert就是在keyspace这个层面上进行的。
Super Column
到目前为止,我们讨论过了普通的行和列。Cassandra还支持一种Super Column: 这种Column的值是个Super Column, 也就是说一个Super Column是一个有序的Column的列表。来看个例子:
{
"mccv": {
"Tags": {
"cassandra": {
"incubator": {"incubator": "http://incubator.apache.org/cassandra/"},
"jira": {"jira": "http://issues.apache.org/jira/browse/CASSANDRA"}
},
"thrift": {
"jira": {"jira": "http://issues.apache.org/jira/browse/THRIFT"}
}
}
}
}
在这里, 我的ColumnFamily是Tags, 定义了两个Super Column: cassandra和thrift, 而在这每个里面我们定义了一些书签。和普通的Column一样,Super Column是稀疏的:每一行可以包含尽可能多或者尽可能少的列,Cassandra对这个不作限制。
<未完...>