在SequoiaDB巨杉數(shù)據(jù)庫聯(lián)合創(chuàng)始人兼CTO王濤看來,目前只有少量的NoSQL數(shù)據(jù)庫支持事務機制,如VoltDB、RavenDB、SequoiaDB、MarkLogic。并且,“NoSQL支持事務(ACID)是未來的趨勢,不支持事務的NoSQL會大大縮小其應用場景?!睂τ贏CID來說,是指數(shù)據(jù)庫事務機制正確執(zhí)行的四大基本要素,包含了:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。
成都創(chuàng)新互聯(lián)公司技術團隊十余年來致力于為客戶提供成都網(wǎng)站設計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設、成都品牌網(wǎng)站建設、成都營銷網(wǎng)站建設、搜索引擎SEO優(yōu)化等服務。經(jīng)過多年發(fā)展,公司擁有經(jīng)驗豐富的技術團隊,先后服務、推廣了成百上千網(wǎng)站,包括各類中小企業(yè)、企事單位、高校等機構單位。
NewSQL是對一類現(xiàn)代關系型數(shù)據(jù)庫的統(tǒng)稱,這類數(shù)據(jù)庫對于一般的OLTP讀寫請求提供可橫向擴展的性能,同時支持事務的ACID保證。這些系統(tǒng)既擁有NoSQL數(shù)據(jù)庫的擴展性,又保持傳統(tǒng)數(shù)據(jù)庫的事務特性。NewSQL重新將“應用程序邏輯與數(shù)據(jù)操作邏輯應該分離”的理念帶回到現(xiàn)代數(shù)據(jù)庫的世界,這也驗證了歷史的發(fā)展總是呈現(xiàn)出螺旋上升的形式。
在21世紀00年代中,出現(xiàn)了許多數(shù)據(jù)倉庫系統(tǒng) (如 Vertica,Greeplum 和AsterData),這些以處理OLAP 請求為設計目標的系統(tǒng)并不在本文定義的NewSQL范圍內(nèi)。OLAP 數(shù)據(jù)庫更關注針對海量數(shù)據(jù)的大型、復雜、只讀的查詢,查詢時間可能持續(xù)秒級、分鐘級甚至更長。
NoSQL的擁躉普遍認為阻礙傳統(tǒng)數(shù)據(jù)庫橫向擴容、提高可用性的原因在于ACID保證和關系模型,因此NoSQL運動的核心就是放棄事務強一致性以及關系模型,擁抱最終一致性和其它數(shù)據(jù)模型?(如 key/value,graphs 和Documents)。
兩個最著名的NoSQL數(shù)據(jù)庫就是Google的BigTable和Amazon的Dynamo,由于二者都未開源,其它組織就開始推出類似的開源替代項目,包括Facebook的 Cassandra (基于BigTable和Dynamo)、PowerSet的 Hbase(基于BigTable)。有一些創(chuàng)業(yè)公司也加入到這場NoSQL運動中,它們不一定是受BigTable和Dynamo的啟發(fā),但都響應了NoSQL的哲學,其中最出名的就是MongoDB。
在21世紀00年代末,市面上已經(jīng)有許多供用戶選擇的分布式數(shù)據(jù)庫產(chǎn)品。使用NoSQL的優(yōu)勢在于應用開發(fā)者可以更關注應用邏輯本身,而非數(shù)據(jù)庫的擴展性問題;但與此同時許多應用,如金融系統(tǒng)、訂單處理系統(tǒng),由于無法放棄事務的一致性要求被拒之門外。
一些組織,如Google,已經(jīng)發(fā)現(xiàn)他們的許多工程師將過多的精力放在處理數(shù)據(jù)一致性上,這既暴露了數(shù)據(jù)庫的抽象、又提高了代碼的復雜度,這時候要么選擇回到傳統(tǒng)DBMS時代,用更高的機器配置縱向擴容,要么選擇回到中間件時代,開發(fā)支持分布式事務的中間件。這兩種方案成本都很高,于是NewSQL運動開始醞釀。
NewSQL數(shù)據(jù)庫設計針對的讀寫事務有以下特點:
1、耗時短。
2、使用索引查詢,涉及少量數(shù)據(jù)。
3、重復度高,通常使用相同的查詢語句和不同的查詢參考。
也有一些學者認為NewSQL系統(tǒng)是特指實現(xiàn)上使用Lock-free并發(fā)控制技術和share-nothing架構的數(shù)據(jù)庫。所有我們認為是NewSQL的數(shù)據(jù)庫系統(tǒng)確實都有這樣的特點。
像MongoDB, Cassandra, HBase, DynamoDB, 和
Riak這些NoSQL缺乏傳統(tǒng)的原子事務機制,所謂原子事務機制是可以保證一系列寫操作要么全部完成,要么全部不會完成,不會發(fā)生只完成一系列中一兩個
寫操作;因為數(shù)據(jù)庫不提供這種事務機制支持,開發(fā)者需要自己編寫代碼來確保一系列寫操作的事務機制,比較復雜和測試。
這些NoSQL數(shù)據(jù)庫不提供事務機制原因在于其分布式特點,一系列寫操作中訪問的數(shù)據(jù)可能位于不同的分區(qū)服務器,這樣的事務就變成分布式事務,在分
布式事務中實現(xiàn)原子性需要彼此協(xié)調(diào),而協(xié)調(diào)是耗費時間的,每臺機器在一個大事務過程中必須依次確認,這就需要一種協(xié)議確保一個事務中沒有任何一臺機器寫操
作失敗。
這種協(xié)調(diào)是昂貴的,會增加延遲時間,關鍵問題是,當協(xié)調(diào)沒有完成時,其他操作是不能讀取事務中寫操作結果的,這是因為事務的all-or-
nothing原理導致,萬一協(xié)調(diào)過程發(fā)現(xiàn)某個寫操作不能完成,那么需要將其他寫操作成功的進行回滾。針對分布式事務的分布式協(xié)調(diào)對整體數(shù)據(jù)庫性能有嚴重
影響,不只是吞吐量還包括延遲時間,這樣大部分NoSQL數(shù)據(jù)庫因為性能問題就選擇不提供分布式事務。
MongoDB, Riak, HBase, 和 Cassandra提供基于單一鍵的事務,這是因為所有信息都和一個鍵key有關,這個鍵是存儲在單個服務器上,這樣基于單鍵的事務不會帶來復雜的分布式協(xié)調(diào)。
那么看來擴展性性能和分布式事務是一對矛盾,總要有取舍?實際上是不完全是,現(xiàn)在完全有可能提供高擴展的性能同時提供分布式原子事務。
FIT是這樣一個在分布式系統(tǒng)提供原子事務的策略,在fairness公平性, isolation隔離性, 和throughput吞吐量(簡稱FIT)可以權衡。
一個支持分布式事務的可伸縮分布式系統(tǒng)能夠完成這三個屬性中兩個,公平是事務之間不會相互影響造成延遲;隔離性提供一種幻覺好像整個數(shù)據(jù)庫只有它自
己一個事務,隔離性保證當任何同時發(fā)生的事務發(fā)生沖突時,能夠保證彼此能看到彼此的寫操作結果,因此減輕了程序員為避免事務讀寫沖突的強邏輯推理要求;吞
吐量是指每單元時間數(shù)據(jù)庫能夠并發(fā)處理多少事務。
FIT是如下進行權衡:
保證公平性fairness 和隔離性isolation, 但是犧牲吞吐量
保證公平性fairness和吞吐量, 犧牲隔離性isolation
保證隔離性isolation和吞吐量throughput, 但是犧牲公平性fairness.
犧牲公平性:放棄公平性,數(shù)據(jù)庫能有更多機會降低分布式事務的成本,主要成本是分布式協(xié)調(diào)帶來的,也就是說,不需要在每個事務過程內(nèi)對每個機器都依
次確認事務完成,這樣排隊式的確認commit事務是很浪費時間的,放棄公平性,意味著可以在事務外面進行協(xié)調(diào),這樣就只是增加了協(xié)調(diào)時間,不會增加互相
沖突事務因為彼此沖突而不能運行所耽擱的時間,當系統(tǒng)不需要公平性時,需要根據(jù)事務的優(yōu)先級或延遲等標準進行指定先后執(zhí)行順序,這樣就能夠獲得很好的吞吐
量。
G-Store是一種放棄公平性的 Isolation-Throughput
的分布式key-value存儲,支持多鍵事務(multi-key transactions),MongoDB 和
HBase在鍵key在同樣分區(qū)上也支持多鍵事務,但是不支持跨分區(qū)的事務。
總之:傳統(tǒng)分布式事務性能不佳的原因是確保原子性(分布式協(xié)調(diào))和隔離性同時重疊,創(chuàng)建一個高吞吐量分布式事務的關鍵是分離這兩種關注,這種分離原
子性和隔離性的視角將導致兩種類型的系統(tǒng),第一種選擇是弱隔離性能讓沖突事務并行執(zhí)行和確認提交;第二個選擇重新排序原子性和隔離性機制保證它們不會某個
時間重疊,這是一種放棄公平的事務執(zhí)行,所謂放棄公平就是不再同時照顧原子性和隔離性了,有所傾斜,放棄高標準道德要求就會帶來高自由高效率。
關系數(shù)據(jù)庫經(jīng)過幾十年的發(fā)展,已經(jīng)非常成熟,但同時也存在不足:
表結構是強約束的,業(yè)務變更時擴充很麻煩。
如果對大數(shù)據(jù)量的表進行統(tǒng)計運算,I/O會很高,因為即使只針對某列進行運算,也需要將整行數(shù)據(jù)讀入內(nèi)存。
全文搜索只能使用 Like 進行整表掃描,性能非常低。
針對這些不足,產(chǎn)生了不同的 NoSQL 解決方案,在某些場景下比關系數(shù)據(jù)庫更有優(yōu)勢,但同時也犧牲了某些特性,所以不能片面的迷信某種方案,應將其作為 SQL 的有利補充。
NoSQL != No SQL,而是:
NoSQL = Not Only SQL
典型的 NoSQL 方案分為4類:
Redis 是典型,其 value 是具體的數(shù)據(jù)結構,包括 string, hash, list, set, sorted set, bitmap, hyperloglog,常被稱為數(shù)據(jù)結構服務器。
以 list 為例:
LPOP key 是移除并返回隊列左邊的第一個元素。
如果用關系數(shù)據(jù)庫就比較麻煩了,需要操作:
Redis 的缺點主要體現(xiàn)在不支持完成的ACID事務,只能保證隔離性和一致性,無法保證原子性和持久性。
最大的特點是 no-schema,無需在使用前定義字段,讀取一個不存在的字段也不會導致語法錯誤。
特點:
以電商為例,不同商品的屬性差異很大,如冰箱和電腦,這種差異性在關系數(shù)據(jù)庫中會有很大的麻煩,而使用文檔數(shù)據(jù)庫則非常方便。
文檔數(shù)據(jù)庫的主要缺點:
關系數(shù)據(jù)庫是按行來存儲的,列式數(shù)據(jù)庫是按照列來存儲數(shù)據(jù)。
按行存儲的優(yōu)勢:
在某些場景下,這些優(yōu)勢就成為劣勢了,例如,計算超重人員的數(shù)據(jù),只需要讀取體重這一列進行統(tǒng)計即可,但行式存儲會將整行數(shù)據(jù)讀取到內(nèi)存中,很浪費。
而列式存儲中,只需要讀取體重這列的數(shù)據(jù)即可,I/O 將大大減少。
除了節(jié)省I/O,列式存儲還有更高的壓縮比,可以節(jié)省存儲空間。普通行式數(shù)據(jù)庫的壓縮比在 3:1 到 5:1 左右,列式數(shù)據(jù)庫在 8:1 到 30:1,因為單個列的數(shù)據(jù)相似度更高。
列式存儲的隨機寫效率遠低于行式存儲,因為行式存儲時同一行多個列都存儲在連續(xù)空間中,而列式存儲將不同列存儲在不連續(xù)的空間。
一般將列式存儲應用在離線大數(shù)據(jù)分析統(tǒng)計場景,因為這時主要針對部分列進行操作,而且數(shù)據(jù)寫入后無須更新。
關系數(shù)據(jù)庫通過索引進行快速查詢,但在全文搜索的情景下,索引就不夠了,因為:
假設有一個交友網(wǎng)站,信息表如下:
需要匹配性別、地點、語言列。
需要匹配性別、地點、愛好列。
實際搜索中,各種排列組合非常多,關系數(shù)據(jù)庫很難支持。
全文搜索引擎是使用 倒排索引 技術,建立單詞到文檔的索引,例如上面的表信息建立倒排索引:
所以特別適合根據(jù)關鍵詞來查詢文檔內(nèi)容。
上面介紹了幾種典型的NoSQL方案,及各自的適用場景和特點,您可以根據(jù)實際需求進行選擇。