我现在的员工有很多物品。每个项目都有user_id
和明显item_id
属性。为了提高性能和高可用性,我的团队决定对表格进行分类。
我们正在讨论两种策略:
分片item_id
就高可用性而言,如果分片已关闭,则所有用户都会丢失临时1 / N的项目。性能将在所有分片中均匀分布(随机分布)
分片user_id
如果分片已关闭,则N个用户中的1个将无法访问其商品。性能可能不是因为我们拥有1000个项目的用户以及只有一个项目的用户。此外,还有一个很大的缺点 - 现在我们需要传递item_id和user_id才能访问项目。
所以我的问题是 - 选择哪一个?也许你可以用一些数学公式来指导我,以决定在不同情况下哪一个更好
P.S。我们已经有了副本,但它们对我们的写入吞吐量变得无用了
更新
我们有serp页面,我们需要按ID获取项目以及用户想要查看他/她的项目的用户配置文件等页面。与第二种模式不同,第一种模式是最常用的模式。 我们可以轻松放弃ACID事务,因为我们已经开始构建微服务(因此最终几乎所有大型实体都将被封装在特定的微服务中)。
答案 0 :(得分:3)
我看到了几种攻击方式:
<强>折衷强>
item_id
分片意味着您将无法对单个user_id
的信息执行单个查询...您需要查询每个分片然后在应用程序级别聚合结果。我发现汇总有比你想象的更多的陷阱......最好把它保存在数据库中。user_id
进行分片,并且想要通过将用户移动到另一个分片来重新平衡分片,则需要立即原子地移动所有用户的行。如果有很多行,这可能很难。如果您按item_id
进行分片,则可以一次移动一个项目。这允许您逐步重新平衡您的分片,这很棒。关键权衡似乎是能够查询所有特定用户的数据(按user_id
进行分片),而不是跨分片更轻松地平衡和重新平衡数据(按item_id
进行分片)。 / p>
我将专注于您需要如何存储和访问数据的问题。如果您确实只需要item_id
访问,则按item_id
进行分片。避免拆分您的数据库会妨碍您查询数据库。
如果您仍然不确定,请注意您可以按item_id
进行分片,然后选择稍后user_id
进行分片(您可以通过基于user_id
进行重新平衡然后执行新行只会写入他们user_id
所属的分片。)
根据您的更新,听起来您的主要关注点不是关系查询,而是扩展对此特定数据池的写入。如果是这种情况,按item_id
分片可以让您最灵活地随着时间的推移重新平衡数据,并且不太可能在第一时间产生热点或变得不平衡。这需要基于user_id
跨分片聚合查询,但只要那些“给定用户的所有项目”查询不需要一致性保证,您应该没问题。
答案 1 :(得分:2)
我担心没有任何公式可以计算所有案例的答案。它取决于您的数据模式和系统功能要求。
如果您的系统中单独的item_id
具有合理的含义,并且您的用户通常使用来自单独的item_id
的数据(例如Instagram
之类的服务item_id
与用户照片有关,我建议你按item_id
进行分片,因为从技术角度来看,这个选择有很多好处:
user_id
访问item_id
这种方法也有一些缺点。例如,备份给定用户的所有项目将更加困难。
如果只有完整的item_id
系列具有合理含义,则user_id