Cassandra- UserProfilie的数据建模

时间:2015-03-31 09:56:30

标签: cassandra

我是一个用户模型,具有以下属性: -

class User(Model):
    user_id = columns.Integer(primary_key=True)
    username = columns.Text()
    email = columns.Text()
    fname = columns.Text()
    lname = columns.Text()
    age = columns.Text()
    state = columns.Text()
    city = columns.Text()
    country = columns.Text()
    gender = columns.Text()
    phone = columns.Text()
    school_name = columns.Text()
    created_at = columns.Text()
    race = columns.boolean()

这是我的普通RDBMS模型。我的查询如下: -

1) Get all users with city = 'something'

2) Get a user with email = 'something' 

3) Get a user with username = 'something' 

4) Get all users with phones IN ('something' )

5) Get all users with state = 'something' 

6) Get all users with age > something

7) Get all users with gender = 'something' 

8) Get all users with race = 'something' 

9) Get count(*),school_name users Group By schoolname

10) Get all users with created_date > 'something' LIMIT 1000

11) Get all users with username IN ('something') AND age IN ('something') AND phone IN ('something') AND state IN ('something') AND so on  LIMIT 1000

我可以在RDBMS中使用简单的Select查询获得上述查询结果,但问题在于Cassandra。

因为要在Cassandra中获得上述查询的结果,建议每个查询使用不同的模型,这将加快读取能力。在这个时代,磁盘比过去便宜。话虽如此,我知道在问题上抛出更多磁盘并不容易。我看到的更大问题是调整应用程序的DAO层以保持10个不同的表同步。 (另外,我内心的本能不相信有10个模型可用于不同的查询。:P)

可以请某人在Cassandra解释我正确的模型以获得这些查询的结果吗?

PS:上述模型的操作可以是读/写/更新/删除。 查询11 是最重要的查询。

最重要的是,考虑到可以更新有关特定用户的信息,可以在大量数据上快速进行这些查询。

2 个答案:

答案 0 :(得分:1)

最简单的方法可能是将Datastax Enterprise与Search(Solr)或Analytics(Spark)选项一起使用。您可以从www.datastax.com免费下载用于测试目的。只要您的SLA数据可用于查询超过1秒,lucene索引就应该能够处理这些不同的搜索选项。

更大的问题是你为什么要在这里使用Cassandra?你是什​​么意思大量的数据?通常,当您的应用程序具有低延迟读写需求,复制到许多服务器和许多数据中心的能力以及零停机时间时,Cassandra最佳服务。在数据集市/仓库或分析数据库中通常不需要这样,根据查询类型和您需要在数据集市/数据库中进行大量数据"似乎指向。您不希望每个Cassandra节点通常放置超过1到3T的数据,尽管有一些异常值......

答案 1 :(得分:0)

你正面临着真正的卡桑德拉限制:如果你肯定要和卡桑德拉一起去,你需要遵循“卡桑德拉规则”。其中有

  • 非规范化
  • 明智地选择索引

让我们开始吧。每个用户都应具有唯一的ID,用户名,电子邮件和电话。这意味着这些列不适合用于索引(read here why),因此非规范化是正确的方法。

根据您的查询,您将拥有user_by_username,user_by_email和user_by_phones。您可能认为每次重复数据在更新和磁盘使用方面都很繁琐:因此您可以通过创建每个包含仅作为用户ID的值来实现折衷。 e.g:

 user_email     | user_id 
--------------+-------------------
 some@thing.com | 123-456-7aa |    
 girl@hello.org | efg-123-ghi | 

在KS内的另一个表中,您需要一个表,id将检索有关用户的所有信息。这将解决update problem,如果您需要更新电子邮件地址或手机,则只能更新几个表而不是N.黑暗的一面是您必须执行两个查询来获取数据。

让我们继续。

由于以下原因,

stategenderrace是被编入索引的合适人选:

  1. 低基数
  2. 许多行都包含这些值
  3. 通过编制索引,您将解决其他一些查询。最难的部分是像

    这样的查询
    select * from users where age > xyz
    

    Cassandra不允许这种查询,因为您需要在群集部分执行“!equals”操作。要做到这一点,你需要通过某种公共密钥“组织”用户:如状态或“状态组” - 这意味着要知道具有特定年龄的所有用户,您将不得不查询每个分区。

    注意:我没有提供解决方案,这不是我的目标 - 我正在尝试做的是提供一种方法来解决Cassandra的这个问题。

    HTH,
    卡罗