Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
NoSQL – MongoDb介
紹
大綱
• NoSQL介紹
• CAP理論介紹
• MongoDb介紹
• MongoDb開發
• MongoDb管理
• MongoDb的工具
NoSQL介紹
• NoSQL是Not Only SQL。
• NoSQL的目標在於解決過去關聯式資料庫(RDBMS)在某些系統應用
環境下的不足。
• RDBMS提供強大的交易功能,但是對於過大的資料量以及每秒過多的
讀寫需求(Record ...
SQL過去的問題
• Schema調整不易
• Join很傷效能
• 過度要求的交易一致性,在某些應用場景不合適
NoSQL的歷史
• 最早出現在1998年,不提供SQL的關聯式資料庫。
• 2009年,發起分散式資料庫的議題,此時的NoSQL已不強調關聯,開始放
棄ACID。
NoSQL特性
• 執行在一堆便宜的伺服器上。
• 降低效能瓶頸。
• 適量的功能模組。
• 開放原始碼。
NoSQL的種類
儲存類型 NoSQL產品 特性
Document MongoDb Document儲存一般會使用類似於Json格式儲存, 如此
就可以針對某些欄位建立索引,實現RDBMS某些功能。
欄(Column) Hbase, Cassa...
CAP理論介紹
• CAP理論是NoSQL系統架構設計的核心觀念。
• CAP理論與過去系統設計有著極大的不同,故,需要調整設計的想法。
• CAP理論適用在某些特定場合(i.e. 分散式),並非是所有情境。
關聯式資料庫主要的功能
• 交易
• 處理關聯
• 強大的工具組(Toolkit)
• 年代悠久,人才資源豐沛
ACID的問題
• ACID是四個字的縮寫:
• Atomic(原子性/不可分割性)
• Consistency(一致性)
• Isolation(隔離性)
• Durability(持久化)
• 時下用於達成ACID設計的手法有兩種:
• 日...
交易隔離等級
交易隔離等級 描述
Read Uncommitted 幾乎沒做資料保護,容易出現髒資料讀取;其效能最高
Read Committed 只允許讀取已認可的資料,重覆讀取時有可能讀到髒資料
Read Committed Snapsho...
交易的優缺點
• 優點:
• 資料的強制且快速的一致化
• 缺點:
• 消耗大量資源
• 帶來死結
• (思辨)
是否真的有必要做到即時且強制的一致化?
CAP的基本思維
• CAP是三個字的縮寫:
• Consistency(一致性)
• Availability(可用性)
• Partition Tolerance(分區容錯)
• 在分散式的環境中,僅能在上述三種特性中完成其中兩者。
一致性(Consistency)
• CAP中所提到的一致性指的是強一致性。
• 系統在執行過某項操作後仍處於一致的狀態。
• 在分散式系統中,若更新了一筆資料成功後,所有讀取這筆更新過後資
料的操作都會到讀取到相同的資料。
可用性(Availability)
• 只要Node的健康狀態是優良的,它必定要能夠回應使用者的請求
(Request)。
分區容錯(Partition Tolerance)
• 在分散式系統中某個節點毀損仍可提供服務。
正常狀態 異常狀態
CAP的認知
• (一致性, 可用性) -> 可擴展性低
• (一致性, 分區容忍) -> 性能低
• (可用性, 分區容忍) -> 一致性低
其實,CAP並沒有聲明
• 放棄一致性
• 不一致應該要是一個例外,不是常態
• 放棄交易(ACID)
• 其實只需要調整C和I的預期
• 不使用SQL
• 已有不少NoSQL也使用類SQL語法
BASE
• BASE其實是三個字的縮寫:
• Basically Available(基本可用): 盡可能滿足CAP中的A和P。
• Soft-State(軟式狀態): 資料狀態可以有一段時間不一致。
• Eventual Consisten...
不一致窗(Non-Consistency Window)
• 最終一致性會產生一個資料不一致的時間區間,而這個區間就是不一
致窗。
• 每個系統依其特性甚至是功能都有其不一致窗的最低容忍程度,可以
說系統在設計某個功能時要詳細琢磨其不一致窗的容...
MongoDb的介紹
• 2007年10gen公司想開發一個PaaS平台,但開發人員只對他們的資料庫
有興趣,後來抽出來成為MongoDb。
• 以C++開發,採GNU_AGPL方式授權。
• 2009年11月推出1.0版,之後每三個月改版一次...
MongoDb的資料結構
• MongoDb的資料結構如下
• DataBase
• Collection => 類似RDBMS中的Table
• Document => 類似RDBMS中的Record
• Field => 類似RDBMS中的...
MongoDb的特性
• Document是使用BSON資料格式儲存。
• 語法思維與JavaScript相似。
• 以參考(DbRef)與內嵌式Document來達成RDBMS中的資料表關聯。
• 讀取效能高於寫入效能。
• Schema-F...
MongoDb的前題假設
• 假設有足夠大的硬碟空間
• 記憶體足夠放入所有的熱資料
• 系統是64位元
• 系統採用Little-Endian
• 多台提供給MongoDb使用的伺服器
• 允許安全與效能的抉擇
MongoDb適用場景
• 網站登入/出
• 快取
• 大型檔案的儲存
• 需擴充
• 事件紀錄
MongoDb不適用場景
• 高交易需求的系統;銀行/會計系統。
• BI應用;針對特定問題的BI資料庫會進行特殊優化的查詢方式,對於此
類型應用,採用Data Warehouse較適合。
MongoDb業界實例
MongoDb的安裝
• 連外文章
MongoDb連線
• MongoDb提供以命令提示字元連線,其連線字串規則如下:
• Mongo [options] [db address] [js檔案完整路徑]
• db address範例:
• MyDb
• 127.0.0.1/MyD...
MongoDb連線字串可選參數
參數 描述 範例
--shell 執行完指定的.js檔之後跑shell mongo –-shell myDb
--nodb 剛啟動時不會先連到資料庫 mongo –-nodb
--norc 剛啟動時不會先執行js...
MongoDb中重要的集合
集合 作用
system.namespaces 儲存命名空間資訊
system.indexes 儲存索引資訊
system.profile 儲存優化器資訊
system.users 儲存帳戶資訊
local.sour...
MongoDb的資料型別(1)
資料型別 描述 範例
Null 代表空值或不存在 {"x":null}
Boolean True/false {"x":true}
String 任意UTF-8的字串 {"x":"foobar"}
Symbol ...
MongoDb的資料型別(2)
資料型別 描述 範例
date 儲存從1970/1/1開始到現在的毫秒數 {"x": new Date()}
Regular expression 採用JavaScript的正則式語法 {"x": /foobar...
MongoDb的Document
• MongoDb可以隨意添加或減少每一筆Document。
• 每筆Document大小都不得超過4MB。
• MongoDb的Document預設會額外添加一個欄位:_id。_id預設資料型別
為:Obje...
MongoDb開發
• Mongo官方提供與MongoDb介接的程式語言驅動程式,支援語言如下:
• C/C++
• C#
• Erlang
• Java
• JavaScript
• Node.js
• Perl
• PHP
• Python...
MongoDb Shell
• MongoDb可以使用命令提示字元操作資料庫。
資料庫名稱
MongoDb版本
一般操作指令
指令 描述
show dbs 列出連線的這個MongoDb實體內
含的所有資料庫
show
collections
列出連線的這個資料庫內含的所有
集合
Use
MyDb
切換到另一個資料庫
db.Collectio
n.drop...
查詢(與SQL的對應)
集合(資料表)
查詢條件
投影
游標修飾子
投影
資料表
查詢條件
游標修飾子
查詢處理
MongoDb查詢的運算子
運算子 對等運算 運算子 對等運算
$gt > $lt <
$gte >= $lte <=
$all 符合所有列舉值 $exists 判斷指令欄位是否存在
$mod 運算的欄位符合指定的模數與餘數 $ne !=
$n...
查詢游標
• MongoDb使用find()方法進行查詢,其回傳值為查詢資料結果的游標,可以使
用游標提供的API進行遍覽:
• 以下條件發生時,游標會自動回收:
• 超過10min沒有任何動作
• 用戶端資源耗盡
• MongoDb預設會做空...
查詢實務應用
應用 範例
OR條件 db.users.find({"$or": [{"ticket_no" : 725}, {"winner": true}]})
值區間 db.users.find({"age": {"$lt": 30, "$...
游標修飾子
指令 描述 範例
count 查詢紀錄條數 db.users.find().count()
skip 指定結果集的啟始位址 db.users.find().skip(3)
limit 限制結果集的筆數 db.users.find()...
群組運算
指令 描述 範例
distinct 取得指定欄位的不重覆值 db.users.distinct("name")
group 與SQL的group功能一致 db.coll.group({
key: {a: true, b: true},...
MapReduce
• Mapreduce: 要操作的集合名稱
• Map: 映射函數
• Reduce: 統計函數
• Out: 統計後的結果集
Map函數
Reduce函數
MapReduct
最終結果
新增
集合(資料表)
欄位: 值
欄位: 值
欄位: 值
資料表
欄位
值
新增的本質
• 當執行插入,驅動程式在將資料傳至資料庫之前,會先將資料轉換成為
BSON;資料庫會試著解讀BSON,確認_id欄位是否存在,並且檢查
Document大小不超過4MB。
刪除
集合(資料表)
查詢條件
查詢條件
資料表
刪除的幾種方式
• 除了依條件刪除指定的Document之外,還可以有以下方式:
• db.users.remove() – 刪除users集合中所有Document。
• db.users.drop() – 刪除users集合所有Docume...
更新
• 有幾種處理方式:
• 替換Document
• 使用修飾子
• 多筆更新/upsert
替換Document
MongoDb為Update提供的修飾子
修飾子 描述 範例
$set 針對欄位進行修改 db.users.update({name:'john'},{$set:{name:'john2'}})
$unset 移除某個欄位 db.users.u...
多筆更新
• MongoDb預設只會針對符合條件的第一筆Document進行修改。
• MongoDb在update的API為:
• update(條件,新值,upsert,multi);
• Upsert會依條件判斷是否有
該筆Documen...
MongoDb開發-C#
• 可以到MongoDb的官網下載C#的Driver或是直接從Nuget管理套件下
載Mongo C# Driver。
使用套件簡化程式
GridFS
• MongoDb在處理大型二進位資料的儲存方面採用GridFS機制。
• GridFS將大型二進位資料切割成一塊塊的Chunk(區塊)以及檔案的
MetaData,分別存入集合:fs.chunks和fs.files。
(取出)
...
GridFS的檔案MetaData
屬性名稱 描述
filename 儲存的檔案名稱
chunkSize Chunk大小
uploadDate 上傳檔案進資料庫的時間
md5 檔案的md5,用於檢驗檔案完整性
length 檔案大小(註:單位為...
以C#撰寫
MongoDb的管理
• 管理的操作主要有下列幾個項目:
• 連線控制
• 帳戶管理
• 資料匯入/出
• 資料複製
• 資料庫壓縮
• HA
• 效能監控
連線控制
• MongoDb在啟動實體的時候預設是開放連線的,但若希望限定只有特
定IP才能連線,需要在實體啟動的指令(註:mongod)再加上欲綁定的IP。
• MongoDb預設傾聽的埠號:27017,但由於是預設可能有被攻擊的風險,
故,...
帳戶連線管理
• MongoDb對於帳戶的管理不像RDBMS那般複雜,最多只能控制帳戶是
否唯讀。
• 設定實體要驗證登入的用戶帳號:
• 若僅是設定實體要驗證但是卻沒有加入任何帳號到該實體,則
MongoDb這個實體仍然不會去驗證帳戶。
Admin資料庫
• MongoDb實體在啟動後預設會有一個用來管理帳戶的資料庫:
• admin.system.users
• 當admin.system.users的內容為空時,縱使在啟動MongoDb實體時有加上
啟用登入驗證的參數(註:...
建立超級帳戶的步驟
• 登入MongoDb的實體,切換到admin資料庫
• 輸入: db.addUser({user:'root',pwd:'123',
roles:['userAdminAnyDatabase']})
• 切回test資料庫...
使用超級帳戶建立其它帳戶
• 使用超級帳戶登入實體。
• 先切換到admin資料庫,並輸入:db.auth('root','123')
• 切換到欲添加其它帳戶的資料庫: use test
• 添加帳戶: db.addUser('john','...
版本2.4之後的變異
• MongoDb在版本2.4之後對於帳戶權限控制有了更多樣化的設定
• 在2.4之前沒有角色的概念,僅能對帳戶設定唯讀與否
• 新增角色如下:
角色 描述 角色 描述
read 在指定的資料庫中可讀取任
何集合的資料
r...
一次性套用權限到所有資料庫
角色 描述 角色 描述
readAnyDatabase 可讀取所有資料庫的
資料
readWriteAnyDatabase 可讀寫所有資料庫的
資料
userAdminAnyDatabase dbAdminAnyDa...
陷阱
• MongoDb為了要能夠相容前面版本,所以把新的帳戶API關閉,要使用
新的API必須要在啟動MongoDb實體的時候設定參數:
supportCompatibilityFormPrivilegeDocuments=0
• 新API:...
資料匯出
• MongoDb的資料匯出指令為:mongoexport
• 可以匯出的資料格式為:Json/CSV
資料匯出參數
參數 描述 參數 描述
-h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號
-u <username> 登入帳戶 -p <password> 登入密碼
--db <dbName> ...
• 欲匯出的資料:
• 資料庫:test
• 集合: Student
• 匯出年齡大於18歲且檔案格式為CSV,資料欄位僅:name,age:
• 匯出結果:
資料匯入參數
參數 描述 參數 描述
-h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號
-u <username> 登入帳戶 -p <password> 登入密碼
--db <dbName> ...
• 清空集合Student中的資料
• 匯入CSV資料:
• 匯入資料:
• 匯入結果:
資料備份
• 備份指令為:mongodump
• 內部動作原理其實是先進行查詢,再將資料寫入備份檔案中。
• 備份過程中會一定程度的降低系統效能。
• 備份的資料並不一定是完整的,因為mongodump只是下一道普通的查
詢命令 。
資料備份參數
參數 描述 參數 描述
-h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號
-u <username> 登入帳戶 -p <password> 登入密碼
--db <dbName> ...
備份test資料庫
備份資料庫的Best Practice
• 備份資料庫會造成一定程度的效能損耗,除此之外,備份的資料無法完整符合
當下的資料。
• 若系統有組態ReplicaSet,則可以在Slave節點上進行資料庫鎖定後再執行備份
指令:
db.runCom...
資料還原參數
參數 描述 參數 描述
-h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號
-u <username> 登入帳戶 -p <password> 登入密碼
--db <dbName> ...
還原
資料複製
• MongoDb提供遠端複製集合/資料庫的指令。
• 複製資料庫的指令也可用在原機複製,但集合就不支援原機複製。
複製集合
• 語法:
db.runCommand({cloneCollection: 'TT.Student',from:'127.0.0.1:27017'})
• 除了複製集合之外,也會複製索引。
複製資料庫
資料庫壓縮
• MongoDb預設會預分配空間給資料,但是資料在經過一段時間的異動
操作後會產生大小不一的空間破碎,而這些空間破碎除了造成硬碟空
間利用率下降之外,也造成資料查詢速度的緩慢。
• MongoDb提供兩個查詢集合大小的指令:
• ...
ReplicaSet
• 帶來的優勢:
• Slave可以執行查詢,降低Master的查詢壓力
• 可在Slave上備份,避免備份因素而需要鎖定Master的資料庫
• 當Master故障時,可以快速切換到Slave,減少DownTime
• ...
OpLog
• 建立ReplicaSet後每個MongoDb實體都會啟動OpLog。
• OpLog是一個MongoDb的Collection。
• OpLog會紀錄資料異動歷程,當紀錄的資料超過所限制的大小會清掉
最舊的資料再開始紀錄。
• ...
啟動三個實體
• 分別啟動三個實體,其埠號分別
是:
• 實體1: 30000
• 實體2: 30001
• 實體3: 30002
• ReplicaSet的重要參數: replSet;所
有實體都使用同一個replSet名
稱:MyRS。
啟動ReplicaSet
• 連入實體1,並輸入:
rs.initiate()
• 直到看到實體1的實體寄宿的
Console顯示它已成為Primary為
止。(通常會等待5分鐘)
加入Secondary
• 加入Secondary的指令為:
• rs.add(‘[主機名稱]:Port’)
• 直到看到實體1的實體寄宿的
Console顯示它已成為Secondary
為止。
加入Arbiter
• 加入Secondary的指令為:
• rs.addArb(‘[主機名稱]:Port’)
• 直到看到實體1的實體寄宿的
Console顯示它已成為Secondary
為止。
rs.Add
屬性 描述
_id 從0開始的序號
host 資料格式為[主機名稱]<:Port>
arbiterOnly True/False,標明此成員是否為仲裁者
buildIndex True/False,標明此成員是否要建立索引
hid...
確認ReplicaSet中每個節點的狀態
設定Secondary允許讀取
ReplicaSet的節點角色
角色 描述
Primary 主節點,一個ReplicaSet中僅能有一個主節點
Secondary 副節點,持有主節點的資料複本,Client可視且可讀取其資料。
Secondary(Priority0) 與Se...
ReplicaSet發起投票的狀況
• ReplicaSet之間彼此每2秒會Ping對方,如果Primary超過10秒沒有回應,則
代表Primary已經Fail。
• 新的ReplicaSet剛成立。
• Primary被管理人員手動Step...
投票狀況1
ReplicaSet的節點狀態
狀態 是否允許投票 描述
StartUp 解譯ReplicaSet的組態資料
Primary 主節點;唯一可接受寫入請求的節點
Secondary 副節點,可接受讀取請求,在主節點發生錯誤時可以替代
Recove...
複寫相關API(1)
函數 描述 範例
initiate 初始化整個ReplicaSet rs.initiate()
conf 組態整個ReplicaSet的成員設定
reconf 異動過ReplicaSet後,重新套用組態 var cfg =...
複寫相關API(2)
函數 描述 範例
stepDown Primary節點自動降級為Secondary rs.stepDown()
freeze 成員在指定的時間內,若Primary故障則該成員無
法成為Primary
rs.freeze(3...
寫考量(Write Concern)
• 當Mongo的佈署架構使用了ReplicaSet之後,就會開始出現”最終一致性”
方面的議題。
項目 描述
ErrorIgnore Client無法得知MongoDb實體回應的錯
誤,但效能是最高的
U...
讀喜好(Read Preference)
• 具備ReplicaSet的MongoDb,其讀取的負擔可以分散給Secondary節點,也
因此有各種不同讀取上的機制。
項目 描述
Primary 預設;所有人都只讀取Primary的資料
Pri...
NoSQL-MongoDB介紹
NoSQL-MongoDB介紹
Upcoming SlideShare
Loading in …5
×

NoSQL-MongoDB介紹

完整的MongoDB介紹,從開發到管理

  • Be the first to comment

NoSQL-MongoDB介紹

  1. 1. NoSQL – MongoDb介 紹
  2. 2. 大綱 • NoSQL介紹 • CAP理論介紹 • MongoDb介紹 • MongoDb開發 • MongoDb管理 • MongoDb的工具
  3. 3. NoSQL介紹 • NoSQL是Not Only SQL。 • NoSQL的目標在於解決過去關聯式資料庫(RDBMS)在某些系統應用 環境下的不足。 • RDBMS提供強大的交易功能,但是對於過大的資料量以及每秒過多的 讀寫需求(Record per Second, rps)會浪費太多系統資源在於交易控制與 資源分配。 • 目前商業的RDBMS所提供的功能很完整但是並非每個功能模組都會 需要用到,但都需要一齊買單。
  4. 4. SQL過去的問題 • Schema調整不易 • Join很傷效能 • 過度要求的交易一致性,在某些應用場景不合適
  5. 5. NoSQL的歷史 • 最早出現在1998年,不提供SQL的關聯式資料庫。 • 2009年,發起分散式資料庫的議題,此時的NoSQL已不強調關聯,開始放 棄ACID。
  6. 6. NoSQL特性 • 執行在一堆便宜的伺服器上。 • 降低效能瓶頸。 • 適量的功能模組。 • 開放原始碼。
  7. 7. NoSQL的種類 儲存類型 NoSQL產品 特性 Document MongoDb Document儲存一般會使用類似於Json格式儲存, 如此 就可以針對某些欄位建立索引,實現RDBMS某些功能。 欄(Column) Hbase, Cassandra, Hypertable 依欄位儲存,最大的特點是方便將儲存的內容結構化, 當查詢某幾欄時有最好的I/O。 鍵值組 Redis, Tokyo Cabinet/Tokyo Tyrant, Flare 透過鍵快速檢索到值,值沒有特定格式。 物件 db4o, Versant 以物件導向語法操作資料庫。 圖形 Neo4J, FlockDB 圖形關聯的最佳化儲存。 XML Berkeley DB XML, BaseX 支援XML的內部查詢語法。(Xquery)
  8. 8. CAP理論介紹 • CAP理論是NoSQL系統架構設計的核心觀念。 • CAP理論與過去系統設計有著極大的不同,故,需要調整設計的想法。 • CAP理論適用在某些特定場合(i.e. 分散式),並非是所有情境。
  9. 9. 關聯式資料庫主要的功能 • 交易 • 處理關聯 • 強大的工具組(Toolkit) • 年代悠久,人才資源豐沛
  10. 10. ACID的問題 • ACID是四個字的縮寫: • Atomic(原子性/不可分割性) • Consistency(一致性) • Isolation(隔離性) • Durability(持久化) • 時下用於達成ACID設計的手法有兩種: • 日誌 • MultiVersion • 要真正達到分散式系統的ACID是相當困難的。
  11. 11. 交易隔離等級 交易隔離等級 描述 Read Uncommitted 幾乎沒做資料保護,容易出現髒資料讀取;其效能最高 Read Committed 只允許讀取已認可的資料,重覆讀取時有可能讀到髒資料 Read Committed Snapshot Read Committed具有Snapshot的能力 Snapshot 多版本策略,讓讀取與寫入同一筆資料可以同步進行 Repeatable 連查詢的資料也會鎖定,但允許另一個交易新增/刪除,故,有幽靈資料 Serializable 所有操作皆會鎖定,資源消耗最大,
  12. 12. 交易的優缺點 • 優點: • 資料的強制且快速的一致化 • 缺點: • 消耗大量資源 • 帶來死結 • (思辨) 是否真的有必要做到即時且強制的一致化?
  13. 13. CAP的基本思維 • CAP是三個字的縮寫: • Consistency(一致性) • Availability(可用性) • Partition Tolerance(分區容錯) • 在分散式的環境中,僅能在上述三種特性中完成其中兩者。
  14. 14. 一致性(Consistency) • CAP中所提到的一致性指的是強一致性。 • 系統在執行過某項操作後仍處於一致的狀態。 • 在分散式系統中,若更新了一筆資料成功後,所有讀取這筆更新過後資 料的操作都會到讀取到相同的資料。
  15. 15. 可用性(Availability) • 只要Node的健康狀態是優良的,它必定要能夠回應使用者的請求 (Request)。
  16. 16. 分區容錯(Partition Tolerance) • 在分散式系統中某個節點毀損仍可提供服務。 正常狀態 異常狀態
  17. 17. CAP的認知 • (一致性, 可用性) -> 可擴展性低 • (一致性, 分區容忍) -> 性能低 • (可用性, 分區容忍) -> 一致性低
  18. 18. 其實,CAP並沒有聲明 • 放棄一致性 • 不一致應該要是一個例外,不是常態 • 放棄交易(ACID) • 其實只需要調整C和I的預期 • 不使用SQL • 已有不少NoSQL也使用類SQL語法
  19. 19. BASE • BASE其實是三個字的縮寫: • Basically Available(基本可用): 盡可能滿足CAP中的A和P。 • Soft-State(軟式狀態): 資料狀態可以有一段時間不一致。 • Eventual Consistency(最終一致性): 不強調高一致性。 • BASE與ACID不同之處在於它並不強調強一致性,藉由最終一致性允 許資料在一段時間內不一致來提供可用性。
  20. 20. 不一致窗(Non-Consistency Window) • 最終一致性會產生一個資料不一致的時間區間,而這個區間就是不一 致窗。 • 每個系統依其特性甚至是功能都有其不一致窗的最低容忍程度,可以 說系統在設計某個功能時要詳細琢磨其不一致窗的容忍程度;若不一 致窗的寬度是0,則此功能勢必會需要關聯式資料庫最高交易隔離等級, 但同時意味著此功能效能始終先天就存在瓶頸。
  21. 21. MongoDb的介紹 • 2007年10gen公司想開發一個PaaS平台,但開發人員只對他們的資料庫 有興趣,後來抽出來成為MongoDb。 • 以C++開發,採GNU_AGPL方式授權。 • 2009年11月推出1.0版,之後每三個月改版一次,目前穩定版本為:2.4.8 • 是Document-Oriented的資料庫。 • 適合Web環境。
  22. 22. MongoDb的資料結構 • MongoDb的資料結構如下 • DataBase • Collection => 類似RDBMS中的Table • Document => 類似RDBMS中的Record • Field => 類似RDBMS中的Column • 一個DataBase可以擁有好幾個Collection;一個Collection可以有好幾筆 Document。 Document 資料庫 集合 集合 Document
  23. 23. MongoDb的特性 • Document是使用BSON資料格式儲存。 • 語法思維與JavaScript相似。 • 以參考(DbRef)與內嵌式Document來達成RDBMS中的資料表關聯。 • 讀取效能高於寫入效能。 • Schema-Free • 採用BASE理論 • 資料操作是採用無回應式。
  24. 24. MongoDb的前題假設 • 假設有足夠大的硬碟空間 • 記憶體足夠放入所有的熱資料 • 系統是64位元 • 系統採用Little-Endian • 多台提供給MongoDb使用的伺服器 • 允許安全與效能的抉擇
  25. 25. MongoDb適用場景 • 網站登入/出 • 快取 • 大型檔案的儲存 • 需擴充 • 事件紀錄
  26. 26. MongoDb不適用場景 • 高交易需求的系統;銀行/會計系統。 • BI應用;針對特定問題的BI資料庫會進行特殊優化的查詢方式,對於此 類型應用,採用Data Warehouse較適合。
  27. 27. MongoDb業界實例
  28. 28. MongoDb的安裝 • 連外文章
  29. 29. MongoDb連線 • MongoDb提供以命令提示字元連線,其連線字串規則如下: • Mongo [options] [db address] [js檔案完整路徑] • db address範例: • MyDb • 127.0.0.1/MyDb • 127.0.0.1:27017/MyDb
  30. 30. MongoDb連線字串可選參數 參數 描述 範例 --shell 執行完指定的.js檔之後跑shell mongo –-shell myDb --nodb 剛啟動時不會先連到資料庫 mongo –-nodb --norc 剛啟動時不會先執行js檔 mongo –-norc --port [port號] 指定連線的埠號 mongo –-port 27017 --host [主機名] 指定連線到某台主機 mongo –-host MyPC -u 連線時的帳戶 mongo –u root -p 連線時的密碼 mongo –u root –p P@$$w0rd
  31. 31. MongoDb中重要的集合 集合 作用 system.namespaces 儲存命名空間資訊 system.indexes 儲存索引資訊 system.profile 儲存優化器資訊 system.users 儲存帳戶資訊 local.sources 儲存Replica Set的組態和狀態資訊
  32. 32. MongoDb的資料型別(1) 資料型別 描述 範例 Null 代表空值或不存在 {"x":null} Boolean True/false {"x":true} String 任意UTF-8的字串 {"x":"foobar"} Symbol MongoDb Shell不支援的符號會自動轉成字串 Object Id {"x":ObjectId()} Number 長度為4/8 byte的整數與8byte的浮點數 {"x":1} Long Number 超過8byte的整數或浮點數會以top和bottom描述 高低位4byte的值 {"x":9223372036854776000}
  33. 33. MongoDb的資料型別(2) 資料型別 描述 範例 date 儲存從1970/1/1開始到現在的毫秒數 {"x": new Date()} Regular expression 採用JavaScript的正則式語法 {"x": /foobar/i} Code JavaScript 函數 {"x": function() { ... }} Array 陣列 {"x": ["a","b","c"]} Embedded document 嵌套的document {"x": {"foo","bar"}}
  34. 34. MongoDb的Document • MongoDb可以隨意添加或減少每一筆Document。 • 每筆Document大小都不得超過4MB。 • MongoDb的Document預設會額外添加一個欄位:_id。_id預設資料型別 為:ObjectId,但亦可指定為其它型別。 • ObjectId的大小為12bytes,並且使用24個16進位的字串來表示;每兩個數字代 表一個Byte。 • ObjectId範例: • 0|1|2|3|4|5|6|7|8|9|10|11 時間戳記 機器 PID 增加量
  35. 35. MongoDb開發 • Mongo官方提供與MongoDb介接的程式語言驅動程式,支援語言如下: • C/C++ • C# • Erlang • Java • JavaScript • Node.js • Perl • PHP • Python • Ruby • Scala
  36. 36. MongoDb Shell • MongoDb可以使用命令提示字元操作資料庫。 資料庫名稱 MongoDb版本
  37. 37. 一般操作指令 指令 描述 show dbs 列出連線的這個MongoDb實體內 含的所有資料庫 show collections 列出連線的這個資料庫內含的所有 集合 Use MyDb 切換到另一個資料庫 db.Collectio n.drop() 刪除指定集合
  38. 38. 查詢(與SQL的對應) 集合(資料表) 查詢條件 投影 游標修飾子 投影 資料表 查詢條件 游標修飾子
  39. 39. 查詢處理
  40. 40. MongoDb查詢的運算子 運算子 對等運算 運算子 對等運算 $gt > $lt < $gte >= $lte <= $all 符合所有列舉值 $exists 判斷指令欄位是否存在 $mod 運算的欄位符合指定的模數與餘數 $ne != $nin not in(…) $size 指定的欄位為陣列且大小符合指定值 $in in(…)
  41. 41. 查詢游標 • MongoDb使用find()方法進行查詢,其回傳值為查詢資料結果的游標,可以使 用游標提供的API進行遍覽: • 以下條件發生時,游標會自動回收: • 超過10min沒有任何動作 • 用戶端資源耗盡 • MongoDb預設會做空間預分配的動作,但有的時候修改過的資料遠大於原本 的資料,這會讓資料無法替換掉原始資料而被放置到尾端,這個時候就會發生 游標資料重覆出現的狀況。
  42. 42. 查詢實務應用 應用 範例 OR條件 db.users.find({"$or": [{"ticket_no" : 725}, {"winner": true}]}) 值區間 db.users.find({"age": {"$lt": 30, "$gt": 20}}); 反閘 db.users.find({"id_num": {"$not": {"$mod" : [5,1]}}) 正則式 db.users.find("name": /john/i}) 陣列元素完整符合 db.food.find({"fruit": ["apple", "banana"]}) 陣列元素內含指定值 db.food.find({"fruit": {"$all": ["apple", "banana"]}}) 陣列元素指定筆數 db.food.findOne({"name": /^a/i},{"fruit": {"$slice":[1,5]}}) 查詢內嵌Document db.people.find({"name.first": "joe", "name.last": "Schmoe"})
  43. 43. 游標修飾子 指令 描述 範例 count 查詢紀錄條數 db.users.find().count() skip 指定結果集的啟始位址 db.users.find().skip(3) limit 限制結果集的筆數 db.users.find().limit(10) Sort 排序 db.users.find().sort({age:1,name:-1})
  44. 44. 群組運算 指令 描述 範例 distinct 取得指定欄位的不重覆值 db.users.distinct("name") group 與SQL的group功能一致 db.coll.group({ key: {a: true, b: true}, cond: {active: 1}, reduce: function(obj,prev) { prev.csum +=obj.c;}, initial: {csum: 0} }); (等同)Select a,b,sum(c) From coll Where active=1 group by a,b
  45. 45. MapReduce • Mapreduce: 要操作的集合名稱 • Map: 映射函數 • Reduce: 統計函數 • Out: 統計後的結果集 Map函數 Reduce函數 MapReduct 最終結果
  46. 46. 新增 集合(資料表) 欄位: 值 欄位: 值 欄位: 值 資料表 欄位 值
  47. 47. 新增的本質 • 當執行插入,驅動程式在將資料傳至資料庫之前,會先將資料轉換成為 BSON;資料庫會試著解讀BSON,確認_id欄位是否存在,並且檢查 Document大小不超過4MB。
  48. 48. 刪除 集合(資料表) 查詢條件 查詢條件 資料表
  49. 49. 刪除的幾種方式 • 除了依條件刪除指定的Document之外,還可以有以下方式: • db.users.remove() – 刪除users集合中所有Document。 • db.users.drop() – 刪除users集合所有Document和索引。
  50. 50. 更新 • 有幾種處理方式: • 替換Document • 使用修飾子 • 多筆更新/upsert
  51. 51. 替換Document
  52. 52. MongoDb為Update提供的修飾子 修飾子 描述 範例 $set 針對欄位進行修改 db.users.update({name:'john'},{$set:{name:'john2'}}) $unset 移除某個欄位 db.users.update({name:'john'},{$unset:{age:1}}) $inc 增加/減少某數字型欄位的值 db.users.update({name:'john'},{$inc:{age:10}}) $push 增加某值到陣列型欄位中 db.user.update({name:'john'},{$push,{comment:'Hi'}}) $addToSet 增加某值到陣列且不重覆 db.user.update({name:'john'},{$addToSet:{emails:'john @mail.com'}}) $ 位址運算子 db.user.update({name:'john'},{$set:{emails.$.subject:'hi'} }) $pop 刪除陣列中第一/最後值 db.user.update({name:'john'},{$pop:{emails:1}}) $pull 刪除陣列某個指定值 db.user.update({name:'john'},{$pull:{emails:'tom@mail.c om'}}) $pullAll 刪除陣列多個指定值 db.user.update({name:'john'},{$pullAll:{emails:['tom@m ail.com','tom@mail.com']}})
  53. 53. 多筆更新 • MongoDb預設只會針對符合條件的第一筆Document進行修改。 • MongoDb在update的API為: • update(條件,新值,upsert,multi); • Upsert會依條件判斷是否有 該筆Document存在,若有則修 改其值;若無則新增一筆。 • db.users.update({name:'john'}, {$set:{name:'john'}},true,false) • 若設定了multi,則update會更新多筆。 • db.users.update({name:'john'}, {$set:{name:'john'}},false,true)
  54. 54. MongoDb開發-C# • 可以到MongoDb的官網下載C#的Driver或是直接從Nuget管理套件下 載Mongo C# Driver。
  55. 55. 使用套件簡化程式
  56. 56. GridFS • MongoDb在處理大型二進位資料的儲存方面採用GridFS機制。 • GridFS將大型二進位資料切割成一塊塊的Chunk(區塊)以及檔案的 MetaData,分別存入集合:fs.chunks和fs.files。 (取出) (儲存)
  57. 57. GridFS的檔案MetaData 屬性名稱 描述 filename 儲存的檔案名稱 chunkSize Chunk大小 uploadDate 上傳檔案進資料庫的時間 md5 檔案的md5,用於檢驗檔案完整性 length 檔案大小(註:單位為Bytes)
  58. 58. 以C#撰寫
  59. 59. MongoDb的管理 • 管理的操作主要有下列幾個項目: • 連線控制 • 帳戶管理 • 資料匯入/出 • 資料複製 • 資料庫壓縮 • HA • 效能監控
  60. 60. 連線控制 • MongoDb在啟動實體的時候預設是開放連線的,但若希望限定只有特 定IP才能連線,需要在實體啟動的指令(註:mongod)再加上欲綁定的IP。 • MongoDb預設傾聽的埠號:27017,但由於是預設可能有被攻擊的風險, 故,仍需要置換埠號。
  61. 61. 帳戶連線管理 • MongoDb對於帳戶的管理不像RDBMS那般複雜,最多只能控制帳戶是 否唯讀。 • 設定實體要驗證登入的用戶帳號: • 若僅是設定實體要驗證但是卻沒有加入任何帳號到該實體,則 MongoDb這個實體仍然不會去驗證帳戶。
  62. 62. Admin資料庫 • MongoDb實體在啟動後預設會有一個用來管理帳戶的資料庫: • admin.system.users • 當admin.system.users的內容為空時,縱使在啟動MongoDb實體時有加上 啟用登入驗證的參數(註:auth)仍是無用。
  63. 63. 建立超級帳戶的步驟 • 登入MongoDb的實體,切換到admin資料庫 • 輸入: db.addUser({user:'root',pwd:'123', roles:['userAdminAnyDatabase']}) • 切回test資料庫再次輸入db.addUser('root','123') • 重啟MongoDb實體,並加上驗證參數: --auth
  64. 64. 使用超級帳戶建立其它帳戶 • 使用超級帳戶登入實體。 • 先切換到admin資料庫,並輸入:db.auth('root','123') • 切換到欲添加其它帳戶的資料庫: use test • 添加帳戶: db.addUser('john','123')
  65. 65. 版本2.4之後的變異 • MongoDb在版本2.4之後對於帳戶權限控制有了更多樣化的設定 • 在2.4之前沒有角色的概念,僅能對帳戶設定唯讀與否 • 新增角色如下: 角色 描述 角色 描述 read 在指定的資料庫中可讀取任 何集合的資料 readWrite 在指定的資料庫中可讀寫 任何集合的資料 dbAdmin 在指定的資料庫中可執行資 料庫維護指令 userAdmin 在指定的資料庫中為超級 帳戶
  66. 66. 一次性套用權限到所有資料庫 角色 描述 角色 描述 readAnyDatabase 可讀取所有資料庫的 資料 readWriteAnyDatabase 可讀寫所有資料庫的 資料 userAdminAnyDatabase dbAdminAnyDatabase 可執行所有資料庫的 維護指令
  67. 67. 陷阱 • MongoDb為了要能夠相容前面版本,所以把新的帳戶API關閉,要使用 新的API必須要在啟動MongoDb實體的時候設定參數: supportCompatibilityFormPrivilegeDocuments=0 • 新API: • db.addUser({user:'root',pwd:'123',roles:['readWrite','userAdmin'],otherDBRol es:{test:['userAdmin']}}
  68. 68. 資料匯出 • MongoDb的資料匯出指令為:mongoexport • 可以匯出的資料格式為:Json/CSV
  69. 69. 資料匯出參數 參數 描述 參數 描述 -h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號 -u <username> 登入帳戶 -p <password> 登入密碼 --db <dbName> 指定匯入的資料庫 -c <collection> 指定匯入的集合 --f <field1, field2,..> 指定匯入的欄位 --fieldFile <fileName> 指定額外的欄位檔名 --q <json> 資料匯出篩選條件 --csv 指定匯出格式為csv -k 讀取replica set中的副節點 資料 -o 匯出的檔案完整路徑 --jsonArray 匯入的資料格式為json陣 列 --forceTableScan 略過_id欄位,僅掃描資料欄 位
  70. 70. • 欲匯出的資料: • 資料庫:test • 集合: Student • 匯出年齡大於18歲且檔案格式為CSV,資料欄位僅:name,age: • 匯出結果:
  71. 71. 資料匯入參數 參數 描述 參數 描述 -h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號 -u <username> 登入帳戶 -p <password> 登入密碼 --db <dbName> 指定匯入的資料庫 -c <collection> 指定匯入的集合 --f <field1, field2,..> 指定匯入的欄位 --fieldFile <fileName> 指定額外的欄位檔名 --ignoreBlanks 值為空則忽略該欄位 --type <json/csv/tsv> 宣告匯入的資料格式 --file <filename> 匯入的檔案名稱 --drop 匯入前清空集合資料 --headerline 首欄作為欄位名稱 --upsert 僅匯入集合沒有的資料 --upsertFields <field1,..> upsert比較的欄位 (預設僅比較_id欄位) --stopOnError 當有錯誤發生時停止繼 續匯入 --jsonArray 匯入的資料格式為json陣列
  72. 72. • 清空集合Student中的資料 • 匯入CSV資料: • 匯入資料: • 匯入結果:
  73. 73. 資料備份 • 備份指令為:mongodump • 內部動作原理其實是先進行查詢,再將資料寫入備份檔案中。 • 備份過程中會一定程度的降低系統效能。 • 備份的資料並不一定是完整的,因為mongodump只是下一道普通的查 詢命令 。
  74. 74. 資料備份參數 參數 描述 參數 描述 -h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號 -u <username> 登入帳戶 -p <password> 登入密碼 --db <dbName> 指定匯入的資料庫 -c <collection> 指定匯入的集合 --f <field1, field2,..> 指定匯入的欄位 --fieldFile <fileName> 指定額外的欄位檔名 --q <json> 資料匯出篩選條件 -o 匯出的檔案完整路徑 --repair 讀取replica set中的副 節點資料 --forceTableScan 略過_id欄位,僅掃描資 料欄位
  75. 75. 備份test資料庫
  76. 76. 備份資料庫的Best Practice • 備份資料庫會造成一定程度的效能損耗,除此之外,備份的資料無法完整符合 當下的資料。 • 若系統有組態ReplicaSet,則可以在Slave節點上進行資料庫鎖定後再執行備份 指令: db.runCommand({fsync:1, lock:true}) – 鎖定 • 解鎖較為複雜: use admin db.$cmd.sys.unlock.findOne() db.currentOp() [若回傳{“inprog”:[]}代表解鎖成功了]
  77. 77. 資料還原參數 參數 描述 參數 描述 -h <hostname><:port> 指定匯入的主機名稱 --port MongoDb實體的埠號 -u <username> 登入帳戶 -p <password> 登入密碼 --db <dbName> 指定匯入的資料庫 -c <collection> 指定匯入的集合 -objcheck 驗證匯入的每筆資料 --noobjcheck 不驗證匯入的資料 --filter ‘<json>’ 篩選匯入的資料 --drop 匯入前先清除資料庫資料 --keepIndexVersion 避免匯入時索引異動 --noOptionsRestore 避免匯入時組態的異動 --noIndexRestore 保留原資料庫索引
  78. 78. 還原
  79. 79. 資料複製 • MongoDb提供遠端複製集合/資料庫的指令。 • 複製資料庫的指令也可用在原機複製,但集合就不支援原機複製。
  80. 80. 複製集合 • 語法: db.runCommand({cloneCollection: 'TT.Student',from:'127.0.0.1:27017'}) • 除了複製集合之外,也會複製索引。
  81. 81. 複製資料庫
  82. 82. 資料庫壓縮 • MongoDb預設會預分配空間給資料,但是資料在經過一段時間的異動 操作後會產生大小不一的空間破碎,而這些空間破碎除了造成硬碟空 間利用率下降之外,也造成資料查詢速度的緩慢。 • MongoDb提供兩個查詢集合大小的指令: • db.Student.storageSize() –MongoDb分配給這個集合的空間(包含預分配的空間) • db.Student.totalSize() –實際資料的大小加上此集合所用到的索引大小 • 壓縮資料庫:(註: 會大量消耗硬碟空間以及阻塞用戶) • db.repairDatabase()
  83. 83. ReplicaSet • 帶來的優勢: • Slave可以執行查詢,降低Master的查詢壓力 • 可在Slave上備份,避免備份因素而需要鎖定Master的資料庫 • 當Master故障時,可以快速切換到Slave,減少DownTime • Master會將讀取的請求交遞給Slave。
  84. 84. OpLog • 建立ReplicaSet後每個MongoDb實體都會啟動OpLog。 • OpLog是一個MongoDb的Collection。 • OpLog會紀錄資料異動歷程,當紀錄的資料超過所限制的大小會清掉 最舊的資料再開始紀錄。 • Slave會定期查詢Master的OpLog,若有差異出現則進行資料同步。
  85. 85. 啟動三個實體 • 分別啟動三個實體,其埠號分別 是: • 實體1: 30000 • 實體2: 30001 • 實體3: 30002 • ReplicaSet的重要參數: replSet;所 有實體都使用同一個replSet名 稱:MyRS。
  86. 86. 啟動ReplicaSet • 連入實體1,並輸入: rs.initiate() • 直到看到實體1的實體寄宿的 Console顯示它已成為Primary為 止。(通常會等待5分鐘)
  87. 87. 加入Secondary • 加入Secondary的指令為: • rs.add(‘[主機名稱]:Port’) • 直到看到實體1的實體寄宿的 Console顯示它已成為Secondary 為止。
  88. 88. 加入Arbiter • 加入Secondary的指令為: • rs.addArb(‘[主機名稱]:Port’) • 直到看到實體1的實體寄宿的 Console顯示它已成為Secondary 為止。
  89. 89. rs.Add 屬性 描述 _id 從0開始的序號 host 資料格式為[主機名稱]<:Port> arbiterOnly True/False,標明此成員是否為仲裁者 buildIndex True/False,標明此成員是否要建立索引 hidden True/False,標明此成員不接受讀取請求 Priority 1~100,指定當Primary故障後,此成員替補的優先權 tag 資料格式為Document,描述此成員的相關資訊;常用於getLastError SlaveDelay 0~N,設定此成員的資料落後Primary幾秒 Votes 0~1,控制當投票時,該成員的選票權重
  90. 90. 確認ReplicaSet中每個節點的狀態
  91. 91. 設定Secondary允許讀取
  92. 92. ReplicaSet的節點角色 角色 描述 Primary 主節點,一個ReplicaSet中僅能有一個主節點 Secondary 副節點,持有主節點的資料複本,Client可視且可讀取其資料。 Secondary(Priority0) 與Secondary相同,唯一不同之處在於它無法轉任成主節點。 Hidden 持有主節點資料複本,Client看不到,不可轉任成主節點。 Arbiter 不持有任何資料,僅在投票時使用。 Delayed 所持有的資料與主節點有時間點上的落差,不可轉任為主節點。
  93. 93. ReplicaSet發起投票的狀況 • ReplicaSet之間彼此每2秒會Ping對方,如果Primary超過10秒沒有回應,則 代表Primary已經Fail。 • 新的ReplicaSet剛成立。 • Primary被管理人員手動Step Down。
  94. 94. 投票狀況1
  95. 95. ReplicaSet的節點狀態 狀態 是否允許投票 描述 StartUp 解譯ReplicaSet的組態資料 Primary 主節點;唯一可接受寫入請求的節點 Secondary 副節點,可接受讀取請求,在主節點發生錯誤時可以替代 Recovering 節點正處於自我確認或從完成狀態移轉成RollBack狀態 Fatal 此節點遭遇無法修復的錯誤 Startup2 即將成為副節點 Unknown 此節點曾存在Set中,但發生不明錯誤 Arbiter 不會複寫主節點資料,僅參與投票 Down 此節點曾存在Set中,但目前正下線中 RollBack 節點正處於RollBack狀態 Shunned 此節點曾在ReplicaSet,但現在不在了
  96. 96. 複寫相關API(1) 函數 描述 範例 initiate 初始化整個ReplicaSet rs.initiate() conf 組態整個ReplicaSet的成員設定 reconf 異動過ReplicaSet後,重新套用組態 var cfg = rs.conf(); cfg.members[0].priority = 2; rs.reconfig(cfg); add 添加一個新成員到ReplicaSet rs.add({_id:0, host: MyCom:27001}) addArb 添加一個仲裁者進ReplicaSet中 rs.addArb(“MyComp:27001”) status 查看整個ReplicaSet的當前組態 rs.status() remove 將某個成員從ReplicaSet中移除 rs.remove(“MyComp:27001”)
  97. 97. 複寫相關API(2) 函數 描述 範例 stepDown Primary節點自動降級為Secondary rs.stepDown() freeze 成員在指定的時間內,若Primary故障則該成員無 法成為Primary rs.freeze(300) slaveOk 該成員為Secondary且允許被讀取其資料 rs.slaveOk() syncFrom Secondary成員指定資料複寫的來源對象 rs.syncFrom(“MyComp:27001”) isMaster 詢問當前連線的實體是否為Primary db.isMaster()
  98. 98. 寫考量(Write Concern) • 當Mongo的佈署架構使用了ReplicaSet之後,就會開始出現”最終一致性” 方面的議題。 項目 描述 ErrorIgnore Client無法得知MongoDb實體回應的錯 誤,但效能是最高的 Unacknowledged Client僅能得知網路方面的錯誤 Acknowledged Client會等待並偵測錯誤 Jounaled MongoDb實體只會在Commit後回應 Replica Acknowledged 在資料確任寫入Secondary後才回應
  99. 99. 讀喜好(Read Preference) • 具備ReplicaSet的MongoDb,其讀取的負擔可以分散給Secondary節點,也 因此有各種不同讀取上的機制。 項目 描述 Primary 預設;所有人都只讀取Primary的資料 Primary Preffered 主要都讀取Primary,若Primary無法及時服務,則讀取 Secondary Secondary 全都讀取Secondary Secondary Preffered 主要讀Secondary,若無法及時服務,則讀取Primary Nereast 不論是Primary/Secondary,讀取最接近的

×