构建cassandra数据库



我对卡桑德拉一点都不了解。比如说,我有一个类似于Facebook的网站,人们可以在那里分享、点赞、评论、上传图片等等

现在,比方说,我想得到我朋友们做过的所有事情:

  • 用户名1喜欢你的评论
  • 用户名2更新了他的个人资料图片

依此类推。

因此,经过大量阅读,我想我需要为每一件事创建新的Column Family,例如:user_likesuser_commentsuser_shares。基本上,任何你能想到的,即使在我这样做之后,我仍然需要为大多数列创建二级索引,这样我就可以搜索数据了?即便如此,我怎么知道哪些用户是我的朋友呢?我需要先获取我所有朋友的id,然后在所有列族中搜索每个用户id吗?

EDIT好的,所以我读了更多的书,现在我对事情有了更好的理解,但我仍然无法真正弄清楚如何构建我的表,所以我会设置奖励,如果我想按这种顺序存储和检索数据,我想得到一个关于我的表应该是什么样子的清晰示例:

  • 全部
  • 喜欢
  • 评论
  • 收藏夹
  • 下载
  • 股份
  • 消息

所以假设我想检索我所有朋友或我关注的人最后上传的十个文件,这就是它的样子:

John uploaded song AC/DC - Back in Black 10 mins ago

评论和分享之类的每一件事都会类似。。。

现在,最大的挑战可能是将所有类别的最后10件东西放在一起检索,所以列表将是所有东西的混合。。。

现在我不需要一个完整详细表格的答案,我只需要一些非常清楚的例子,说明我将如何像在mysql中使用joins那样构建和检索数据

使用sql,可以构造表以规范化数据,并使用索引和联接进行查询。使用cassandra,您无法做到这一点,因此您需要构造表来为查询提供服务,这需要去规范化。

你想查询你的朋友上传的项目,一种方法是每个用户没有一个表,每当该用户的朋友上传东西时,就写到这个表中。

friendUploads { #columm family
userid { #column 
timestamp-upload-id : null #key : no value
}
}

例如,

friendUploads {
userA {
12313-upload5 : null
12512-upload6 : null
13512-upload8 : null
}
}
friendUploads {
userB {
11313-upload3 : null
12512-upload6 : null
}
}

注意,上传6被复制到两个不同的列,因为上传6的人是用户a和用户B的朋友。

现在,要查询好友的好友上传显示,请在userid列上执行限制为10的getSlice。这将返回按关键字排序的前10个项目。

要将最新项目放在第一位,请使用反向比较器,在较小的时间戳之前对较大的时间戳进行排序。

此代码的缺点是,当用户A上传歌曲时,您必须执行N次写入操作来更新friendUploads列,其中N是用户A的朋友人数。

对于与每个时间戳上传id键关联的值,您可以存储足够的信息来显示结果(可能在json blob中),也可以不存储任何信息,并使用上传id获取上传信息。

为了避免重复写入,您可以使用类似的结构

userUploads { #columm family
userid { #column 
timestamp-upload-id : null #key : no value
}
}

这将存储特定用户的上载。现在,当想要显示用户B的朋友的上传时,您必须执行N个查询,用户B的每个朋友一个查询,并将结果合并到您的应用程序中。查询速度较慢,但写入速度较快。

最有可能的是,如果用户可以有数千个朋友,你会使用第一种方案,并进行更多的写入,而不是更多的查询,因为你可以在用户上传后在后台进行写入,但查询必须在用户等待时进行。

作为一个非规范化的例子,看看twitter rainbird在一次点击时写了多少字。每次写入都用于支持单个查询。

在某些方面,您"可以"将noSQL视为关系存储。在其他情况下,您可以取消规范化以使事情更快。例如,PlayOrm的@OneToMany存储了许多类似的

user1 -> friend.user23, friend.user25, friend.user56, friend.user87

这是宽行方法,所以当你找到你的用户时,你就拥有了他朋友的所有外键。每一行可以是不同的长度。你也可能存储了一个反向引用,这样用户可能会引用那些将他标记为朋友的人,但他没有将他们标记回(我们称之为好友),所以你可能有

user1 -> friend.user23, friend.user25, buddy.user29, buddy.user37

请注意,如果设计正确,您可能不需要"搜索"数据。也就是说,使用PlayOrm,您仍然可以执行可伸缩SQL和连接(您只需要弄清楚如何对表进行分区,使其可以扩展到数万亿行)。

一行可以有数百万列,也可以只有10列。实际上,本月我们正在更新PlayOrm和noSQL模式中的许多文档,因此,如果您关注这一点,您也可以在那里了解更多关于一般noSQL的信息。

院长

将每个DB查询视为对另一台机器上运行的服务的请求。您的目标是尽量减少这些请求的数量(因为每个请求都需要网络往返)。

与RDBMS范式的主要区别在于:在SQL中,通常使用联接和二级索引。在cassandra中,联接是不可能的,因为相关数据将驻留在不同的服务器上。像物化视图这样的东西在cassandra中也用于相同的目的(通过单个查询获取所有相关数据)。

我建议阅读这篇文章:http://maxgrinev.com/2010/07/12/do-you-really-need-sql-to-do-it-all-in-cassandra/

并探讨twissandra样例项目https://github.com/twissandra/twissandra这是你描述的那种项目的优化技术的很好的集合。

最新更新