搜尋
首頁資料庫mysql教程MongoDB 分片片键如何选择

MongoDB 分片片键如何选择

Jun 07, 2016 pm 04:34 PM
mongodb合理如何探討選擇

本文探讨了如何合理设置MongoDB片键以发挥分片机制的优势,作者为Bugsnag.com的工程师Conrad Irwin。Bugsnag为移动应用开发者提供实时的Bug追踪及检测服务,Bugsnag使用MongoDB存储超过TB级的文档数据。 简而言之,使用{_id: ‘hashed’}或{projectId: 1, _i

本文探讨了如何合理设置MongoDB片键以发挥分片机制的优势,作者为Bugsnag.com的工程师Conrad Irwin。Bugsnag为移动应用开发者提供实时的Bug追踪及检测服务,Bugsnag使用MongoDB存储超过TB级的文档数据。

简而言之,使用{_id: ‘hashed’}或{projectId: 1, _id: 1}来作为片键。

几个月前,我们对MongoDB集群进行分片(shard)处理,数据设置了两个副本集合(replica set)。上周,我们添加了一个新的分片。首次分片花了一些功夫,不过我们仍然在没有停机的情况下完成了这个工作,如今添加一个新的分片是很轻而易举的事情。

MongoDB的分片是如何工作的?

MongoDB的分片机制能够帮助你将你的数据库划分到多个服务器,通常在生产环境中可以将数据集划分到多个副本集中。但分片最好在数据库建立早期划分,因为一旦你的数据大于512GB那么分片划分就不是那么容易了。这受到MongoDB纵向扩展能力的限制。

为了实现分片,你必须向MongoDB指定使用哪个索引作为片键,然后MongoDB会根据你的设置将你的数据划分到有着相同片键的数据块(Chunk)中。而后这些数据块将根据片键的大致顺序分散到副本集中。

sharding

正如你所见,分片之后数据的存放位置依赖于片键,所以合理的选择片键十分重要。

好片键的要素

MongoDB的内部机制保证了每个副本集(RS)包含了同样数量的块,在上图中一个RS包含两个块,而在Bugsnag.com的集群中,每个RS包含6300个块。但这几乎是唯一的保证机制了。

片键的选择决定了三个重要的方面:

1. 读和写的分布

其中最重要的一点是读和写的分布。如果你总是朝一台机器写,那么这台机器将会成为写瓶颈,则你的集群的写性能将会降低。这无关乎你的集群有多少个节点,因为所有的写操作都只在一个地方进行。因此,你不应该使用单调递增的`_id`或时间戳作为片键,这样将会导致你一直往最后一个副本集中添加数据。

相类似的是如果你的读操作一直都在同一个副本集上,那么你最好祈求你的任务能在机器内存所能承受的范围之内。通过副本集将读请求划分开能够使你的工作数据集大小随着分片数线性扩展。这样的话你能够将负载压力均分到各台机器的内存和磁盘之上。

2. 数据块的大小

其次是数据块的大小。MongoDB能够将大的数据块划分成更小的,但这种情况仅仅在片键不同的情况下发生。如果你有巨量的数据文档都使用了同样的片键,那么你相应的会得到巨大的数据块。出现巨大块是非常不好的,不仅仅因为它会导致数据的不平均分布,还因为一旦这个数据块的大小超过某个值,那么你就不能够在分片之间移动它了。

3. 每个查询命中的分片数目

最后一点,如果能够保证大部分的查询请求都能够命中尽可能少的分片那就最好了。对于一个查询请求来说,其延迟直接取决于最慢的那个命中服务器的延迟;所以你命中的分片越少,那么理论上来说查询将会越快。这一点并不是硬性的规定,不过如果能够做到充分考虑那么应该是很有利的。因为数据块在分片上的分布仅仅是近似的遵循片键的顺序,而并不是严格的强制指定。

好片键是如何炼成的?

上面说了这么多,那么怎么才能设计一个好的片键呢?

Hashed id

作为第一个方案,你可以使用数据文档_id的哈希作为片键。

db.events.createIndex({_id: 'hashed'})

这个方案能够是的读和写都能够平均分布,并且它能够保证每个文档都有不同的片键所以数据块能够很精细。

似乎还是不够完美,因为这样的话对多个文档的查询必将命中所有的分片。虽说如此,这也是一种比较好的方案了。

多租户混合索引(Multi-tenant compound index)

如果想击败哈希索引模式,那么你需要将关联的文档在索引中尽可能聚集在一起的方法。在Bugsnag,我们通过project聚合文档,因为在我们的业务场景中,我们的app大部分的查询请求都在project范围内。所以对于你的app来说你得指定适合你的聚合方式。

但是我们不能简单地使用projectID作为片键,因为那会导致巨大块的产生,所以我们引入了_id来将大project打散到多个块中。这些打散的块仍旧是索引连续的,所以仍然会分布在用一个分片上。

db.events.createIndex({projectId: 1, _id: 1})

这个方案很适合我们,因为对于一个project来说,读和写几乎是独立于project存在时间的,并且旧的project通常都会被删除掉。如果情况改变,我们可能会看到在新的project会有微小的负载上升情况。

为了避免这种问题,我们未来可能会在当MongoDB支持哈希值的混合索引之后,将索引设置为{projectId: ‘hashed’, _id: 1}。相关文档(SERVER-10220)

总结

找一个好的片键是很难的,不过这真的只有两种方案。如果在应用中找不出一个好的聚合键,那么对_id做哈希吧。如果你能够找到,那么将它与`_id`聚合以避免巨大块的产生。请记住无论你使用何种聚合键,它都需要能够将读和写平均分布以充分利用集群中的每个节点。

转自: https://bugsnag.com/blog/mongo-shard-key http://blog.jobbole.com/68854/

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
MySQL的許可與其他數據庫系統相比如何?MySQL的許可與其他數據庫系統相比如何?Apr 25, 2025 am 12:26 AM

MySQL使用的是GPL許可證。 1)GPL許可證允許自由使用、修改和分發MySQL,但修改後的分發需遵循GPL。 2)商業許可證可避免公開修改,適合需要保密的商業應用。

