2017-09-28 47 views
3

我们目前正在研究使用多个列族对我们的bigtable查询性能的影响。我们发现将列拆分成多个列族不会提高性能。有没有人有过类似的经历?Bigtable性能影响列族

关于我们的基准设置的更多细节。此时,我们生产表中的每行包含大约5列,每列包含0.1到1 KB的数据。所有列都存储在一个列族中。在执行行键范围过滤器(平均返回340行)并应用列正则表达式过滤器(每行只返回1列)时,查询平均需要23,3ms。我们创建了一些测试表,我们将每行的列/数据量增加了5倍。在测试表1中,我们将所有内容都保存在一个列中。正如预期的那样,这将相同查询的查询时间增加到40.6ms。在测试表2中,我们将原始数据保存在一个列族中,但额外的数据被放入另一个列族中。当查询包含原始数据的列族(因此包含与原始表相同数量的数据)时,查询时间平均为44.3ms。因此,使用更多色谱柱系列时,性能甚至会下降。

这与我们预期的完全相反。例如。这是在Bigtable的文档(https://cloud.google.com/bigtable/docs/schema-design#column_families

分组数据提到的成列的家庭可以让你从一个家庭,或家庭的多重检索数据,而不是检索所有数据的每个一行。尽可能地将数据分组,以便在最频繁的API调用中获得所需的信息,但不能再多了。

任何人对我们的发现有解释吗?

benchmark results


(编辑:增加了一些更多细节)

单个行中的含量:

表1

  • CF1

    • COL1
    • COL2
    • ...
    • col25

表2

  • CF1
    • COL1
    • COL2
    • ..
    • COL5
  • CF2
    • COL6
    • COL7
    • ...
    • col25

我们使用转客户端执行的基准。调用API的代码看起来基本如下:

filter = bigtable.ChainFilters(bigtable.FamilyFilter(request.ColumnFamily), 
      bigtable.ColumnFilter(colPattern), bigtable.LatestNFilter(1)) 
tbl := bf.Client.Open(table) 
rr := bigtable.NewRange(request.RowKeyStart, request.RowKeyEnd) 
err = tbl.ReadRows(c, rr, func(row bigtable.Row) bool {return true}, bigtable.RowFilter(filter)) 

回答

0

如果您检索每行X细胞,它不会作出重大的性能差异这些细胞是否在X单独列户或1列的家庭与X列限定符。

的性能差异进来,如果你实际上只需要一个行具有某种特定的目的细胞 - 你可以在避免选择所有单元格的行,而不只是获取一个列族(通过指定filter on the ReadRow call


一个更重要的因素是简单地选择精确描述数据的模式。如果你这样做,任何以上类型的收益都会自然而然地发生。你也会避免触及100列家族推荐限制。

例如:假设您正在编写排行榜软件,并且您想要存储玩家每次游戏所获得的分数以及一些个人信息。你的模式可能是:

  • 行键:用户名
  • 柱族USER_INFO
    • 列预选赛FULL_NAME
    • 列预选赛password_hash
  • 柱族game_scores
    • 列预选赛candy_royale
    • 列预选赛clash_of_tanks

具有存储作为game_scores列族中的一个单独列每场比赛允许所有得分对于一次抓取用户而不抓取user_info,允许保留数量列家族可管理,允许每个游戏的时间系列独立分数以及镜像数据性质的其他好处。

+1

Hi @David,谢谢你的回复。我已经更新了一些关于行内容和我们正在执行的查询的更多细节。正如你所看到的,我们确实执行了一个FamilyFilter。在我们的基准测试中,我们通过在** cf1 **上应用FamilyFilter来获取** col1 **,然后执行与** col1 **完全匹配的ColumnFilter。所以我们希望对于表2来说,查询会更快,因为FamilyFilter会返回更少的数据。这个假设是不正确的? – krelst