1. 程式人生 > >分散式檔案儲存資料庫 MongoDB

分散式檔案儲存資料庫 MongoDB

![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d6ab0d658de64418887f6a20c0595276~tplv-k3u1fbpfcp-zoom-1.image " ")    ## MongoDB 簡介      Mongo 並非芒果(Mango)的意思,而是源於 Humongous(巨大的;龐大的)一詞。   MongoDB 是一個基於分散式檔案儲存的 NoSQL 資料庫。由 C++ 語言編寫。旨在為 WEB 應用提供可擴充套件的高效能資料儲存解決方案。關於什麼是 NoSQL 可閱讀《[學了那麼多 NoSQL 資料庫 NoSQL 究竟是啥](https://juejin.im/post/6886275395723264014)》   MongoDB 是一個介於關係型資料庫和非關係型資料庫之間的產品,是非關係型資料庫當中功能最豐富,最像關係資料庫的。 ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/aa2766cd141047eaa9339ced562e770f~tplv-k3u1fbpfcp-zoom-1.image " ") ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a9e4304a5a8646e18982666cf7ae6719~tplv-k3u1fbpfcp-zoom-1.image " ")   MongoDB 使用 BSON(Binary JSON)物件來儲存,與 JSON 格式的鍵值對(key/value)類似,欄位值可以包含其他文件,陣列及文件陣列。支援的查詢語言非常強大,其語法有點類似於面向物件的查詢語言,幾乎可以實現類似關係型資料庫單表查詢的絕大部分功能,而且還支援對資料建立索引。    ## MongoDB 歷史      2007 年,Dwight Merriman,Eliot Horowitz 和 Kevin Ryan 成立 10gen 軟體公司,在成立之初,這家的公司目標是進軍雲端計算行業,為企業提供雲端計算服務。在開發雲端計算產品時,他們準備開發一個類似於資料庫的元件,為雲端計算產品提供儲存服務。當時是關係型資料庫一統天下的時間,他們覺得傳統的關係型資料庫無法滿足他們的要求,他們想要一款程式設計師不懂SQL語言也可以使用的資料儲存產品。   在網路上找了一圈,不管是開源的還是閉源的產品,都沒找到讓他們滿意的東西,既然找不到,那就自己開發吧,反正他們也有那個技術實力,10gen 的創始人都來自谷歌,他們建立的網路廣告公司 DoubleClick 被谷歌收購了,這是他們的第二次創業。   10gen 公司不使用關係型資料庫是有一定原因的,當時他們還在 DoubleClick 公司的時候,就吃過關係型資料庫的苦頭。DoubleClick 是一家網路廣告公司,服務美國眾多的知名公司,該公司每秒提供 40 萬個廣告,但在可伸縮性和敏捷性方面經常遇到困難,因此他們不得不經常自己開發和使用許多自定義資料儲存來解決現有關係型資料庫的不足,這讓他們很是苦惱。   因此他們決定開發一款資料庫產品解決他們在 DoubleClick 時遇到的問題,併為自己的雲端計算產品提供儲存服務。 - MongoDB 最初於 2007 年開發,由位於紐約的一個名為 `10gen` 的組織開發,現在被稱為 `MongoDB Inc.` - 2009 年,經過將近 2 年的開發,10gen 開發出了 MongoDB 的雛形並將它開源以及正式命名為 MongoDB,同時成立開源社群,通過社群運營 MongoDB。 - 2009 年 02 月 MongoDB 1.0 釋出,提供了大部分基本的查詢功能。 - 2009 年 12 月 MongoDB 1.2 釋出,引入了 map-reduce,支援大規模資料處理。 - MongoDB 的第一個真正產品是從 2010 年 03 月釋出的 MongoDB 1.4 版本開始的。 - 2010 年 8 月 MongoDB 1.6 釋出,引入了一些主要特性,比如用於水平伸縮的分片、具備自動故障轉移能力的副本集以及對 IPv6 的支援。 - 2012 年 05 月 23 日,MongoDB 2.1 釋出。該版本採用全新架構,包含諸多增強。 - 2012 年 06 月 06 日,MongoDB 2.0.6 釋出,分散式文件資料庫。 - 2012 年 8 月 MongoDB 2.2 釋出,引入了聚合管道,可以將多個數據處理步驟組合成一個操作鏈。 - 2013 年 MongoDB 推出第一款商業版本 MongoDB Enterprise Advanced。 - 2013 年 04 月 23 日,MongoDB 2.4.3 釋出,此版本包括了一些效能優化,功能增強以及 bug 修復。 - 2013 年 08 月 20 日,MongoDB 2.4.6 釋出,仍然是以效能優化,功能增強和 bug 修復為主。 - 2015 年 03 月 MongoDB 3.0 釋出,包含了新的 WiredTiger 儲存引擎、可插拔儲存引擎 API、增加了 50 個副本集限制和安全改進。同年晚些時候又釋出了 3.2 版本,支援文件驗證、部分索引和一些主要的聚合增強。 - 2016 年 MongoDB 推出了 Atlas 服務,MongoDB Atlas,與公有云服務廠商(谷歌、微軟Azure)合作。這一年,MongoDB 爆出了非常嚴重的安全門事件,黑客通過 MongoDB 的預設監聽地址 0.0.0.0 刪除資料,並且通過此漏洞進行勒索,支付 0.2 到 0.5 的比特幣就可以恢復資料。 - 2017 年 10 月 MongoDB 公司成立 10 週年之際,順利通過 IPO 在紐交所上市。開盤 24 美元,公司估值達到 16 億美元,並獲得 1.92 美元的籌資。 - 2017 年 11 月 MongoDB 3.6 釋出,為多集合連線查詢、變更流和使用 JSON 模式進行文件驗證提供了更好的支援。 - 2018 年 06 月 MongoDB 4.0 釋出,這一版本的釋出獲得了廣泛的關注,提供了跨文件事務處理能力。這是一個重要的里程碑,MongoDB 已經為高資料完整性需求做好了準備。 - 2019 年 03 月 18 日,Forrester 授予 MongoDB NoSQL 領導者稱號。 - 2019 年 10 月 MongoDB 4.2 釋出,開始支援分散式事務。 - 截至 2020 年 10 月,MongoDB 的社群版版本是 4.4.1,擴充套件性和效能增強,降低複製延遲,可用性和容錯性增強,查詢能力和易用性增強,MongoDB 雲平臺的功能更新。MongoDB 逐漸的從一個專注於資料庫服務的廠商,轉變為提供資料平臺服務的廠商。   截至 2020 年,MongoDB 的全球下載量達到了 1.1 億次。MongoDB 公司目前有 2000 多名員工,有超過 18000 名付費客戶,其中有很多客戶同時使用 MongoDB Atlas 和 MongoDB 企業版。大多數大公司在內部的一些場景中仍然使用的是社群版。MongoDB 社群版仍然是開源的,除了一些關鍵特性外,它與 MongoDB 企業版差不多。    ## MongoDB 支援語言    ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/163479d8cdbc40a6b03f408c447ac27b~tplv-k3u1fbpfcp-zoom-1.image " ")    ## MongoDB 與關係型資料庫術語對比    ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/31e8c1493a2a45d0859fb2de4324e6f7~tplv-k3u1fbpfcp-zoom-1.image " ") | SQL 術語概念 | MongoDB 術語概念 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | database(資料庫) | database(資料庫) | | table(表) | collection(集合) | | row(行) | document or BSON document(文件) | | column(列) | field(欄位) | | index(索引) | index(索引) | | table joins(表連線) | embedded documents and linking(嵌入的文件和連結) | | primary key Specify any unique column or column combination as primary key.(指定任意唯一的列或列組合作為主鍵) | primary keyIn MongoDB, the primary key isautomatically set to the `_id` field.(在 MongoDB 中,主鍵被自動設定為 `_id` 欄位) | | aggregation (e.g. group by) | MongoDB provides three ways to perform aggregation: the aggregation pipeline, the map-reduce function, and single purpose aggregation methods.(聚合操作) |    ## MongoDB 資料型別    | 資料型別 | 描述 | | :----------------- | :----------------------------------------------------------- | | String | 字串。儲存資料常用的資料型別。在 MongoDB 中,UTF-8 編碼的字串才是合法的。 | | Integer | 整型數值。用於儲存數值。根據你所採用的伺服器,可分為 32 位或 64 位。 | | Boolean | 布林值。用於儲存布林值(真/假)。 | | Double | 雙精度浮點值。用於儲存浮點值。 | | Min/Max keys | 將一個值與 BSON(二進位制的 JSON)元素的最低值和最高值相對比。 | | Arrays | 用於將陣列或列表或多個值儲存為一個鍵。 | | Timestamp | 時間戳。記錄文件修改或新增的具體時間。 | | Object | 用於內嵌文件。 | | Null | 用於建立空值。 | | Symbol | 符號。該資料型別基本上等同於字串型別,但不同的是,它一般用於採用特殊符號型別的語言。 | | Date | 日期時間。用 UNIX 時間格式來儲存當前日期或時間。你可以指定自己的日期時間:建立 Date 物件,傳入年月日資訊。 | | Object ID | 物件 ID。用於建立文件的 ID。 | | Binary Data | 二進位制資料。用於儲存二進位制資料。 | | Code | 程式碼型別。用於在文件中儲存 JavaScript 程式碼。 | | Regular expression | 正則表示式型別。用於儲存正則表示式。 |    ## MongoDB 下載與安裝    ### 下載      官網:https://www.mongodb.com/   下載地址:https://www.mongodb.com/try/download/community   在頁面中選擇 `MongoDB Community Server` 社群版,根據自己的系統選擇對應的版本,我自己使用的是 `CentOS` 版本。而 MongoDB 只有 `RedHat` 版本,下載使用即可。 >   CentOS 是 Community ENTerprise Operating System 的簡稱,也可以叫它社群企業作業系統,是 Linux 作業系統中的一個發行版本。 > >   CentOS 並不是全新的 Linux 發行版,它是 Red Hat 家族發行的企業版的產品 Red Hat Enterprise Linux(以下稱之為 RHEL)的克隆版本。RHEL 是很多企業採用的 Linux 發行版本,需要向 Red Hat 付費才可以使用,並能得到付費對應的服務,技術支援和版本升級。CentOS 可以像 RHEL 一樣的構築 Linux 系統環境,但不需要向 Red Hat 支付任何的產品和服務費用,同時也得不到任何有償技術支援和升級服務。 ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7d415217a2e14cf9a907c0841e9ecaaf~tplv-k3u1fbpfcp-zoom-1.image " ")      還可以通過:https://docs.mongodb.com/manual/installation/ 確認該版本軟體是否支援你的作業系統。 ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3f21ae7fd86b4c3f9500334139a4d996~tplv-k3u1fbpfcp-zoom-1.image " ")    ### 安裝      將資源上傳至伺服器 `/usr/local/src`,解壓至 `/usr/local` 並重命名為 `mongodb`。 ```shell # 建立 mongodb 目錄 mkdir -p /usr/local/mongodb # 解壓 mongodb 至指定目錄 tar -zxvf /usr/local/src/mongodb-linux-x86_64-rhel70-4.4.1.tgz -C /usr/local/ # 重新命名解壓目錄為 mongodb mv /usr/local/mongodb-linux-x86_64-rhel70-4.4.1/ /usr/local/mongodb ```    ### 建立資料/日誌目錄      建立用於存放資料和日誌的資料夾,並修改其許可權增加讀寫許可權。 ```shell # 建立存放資料的目錄 mkdir -p /usr/local/mongodb/data/db # 建立存放日誌的目錄 mkdir -p /usr/local/mongodb/logs # 建立日誌記錄檔案 touch /usr/local/mongodb/logs/mongodb.log ```    ## 啟動 MongoDB    ### 前臺啟動      MongoDB 的預設啟動方式為前臺啟動。所謂的前臺啟動就是 MongoDB 啟動程序後會佔用當前的終端視窗。 ```shell # 切換至指定目錄 cd /usr/local/mongodb/ # 前臺啟動 bin/mongod --dbpath /usr/local/mongodb/data/db/ --logpath /usr/local/mongodb/logs/mongodb.log --logappend --port 27017 --bind_ip 0.0.0.0 ``` - `--dbpath`:指定資料檔案存放目錄 - `--logpath`:指定日誌檔案,注意是指定檔案不是目錄 - `--logappend`:使用追加的方式記錄日誌 - `--port`:指定埠,預設為 27017 - `--bind_ip`:繫結服務 IP,若繫結 127.0.0.1,則只能本機訪問,預設為本機地址    ### 後臺啟動      所謂的後臺啟動就是以守護程序的方式啟動 MongoDB。命令中新增 `--fork` 即可。 ```shell # 後臺啟動 bin/mongod --dbpath /usr/local/mongodb/data/db/ --logpath /usr/local/mongodb/logs/mongodb.log --logappend --port 27017 --bind_ip 0.0.0.0 --fork ```   通過命令啟動的方式並不適合管理,畢竟每次輸入命令都需要考慮各引數的配置。我們可以通過配置檔案來配置啟動引數,然後通過指定配置檔案的方式啟動服務,這樣在管理 MongoDB 上就比較方便了。    #### 配置檔案      在 `bin` 目錄下增加一個 `mongodb.conf` 配置檔案。 ```conf # 資料檔案存放目錄 dbpath = /usr/local/mongodb/data/db # 日誌檔案存放目錄 logpath = /usr/local/mongodb/logs/mongodb.log # 以追加的方式記錄日誌 logappend = true # 埠預設為 27017 port = 27017 # 對訪問 IP 地址不做限制,預設為本機地址 bind_ip = 0.0.0.0 # 以守護程序的方式啟用,即在後臺執行 fork = true ```    #### 啟動    ```shell # 切換至指定目錄 cd /usr/local/mongodb/ # 指定配置檔案的方式啟動服務 bin/mongod -f bin/mongodb.conf ```    ## 客戶端訪問      可以通過 `bin` 目錄中的 `mongo` 來訪問 `MongoDB` 伺服器。   命令為:`bin/mongo --host 連線的主機地址(預設127.0.0.1) --port 埠(預設27017)` ```shell [root@localhost mongodb]# bin/mongo MongoDB shell version v4.4.1 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("2bf54fad-83bc-444c-8bee-166a224445b8") } MongoDB server version: 4.4.1 --- The server generated these startup warnings when booting: 2020-10-21T10:47:44.855+08:00: ***** SERVER RESTARTED ***** 2020-10-21T10:47:47.024+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2020-10-21T10:47:47.024+08:00: You are running this process as the root user, which is not recommended 2020-10-21T10:47:47.024+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-10-21T10:47:47.024+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' 2020-10-21T10:47:47.024+08:00: Soft rlimits too low 2020-10-21T10:47:47.024+08:00: currentValue: 1024 2020-10-21T10:47:47.024+08:00: recommendedMinimum: 64000 --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- > ```      `help` 幫助命令。 ```shell > help db.help() help on db methods db.mycoll.help() help on collection methods sh.help() sharding helpers rs.help() replica set helpers help admin administrative help help connect connecting to a db help help keys key shortcuts help misc misc things to know help mr mapreduce show dbs show database names show collections show collections in current database show users show users in current database show profile show most recent system.profile entries with time >= 1ms show logs show the accessible logger names show log [name] prints out the last segment of log in memory, 'global' is default use set current database db.mycoll.find() list objects in collection mycoll db.mycoll.find( { a : 1 } ) list objects in mycoll where a == 1 it result of the last line evaluated; use to further iterate DBQuery.shellBatchSize = x set default number of items to display on shell exit quit the mongo shell ```      `db.version()` 檢視版本資訊。 ```shell > db.version() 4.4.1 ```      `show dbs` 檢視所有資料庫。 ```shell > show dbs admin 0.000GB config 0.000GB local 0.000GB ```   這裡先簡單通過客戶端進行訪問測試,後面會詳細羅列客戶端操作 MongoDB 資料庫、集合、文件、索引、內建函式等相關的操作。    ## 關閉 MongoDB    ### 前臺啟動關閉      使用 `Ctrl + c` 即可關閉。    ### 後臺啟動關閉      使用 `--shutdown` 引數即可關閉。 ```shell # 命令啟動方式的關閉 bin/mongod --dbpath /usr/local/mongodb/data/db/ --logpath /usr/local/mongodb/logs/mongodb.log --logappend --port 27017 --bind_ip 0.0.0.0 --fork --shutdown # 配置檔案啟動方式的關閉 bin/mongod -f bin/mongodb.conf --shutdown ```    ### kill 命令關閉      通過 `kill -9` 的方式強制關閉程序,一般這種方式都不怎麼推薦使用。 ```shell # 檢視 mongodb 執行的程序資訊 ps -ef | grep mongodb # kill -9 強制關閉 kill -9 pid ``` ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f6f04191716a4d899425f33f68fc96b2~tplv-k3u1fbpfcp-zoom-1.image " ")    ### MongoDB 函式關閉      連線到 MongoDB 服務後,切換到 admin 資料庫,並使用相關函式關閉服務。 ```shell # 連線 mongodb bin/mongo # 切換 admin 資料庫 use admin # 執行以下函式(2選1)即可關閉服務 db.shutdownServer() db.runCommand(“shutdown”) ```    ## 環境變數      每次操作 MongoDB 都需要進入具體的目錄才行,比如啟動服務,客戶端進行連線等,可不可以在任意目錄都能進行操作。答案當然是可以的,只需要將 MongoDB 相關目錄新增至系統環境變數即可。   先通過 `vim /etc/profile` 編輯系統環境變數檔案,新增以下內容。 ```shell # 新增環境變數 export MONGODB_HOME=/usr/local/mongodb export PATH=$PATH:$MONGODB_HOME/bin ```   然後通過 `source /etc/profile` 重新載入系統環境變數。這樣在系統任意目錄下都可以直接操作 MongoDB 了。 ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/16df2602844f45d5b6944eecabce0c37~tplv-k3u1fbpfcp-zoom-1.image " ")   本文講解了 MongoDB 的一些入門級內容,教會了大家如何基於 Linux 環境下載與安裝 MongoDB。下文我們先從安全問題入手,看看 MongoDB 未加密導致的慘痛經歷與教訓,順便再教大家一波實用的解決方案。 ![](//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/24c3324458034c55ac1c9f18b9ce7772~tplv-k3u1fbpfcp-zoom-1.image) 本文采用 `知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議`。 大家可以通過 `分類` 檢視更多關於 `MongoDB` 的文章。