1. 程式人生 > >第七章 NoSQL資料庫技術(二)

第七章 NoSQL資料庫技術(二)

 

文件型資料庫

文件是處理資訊的基本單位。文件可以很長、很複雜、可以無結構

一個文件對包含的資料型別和內容進行“自我描述”。XML文件、HTML文件和JSON 文件

嵌入式文件 --文件儲存模型支援巢狀結構

每個文件的ID就是它唯一的鍵,ID在一個數據庫“集合”中是唯一的, 檢索排序的ID效能好。

 

MongoDB 資料庫

MongoDB 是基於分散式檔案儲存的開源資料庫系統。 將資料儲存為一個文件,資料結構由鍵值對組成,欄位值可以包含其他文件,陣列及文件陣列。 每一行的儲存格式為 field:value。 每個文件可以匹配所表示實體的資料域。 資料關係有兩種:引用和嵌入文件。 寫操作在文件級別是原子性的,沒有單個寫操作對超過一個文件或者超過一個集合是原子性的。

MongoDB資料模型

基本的概念是文件、集合、資料庫。 文件是MongoDB中資料的基本單元 集合可以被看作沒有模式的表, 每個例項都可容納多個獨立資料庫,每個資料庫都有自己的集合和許可權。

層次關係:  文件—集合---資料庫。

 

文件

多個鍵及其關聯的值有序地放置在一起就是文件。 文件是一組鍵值(key-value)對(即BSON)。 文件不需要設定相同的欄位,相同的欄位不需要相同的資料型別。 一個文件包含一組欄位,每一個欄位都是一個key/value對, 其中key必須為字串型別, value包含string,int,float,timestamp,binary 等型別, 或一個文件, 或陣列型別。

單鍵值文件{“userName”:“BBS11”}, 多鍵值文件{ "_id" : ObjectId("580dfe72729"),  "name" :  "test", "add": "china" },文件中的鍵/值對是有序的。 文件中的值可以是在雙引號裡面的字串,還可以是其他幾種資料型別(甚至可以是整個嵌入的文件)。 MongoDB文件不能有重複的鍵。文件的鍵是字串。文件中的值不僅可以是字串,也可以是其他資料型別(或者嵌入其他文件)

集合

把一組相關的文件放到一起組成了集合 集合是模式自由的,一個集合裡面的文件可以是各式各樣的。

例如:下面的兩個文件可以出現在同一集合中

{“name”:”arthur”}

{“name”:”arthur”,”sex”:”male”}

MongoDB提供了一些特殊功能的集合,例如:capped collection、system.indexes、system.namespaces等。

元資料是定義資料的資料, 資料庫的資訊是儲存在集合中。

資料庫

多個文件組成集合,資料庫由多個集合組成 MongoDB例項可承載多個數據庫,互相之間彼此獨立 開發中通常將一個應用(或同一種業務型別)的所有資料存放到同一個資料庫中;磁碟上,MongoDB將不同資料庫存放在不同檔案中。 一個MongoDB 例項可以包含一組資料庫,一個數據庫可以包含一組集合(Collection集合),一個集合可以包含一組文件。一個mongodb中可以建立多個數據庫。 系統資料庫包括:admin、local、config等。

 

面向集合且模式自由的文件型資料庫。面向集合--資料被分組為集合(文件);資料模式自由;儲存的資料是鍵值對的集合,鍵是字串,值是任意型別,包括陣列和文件。

文件是MongoDB中資料的基本單元,集合可以被看作沒有模式的表,MongoDB每個例項都可容納多個獨立資料庫,每個資料庫都有自己的集合和許可權(資料庫)。 文件(Document)---文件組集合:Collection -- 多個集合:資料庫(database)。一個例項支援多個數據庫(database)

資料庫對應檔案資訊

