1

我的文档结构是:

"_id": ObjectId("50c41fae0e708237dc7a5187"),
"uid": "999",
"appname": "authentication",
"activityId": "login",
"activityName": "login",
"date": ISODate("2012-12-09T05: 20: 46.117Z"),
"yearmonth": "201212"

uid 是其他应用程序从 RDMS 序列生成的用户 ID。yearmonth 是我在应用程序中创建的人工字段,仅用于更好的分片键。

写入模式:当用户登录或在站点上执行特定操作时,我将事件写入 mongoDB。这意味着 uid 是相对随机的,具有非常高的基数。对于同一个 uid,我可以编写数百个事件。

读取模式:大多数查询都基于 uid 作为第一个查询参数。{uid:"9999",date:{$gt: ....}, activityId:'login'}

我最初的分片键是 {uid:1, date:1}。- 如果任何一个 uid 有太多文档,则提供良好的查询隔离并具有可拆分的块。现在,基于如何选择分片键:纸牌游戏文章和一些网络研讨会和论坛上的评论,我意识到更好的密钥应该是 {coarse timestamp:1 , search criteria:1} 。想法是为分片键提供更好的局部性以帮助提高写入性能。所以我创建了 yearmonth 字段并考虑将我的分片键更改为 {yearmonth:1, uid:1}

问题是:我是否因为更改而松散了查询隔离和读取操作的性能?我的查询参数将不再匹配分片键的第一个元素。

4

1 回答 1

0

我会坚持使用 uid,因为这是您将用来获取数据的密钥。

分片键- uid

尤其是当它是基于随机 uid 的事件插入和读取时,将 uid 保留为 shard key 将是非常理想的。

当块变大时,MongoDB中的平衡器将自动平衡不同分片服务器上的块。所以你也在这里(因为自动平衡会照顾一些分片服务器变得太大)。

希望这可以帮助。

于 2012-12-20T18:57:12.623 回答