程序员修神之路--用NOSql给高并发系统加速
記得長按,領(lǐng)取技術(shù)書籍哦
隨著互聯(lián)網(wǎng)大潮的到來,越來越多網(wǎng)站,應(yīng)用系統(tǒng)需要海量數(shù)據(jù)的支撐,高并發(fā)、低延遲、高可用、高擴展等要求在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫中已經(jīng)得不到滿足,或者說關(guān)系型數(shù)據(jù)庫應(yīng)對這些需求已經(jīng)顯得力不從心了。關(guān)系型數(shù)據(jù)庫經(jīng)過幾十年的發(fā)展已經(jīng)很成熟,強大的sql語句支持,完美的ACID屬性的支持,使得關(guān)系型數(shù)據(jù)庫廣泛應(yīng)用于各種各樣的應(yīng)用系統(tǒng)中,但是應(yīng)用的場景廣泛并非意味著完美。
- 由于關(guān)系型數(shù)據(jù)庫是按行進行存儲的,在某些只統(tǒng)計一列的需求場景下,也需要把整行讀入內(nèi)存,導(dǎo)致了一個小小的統(tǒng)計需求高IO的缺點
- 關(guān)系型數(shù)據(jù)庫無法存儲數(shù)據(jù)結(jié)構(gòu),比如:一個商品可以從屬于多個分類,業(yè)務(wù)上的從屬關(guān)系體現(xiàn)到存儲上是一個列表而已,但是關(guān)系型數(shù)據(jù)庫需要把這些關(guān)系存儲為多行,無法直接存儲為一個列表。
- 關(guān)系型數(shù)據(jù)庫中的存儲單位表的架構(gòu)是強約束,操作不存在的列會報出異常,而且添加、更新、刪除列必須執(zhí)行DDL語句,如果表的現(xiàn)存數(shù)據(jù)量比較大,會出現(xiàn)長時間鎖表的現(xiàn)象。
- 關(guān)系型數(shù)據(jù)庫全文搜索功能普通比較弱,用like去匹配關(guān)鍵詞的時候,數(shù)據(jù)量比較大的情況下會出現(xiàn)慢查詢的現(xiàn)象。
- 關(guān)系型數(shù)據(jù)庫基于表格的關(guān)系模型使得很難添加新的或不同種類的關(guān)聯(lián)信息。
由于以上這些諸多問題,便誕生了以“NOSQL”為口號的很多解決方案。在某些關(guān)系型數(shù)據(jù)庫不擅長的領(lǐng)域,Nosql表現(xiàn)的很出色。上天是公平的,給你打開了一扇窗戶,必會給你關(guān)上半扇門,NoSql是以犧牲ACID某個或者某些特性為代價的。
NoSQL并不是銀彈,更多的時候是關(guān)系型數(shù)據(jù)庫一個有力補充,或者是特定場景下優(yōu)于關(guān)系型數(shù)據(jù)庫的一種解決方案
NoSQLNoSQL,泛指非關(guān)系型的數(shù)據(jù)庫。現(xiàn)在大家更喜歡翻譯成:not only sql
根據(jù)NoSQL的存儲等特性,大體可以分為以下幾類
- 鍵值(Key-Value)存儲數(shù)據(jù)庫。相關(guān)的產(chǎn)品:Redis、Riak、SimpleDB、Chordless、Scalaris、Memcached。主要解決關(guān)系數(shù)據(jù)庫無法存儲數(shù)據(jù)結(jié)構(gòu)的問題。
- 列存儲數(shù)據(jù)庫。相關(guān)產(chǎn)品:BigTable、HBase、Cassandra、HadoopDB、GreenPlum、PNUTS。解決關(guān)系數(shù)據(jù)庫大數(shù)據(jù)場景下的 I/O 問題
- 文檔數(shù)據(jù)庫。相關(guān)產(chǎn)品:MongoDB、CouchDB、ThruDB、CloudKit、Perservere、Jackrabbit。解決關(guān)系數(shù)據(jù)庫強 schema 約束的問題。
- 圖形數(shù)據(jù)庫。相關(guān)產(chǎn)品:Neo4J、OrientDB、InfoGrid、GraphDB。主要解決大量復(fù)雜、互連接、低結(jié)構(gòu)化的圖結(jié)構(gòu)場合,如社交網(wǎng)絡(luò)、推薦系統(tǒng)等
- 全文搜索引擎。相關(guān)產(chǎn)品:Elasticsearch。主要解決關(guān)系數(shù)據(jù)庫的全文搜索性能問題。
由此可見,沒有哪一種NoSql是完美的,每一種Nosql都有自己擅長的領(lǐng)域,這也是我們做系統(tǒng)架構(gòu)中要考慮的重要因素。
場景1
電商的商品設(shè)計過程中,每種商品的屬性都不同,屬性數(shù)目不同,屬性名不同,同一個商品有可能會屬于多個分類,而且隨著業(yè)務(wù)的發(fā)展,很多商品會增加新的屬性,而且最令程序員頭疼莫過于每種屬性都有可能有搜索的可能性(當(dāng)然搜索可以利用搜索引擎來實現(xiàn))。遇到這樣的需求場景,如果利用關(guān)系型數(shù)據(jù)庫來存儲的話,表的字段會非常多,而且字段的定義非常令人頭疼。
這樣的場景非常適合NOsql中的文檔型數(shù)據(jù)庫,比如MongoDB。文檔型數(shù)據(jù)庫新增字段非常簡單,不像關(guān)系型數(shù)據(jù)庫需要先執(zhí)行DDL來增加字段,直接可以利用程序來進行讀寫,歷史數(shù)據(jù)就算是沒有相應(yīng)的字段也不會有異常的情況發(fā)生。最重要的一點,文檔型數(shù)據(jù)庫很擅長存儲復(fù)雜結(jié)構(gòu)的數(shù)據(jù),一般情況下業(yè)務(wù)上可以利用表現(xiàn)能力很強的json數(shù)據(jù)結(jié)構(gòu)。
{"Id":1,"ProductName":"杜蕾斯加強版","Price":100,"Type":[1,2,4],"Length":20,"Height":2}如果所有商品信息都用mongodb來存儲的話,有的場景并不是十分完美。比如商品被成功購買之后扣庫存的問題,聯(lián)合查詢的問題,由于Nosql天生對ACID支持不足的原因,一個事務(wù)性的操作很難在Nosql中實現(xiàn),所以設(shè)計系統(tǒng)的時候在很多情況下是關(guān)系數(shù)據(jù)庫+Nosql 來共同實現(xiàn)業(yè)務(wù)。
場景2
很多具體的業(yè)務(wù)中都有記錄數(shù)據(jù)然后進行統(tǒng)計的需求場景,比如那些統(tǒng)計uv,pv的系統(tǒng)。日志型的數(shù)據(jù)量非常大,而且還有可能有峰值的出現(xiàn),如果用關(guān)系型數(shù)據(jù)庫來存儲,很有可能在IO上會出現(xiàn)瓶頸,而且有可能會影響其他正常的業(yè)務(wù),更不幸的是當(dāng)執(zhí)行統(tǒng)計語句的時候,性能更是差強人意。這樣的日志型統(tǒng)計業(yè)務(wù)很適合HBase這樣的列式Nosql,業(yè)務(wù)上要統(tǒng)計一天的uv,pv數(shù)據(jù),HBase很適合統(tǒng)計某一列數(shù)據(jù)的場景,因為只需要把對應(yīng)的列進行統(tǒng)計即可,不像關(guān)系型數(shù)據(jù)庫那樣需要把所有行都加載進內(nèi)存,而且列式存儲一般比行式存儲擁有更大的壓縮比例,占用的磁盤空間會更少。
列式存儲的應(yīng)用場景有一定的限制,一般用于統(tǒng)計和大數(shù)據(jù)的分析中。
場景3
在多數(shù)高并發(fā)系統(tǒng)中都存在緩存的設(shè)計,而緩存的一般數(shù)據(jù)結(jié)構(gòu)都是K-V結(jié)構(gòu)。緩存是一種提高系統(tǒng)性能的有效手段,因其需要提供快速訪問的特性,一般緩存都放置于內(nèi)存當(dāng)中。比如現(xiàn)在我們要設(shè)計一個用戶管理系統(tǒng),每個用戶信息可以做緩存以便提供高速的訪問,由于很多系統(tǒng)都采用分布式的部署方式,所以采用進程內(nèi)的緩存方式并不可取,這個時候就需要有一種高速的外部存儲來提供這種業(yè)務(wù),這正是kv型Nosql的典型應(yīng)用場景之一。其中以redis為代表,具體的業(yè)務(wù)中可以以用戶id為key,用戶的信息為value存儲在redis中,而且redis在3.0之后可以做集群了,在高可用和擴展上更能助力業(yè)務(wù)方。redis支持的數(shù)據(jù)類型很多,在不同的場景下選擇不同的數(shù)據(jù)類型。
場景4
當(dāng)一個系統(tǒng)有搜索的業(yè)務(wù)時候,如果搜索的條件是一些簡單的類型搜索,關(guān)系型數(shù)據(jù)庫還可以滿足,但是如果有全文搜索,就是我們平時sql寫的like ‘%xx%’這樣的搜索,關(guān)系型數(shù)據(jù)庫可能并不是最好的選擇,全文搜索引擎類型的Nosql也許是一個更好的解決方案,其中以Elasticsearch 為代表。全文搜索引擎的搜索的條件可以隨意排列組合,并且可以實現(xiàn)關(guān)系型數(shù)據(jù)庫like方式的模糊匹配。
全文搜索引擎的技術(shù)原理稱為“倒排索引”(inverted index),是一種索引方法,其基本原理是建立單詞到文檔的索引。與之相對是,是“正排索引”,其基本原理是建立文檔到單詞的索引。
場景5
在社交系統(tǒng)中最常見例子就是社會網(wǎng)絡(luò)中人與人之間的關(guān)系。關(guān)系型數(shù)據(jù)庫用于存儲“關(guān)系型”數(shù)據(jù)的效果并不好,其查詢復(fù)雜、緩慢、超出預(yù)期,而圖形數(shù)據(jù)庫的獨特設(shè)計恰恰彌補了這個缺陷,解決關(guān)系型數(shù)據(jù)庫存儲和處理復(fù)雜關(guān)系型數(shù)據(jù)功能較弱的問題。其中以Neo4j為代表。想深入研究的同學(xué)請移步百度。
無論是關(guān)系型數(shù)據(jù)庫還是nosql數(shù)據(jù)庫都不是銀彈,每一種事物都有它最善長的領(lǐng)域。設(shè)計一個好的系統(tǒng),需要綜合考慮各種因素,根據(jù)具體的業(yè)務(wù)場景來選擇最合適的解決方案。
總結(jié)
以上是生活随笔為你收集整理的程序员修神之路--用NOSql给高并发系统加速的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hyper-V + CentOS7 安装
- 下一篇: 程序员修神之路--高并发系统设计负载均衡