- Proven: Digg,facebook,Twitter在使用
- Fault Tolerant:数据自动replicated到多个节点
- decentralized: 所有节点都是相同的
- you're in control:可以为每次的update选择同步或异步的复制
- Rich Data Model:不只是简单的key/value
- Elastic:线性的扩展
- Highly available:可调节的一致模型,从"writes never fail" -> "block for all replicates to be readable"
其他特性不必说了,分布式key/value居家必备。我最关注的是Rich Data Model,就像它自己强调的,不再是简单的Key/Value了。
浏览了相关的文档,我可以大致的描述一下。Cassandra的数据 模型可以被简单的认为是4或5维的hash。我们从下往上介绍:
最基础的是Column,由 name,value,timestamp组成,例如
{
name: "emailAddress",
value: "arin@example.com",
timestamp: 123456789
}
SuperColumn, 顾名思义,SuperColumn可以包含多个column。SuperColumn是可选的,你可以只使用最简单的column。
{
name: "homeAddress", // SuperColumn name
value: { // value就是多个column的list
street: {name: "street", value: "1234 x street", timestamp: 123456789},
city: {name: "city", value: "san francisco", timestamp: 123456789},
zip: {name: "zip", value: "94107", timestamp: 123456789},
}
}
ColumnFamily,column容器,类似数据库中表的概念。
ColumnFamily 中的每一行由key和column list组成。和数据表的最大区别是没有预定义的schema,每一行可以包含任意多个column。
UserProfile = { // this is a ColumnFamily
phatduckk: { // key
// 下面是column list
username: "phatduckk",
email: "phatduckk@example.com",
phone: "(900) 976-6666"
},
ieure: { // key
// 下面是column list
username: "ieure",
email: "ieure@example.com",
phone: "(888) 555-1212"
age: "66",
gender: "undecided"
},
}
在 Cassandra中,一个key甚至可以关联多个“表”中的同一行:
{
"mccv":{ // key
"Users":{ // Columnfamily,用户“表”
// column list
"emailAddress":{"name":"emailAddress", "value":"foo@bar.com"},
"webSite":{"name":"webSite", "value":"http://bar.com"}
},
"Stats":{ // Columnfamily,状态“表”
// column list
"visits":{"name":"visits", "value":"243"}
}
}
}
另外一个很重要的特性,同一行的column是按照column name排序的,注意,是用column name排序!Cassandra支持几种排序方式,BytesType, UTF8Type, LexicalUUIDType, TimeUUIDType, AsciiType, and LongType.在数据存储的时候已经进行了排序,所以当通过key取出column时是有序的。
key {
{name: 3, value: "101010101010"},
{name: 123, value: "hello there"},
{name: 976, value: "kjjkbcjkcbbd"},
{name: 832416, value: "kjjkbcjkcbbd"}
}
这个例子使用了LongType排序类型,按照name的升序排序。 这个特性非常有用,可以想象如果使用TimeUUIDType类型,所有的column都会按照时间排序。
Keyspaces,column families容器,对应于数据库概念的database,一般是每个应用配置一个Keyspace。
最上层是Cluster, 代表一个Cassandra实例。Cluster可以包含多个 keysapces。
简单的概括一下:
- column: a name,value and a timestamp
- SuperColumns:包含多个子columns
- ColumnFamilies: “表”,包含column和superColumn
- keyspace:“数据库”,包含多个ColumnFamilies,一般是每个 应用一个
- cluster: 逻辑实例节点,包含多个 keysapces
介绍完概念我们看一个具 体的例子是如何使用这种数据模型的。我参考的是Digg工程师写的一篇介绍,并进行了简化,感觉这样更能突出Cassandra数据模型的特点。完整的描 述可以参考后面的reference,里面还包括了一篇介绍Twitter是如何使用Cassandra数据模型的。
设想一个简单的 blog系统,可以为每篇blog指定多个tag,并可以按照时间逆序浏览每个tag的blog列表,当然也可以按照时间浏览所有blog。
首先定义一个BlogEntries ColumnFamily,标题作为key,一行代表一篇blog,用逗号分隔表示多个tag,很好理解:
BlogEntries : { // ColumnFamily
i-got-a-new-guitar : { // key,blog标题
title: This is a blog entry about my new, awesome guitar,
body: this is a cool entry. etc etc yada yada
author: Arin Sarkissian
tags: life,guitar,music // 逗号分隔的多个tag
pubDate: 1250558004
slug: i-got-a-new-guitar
},
// 其他blog列表
another-cool-guitar : {
...
tags: guitar,
slug: another-cool-guitar
},
scream-is-the-best-movie-ever : {
...
tags: movie,horror,
slug: scream-is-the-best-movie-ever
}
}
再来看看Tag“表”怎么定义,把tag 作为key,每一行包含了所有标记了这个tag的blog list。Cassandra中的column不像在数据库中,不需要预先定义。
TaggedPosts : { // CF
// 标记了guitar tag的blog
guitar : { // key,tag name
// 列名是TimeUUIDType类型,value对应的是BlogEntries中的key
timeuuid_1 : i-got-a-new-guitar,
timeuuid_2 : another-cool-guitar,
},
// 所有blog都列在这个特殊的tag下
__notag__ : {
timeuuid_1b : i-got-a-new-guitar,
timeuuid_2b : another-cool-guitar,
timeuuid_2b : scream-is-the-best-movie-ever,
},
// 标记了movie tag的blog
movie: {
timeuuid_1c: scream-is-the-best-movie-ever
}
}
我们把列名定义为TimeUUIDType类型。记得前面提 到过,Cassandra是按照列名来排序的,TimeUUIDType就是按照时间来排序的。那么我们通过tag取出的blog列表自然就是按照时间排序的了。Cassandra的api支持根据key和范围条件获取一部分的column list,类似数据库的分页,而且取出来的列都是有序的。定义了两个简单的ColumnFamily,干净漂亮的完成了需求。
可以看 出,Cassandra已经超越了简单的key/value,数据模型是相当的灵活。其核心可以概括为两句话:
1. 由key指明的每一行可以包含任意多的column
2. 每一行内的column是按照name排序的
Reference
cassandra 项目主页
http://cassandra.apache.org/
DataModel
http://wiki.apache.org/cassandra/DataModel
API
http://wiki.apache.org/cassandra/API
Digg 工程师写的DataModel介绍
http://arin.me/blog/wtf-is-a-supercolumn-cassandra-data-model
Twitter 的DataModel介绍
http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/
B2B DBA写的一篇介绍
http://www.hellodba.net/2010/02/cassandra.html
江 枫写的两篇介绍
Cassandra存储机制 http://www.ningoo.net/html/2010/cassandra_storage.html
Cassandra Commitlog http://www.ningoo.net/html/2010/cassandra_commitlog.html
Yahoo针对多个Key/Value系统的比较测试
http://www.brianfrankcooper.net/pubs/ycsb-v4.pdf
没有评论:
发表评论