




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、NoSQL數(shù)據(jù)庫MongoDB和Redis目錄1NoSQL簡(jiǎn)述42MongoDB簡(jiǎn)介43術(shù)語介紹54MongoDB資源消耗65交互式shell66一般功能76.1插入76.2查詢76.3刪除76.4索引86.5map/reduce87模式設(shè)計(jì)88嵌入與引用99GridFS119.1GridFS表示的對(duì)象信息119.2GridFS管理1210Replication(復(fù)制)1310.1master-slave模式1310.2replica pairs模式1310.3受限的master-master復(fù)制1411Sharding(分片)1411.1sharding介紹1411.2sharding的配置
2、和管理1512Java API簡(jiǎn)介1613MongoDB實(shí)例分析1713.1圖片保存在文件系統(tǒng)中1713.2圖片保存在數(shù)據(jù)庫中1914MongoDB常用API總結(jié)2315Redis簡(jiǎn)介2715.1Redis特性2716Redis數(shù)據(jù)類型2816.1String類型2816.2List類型2816.3Set類型2916.4ZSet類型2916.5Hash類型2917All data in memory, but saved on disk2918Redis的Master-Slave模式3019Redis虛擬內(nèi)存管理3120Redis實(shí)例分析3121Redis命令總結(jié)3221.1連接操作相關(guān)的命令
3、3221.2對(duì)value操作的命令3221.3對(duì)String操作的命令3321.4對(duì)List操作的命令3321.5對(duì)Set操作的命令3421.6對(duì)zset(sorted set)操作的命令3521.7對(duì)Hash操作的命令3521.8持久化3621.9遠(yuǎn)程服務(wù)控制36NoSQL數(shù)據(jù)庫MongoDB和Redis1NoSQL簡(jiǎn)述CAP(Consistency,Availabiity,Partition tolerance)理論告訴我們,一個(gè)分布式系統(tǒng)不可能滿足一致性,可用性和分區(qū)容錯(cuò)性這三個(gè)需求,最多只能同時(shí)滿足兩個(gè)。關(guān)系型數(shù)據(jù)庫通過把更新操作寫到事務(wù)型日志里實(shí)現(xiàn)了部分耐用性,但帶來的是寫性能的下降
4、。MongoDB等NoSQL數(shù)據(jù)庫背后蘊(yùn)涵的哲學(xué)是不同的平臺(tái)應(yīng)該使用不同類型的數(shù)據(jù)庫,MongoDB通過降低一些特性來達(dá)到性能的提高,這在很多大型站點(diǎn)中是可行的。因?yàn)镸ongoDB是非原子性的,所以如果如果應(yīng)用需要事務(wù),還是需要選擇MySQL等關(guān)系數(shù)據(jù)庫。NoSQL數(shù)據(jù)庫,顧名思義就是打破了傳統(tǒng)關(guān)系型數(shù)據(jù)庫的范式約束。很多NoSQL數(shù)據(jù)庫從數(shù)據(jù)存儲(chǔ)的角度看也不是關(guān)系型數(shù)據(jù)庫,而是key-value數(shù)據(jù)格式的hash數(shù)據(jù)庫。由于放棄了關(guān)系數(shù)據(jù)庫強(qiáng)大的SQL查詢語言和事務(wù)一致性以及范式約束,NoSQL數(shù)據(jù)庫在很大程度上解決了傳統(tǒng)關(guān)系型數(shù)據(jù)庫面臨的諸多挑戰(zhàn)。在社區(qū)中,NoSQL是指“not only
5、 sql”,其特點(diǎn)是非關(guān)系型,分布式,開源,可水平擴(kuò)展,模式自由,支持replication,簡(jiǎn)單的API,最終一致性(相對(duì)于即時(shí)一致性,最終一致性允許有一個(gè)“不一致性窗口”,但能保證最終的客戶都能看到最新的值)。2MongoDB簡(jiǎn)介mongo取自“humongous”(海量的),是開源的文檔數(shù)據(jù)庫nosql數(shù)據(jù)庫的一種。MongoDB是一種面向集合(collection)的,模式自由的文檔(document)數(shù)據(jù)庫。面向集合是說數(shù)據(jù)被分成集合的形式,每個(gè)集合在數(shù)據(jù)庫中有惟一的名稱,集合可以包含不限數(shù)目的文檔。除了模式不是預(yù)先定義好的,集合與RDBMS中的表概念類似,雖然二者并不是完全對(duì)等。數(shù)
6、據(jù)庫和集合的創(chuàng)建是“l(fā)azy”的,即只有在第一個(gè)document被插入時(shí)集合和數(shù)據(jù)庫才真正創(chuàng)建這時(shí)在磁盤的文件系統(tǒng)里才能看見。模式自由是說數(shù)據(jù)庫不需要知道存放在集合中的文檔的結(jié)構(gòu),完全可以在同一個(gè)集合中存放不同結(jié)構(gòu)的文檔,支持嵌入子文檔。文檔類似于RDBMS中的記錄,以BSON的格式保存。BSON是Binary JSON的簡(jiǎn)稱,是對(duì)JSON-like文檔的二進(jìn)制編碼序列化。像JSON(JavaScript Object Notation)一樣,BSON支持在對(duì)象和數(shù)組內(nèi)嵌入其它的對(duì)象和數(shù)組。有些數(shù)據(jù)類型在JSON里不能表示,但可以在BSON里表示,如Date類型和BinData(二進(jìn)制數(shù)據(jù)),
7、Python原生的類型都可以表示。與Protocal Buffers(Google開發(fā)的用以處理對(duì)索引服務(wù)器請(qǐng)求/應(yīng)答的協(xié)議)相比,BSON模式更自由,所以更靈活,但這樣也使得每個(gè)文檔都要保存字段名,所以空間壓縮上不如Protocol Buffers。BSON第一眼看上去像BLOB,但MongoDB理解BSON的內(nèi)部機(jī)制,所以MongoDB可以深入BSON對(duì)象的內(nèi)部,即使是嵌套的對(duì)象,這樣MongoDB就可以在頂層和嵌套的BSON對(duì)象上建立索引來應(yīng)對(duì)各種查詢了。MongoDB可運(yùn)行在Linux、Windows和OS X平臺(tái),支持32位和64位應(yīng)用,默認(rèn)端口為27017。推薦運(yùn)行在64位平臺(tái),因
8、為MongoDB為了提高性能使用了內(nèi)存映射文件進(jìn)行數(shù)據(jù)管理,而在32位模式運(yùn)行時(shí)支持的最大文件為2GB。MongoDB查詢速度比MySQL要快,因?yàn)樗點(diǎn)ache了盡可能多的數(shù)據(jù)到RAM中,即使是non-cached數(shù)據(jù)也非???。當(dāng)前MongoDB官方支持的客戶端API語言就多達(dá)8種(C|C+|Java|Javascript|Perl|PHP|Python|Ruby),社區(qū)開發(fā)的客戶端API還有Erlang、Go、Haskell.3術(shù)語介紹數(shù)據(jù)庫、集合、文檔每個(gè)MongoDB服務(wù)器可以有多個(gè)數(shù)據(jù)庫,每個(gè)數(shù)據(jù)庫都有可選的安全認(rèn)證。數(shù)據(jù)庫包括一個(gè)或多個(gè)集合,集合以命名空間的形式組織在一起,用“.”隔
9、開(類似于JAVA/Python里面的包),比如集合blog.posts和blog.authors都處于"blog"下,不會(huì)與bbs.authors有名稱上的沖突。集合里的數(shù)據(jù)由多個(gè)BSON格式的文檔對(duì)象組成,document的命名有一些限定,如字段名不能以"$"開頭,不能有".",名稱"_id"被保留為主鍵。如果插入的文檔沒有提供“_id”字段,數(shù)據(jù)庫會(huì)為文檔自動(dòng)生成一個(gè)ObjectId對(duì)象作為“_id”的值插入到集合中。字段“_id”的值可以是任意類型,只要能夠保證惟一性。BSON ObjectID是一個(gè)12字
10、節(jié)的值,包括4字節(jié)的時(shí)間戳,3字節(jié)的機(jī)器號(hào),2字節(jié)的進(jìn)程id以及3字節(jié)的自增計(jì)數(shù)。建議用戶還是使用有意義的“_id”值。MongoDb相比于傳統(tǒng)的SQL關(guān)系型數(shù)據(jù)庫,最大的不同在于它們的模式設(shè)計(jì)(Schema Design)上的差別,正是由于這一層次的差別衍生出其它各方面的不同。如果將關(guān)系數(shù)據(jù)庫簡(jiǎn)單理解為由數(shù)據(jù)庫、表(table)、記錄(record)三個(gè)層次概念組成,而在構(gòu)建一個(gè)關(guān)系型數(shù)據(jù)庫的時(shí)候,工作重點(diǎn)和難點(diǎn)都在數(shù)據(jù)庫表的劃分與組織上。一般而言,為了平衡提高存取效率與減少數(shù)據(jù)冗余之間的矛盾,設(shè)計(jì)的數(shù)據(jù)庫表都會(huì)盡量滿足所謂的第三范式。相應(yīng)的,可以認(rèn)為MongoDb由數(shù)據(jù)庫、集合(colle
11、ction)、文檔對(duì)象(Document-oriented、BSON)三個(gè)層次組成。MongoDb里的collection可以理解為關(guān)系型數(shù)據(jù)庫里的表,雖然二者并不完全對(duì)等。當(dāng)然,不要期望collection會(huì)滿足所謂的第三范式,因?yàn)樗鼈兏揪筒辉谕粋€(gè)概念討論范圍之內(nèi)。類似于表由多條記錄組成,集合也包含多個(gè)文檔對(duì)象,雖然說一般情況下,同一個(gè)集合內(nèi)的文檔對(duì)象具有相同的格式定義,但這并不是必須的,即MongoDb的數(shù)據(jù)模式是自由的(schema-free、模式自由、無模式),collection中可以包含具有不同schema的文檔記錄,支持嵌入子文檔。4MongoDB資源消耗考慮到性能的原因,m
12、ongo做了很多預(yù)分配,包括提前在文件系統(tǒng)中為每個(gè)數(shù)據(jù)庫分配逐漸增長(zhǎng)大小的文件集。這樣可以有效地避免潛在的文件系統(tǒng)碎片,使數(shù)據(jù)庫操作更高效。一個(gè)數(shù)據(jù)庫的文件集從序號(hào)0開始分配,0,1.,大小依次是64M,128M,256M,512M,1G,2G,然后就是一直2G的創(chuàng)建下去(32位系統(tǒng)最大到512M)。所以如果上一個(gè)文件是1G,而數(shù)據(jù)量剛好超過1G,則下一個(gè)文件(大小為2G)則可能有超過90%都是空的。如果想使磁盤利用更有效率,下面是一些解決方法:1. 只建立一個(gè)數(shù)據(jù)庫,這樣最多只會(huì)浪費(fèi)2G。2. 每個(gè)文檔使用自建的“_id”值而不要使用默認(rèn)的ObjectId對(duì)象。3. 由于每個(gè)document
13、的每個(gè)字段名都會(huì)存放,所以如果字段名越長(zhǎng),document的數(shù)據(jù)占用就會(huì)越大,因此把字段名縮短會(huì)大大降低數(shù)據(jù)的占用量。如把“timeAdded”改為“tA”。Mongo使用內(nèi)存映射文件來訪問數(shù)據(jù),在執(zhí)行插入等操作時(shí),觀察mongod進(jìn)程的內(nèi)存占用時(shí)會(huì)發(fā)現(xiàn)量很大,當(dāng)使用內(nèi)存映射文件時(shí)是正常的。并且映射數(shù)據(jù)的大小只出現(xiàn)在虛擬內(nèi)存那一列,常駐內(nèi)存量才反應(yīng)出有多少數(shù)據(jù)cached在內(nèi)存中?!景凑誱ongodb官方的說法,mongodb完全由系統(tǒng)內(nèi)核進(jìn)行內(nèi)存管理,會(huì)盡可能的占用系統(tǒng)空閑內(nèi)存,用free可以看到,大部分內(nèi)存都是作為io cache被占用的,而這部分內(nèi)存是可以釋放出來給應(yīng)用使用的?!?交互式
14、shellmongo類似于MySQL中的mysql進(jìn)程,但功能遠(yuǎn)比mysql強(qiáng)大,它可以使用JavaScript語法的命令從交互式shell中直接操作數(shù)據(jù)庫。如查看數(shù)據(jù)庫中的內(nèi)容,使用游標(biāo)循環(huán)查看查詢結(jié)果,創(chuàng)建索引,更改及刪除數(shù)據(jù)等數(shù)據(jù)庫管理功能。下面是一個(gè)在mongo中使用游標(biāo)的例子:> for(var cur = db.posts.find(); cur.hasNext();) . print(tojson(cur.next();. 輸出: "_id" : ObjectId("4bb311164a4a1b0d84000000"), "
15、date" : "Wed Mar 31 17:05:23 2010", "content" : "blablablabla", "author" : "navygong", "title" : "the first blog".其它的documents。6一般功能6.1插入客戶端把數(shù)據(jù)序列化為BSON格式傳給DB后被存儲(chǔ)在磁盤上,在讀取時(shí)數(shù)據(jù)庫幾乎不做什么改動(dòng)直接把對(duì)象返回給客戶端,由client完成unserialized。如:> doc
16、 = 'author': 'joe', 'created': new Date('2010, 6, 21'), 'title':'Yet another blog post', 'text': 'Here is the text.', 'tags': 'example', 'joe', 'comments': 'author': 'jim', 'comment
17、9;: 'I disgree', 'author': 'navy', 'comment': 'Good post', '_id': 'test_id'> db.posts.insert(doc)6.2查詢基本上你能想到的查詢種類MongoDB都支持,如等值匹配,<,<=,>, >=,$ne,$in,$mod,$all,$size1,$exists,$type2,正則表達(dá)式匹配,全文搜索,.。還有distinct(),sort(),count(),skip
18、()3,group()4,.。這里列表的查詢中很多用法都和一般的RDBMS不同。1 匹配一個(gè)有size個(gè)元素的數(shù)組。如db.things.find(a: $size: 1)能夠匹配文檔a: "foo"。2 根據(jù)類型匹配。db.things.find(a : $type : 16)能夠匹配所有a為int類型的文檔。BSON協(xié)議中規(guī)定了各種類型對(duì)應(yīng)的枚舉值。3 指定跳過多少個(gè)文檔后開始返回結(jié)果,可以用在分頁中。如:db.students.find().skip(pageNumber-1)*nPerPage).limit(nPerPage).forEach( function(s
19、tudent) print( + "<p>"); )。4 在sharded MongoDB配置環(huán)境中應(yīng)該應(yīng)該使用map/reduce來代替group()。6.3刪除可以像查詢一樣指定條件來刪除特定的文檔。6.4索引可以像在一般的RDBMS中一樣使用索引。提供了建立(一般、惟一、組合)索引、刪除索引、重建索引等各種方法。索引信息保存在集合“system.indexes”中。6.5map/reduceMongoDB提供了map/reduce方法來進(jìn)行數(shù)據(jù)的批處理及聚集操作。和Hadoop的使用類似,從集合中接收輸入,結(jié)果輸出到另一個(gè)集合。如果
20、你需要使用group,map/reduce會(huì)是個(gè)不錯(cuò)的選擇。但MongoDB中的索引和標(biāo)準(zhǔn)查詢不是使用map/reduce,而是與MySQL相似。7模式設(shè)計(jì)Mongo式的模式設(shè)計(jì)使用Mongo有很多種方式,你本能上可能會(huì)像使用關(guān)系型數(shù)據(jù)庫一樣去使用。當(dāng)然這樣也可以工作得很好,但卻沒能發(fā)揮出Mongo的真正威力。Monog是專門設(shè)計(jì)為富對(duì)象模型(rich object model)使用的。例如:如果你建立了一個(gè)簡(jiǎn)單的在線商店并且把產(chǎn)品信息存儲(chǔ)在關(guān)系型數(shù)據(jù)庫中,那你可能會(huì)有兩個(gè)像這樣的表:itemtitlepriceskuitem_featuresskufeature_namefeature_va
21、lue你進(jìn)行了范式處理因?yàn)椴煌奈锲酚胁煌奶卣鳎@樣你不用建立一個(gè)包含所有特征的表了。在Mongo中你也可以像上面那樣建立兩個(gè)集合,但像下面這樣存儲(chǔ)每種物品會(huì)更有效。item : "title" : <title> , "price" : <price> , "sku" : <sku> , "features" : "optical zoom" : <value> , . 因?yàn)橹灰樵円粋€(gè)集合就能取得一件物品的所有信息,而這些信息都保存在磁盤上同
22、一個(gè)地方,因此大大提高了查詢的速度。如果你想插入或更新一種特征,如db.items.update( sku : 123 , "$set" : "features.zoom" : "5" ),也不必在磁盤上移動(dòng)整個(gè)對(duì)象,因?yàn)镸ongo為每個(gè)對(duì)象在磁盤上預(yù)留了空間來適應(yīng)對(duì)象的增長(zhǎng)。8嵌入與引用以一實(shí)例來說,假設(shè)需要設(shè)計(jì)一個(gè)小型數(shù)據(jù)庫來存儲(chǔ)“學(xué)生、地址、科目、成績(jī)”這些信息,那么關(guān)系型數(shù)據(jù)庫的設(shè)計(jì)如圖1所示,而key-value型數(shù)據(jù)庫的設(shè)計(jì)則可能如圖2所示。圖1 關(guān)系型的數(shù)據(jù)庫設(shè)計(jì)圖2 key-value型的數(shù)據(jù)庫設(shè)計(jì)對(duì)比圖1和圖2,在關(guān)
23、系型的數(shù)據(jù)庫設(shè)計(jì)里劃分出了4個(gè)表,而在key-value型的數(shù)據(jù)庫設(shè)計(jì)里卻只有兩個(gè)集合。如果說集合與表一一對(duì)應(yīng)的話,那么圖2中應(yīng)該也有4個(gè)集合才對(duì),把本應(yīng)該是集合的address和scores直接合入了集合students中,原因在于在key-value型的數(shù)據(jù)庫里,數(shù)據(jù)模式是自由的。以scores來說,在關(guān)系型的數(shù)據(jù)庫設(shè)計(jì)中將其單獨(dú)成一個(gè)表是因?yàn)閟tudent與score是一對(duì)多的關(guān)系,如果將score合入student表,那么就必須預(yù)留最多可能的字段,這會(huì)存在浪費(fèi),并且當(dāng)以后新增一門課程時(shí)擴(kuò)展困難,因此一般都會(huì)將score表單獨(dú)出來。而對(duì)于key-value型的數(shù)據(jù)庫就不同了,其score
24、s字段就是一個(gè)BSON,該BSON可以只有一個(gè)for_course,也可以有任意多個(gè)for_course,其固有的模式自由特性使得它可以將score包含在內(nèi)而無需另建一個(gè)score集合。對(duì)于與student為一對(duì)一關(guān)系的address表也可以直接合入student,無需擔(dān)心address的擴(kuò)展性,當(dāng)以后需要給address新增一個(gè)province字段,直接在數(shù)據(jù)插入時(shí)加上這個(gè)值即可。當(dāng)然,對(duì)于與student成多對(duì)多關(guān)系course表,為了減少數(shù)據(jù)冗余,可以將course建立為一個(gè)集合,同關(guān)系型的數(shù)據(jù)庫設(shè)計(jì)中類似。students文檔中嵌入了address文檔和scores文檔,scores文
25、檔的“for_course”字段的值是指向courses集合的文檔的引用。如果是關(guān)系型數(shù)據(jù)庫,需要把“scores”作為一個(gè)單獨(dú)的表,然后在students表中建立一個(gè)指向“scores”的外鍵。所以Mongo模式設(shè)計(jì)中的一個(gè)關(guān)鍵問題就是“是值得為這個(gè)對(duì)象新建一個(gè)集合呢,還是把這個(gè)對(duì)象嵌入到其它的集合中”。在關(guān)系型數(shù)據(jù)庫中為了范式的要求,每個(gè)子項(xiàng)都要建一個(gè)單獨(dú)的表,但在Mongo中使用嵌入式對(duì)象更有效,所以你應(yīng)該給出不使用嵌入式對(duì)象而單獨(dú)建一個(gè)集合的理由。為什么說引用要慢些呢,以上面的students集合為例,比如執(zhí)行:print( student.scores0.for_course.nam
26、e );如果這是第一次訪問scores0,那些客戶端必須執(zhí)行:student.scores0.for_course = db.courses.findOne(_id:_course_id_to_find_); /偽代碼所以每一次遍歷引用都要對(duì)數(shù)據(jù)庫進(jìn)行一次這樣的查詢,即使所有的數(shù)據(jù)都在內(nèi)存中。再考慮到從客戶端到服務(wù)器端的種種延遲,這個(gè)時(shí)間也不會(huì)低。有一些規(guī)則可以決定該用嵌入還是引用:1. 第一個(gè)類對(duì)象,也就是處于頂層的,往往應(yīng)該有自己的集合。2. 排列項(xiàng)詳情對(duì)象應(yīng)該用嵌入。3. 處于被包含關(guān)系的應(yīng)該用嵌入。4. 多對(duì)多的關(guān)系通常應(yīng)該用引用。5. 數(shù)據(jù)量小的集合可以放心地做成一個(gè)單獨(dú)的集合,因?yàn)?/p>
27、整個(gè)集合可以很快地cached。6. 要想獲得嵌入式對(duì)象的系統(tǒng)級(jí)視圖會(huì)更困難一些。如上面的“Scores”如果不做成嵌入式對(duì)象可以更容易地查詢出分?jǐn)?shù)排名前100的學(xué)生。7. 如果嵌入的是大對(duì)象,需要留意到BSON對(duì)象的4M大小限定(后面會(huì)講到)。8. 如果性能是關(guān)鍵就用嵌入。下面是一些示例:1. Customer/Order/Order Line-Itemcutomers和orders應(yīng)該做成一個(gè)集合,line-items應(yīng)該以數(shù)組的形式嵌入在order中。2. 博客系統(tǒng)posts應(yīng)該是一個(gè)集合;author可以是一個(gè)單獨(dú)的集合,如果只需記錄作者的email地址也可以以字段的方式存在于post
28、s中;comments應(yīng)該做成嵌入的對(duì)象。9GridFS GridFS是MongoDB中用來存儲(chǔ)大文件而定義的一種文件系統(tǒng)。MongoDB默認(rèn)是用BSON格式來對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)和網(wǎng)絡(luò)傳輸。但由于BSON文檔對(duì)象在MongoDB中最大為4MB,無法存儲(chǔ)大的對(duì)象。即使沒有大小限制,BSON也無法滿足對(duì)大數(shù)據(jù)集的快速范圍查詢,所以MongoDB引進(jìn)了GridFS。9.1GridFS表示的對(duì)象信息1. 文件對(duì)象(類GridFSFile 的對(duì)象)的元數(shù)據(jù)信息。結(jié)構(gòu)如下 "_id" : <unspecified>, / unique ID for this file
29、 "filename" : data_string, / human name for the file "contentType" : data_string, / valid mime type for the object "length" : data_number, / size of the file in bytes "chunkSize" : data_number, / size of each of the chunks. Default is 256k "uploadDate&quo
30、t; : data_date, / date when object first stored "aliases" : data_array of data_string, / optional array of alias strings "metadata" : data_object, / anything the user wants to store "md5" : data_string /result of running "filemd5" command on the file's chu
31、nks如下是put進(jìn)去的一個(gè)文件例子: _id: ObjId(4bbdf6200459d967be9d8e98),filename: "/home/hjgong/source_file/wnwb.svg", length: 7429, chunkSize: 262144, uploadmd5: "ccd93f05e5b9912c26e68e9955bbf8b9"2. 數(shù)據(jù)的二進(jìn)制塊以及一些統(tǒng)計(jì)信息。結(jié)構(gòu)如下:"_id": <unspecified>, / object id of the chunk in the _chu
32、nks collection "files_id": <unspecified>, / _id value of the owning files collection entry "n": data_number, / "chunk number" - starting with 0 "data": data_binary (type 0x02), / binary data for chunk因此使用GridFS可以儲(chǔ)存富媒體文件,同時(shí)存入任意的附加信息,因?yàn)檫@些信息實(shí)際上也是一個(gè)普通的collec
33、tion。以前,如果要存儲(chǔ)一個(gè)附件,通常的做法是,在主數(shù)據(jù)庫中存放文件的屬性同時(shí)記錄文件的path,當(dāng)查詢某個(gè)文件時(shí),需要首先查詢數(shù)據(jù)庫,獲得該文件的path,然后從存儲(chǔ)系統(tǒng)中獲得相應(yīng)的文件。在使用GridFS時(shí)則非常簡(jiǎn)單,可以直接將這些信息直接存儲(chǔ)到文件中。比如下面的Java代碼,將文件file(file可以是圖片、音頻、視頻等文件)儲(chǔ)存到db中:其中該方法的第一個(gè)參數(shù)的類型還可以是InputStream,byte,從而實(shí)現(xiàn)多個(gè)重載的方法。9.2GridFS管理 MongoDB提供的工具mongofiles可以從命令行操作GridFS。如: ./mongofiles -host localh
34、ost:1727 -u navygong -p 111 put /source_file/wnwb.svg 每種語言提供的MongoDB客戶端API都提供了一套方法,可以像操作普通文件一樣對(duì)GridFS文件進(jìn)行操作,包括read(),write(),tell(),seek()等。10Replication(復(fù)制) Mongo提供了兩種方式的復(fù)制:簡(jiǎn)單的master-slave配置及replica pair的概念。 如果安全認(rèn)證被enable,不管哪種replicate方式,都要在master/slave中創(chuàng)建一個(gè)能為各個(gè)database識(shí)別的用戶名/密碼。認(rèn)證步驟如下: slave先在loca
35、l.system.users里查找一個(gè)名為"repl"的用戶,找到后用它去認(rèn)證master。如果"repl"用戶沒有找到,則使用local.system.users中的第一個(gè)用戶去認(rèn)證。local數(shù)據(jù)庫和admin數(shù)據(jù)庫一樣,local中的用戶可以訪問整個(gè)db server。10.1master-slave模式一個(gè)server可以同時(shí)為master和slave。一個(gè)slave可以有多個(gè)master,這種方式并不推薦,因?yàn)榭赡軙?huì)產(chǎn)生不可預(yù)期的結(jié)果。在該模式中,一般是在兩個(gè)不同的機(jī)器上各部署一個(gè)MongDB實(shí)例,一個(gè)為master,另一作為slave。將Mo
36、ngoDB作為master啟動(dòng),只需要在命令行輸入:./mongod -master然后主服務(wù)進(jìn)程將會(huì)在數(shù)據(jù)庫中創(chuàng)建一個(gè)集合local.oplog.$main,該collection主要記錄了事務(wù)日志,即需要在slave執(zhí)行的操作。而將MongoDB作為slave啟動(dòng),只需要在命令行輸入:./mongod -slave -source <masterhostname>:<port>port不指定時(shí)即使用默認(rèn)端口,masterhostname是master的IP或master機(jī)器的FQDN。其他配置選項(xiàng):-autoresync:自動(dòng)sync,但在10分鐘內(nèi)最多只會(huì)進(jìn)行一次
37、。-oplogSize:指定master上用于存放更改的數(shù)據(jù)量,如果不指定,在32位機(jī)上最少為50M,在64位機(jī)上最少為 1G,最大為磁盤空間的5%。10.2replica pairs模式以這種方式啟動(dòng)后,數(shù)據(jù)庫會(huì)自動(dòng)協(xié)商誰是master誰是slave。一旦一個(gè)數(shù)據(jù)庫服務(wù)器斷電,另一個(gè)會(huì)自動(dòng)接管,并從那一刻起起為master。萬一另一個(gè)將來也出錯(cuò)了,那么master狀態(tài)將會(huì)轉(zhuǎn)回給第一個(gè)服務(wù)器。以這種復(fù)制方式啟動(dòng)本地MongoDB的命令如下:./mongod -pairwith <remoteserver> -arbiter <arbiterserver>其中remote
38、server是pair里的另一個(gè)server,arbiterserver是一個(gè)起仲裁作用的Mongo數(shù)據(jù)庫服務(wù)器,用來協(xié)商pair中哪一個(gè)是master。arbiter運(yùn)行在第三個(gè)機(jī)器上,利用“平分決勝制”決定在pair中的兩臺(tái)機(jī)器不能聯(lián)系上對(duì)方時(shí)讓哪一個(gè)做master,一般是能同arbiter通話的那臺(tái)機(jī)器做master。如果不加-arbiter選項(xiàng),出現(xiàn)網(wǎng)絡(luò)問題時(shí)兩臺(tái)機(jī)器都作為master。命令db.$cmd.findOne(ismaster:1)可以檢查當(dāng)前哪一個(gè)database是master。pair中的兩臺(tái)機(jī)器只能滿足最終一致性。當(dāng)replica pair中的一臺(tái)機(jī)器完全掛掉時(shí),需要
39、用一臺(tái)新的來代替。如(n1, n2)中的n2掛掉,這時(shí)用n3來代替n2。步驟如下:1. 告訴n1用n3來代替n2:db.$cmd.findOne(replacepeer:1);2. 重啟n1讓它同n3對(duì)話:./mongod -pairwith n3 -arbiter <arbiterserver>3. 啟動(dòng)n3:./mongod -pairwith n1 -arbiter <arbiterserver>。在n3的數(shù)據(jù)沒有同步到n1前n3還不能做master,這個(gè)過程長(zhǎng)短由數(shù)據(jù)量的多少?zèng)Q定。10.3受限的master-master復(fù)制Mongo不支持完全的master-m
40、aster復(fù)制,通常情況下不推薦使用master-master模式,但在一些特定的情況下master-master也可用。master-master也只支持最終一致性。配置master-master只需運(yùn)行mongod時(shí)同時(shí)加上-master選項(xiàng)和-slave選項(xiàng)。如下:$ nohup mongod -dbpath /data1/db -port 27017 -master -slave -source localhost:27018 > /tmp/dblog1 &$ nohup mongod -dbpath /data2/db -port 27018 -master -slav
41、e -source localhost:27017 > /tmp/dblog2 &這種模式對(duì)插入、查詢及根據(jù)_id進(jìn)行的刪除操作都是安全的。但對(duì)同一對(duì)象的并發(fā)更新無法進(jìn)行。11Sharding(分片)11.1sharding介紹MongoDB包括一個(gè)自動(dòng)分片的的模塊(“mongos”),從而可以構(gòu)建一個(gè)大的水平可擴(kuò)展的數(shù)據(jù)庫集群,可以動(dòng)態(tài)地添加和移走機(jī)器。如下是一個(gè)數(shù)據(jù)庫集群的示意圖:mongod:數(shù)據(jù)庫服務(wù)器進(jìn)程,類似于mysqld。shards:每個(gè)shard有一個(gè)或多個(gè)mongod,通常是一個(gè)master,多個(gè)slave組成replication。數(shù)據(jù)由集合按一個(gè)預(yù)定的順序
42、劃分,某一個(gè)范圍的數(shù)據(jù)被放到一個(gè)特定的shard中,這樣可以通過shard的key進(jìn)行有效的范圍查詢。shard keys:用于劃分集合,格式類似于索引的定義,也是把一個(gè)或多個(gè)字段作為key,以key來分布數(shù)據(jù)。如: name : 1 (1代表升序,-1代表降序)、 _id : 1 、 lastname : 1, firstname : 1 、 tag : 1, timestamp : -1 。如果有100萬人同名,可能還需要?jiǎng)澐郑驗(yàn)榉诺揭粋€(gè)塊里太大了,這時(shí)定義的shar key不能只有一個(gè)name字段了。劃分能夠保證相鄰的數(shù)據(jù)存儲(chǔ)在一個(gè)server(當(dāng)然也在相同的塊上)。chunks:是一
43、個(gè)集合里某一范圍的數(shù)據(jù),(collection, minkey, maxkey)描述了一個(gè)chunk。塊的大小有限定,當(dāng)塊里的數(shù)據(jù)超過最大值,塊會(huì)一分為二。如果一個(gè)shard里的數(shù)據(jù)過多(添加shard時(shí),可以指定這個(gè)shard上可以存放的最大數(shù)據(jù)量maxSize),就會(huì)有塊遷移到其它的shard。同樣,當(dāng)添加新的server時(shí),為了平衡各個(gè)server的負(fù)載,也會(huì)遷移chunk過去。config server(配置服務(wù)器):存儲(chǔ)了集群的元信息,包括每一個(gè)shard、一個(gè)shard里的server、以及每一個(gè)chunk的基本信息。其中主要是chunk的信息,每個(gè)config server中都有
44、一份所有chunk信息的完全拷貝。使用兩階段提交協(xié)議來保證配置信息在config server間的一致。mongos:可以認(rèn)為是一個(gè)“數(shù)據(jù)庫路由器”,用以協(xié)調(diào)集群的各個(gè)部分,使它們看起來像一個(gè)系統(tǒng)。mongos沒有固定的狀態(tài),可以在 server需要的時(shí)候運(yùn)行。mongos啟動(dòng)后會(huì)從config server里取出元信息,然后接收客戶請(qǐng)求,把請(qǐng)求路由到合適的server,得到結(jié)果后送回客戶。一個(gè)系統(tǒng)可以有多個(gè)mongos例程,每個(gè)例程都需要內(nèi)存來存儲(chǔ)元信息。例程間不需協(xié)同工作,每個(gè)mongos只需要協(xié)同shard servers和config servers工作即可。當(dāng)然shard serve
45、rs間也會(huì)彼此對(duì)話,也會(huì)同config servers對(duì)話。11.2sharding的配置和管理mongod的啟動(dòng)選項(xiàng)中也包含了與sharding相關(guān)的參數(shù),如-shardsvr(聲明這是一個(gè)shard db),-configsvr(聲明這是一個(gè)config db)。mongos的啟動(dòng)選項(xiàng)-configdb指定config server的位置。下面的鏈接地址是一個(gè)簡(jiǎn)單的sharding配置例子:/display/DOCS/A+Sample+Configuration+Session。 像安全和認(rèn)證一樣,如果要sharding,先要允許一個(gè)數(shù)據(jù)庫shar
46、ding,然后要指定數(shù)據(jù)庫里集合的分片方式,這些都有相應(yīng)的命令可以完成。12Java API簡(jiǎn)介要使用Java操作MongoDB,在官網(wǎng)上下載jar包,目前最新的版本是:。首先介紹一下比較常用的幾個(gè)類:Mongo:連接服務(wù)器,執(zhí)行一些數(shù)據(jù)庫操作的選項(xiàng),如新建立一個(gè)數(shù)據(jù)庫等;DB:對(duì)應(yīng)一個(gè)數(shù)據(jù)庫,可以用來建立集合等操作;DBCollection:對(duì)應(yīng)一個(gè)集合(類似表),可能是我們用得最多的,可以添加刪除記錄等;DBObject接口和BasicDBObject對(duì)象:表示一個(gè)具體的記錄,BasicDBObject實(shí)現(xiàn)了DBObject,因?yàn)槭莐ey-value的數(shù)據(jù)結(jié)構(gòu),所以用起來其實(shí)和HashMa
47、p是基本一致的;DBCursor:用來遍歷取得的數(shù)據(jù),實(shí)現(xiàn)了Iterable和Iterator。下面以一段簡(jiǎn)單的例子說明:13MongoDB實(shí)例分析下面通過一個(gè)實(shí)例說明如何用MongoDB作為數(shù)據(jù)庫。該實(shí)例中有一個(gè)user實(shí)體,包含一個(gè)name屬性,每個(gè)user對(duì)應(yīng)一到多個(gè)圖片image。按照關(guān)系型數(shù)據(jù)庫設(shè)計(jì),可以設(shè)計(jì)一個(gè)user表和一個(gè)image表,其中image表中有一個(gè)關(guān)聯(lián)到user表的外鍵。如果將這兩個(gè)表對(duì)應(yīng)為兩個(gè)collection,即image對(duì)應(yīng)的collection中的每一個(gè)document都有一個(gè)key,其value是該image關(guān)聯(lián)的user。但為了體現(xiàn)MongoDB的效率
48、,即MongoDB是schema-free的,而且支持嵌入子文檔,因此在實(shí)現(xiàn)時(shí),將一個(gè)user發(fā)布的image作為該user的子文檔嵌入其中,這樣只需要定義一個(gè)collection,即userCollection。如下圖所示:對(duì)于圖片等文件,可以存儲(chǔ)在文件系統(tǒng)中,也可以存儲(chǔ)在數(shù)據(jù)庫中。因此下面分兩種情況實(shí)現(xiàn)。13.1圖片保存在文件系統(tǒng)中這種情況下,圖片實(shí)體中需要記錄圖片的路徑uri,因此Image類的定義如下:因?yàn)樵贛ongoDB中,當(dāng)保存的對(duì)象沒有設(shè)置ID時(shí),mongoDB會(huì)默認(rèn)給該條記錄設(shè)置一個(gè)ID("_id"),因此在類中沒有定義id屬性(下同)。因?yàn)橐粋€(gè)user對(duì)應(yīng)
49、多個(gè)image,所以在user實(shí)體中需要記錄對(duì)應(yīng)的image。如下:在main函數(shù)中實(shí)現(xiàn)如下功能:首先定義一個(gè)user(假設(shè)id為1),其對(duì)應(yīng)3張圖片,然后將該user插入userCollection中。然后,通過查詢查找到該user(根據(jù)id),再發(fā)布第4張圖片,更新該user,然后打印出其信息。部分代碼如下:程序運(yùn)行后,在控制臺(tái)打印出的信息如下:從該結(jié)果容易看出,用戶user有兩個(gè)屬性“_id”和“Name”,而且ImageList作為其子文檔(數(shù)組)嵌入其中,該數(shù)組中是3個(gè)圖片,每個(gè)圖片仍然是bson格式。13.2圖片保存在數(shù)據(jù)庫中這種情況下,圖片實(shí)體只需要存儲(chǔ)文件名即可,因此Image
50、2類的定義如下:User2類和上面類似,如下所示:實(shí)現(xiàn)了類MongoTest2,其功能仍然是一個(gè)user對(duì)應(yīng)3個(gè)圖片,存入數(shù)據(jù)庫中后,通過查詢得到該user后,再插入第4幅圖片,然后打印出信息。同時(shí)為了演示文件的查詢,對(duì)存入MongoDB中的圖片進(jìn)行了查詢并打印出其部分元數(shù)據(jù)信息。部分代碼如下所示:運(yùn)行程序,控制臺(tái)打印出的結(jié)果如下:14MongoDB常用API總結(jié)Ø 類轉(zhuǎn)換 當(dāng)把一個(gè)類對(duì)象存到mongoDB后,從mongoDB取出來時(shí)使用setObjectClass()將其轉(zhuǎn)換回原來的類。 public class Tweet implements DBObject /* . */
51、Tweet myTweet = new Tweet(); myTweet.put("user", "bruce"); myTweet.put("message", "fun"); myTweet.put("date", new Date(); collection.insert(myTweet); /轉(zhuǎn)換 collection.setObjectClass(Tweet.class); Tweet myTweet = (Tweet)collection.findOne(); Ø 默認(rèn)ID
52、 當(dāng)保存的對(duì)象沒有設(shè)置ID時(shí),mongoDB會(huì)默認(rèn)給該條記錄設(shè)置一個(gè)ID("_id")。 當(dāng)然你也可以設(shè)置自己指定的ID,如:(在mongoDB中執(zhí)行用db.users.save(_id:1,name:'bruce');) BasicDBObject bo = new BasicDBObject(); bo.put('_id', 1); bo.put('name', 'bruce'); collection.insert(bo); Ø 權(quán)限 判斷是否有mongoDB的訪問權(quán)限,有就返回true,否則返
53、回false。 boolean auth = db.authenticate(myUserName, myPassword); Ø 查看mongoDB數(shù)據(jù)庫列表 Mongo m = new Mongo(); for (String s : m.getDatabaseNames() System.out.println(s); Ø 查看當(dāng)前庫下所有的表名,等于在mongoDB中執(zhí)行show tables; Set<String> colls = db.getCollectionNames(); for (String s : colls) System.out.p
54、rintln(s); Ø 查看一個(gè)表的索引 List<DBObject> list = coll.getIndexInfo(); for (DBObject o : list) System.out.println(o); Ø 刪除一個(gè)數(shù)據(jù)庫 Mongo m = new Mongo(); m.dropDatabase("myDatabaseName"); Ø 建立mongoDB的鏈接 Mongo m = new Mongo("localhost", 27017); /有多個(gè)重載方法,可根據(jù)需要選擇DB db =
55、m.getDB("myDatabaseName"); /相當(dāng)于庫名 DBCollection coll = db.getCollection("myUsersTable");/相當(dāng)于表名查詢數(shù)據(jù) Ø 查詢第一條記錄 DBObject firstDoc = coll.findOne(); findOne()返回一個(gè)記錄,而find()返回的是DBCursor游標(biāo)對(duì)象。 Ø 查詢?nèi)繑?shù)據(jù) DBCursor cur = coll.find(); while(cur.hasNext() System.out.println(cur.next(
56、); Ø 查詢記錄數(shù)量 coll.find().count(); coll.find(new BasicDBObject("age", 26).count(); Ø 條件查詢 BasicDBObject condition = new BasicDBObject(); condition.put("name", "bruce"); condition.put("age", 26); coll.find(condition); Ø 查詢部分?jǐn)?shù)據(jù)塊 DBCursor cursor = co
57、ll.find().skip(0).limit(10); while(cursor.hasNext() System.out.println(cursor.next(); Ø 比較查詢(age > 50) BasicDBObject condition = new BasicDBObject(); condition.put("age", new BasicDBObject("$gt", 50); coll.find(condition); 比較符 "$gt": 大于 "$gte":大于等于 &qu
58、ot;$lt": 小于 "$lte":小于等于 "$in": 包含 /以下條件查詢20<age<=30 condition.put("age", new BasicDBObject("$gt", 20).append("$lte", 30); 插入數(shù)據(jù) Ø 批量插入 List datas = new ArrayList(); for (int i=0; i < 100; i+) BasicDBObject bo = new BasicDBObject();
59、bo.put("name", "bruce"); bo.append("age", i); datas.add(bo); coll.insert(datas); 又如:DBCollection coll = db.getCollection("testCollection"); for(int i=1; i<=100; i+) /插入100條記錄 User user = new User(); user.setName("user_"+i); user.setPoint(i); coll.insert(user); Ø 正則表達(dá)式 查詢所有名字匹配 /joh?n/i 的記錄 Pattern pattern = Ppile("joh?n", CASE_INSENSITIVE); BasicDBObject query = new BasicDBObject("name", pattern); DBCursor cursor = coll.find(query); 1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五私企員工勞動(dòng)合同與員工績(jī)效評(píng)估
- 2025年度無產(chǎn)權(quán)車庫轉(zhuǎn)讓及附屬綠化帶使用協(xié)議
- 二零二五年度科技型企業(yè)融資合作框架
- 2025年度礦山股份合作保險(xiǎn)合同:礦山安全生產(chǎn)責(zé)任險(xiǎn)與財(cái)產(chǎn)險(xiǎn)合作協(xié)議
- 二零二五年度城市軌道交通工程用工管理協(xié)議
- 2025年度首飾抵押借款合同購買設(shè)計(jì)師首飾服務(wù)協(xié)議
- 2025年手房購房合同(含車位及儲(chǔ)藏室)
- 【央企招聘】中煤電力有限公司所屬企業(yè)公開招聘(24人)筆試參考題庫附帶答案詳解
- 2025遼寧鞍山市臺(tái)安農(nóng)業(yè)發(fā)展集團(tuán)有限公司招聘11人筆試參考題庫附帶答案詳解
- 2025福建投資集團(tuán)能源板塊去場(chǎng)招聘114人筆試參考題庫附帶答案詳解
- 2025年健身教練合同協(xié)議樣本
- 2025年常州工業(yè)職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(培優(yōu))
- 2025年湖南商務(wù)職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫必考題
- 中儲(chǔ)糧黑龍江分公司招聘考試試卷2023
- 化學(xué)實(shí)驗(yàn)室安全職責(zé)分配
- 1.2 讀懂彼此的心 第二課時(shí) 課件 2024-2025學(xué)年五年級(jí)下冊(cè)道德與法治 統(tǒng)編版
- 2018-2022年北京市中考真題數(shù)學(xué)試題匯編:選擇壓軸(第8題)
- 2025年哈爾濱鐵道職業(yè)技術(shù)學(xué)院高職單招語文2018-2024歷年參考題庫頻考點(diǎn)含答案解析
- 2025年貴州黔源電力股份有限公司招聘筆試參考題庫含答案解析
- 2024年湖南食品藥品職業(yè)學(xué)院高職單招語文歷年參考題庫含答案解析
- 《船舶油漆作業(yè)》課件
評(píng)論
0/150
提交評(píng)論