我们目前正在调查使用多列系列对我们的bigtable查询的性能的影响。我们发现将列拆分为多个列族不会提高性能。有没有人有类似的经历?
有关我们的基准设置的更多详细信息。此时,生产表中的每一行包含大约5列,每列包含0.1到1 KB的数据。所有列都存储在一个列族中。执行行键范围过滤器(平均返回340行)并应用列regex fitler(每行只返回1列)时,查询平均需要23,3ms。我们创建了一些测试表,其中我们将每行的列/数据量增加了5倍。在测试表1中,我们将所有内容保存在一个列族中。正如预期的那样,这将同一查询的查询时间增加到40,6ms。在测试表2中,我们将原始数据保存在一个列族中,但是额外的数据被放入另一个列族中。查询包含原始数据的列族(因此包含与原始表相同数量的数据)时,查询时间平均为44,3ms。因此,当使用更多列族时,性能甚至会降低。
这与我们预期的完全相反。例如。这在bigtable docs(https://cloud.google.com/bigtable/docs/schema-design#column_families)
中提到将数据分组到列族中允许您从单个族或多个族中检索数据,而不是检索每行中的所有数据。尽可能地将数据分组,以便在最常见的API调用中获得所需的信息,但不再需要。
任何人对我们的调查结果有解释?
(编辑:添加了更多细节)
单行内容:
表1 :
CF1
表2 :
我们正在执行的基准测试是使用go客户端。调用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 :(得分:1)
如果要检索每行X个单元格,那么无论这些单元格是X个单独的列族还是具有X列限定符的1个列族,它都不会产生重大的性能差异。
如果您实际上只需要具有某些特定用途的行的单元格,则会出现性能差异 - 您可以避免选择该行的所有单元格,而只需获取一个列族(通过指定filter on the ReadRow call)
更重要的因素是选择一个准确描述数据的模式。如果你这样做,上述类型的任何增益都将自然而然地产生。此外,您将避免达到100列家族建议的限制。
例如:假设您正在编写排行榜软件,并且您希望存储玩家为每个游戏获得的分数以及一些个人详细信息。您的架构可能是:
将每个游戏存储为game_scores列系列中的单独列,允许一次获取用户的所有分数而无需获取user_info,允许保持列族的数量可管理,允许每个游戏的时间序列分数独立以及反映数据性质的其他好处。
答案 1 :(得分:0)
在多个列族上拆分数据时,性能没有提高的原因是它们存储在同一“位置组”(即文件)中。在内部,Google确实可以将不同的列族划分为不同的地理位置组,但这在其托管的Cloud Bigtable服务中并未公开。请参阅this answer上的评论。