預設資料目錄是/daba/db,儲存所有的資料檔案,每個資料庫都包含一個.ns檔案和一些資料檔案,例如test資料庫,資料庫的檔案就會由test.ns、test.0、test.1、test.2等組成。 預分配空間的機制,用0進行填充。 每新分配一次,它的大小都會是上一個資料檔案大小的2倍,每個資料檔案最大2G。 資料庫的每張表都對應一個名稱空間,每個索引也有對應的名稱空間,這些名稱空間的元資料集中在*.ns檔案中。

資料庫儲存

資料庫中所有的collections以及索引資訊分散儲存在多個數據檔案中,資料分塊的單位為extent(範圍,區域),即一個data file中有多個extents組成,extent中可以儲存collection資料或者indexes資料,一個extent只能儲存同一個collection資料,不同的collections資料分佈在不同的extents中,indexes資料也儲存在各自的extents中; 在每個database的namespace檔案中,每個collection只儲存了第一個extent的位置資訊,每個extent都維護著一個連結串列關係。

MongoDB體系結構

分散式叢集:資料備份--安全性,高讀寫服務的能力和資料儲存能力。 通過副本集(replica)對資料進行備份,通過分片(sharding)對大的資料進行分割,分散式儲存在不同節點上。

mongodb目前為止支援三種叢集模式:主從叢集,副本集叢集,分片叢集。

叢集架構的單機例項(mongod instance):只有一個單機例項,客戶端與其直接連線使用。 副本集(Replica sets):副本集通常由至少3個節點組成。一個主節點,處理客戶端請求,其餘是從節點,複製主節點上的資料。 mongodb各個節點常見的搭配方式為:一主多從(正常情況下至少3個節點組成副本集) 主節點記錄在其上的所有操作,從節點定期輪詢主節點獲取這些操作,資料與一致。 選舉機制:當一個節點掛掉之後需要滿足“大多數”成員投票。

分片(Sharding)

分片是將一個集合的資料分別儲存在不同的shard節點上減輕單機壓力。根據Shard Keys來劃分資料,  資料庫提供了兩種方法:垂直擴充套件和分片。垂直擴充套件:增加CPU、RAM,儲存資源等。分片(水平擴充套件):劃分資料集,資料分佈到多臺伺服器中,每個碎片(chard)是獨立的資料庫 分片叢集有三個元件:Shards碎片,儲存資料,每個碎片都是一個複製集。query routers:查詢路由或mongos例項。configservers:配置伺服器,儲存叢集中的元資料。

叢集中的伺服器

路由伺服器(mongos):路由伺服器負責把對應的資料請求請求轉發到對應的shard伺服器上 mongos,資料庫叢集請求的入口。  配置伺服器(mongos):儲存所有資料庫元資訊(路由、分片)的配置。mongos本身沒有物理儲存分片伺服器和資料路由資訊,只是快取在記憶體裡,配置伺服器則實際儲存這些資料。 配置伺服器相當於叢集大腦,儲存所有資料庫元資訊(路由、分片)的配置。

叢集的組成: 單機mongod 組成副本集 -> 分片, 客戶端通過mongos 讀取 config servers的資訊與分片通訊,通過mongos伺服器的ip和連線方式,mongos 會自動選擇。

Shards:每一個shard包括一個或多個服務和儲存資料的mongod程序這些服務/mongod程序在shard中組成一個複製集。

 

MongoDB的關鍵特性主要是3個,第一個就是靈活動態的文件模型,第二個是高可用副本集,第三個是MongoDB的水平擴充套件,也就是sharding。 MongoDB叢集包括一定數量的mongod(分片儲存資料)、mongos(路由處理)、config server(配置節點)、clients(客戶端)、arbiter(仲裁節點:為了選舉某個分片儲存資料節點那臺為主節點)。

MongoDB 複製原理

