MongoDB - The first sight

Introduction

MongoDB is a document database designed for 易於開發與擴展,資料結構是field and value pairs 的BSON documents (像是JSON object). Value 型態除了string, int可為 document, arrays of document...
MongoDB與DynamoDB都能運用GoeJOSN格式儲存座標地理位置

RDB v.s MongoDB 術語
database -> database
table -> collection
row -> document
column -> field

MongoDB 對應回RDB的專有名詞(aggregation mapping from SQL terms):
WHERE -> match
GROUP BY -> group
HAVING -> match
SELECT -> project
ORDER BY -> sort
LIMIT -> limit
SUM() -> sum
COUNT -> sum/sortByCount
join -> lookup

MongoDB的index

如同NoSQL的設定,沒透過index搜尋則會full collection scan. Index 是個能夠易於traverse 的資料結構。儲存對某field的value by 排序狀態,讓index搜尋時有效的匹配範圍操作的查詢

MongoDB index type

  • Single-field - 除了_id 之外可以自定義其他index,因為欄位單一因此順序不重要。e.g.: {score: 1}
  • Compound Index - 定義index於多欄位 ,架設index為以下兩個組成 {name:1, score: -1},則index會先以name做排序再排score。
  • Multikey Index - 在Content裡面若有array的field,MongoDB會另外建立一個index entry for 這個value
  • Geospatial Index - 支持地理座標為值的index: 2d indexes與2dsphere indexes
  • Text Index -  提供text index能search collection裡的content,這Index不會存特定的停用詞(stop words),例如 "a", "the", "and"...
  • Hash Index - 顧名思義,但查詢只支援equality matches

MongoDB indexing Strategies

建立index有很多面向,依照期望的query 結果、讀寫頻率、系統有多少記憶體空間...等
最佳的策略是在production相同等級的環境以及相同的dataset量級,在index很耗費資源的觀念下,確保建立有用的index,不用的請刪除。基本上一個index就應該能夠應付所需的情境,多個index則可採用index insertions

4個策略
。以查詢field為條件的設為index
。用index對查詢結果做排序
。確保index在RAM合適的使用量
。建立可選擇性的查詢,也就是能在建立index的filed上,又能再縮小範圍,猶如前面ep015提到的結構化文字格式



MondoDB 除了單筆寫入資料外,亦有Bulk write的操作,分為有順序性的跟沒順序性的。ordered vs unordered.
Ordered, 其中一個寫入錯誤就會return並不會執行接下來剩下的操作。
Unordered, 其中一個寫入失敗也會把剩下的operation繼續做完。(execute operation in parallel)

基本上ordered 會需要等一筆資料寫完才會再寫一筆,效率上會比Unordered慢。預設bulkWrite() 是ordered.


了解策略之前,先搞懂專有名詞...
Chunk?
Data partitioning with chunks
MongoDB 用 shard key 去關聯Collection切分過後的data into "Chunks". 當資料成長超過chunk size,MongoDB 切chunks。Insert and update都會觸發chunk split。

chunk size default 64 MB

Bulk Insert 到sharded collection的策略

大量insert 會影響sharded cluster performance,因此有以下策略。
。Pre-Split the Collection (預先拆分 collection) - 假設初始shard為空只有一個chunk, MongoDB需要花時間在接收data並寫入時拆分chuck。為了避免此問題可以預先拆分,有點像是AWS S3 解決initial hotspot issue, 事先預熱避免 5XX error
Unordered Writes to mongos (無順序寫入) - 之前提過的無順序性是parallel 處理的,parameter "ordered" set to "false"
Avoid Monotonic Throttling (避免 throttle 在同一位置) - 假設shard key 在insert時是有順序的增加,那麼每一筆資料必定都是寫在最後一個chuck中,沒有發揮到sharded cluster平行寫入的功用。因此在寫入量超過單一shard能處理的量,可以對shard key做設計讓資料即便insert有順序性也會分散在不同的shard中。

Text Search

MongoDB提供Text Search, MongoDB 只允許在每個collection中建立一個text index, 允許跨多個fields.  Fields 可為string 或者是array of string. $text 會用空白鍵為分割去tokenize 來對文字收尋,搜尋除了基本文字搜尋, 也能做到exact search, exclude, sorting by score等操作。概念跟最早Elasticsearch 全文檢索的操作概念很像。

MongoDB Security

關於Security的幾件事,在上PROD之前需要檢查
  1. 開啟 Access Control以及強制 Authentication, 可用SCRAM 或x.509 authentication機制或結合Kerberos/LDAP架構。
  2. Configure Role-Based Access Control (RBAC) - 建立admin, 建立其他user,根據不同使用者或應用程式去設定access的權限
  3. Encrypt Communication (TLS/SSL)加密通訊 - 啟用TLS/SSL 在mongod and mongos 間傳輸時加密
  4. Encrypt and Protect Data 加密資料 - 可以針對storage layer做資料加密
  5. Limit Network Exposure - 限制網路環境避免暴露在公開的網路中
  6. Audit system activity - enterprise 版本有auditing功能。
  7. 用專用的user跑 MongoDB - 角色權限切得越單純乾淨越好
  8. 若沒有用到javascript去操作MongoDB, 蛇可以下指令關掉支援server side scripting with "--noscripting"
  9. 參考security Standards Compliance
  10. 定期檢查版本是否有安全性漏洞,如CVE

留言

這個網誌中的熱門文章

[專案] 銀行端末系統

如何在MacOS 中自由切換不同Python版本 - pyenv + virtualenv

用 C# 控制 Win7 輸入法