您什麼時候選擇InnoDB而不是Myisam,反之亦然?您什麼時候選擇InnoDB而不是Myisam,反之亦然?Apr 25, 2025 am 12:22 AM

選擇InnoDB而不是MyISAM的情況包括:1)需要事務支持,2)高並發環境,3)需要高數據一致性;反之,選擇MyISAM的情況包括:1)主要是讀操作,2)不需要事務支持。 InnoDB適合需要高數據一致性和事務處理的應用,如電商平台,而MyISAM適合讀密集型且無需事務的應用,如博客系統。

在MySQL中解釋外鍵的目的。在MySQL中解釋外鍵的目的。Apr 25, 2025 am 12:17 AM

在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

MySQL中有哪些不同類型的索引?MySQL中有哪些不同類型的索引?Apr 25, 2025 am 12:12 AM

MySQL中有四種主要的索引類型:B-Tree索引、哈希索引、全文索引和空間索引。 1.B-Tree索引適用於範圍查詢、排序和分組,適合在employees表的name列上創建。 2.哈希索引適用於等值查詢,適合在MEMORY存儲引擎的hash_table表的id列上創建。 3.全文索引用於文本搜索,適合在articles表的content列上創建。 4.空間索引用於地理空間查詢,適合在locations表的geom列上創建。

您如何在MySQL中創建索引?您如何在MySQL中創建索引?Apr 25, 2025 am 12:06 AM

toCreateAnIndexinMysql,usethecReateIndexStatement.1)forasingLecolumn,使用“ createIndexIdx_lastNameEnemployees(lastName); 2)foracompositeIndex,使用“ createIndexIndexIndexIndexIndexDx_nameOmplayees(lastName,firstName,firstName);” 3)forauniqe instex,creationexexexexex,

MySQL與Sqlite有何不同?MySQL與Sqlite有何不同?Apr 24, 2025 am 12:12 AM

MySQL和SQLite的主要區別在於設計理念和使用場景:1.MySQL適用於大型應用和企業級解決方案,支持高性能和高並發;2.SQLite適合移動應用和桌面軟件,輕量級且易於嵌入。

MySQL中的索引是什麼?它們如何提高性能?MySQL中的索引是什麼?它們如何提高性能?Apr 24, 2025 am 12:09 AM

MySQL中的索引是數據庫表中一列或多列的有序結構,用於加速數據檢索。 1)索引通過減少掃描數據量提升查詢速度。 2)B-Tree索引利用平衡樹結構,適合範圍查詢和排序。 3)創建索引使用CREATEINDEX語句,如CREATEINDEXidx_customer_idONorders(customer_id)。 4)複合索引可優化多列查詢,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。 5)使用EXPLAIN分析查詢計劃,避

說明如何使用MySQL中的交易來確保數據一致性。說明如何使用MySQL中的交易來確保數據一致性。Apr 24, 2025 am 12:09 AM

在MySQL中使用事務可以確保數據一致性。 1)通過STARTTRANSACTION開始事務,執行SQL操作後用COMMIT提交或ROLLBACK回滾。 2)使用SAVEPOINT可以設置保存點,允許部分回滾。 3)性能優化建議包括縮短事務時間、避免大規模查詢和合理使用隔離級別。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具