MongoDB 複製是將資料同步在多個伺服器的過程。複製提供了資料的冗餘備份,並在多個伺服器上儲存資料副本,提高了資料的可用性, 並可以保證資料的安全性。複製還允許從硬體故障和服務中斷中恢復資料。 複製: 保障資料的安全性, 資料高可用性 (24*7), 災難恢復, 無需停機維護(如備份,重建索引,壓縮), 分散式讀取資料 MongoDB複製原理: 至少需要兩個節點。其中一個是主節點,負責處理客戶端請求,其餘的都是從節點,負責複製主節點上的資料。mongodb各個節點常見的搭配方式為:一主一從、一主多從。 客戶端從主節點讀取資料,在客戶端寫入資料到主節點時, 主節點與從節點進行資料互動保障資料的一致性。 副本集特徵:N 個節點的叢集, 任何節點可作為主節點, 所有寫入操作都在主節點上, 自動故障轉移, 自動恢復。

 

圖形資料庫

網際網路+、社交網路,智慧推薦等的大規模興起和繁榮。尋找直接朋友或是尋找朋友的朋友這樣的遍歷查詢----圖資料庫。  圖資料庫源起尤拉和圖理論,面向/基於圖的資料庫。 以“圖”資料結構儲存和查詢資料,資料模型以節點和關係(邊)體現,也處理鍵值對。 圖特徵:包含節點和邊;節點上有屬性(鍵值對);邊有名字和方向,開始\結束節點;邊可有屬性。圖是頂點和邊的集合,或圖是一些節點和關聯聯絡(relationship)的集合。

G=(V, E) , V=vertex(節點) , E=edge(邊) 。節點和關係屬性;節點多個標籤(類別);一個屬性圖是由頂點(Vertex),邊(Edge),標籤(Lable),關係型別和屬性組成的有向圖。 頂點-節點(Node),邊--關係(Relationship)點和關係--實體,節點是獨立存在的,節點有設定標籤,相同標籤節點屬於一個分組或集合; 關係通過關係型別來分組,型別相同的關係屬於同一個集合。關係是有向的 圖資料庫可處理大量的、複雜的、互聯的、多變的網狀資料,適用於社交網路、實時推薦、銀行交易環路、金融徵信系統等廣泛的領域。

Neo4j資料庫

Neo4j是開源的用Java實現圖資料庫,有兩種執行方式,一種是服務的方式,對外提供REST介面;另外一種是嵌入式模式,資料以檔案的形式存放在本地,直接對本地檔案進行操作。 Neo4j是一個高效能的NOSQL圖形資料庫,它將結構化資料儲存在網路上而不是表中。Neo4j也可以被看作是一個高效能的圖引擎,該引擎具有成熟資料庫的所有特性。 程式設計師工作在一個面向物件的、靈活的網路結構下而不是嚴格、靜態的表中——但是可以享受到具備完全的事務特性、企業級的資料庫的所有好處。

Neo4j資料模型

每個實體都有ID(Identity)唯一標識,每個節點由標籤(Lable)分組,每個關係都有一個唯一的型別,屬性圖模型的基本概念有: 實體(Entity)是指節點(Node)和關係(Relationship); 每個實體都有零個、一個或多個屬性,一個實體的屬性鍵是唯一的;每個節點都有零個、一個或多個標籤,屬於一個或多個分組; 每個關係都只有一個型別,用於連線兩個節點; 路徑(Path)是指由起始節點和終止節點之間的實體(節點和關係)構成的有序組合; 標記(Token)是非空的字串,用於標識標籤(Lable),關係型別(Relationship Type),或屬性鍵(Property Key); 標籤:用於標記節點的分組,多個節點可以有相同的標籤,一個節點可以有多個Lable,Lable用於對節點進行分組;關係型別:用於標記關係的型別,多個關係可以有相同的關係型別。屬性鍵:用於唯一標識一個屬性;屬性(Property)是一個鍵值對(Key/Value Pair),每個節點或關係可以有一個或多個屬性; 屬性值可以是標量型別,或這標量型別的列表(陣列)。

