速覽
正如發布MongoDB 5.0時承諾的更快發布頻率,年度大版本MongoDB 6.0也于2022年正式跟廣大數據庫愛好者們見面了。目前阿里云MongoDB已經完成了對6.0版本的適配工作,大家可以直接在官網控制臺進行購買和嘗鮮體驗!
該版本的主要功能特性包括:
● 時序集合增強
● Change Stream增強
● 可查詢加密
● 聚合&query能力增強
● 集群同步
總結來看,MongoDB 6.0的新功能旨在促進開發和運營,消除數據孤島,并消除因不必要地使用額外第三方技術而帶來的業務復雜性。
新特性
時序集合(time series collections)
作為從5.0發布時面向時序數據的全新功能,時序集合標志著MongoDB這一OLTP型數據庫希望能處理好更多AP型場景的決心,官方對時序集合的支持也一直保持著高速的更新&改進頻率。比如為了支持更好分布數據而在5.1引入的分片(sharding)、為了改善存儲空間占用而在5.2引入的列式壓縮(columnar compression)以及為了支持部分數據點缺失情況下的時序分析而在5.3引入的密集化和間隙填充(densification and gap-filling)
另外,時序集合的索引方面也有增強。從6.0開始,為了提高讀取性能,時序集合現在包括測量的二級和復合索引。時序數據也開始和空間維度進一步結合形成時空數據,時序結合開始支持地理位置索引(geo-indexing)。通過將地理信息附加到時間序列數據,開發人員可以更好地分析涉及舉例和位置的場景。比如跟蹤夏日冷鏈運輸車的溫度變化情況以及監測特定航線上的貨運船燃料消耗等。
性能方面也有一些優化,主要針對的是查詢以及排序場景。比如MongoDB可以更快返回時序數據中的最后一個數據點("last point" query),而不再需要掃描整個集合以后才得到想要的數據;通過在時間以及元數據字段上的聚簇索引(clustered index)以及二級索引(secondary index)能夠更高效地完成排序操作。
Change Stream
作為支持CDC的核心功能之一,Change Stream迎來了自MongoDB 3.6發布以來的一次重大更新。有了Change Stream,業務可以更容易地實時獲取數據庫的變更,并基于此構建各種事件驅動型的應用或系統,不再需要依賴其他的數據同步中間件。
看新特性之前讓我們先看下之前版本里有關Change Stream功能的更新歷史:
在這次的MongoDB 6.0版本里。對Change Stream的更新包括:
● 支持變更的前后視圖(pre-image和post-image)
● 支持更多的DDL(包括
create/createIndexes/modify/shardCollection)
● 性能提升:聚合框架上pipeline中stage的下推以及優化
●change event新增了wallTime字段,時間戳也能支持多種轉換和展示算子($toDate/$tsSeconds/tsIncrement)以方便業務消費
在之前,客戶端只能通過change events獲取文檔變更后的狀態,現在也能支持獲取變更前的狀態了。這使得一些同時需要變更前&變更后的下游系統(用作校對或審計)能夠充分利用數據庫原生的能力而無需自行在業務層面耦合。更靈活的功能形態將大大擴展changeStream未來的使用場景。與此同時,支持更多的DDL操作也使得Change Stream的應用場景限制變得更少,不再會遇到經常中斷后需要resume的情況。之前的使用場景中,分片集群需要mongos做merge,導致mongos成為整個changeStream的瓶頸點,性能也不夠理想;這次從框架層面的優化以及部分場景下的stage下推帶來的性能提升值得期待。
總而言之,這次大版本的功能升級也是對用戶廣泛訴求(SERVER-36941以及SERVER-46414)的積極響應,表明了MongoDB對數據庫使用者體驗上的關注。
Queryable Encryption (Preview)
數據安全正在肉眼可見地變得越來越重要。已有的傳輸加密或者靜態加密手段沒辦法實現在使用過程中的加密,這使得更復雜的加密和更方便的查詢看起來是背道相馳的事情。MongoDB 6.0推出的可查詢加密可以允許用戶從客戶端加密敏感數據,將其作為完全隨機的加密數據存儲在數據庫服務器端,并對加密數據直接進行豐富的查詢。
從下面的示例中可以看到只有客戶端能看到敏感信息的明文,在query到達server時會同時包含從KMS獲取的加密秘鑰,然后在server端以密文進行查詢并返回,最后在客戶端用驅動利用密鑰解密后以明文呈現。
其特點&優勢包括:
● 從客戶端加密敏感數據,只有客戶端擁有加密密鑰。
● 數據在整個生命周期(傳輸、存儲、使用、審計或備份)中都是加密的。
● 客戶端可以直接對加密數據進行豐富的查詢(等值匹配、范圍、前后綴、子字符串等查詢類型)。
● 強大的數據隱私保護能力,只有能訪問客戶端應用程序和加密密鑰的授權用戶才能看到明文數據。
● 更輕量化的應用程序開發,涉及敏感數據的開發者無需考慮太多安全、合規的事情,數據庫直接提供綜合加密解決方案。
● 降低敏感數據上云的安全顧慮。
值得一提的是,可查詢加密功能依然是預覽(Preview)版本,不建議直接在生產環境使用。社區版不支持客戶端字段級加密(Client-Slide Field Level Encryption)的自動加密,可以使用顯示加密(需要使用驅動的加密庫lib)。
聚合功能
MongoDB的聚合功能允許用戶處理多個文檔并返回計算結果。通過將多個操作符組合到聚合管道中,用戶可以構建出足夠復雜的數據處理管道以提取數據并進行分析。MongoDB 6.0持續在聚合功能上深耕,帶來了一些新的功能以及優化,包括:
● 改進了$lookup對JOINS的支持;
● 改進了$graphlookup 對圖遍歷的支持;
● $lookup和$graphlookup 支持分片集群;
● $lookup性能提升(部分場景可達百倍)。
Query
新增了一些查詢操作符的支持。比如$maxN、$topN、$minN、$bottomN、$lastN、$sortArrary等。主要目的是利用操作符算子將更多的計算從業務中下沉到數據庫中,使得業務層更加輕量化。這些$xxxN可以看做對原本$min/$max/$last操作符的補充,用戶可以視實際業務場景中需要返回一個或者多個結果來使用不同的操作符。
以$maxN為例,其既可以被使用在數組中,也可以集成進聚合語句的管道中。
# 用作arrary中
db.scores.insertMany([
{ "playerId" : 1, "score" : [ 1, 2, 3 ] },
{ "playerId" : 2, "score" : [ 12, 90, 7, 89, 8 ] },
{ "playerId" : 3, "score" : [ null ] },
{ "playerId" : 4, "score" : [ ] }
{ "playerId" : 5, "score" : [ 1293, "2", 3489, 9 ]}
])
# 給每個文檔增加新的字段,保留最大的2個分數
db.scores.aggregate([
{ $addFields: { maxScores: { $maxN: { n: 2, input: "$score" } } } }
])
# 用在聚合pipeline中
db.gamescores.insertMany([
{ playerId: "PlayerA", gameId: "G1", score: 31 },
{ playerId: "PlayerB", gameId: "G1", score: 33 },
{ playerId: "PlayerC", gameId: "G1", score: 99 },
{ playerId: "PlayerD", gameId: "G1", score: 1 },
{ playerId: "PlayerA", gameId: "G2", score: 10 },
{ playerId: "PlayerB", gameId: "G2", score: 14 },
{ playerId: "PlayerC", gameId: "G2", score: 66 },
{ playerId: "PlayerD", gameId: "G2", score: 80 }
])
# 找到單個游戲的3個高分
db.gamescores.aggregate( [
{$match : { gameId : "G1" }},
{
$group:
{
_id: "$gameId",
maxThreeScores:
{$maxN:{input: ["$score","$playerId"],n:3}}
}
}
] )
$maxN和$topN看起來有些重復,實則各有不同的使用場景。topN會返回排序后的結果,而maxN則并不依賴特定的排序規則。
$sortArrary則強化了數組內是若干子對象場景下的排序,用戶可以指定任意一個子文檔內的字段、嵌套字段或者復合字段來按需進行數組的排序。該操作符可以有效簡化部分帶數組排序的復合聚合查詢。
db.engineers.insertOne(
{"team":
[
{"name": "pat","age": 30,"address": { "street": "12 Baker St", "city": "London" }},
{"name": "dallas","age": 36,"address": { "street": "12 Cowper St", "city": "Palo Alto" }},
{"name": "charlie","age": 42,"address": { "street": "12 French St", "city": "New Brunswick" }}
]
}
)
# 多種查詢方式
db.engineers.aggregate( [
{ $project:{_id: 0,result:{$sortArray: { input: "$team", sortBy: { name: 1 } }}}}
] )
db.engineers.aggregate( [
{ $project:{_id: 0,result:{$sortArray: { input: "$team", sortBy: { age: -1, name: 1 } }}}}
] )
db.engineers.aggregate( [
{ $project:{_id: 0,result:{$sortArray: { input: "$team", sortBy: { "address.city": -1 }}}}
] )
更多細節請查閱相關查詢操作符的官方文檔。
彈性
初始化同步(initial sync)用于節點剛加入副本集時的數據同步階段。這一階段因性能差一直被詬病。在6.0官方通過支持基于文件拷貝的初始化同步模式,將同步的性能提升了4倍左右。不過目前僅企業版支持此功能。
水平伸縮方面,MongoDB 6.0在分片上做出了重大改進。將原本默認是64MB的chunk size調整成為了128MB,更大的數據塊,意味著更少的數據遷移頻率以及更低的網絡及路由層開銷。做出這樣的調整應該也是觀察到了廣泛客戶在分片集群上部署海量數據時遭遇到的chunk數量瓶頸及性能問題。為了避免一個全局參數過于武斷,MongoDB 6.0也支持了
configureCollectionBalancing命令,可以為不同的分片表設置不同的chunk size。比如數據規模特別大的分片表,將chunk size調整到256MB;數據規模相對較小但希望在shard上分布更均勻的表,將chunk size調整到64或32MB。
與此同時,該命令還允許對集合進行主動的碎片整理。相較于compact命令提供了更好的碎片整理服務,有效減少磁盤空間占用。
db.adminCommand(
{
configureCollectionBalancing: "<collection>",
chunkSize: <num>,
defragmentCollection: <bool>
}
)
安全性增強
下面的圖里展示了整個MongoDB產品的安全功能矩陣。除了前面提到的全新特性:queryable enryption,本次發布的MongoDB 6.0也帶來了其他安全性增強。
客戶端字段級加密(CSFLE, client-side field-level encryption)自19年發布以來就被廣泛應用于敏感數據的管理中,尤其是在將數據遷移到公有云的場景下。MongoDB6.0的CSFLE將支持任何符合KMIP(Key Management Interoperability Protocol)的密鑰管理提供商。作為領先的行業標準,KMIP優化了加密對象(如加密密鑰、證書等)的存儲、操作和處理,使得整個流程更加規范化。這也標志著,除了基于keyfile的本地秘鑰管理外,mongoDB也支持通過KMIP將自己與第三方秘鑰管理設備集成,為用戶提供更安全的保障。
此外,MongoDB 6.0允許對審計日志加密。審計日志中也可能包含了重要信息,可以被壓縮和加密后寫入磁盤,并且在審計日志的傳播過程中依然保持加密。
此加密功能僅適用于使用WT引擎的企業版本,當然Atlas也是默認開啟加密的。
集群同步(Cluster-to-Cluster Sync)
無論是數據的同構同步(mongo-to-mongo)還是異構同步(others-to-mongo& mongo-to-others)都是mongoDB生態中的一部分,官方在
mongoimport/mongoexport/mongodump/mongorestore的工具矩陣中一直沒有很好得規劃關于『數據同步』這一部分的生態位,因此MongoDB的數據同步也呈現出了百花齊放的形態,包括早期的connector、MongoShake、云服務提供商的DTS服務以及部分創業公司的商業化產品。
伴隨著MongoDB 6.0的發布,官方的同步工具mongosync也終于面世。它能提供跨任何環境的兩個 MongoDB 集群的連續、單向數據同步,無論是混合環境、Atlas、本地還是邊緣環境。用戶還可以實時控制和監控整個同步過程,按需啟動、停止、恢復甚至反轉同步。
集群內的數據同步由副本集和sharding完成,Cluster-to-Cluster Sync希望能解決集群間的同步問題,主要覆蓋以下場景:
● 自建到云服務的遷移或者反過來
● 創建單獨的私有化數據庫
● 支持Devops策略(比如blue-green部署)
● 構建專用的分析環境
● 滿足審計和合規性的本地化要求
● 中心向邊緣的同步
使用方式也與其他數據同步工具并無差異:1)準備好源和目標集群;2)部署mongosync;3)按需啟動同步;4)全量同步完成后,增量數據也會同步;5)利用common endpoint來終止同步關系。
遺憾的是,Cluster-to-Cluster Sync僅與在MongoDB6.0以上版本運行的源和目標集群兼容。這也意味著廣泛使用的其他低版本仍然要依賴之前的第三方同步工具來完成上面提到的數據遷移/同步場景。
因篇幅原因就不在這里列出。更多MongoDB 6.0版本變動細節請參考release-notes。(
https://www.mongodb.com/docs/v6.0/release-notes/6.0/) 云數據庫MongoDB版_兼容MongoDB托管數據庫_文檔型數據庫_數據庫-阿里云