在下面的圖形中,存在三個節點和兩個關係共5個實體;Person和Movie是Lable,ACTED_ID和DIRECTED是關係型別,name,title,roles等是節點和關係的屬性。 實體包括節點和關係,節點有標籤和屬性,關係是有向的,連結兩個節點,具有屬性和關係型別。

1 實體   在示例圖形中,包含三個節點,分別是: Name =‘Tom Hanks’   Name=‘Robert Zemeckis’   title=‘Forrest Group’

                                                                               Born=1956                  born=1951                          released=1994      

2 關係: 包含兩個關係是兩個關係型別ACTED_IN和DIRECTED,兩個關係是連線name屬性為Tom Hank節點和Movie節點的關係,和連線name屬性為Robert Zemeckis的節點和Movie節點的關係。

3 標籤(Lable) 在圖形結構中,標籤用於對節點進行分組,相當於節點的型別,擁有相同標籤的節點屬於同一個分組。一個節點可以擁有零個、一個或多個標籤,因此,一個節點可以屬於多個分組。對分組進行查詢,能夠縮小查詢的節點範圍,提高查詢的效能。 在示例圖形中,有兩個標籤Person和Movie,兩個節點是Person,一個節點是Movie,標籤有點像節點的型別,每個節點可以有多個標籤。

4 屬性(Property)是一個鍵值對(Key/Value),用於為節點或關係提供資訊。每個節點都由name屬性,用於命名節點。 在示例圖形中,Person節點有兩個屬性name和born,Movie節點有兩個屬性:title和released。關係型別ACTED_IN有一個屬性:roles(扮演的角色),該屬性值是一個數組,而關係型別為DIRECTED的關係沒有屬性。

5 遍歷(Traversal)一個圖形,是指沿著關係及其方向,訪問圖形的節點。關係是有向的,從起始節點沿著關係,一步一步導航到結束節點的過程叫做遍歷,遍歷經過的節點和關係的有序組合稱路徑。 在示例圖形中,查詢Tom Hanks參演的電影,遍歷的過程是:從Tom Hanks節點開始,沿著ACTED_IN關係,尋找標籤為Movie的目標節點。

 

Neo4J資料庫的儲存結構

(1) Nodes(節點,類似地鐵圖裡的一個地鐵站): 圖的基本單位節點和關係,都可包含屬性,關係和節點還可以有零到多個標籤。

(2) Relationships(關係,類似兩個相鄰地鐵站之間路線): 組織和連線節點,一個開始節點和一個結束節點。關係有方向進和出。

(3) Properties(屬性,類似地鐵站的名字,位置,大小,進出口數量等):節點和關係可以擁有0到多個屬性,屬性型別java的資料型別一致,分為數值、字串、布林、以及其他的一些型別,欄位名必須是字串。

(4) Labels(標籤,類似地鐵站的屬於哪個區): 標籤通過形容一種角色或者給節點加上一種型別,一個節點可有多個型別,標籤在給屬性建立索引或者約束時候也會用到。

(5) Traversal(遍歷,類似看地圖找路徑): 查詢是遍歷圖譜然後找到路徑,一個開始節點,遍歷相關路徑上的節點和關係,得到最終的結果。

(6) Paths(路徑,類似從一個地鐵站到另一個地鐵站的所有的到達路徑): 路徑是一個或多個節點通過關係連線起來的產物。

(7) Schema(模式,類似儲存資料的結構): neo4j是一個無模式或less模式的圖譜資料庫,使用它不需要定義任何schema。

(8)Indexes(索引): 遍歷圖通過需要大量的隨機讀寫,在欄位屬性上構建索引,構建索引是一個非同步請求,在後臺建立直至成功後,才能生效。

(9)Constraints(約束): 約束定義在某個欄位上,限制欄位值唯一,建立約束會自動建立索引。

Node和Relationship 的 Property 是用一個 Key-Value 的雙向列表來儲存的; Node 的 Relatsionship 是用一個雙向列表來儲存的,通過關係,可以的找到關係的前導和後繼節點( from-to Node). Node 節點儲存第1個屬性和第1個關係ID。圖的儲存結構包括5類檔案:

(1) 儲存 node 的檔案, 儲存節點資料、節點label及其序列Id包括儲存節點陣列、陣列的下標即是該節點的ID 、最大的ID 及已經free的ID。

(2)儲存 relationship 的檔案: 儲存關係資料、關係組資料、關係型別、關係型別陣列資料、關係型別的名稱及其序列Id包括儲存關係 record 陣列資料、關係 group陣列資料、儲關係型別陣列資料、關係型別 token 陣列資料 和ID。

(3)儲存 label 的檔案: label token資料、名字資料及其序列Id 包括儲存lable token 陣列資料、 label token 的 names 資料 和ID。 (4)儲存 property 的檔案:屬性資料、型別、索引等及其序列Id 包括  property 資料、property (key-value 結構)的是陣列的資料、 property (key-value 結構)的值是字串的資料、property (key-value 結構)的key 的索引數、property (key-value 結構)的key 的字串值和ID。

(5)其他的檔案: 版本資訊、日誌等

Neo4j 主要有節點、屬性、關係等檔案是以陣列作為核心儲存結構; 同時對節點、屬性、關係等型別的每個資料項都會分配一個唯一的ID,在儲存時以該ID 為陣列的下標。 在訪問時通過其ID作為下標,實現快速定位。 所以在圖遍歷等操作時,可以實現 free-index。

 

叢集方式

Neo4j主要有兩種cluster方式:Ha(High avaiable)和Causal cluster方式。叢集的主要特點:高吞吐量,持續可靠性,災難恢復。   Causal cluster: 1)核心伺服器(core server),處理讀寫的操作,大多數的核心伺服器主要處理寫操作和 2)一個或多個讀複製伺服器(read replicas),只讀的例項,資料從核心伺服器非同步更新,這些適用於廣泛的資料地理分佈,並允許跨大量伺服器擴充套件查詢工作負載。 HA cluster: 至少有三臺服伺服器組成,1主2從,主伺服器完成寫入之後同步資料到從伺服器,主伺服器既可以寫也能讀,從伺服器只能讀。HA群集可用於全天候正常執行並提高讀取效能。

在這裡以3個節點的Neo4j組成叢集為例子, 討論其體系結構和資料的操作原理。 圖展示了由三個Neo4J結點所組成的Master-Slave叢集。每個叢集都包含一個Master和多個Slave。Master負責資料的寫入,接下來Slave則會將Master中的資料更改同步到自身。

 

叢集資料的寫入通過Master完成,圖資料修改的複雜性(修改圖結點本身、維護各個關係等),圖所進行的操作是讀比寫多很多。 Neo4J內部還有一個寫佇列,暫時快取向Neo4J例項的寫入操作,從而使得Neo4J能夠處理突然到來的大量寫入操作。 在最壞的情況就是Neo4J叢集需要面對持續的大量的寫入操作。需要考慮Neo4J叢集的縱向擴充套件了。

叢集的讀入

資料的讀取可以通過叢集中的任意一個Neo4J例項來完成。 Neo4J內部使用一個快取記錄最近所訪問的資料。這些快取資料會儲存在記憶體中以便快速地響應資料讀取請求。 Neo4J所提供的解決方案被稱為Cache-based Sharding。使用同一個Neo4J例項來響應一個使用者所傳送的所有需求。

叢集容錯機制

叢集中一個例項失效了,其它例項會在短時間內探測到,恢復到正常狀態將資料同步到最新。Master失效通過內建的Leader選舉功能選舉出新的Master。 在Cluster Management組成的幫助下,可以建立一個Global Cluster。其擁有一個Master Cluster以及多個Slave Cluster。資料的寫入通常都是在Master Cluster中進行,而Slave Cluster將只負責提供資料讀取服務。