第七章 NoSQL資料庫技術(一)
NoSQL
NoSQL是Not Only SQL的縮寫,意即“不僅僅是SQL”,即對關係型SQL資料庫系統的補充。
一類非關係資料儲存系統
通常不需要一個固定的表的模式
所有的NoSQL淡化了一個或更多的ACID屬性
相比傳統資料庫叫它分散式資料庫管理系統更貼切, 資料儲存被簡化, 重點被放在了分散式資料管理上
簡單資料型別--鍵值
系統只需支援單記錄級別的原子性
系統的擴充套件性
元資料和應用資料的分離
弱一致性,用最終一致性和時間一致性來滿足使用者對資料一致性的要求
適應資料增長,並且能靈活適應半結構化資料和稀疏資料集。
沒有宣告性查詢語言
儲存方式靈活包括鍵-值對儲存、列儲存、文件儲存、圖形儲存資料庫等,
最終一致性,非結構化和不可預知的資料, 遵守CAP定理, 高效能,高可用性和可伸縮性
整體框架
NoSQL的儲存型別
列儲存資料庫,將同一列的資料儲存在一起,可以儲存結構化和半結構化資料
鍵值儲存資料庫,儲存的資料是有鍵(key)和值(value)兩部分組成,通過key快速查詢到其value,value的格式可以根據具體應用來確定
文件儲存資料庫,儲存的內容是文件型的,可以用格式化檔案(類似json、XML等)的格式儲存
圖儲存資料庫,資料以有向加權圖方式進行儲存
CAP理論
分散式資料庫系統中的事務是一個分散式操作序列,被操作的資料分佈在不同的結點上,分散式事務具有ACID特徵
在分散式的環境下設計和部署系統時,有3個核心的需求:CAP對應一致性(Consistency),可用性(Availability)和分割槽容忍性(Partition Tolerance)
C:在分散式系統中的所有資料備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的資料副本)
A:在叢集中一部分節點故障後,叢集整體是否還能響應客戶端的讀寫請求。(對資料更新具備高可用性)
P:以實際效果而言,分割槽相當於對通訊的時限要求。系統如果不能在時限內達成資料一致性,就意味著發生了分割槽的情況,必須就當前操作在C和A之間做出選擇。
一個分散式系統不可能同時很好的滿足一致性、可用性和分割槽容錯性這三個需求,最多隻能同時較好的滿足兩個。
CA - 單點叢集,滿足一致性,可用性的系統
CP - 滿足一致性,分割槽容忍性的系統
AP - 滿足可用性,分割槽容忍性的系統
一般情況下選擇後兩種中的其中一種,即滿足分割槽容忍性,在CA之間選其一。
CAP是為了探索不同應用的一致性C與可用性A之間的平衡
在網路或其他原因,通過犧牲一定的一致性C來獲得更好的效能與擴充套件性
在有分隔發生,選擇可用性A,集中關注分隔的恢復,需要分隔前、中、後期的處理策略, 及合適的補償處理機制
BASE
Basically Available --基本可用;系統能夠基本執行,一直提供服務。
Soft-state --軟狀態/柔性事務。"Soft state" 可以理解為"無連線"的, 而 "Hard state" 是"面向連線"的;系統不要求一直保持強一致狀態。
Eventual Consistency --最終一致性 系統在某個時刻達到最終一致性。
BASE定義為CAP中AP的衍生,在分散式環境下, BASE是資料的屬性,BASE強調基本的可用性,按照功能劃分資料庫.
BASE的特點是弱一致性、可用性優先、採用樂觀方法、適應變化並且簡單快捷
一致性可以從客戶端和伺服器端兩個角度來看
客戶端關注的是多併發訪問的更新過的資料如何獲取的問題,對多程序併發進行訪問時, 更新的資料在不同程序如何獲得不同策略, 決定了不同的一致性。
伺服器關注的是更新如何複製分佈到整個系統, 以保證最終的一致性。 一致性因為有併發讀寫才出現問題, 一定要結合併發讀寫的場地應用要求。 如何要求一段時間後能夠訪問更新後的資料, 即為最終一致性。
分散式檔案系統
分散式檔案系統(Distributed File System:DFS )是指檔案系統的物理儲存資源不在本地節點上,通過計算機網路與節點相連。
DFS--單個訪問點和一個邏輯結構,使用者透明訪問系統中的任何檔案
DFS將統一網路中的不同計算機上的共享資料夾組織起來,形成一個單獨的、邏輯的、層次式的共享檔案系統。
列儲存資料庫
列式資料庫把一列中的資料值串在一起儲存起來,然後再儲存下一列的資料,以此類推。
查詢中的選擇規則是通過列來定義的,列式儲存資料庫是自動索引化的;資料壓縮比高,查詢速度高
HBase資料模型
HBase 以表的形式表達和儲存資料,表由行和列組成,列劃分為若干個列族(row family)。
HBase表的邏輯檢視是基於行鍵(rowkey)、列族(column family)、列限定符(column qualifier)和時間版本(version)
HBase沒有資料型別,任何列值都被轉換成字串進行儲存;
HBase表的每一行可以有不同的列;
相同RowKey的插入操作被認為是同一行的操作。即相同RowKey的二次寫入操作,第二次可被可為是對該行某些列的更新操作;列由列族和列名連線而成,分隔符是冒號,如 d:Name (d列族名,Name列名)。
表的儲存結構: 邏輯資料模型中空白cell在物理上是不儲存的
假設關係型資料庫Hblog有3個表格
文章表Article(id, title, content, tags, author_id)
作者表Author(id, name, nickname),
日誌表blog(blog_ID, article_id, author_id,pub_time, ...)
用HBASE設計表結構為Hblog, 這裡行鍵是ID, 列族有兩個article和author,article列族中有3個列title, content, tags, author列族有2個列name, nickname。
HBase不支援條件查詢和Order by等查詢,只能按Row key(及其range)或全表掃描;
表建立時只需宣告表名和至少一個列族名,每個Column Family為一個儲存單元;
Column不用建立表時定義即可以動態新增,同一Column Family的Columns會群聚在一個儲存單元上,並依Column key排序
HBAS資料的儲存型別: TableName 是字串;RowKey 和 ColumnName 是二進位制值(Java 型別 byte[]);Timestamp 是一個 64 位整數(Java 型別 long);value 是一個位元組陣列(Java型別 byte[])。
HBASE的資料模型的定義的層次是:
Schema-->Table-->Column Family-->Rowkey-->TimeStamp-->Value
其中:
RowKey:是Byte array,是表中每條記錄的“主鍵”,方便快速查詢,Rowkey的設計非常重要。
Column Family:列族,擁有一個名稱(string),包含一個或者多個相關列
Column:屬於某一個columnfamily,familyName:columnName,每條記錄可動態新增
Version Number:型別為Long,預設值是系統時間戳,可由使用者自定義
Value(Cell):Byte array 。
HBASE的儲存結構:
1、表中所有行都按照row key的字典序排列;
2、Table在行的方向上分割為多個Region;
3、Region按大小分割的,每個表開始只有一個region,隨著資料增多,region不斷增大,當增大到一個閥值的時候,region就會等分會兩個新的region,之後會有越來越多的region;
4、Region是Hbase中分散式儲存和負載均衡的最小單元,不同Region分佈到不同RegionServer上
表Table: 面向列(族)的儲存和許可權控制,列(族)獨立檢索的稀疏儲存。按行鍵的字典排序;Table在行的方向上分割多個Region。
區域Region(表的Regions):每個Region儲存著Table的若干行,Region是分散式儲存的最小單元。
Store(Region中以列族為單位的單元): 區域由一個或者多個Store組成,每個store儲存一個列族。Strore由memStore和0至多個StoreFile
StoreFile:以HFile的格式儲存在分散式檔案系統(HDFS)上
Hbase的系統構架
Hbase是一個分散式的資料庫,使用Zookeeper來管理叢集。
在架構層面上分為Master和多個RegionServer。
在分散式的生產環境中,HBase 需要執行在 HDFS 之上,由 HDFS提供基礎的儲存設施,上層提供訪問的資料的 API,對HBase 的資料進行管理,
主伺服器
管理區域伺服器;
指派區域伺服器對特定區域服務;
恢復失效的區域伺服器,負載均衡和修復時區域伺服器
監聽ZooKeeper中的狀態, 其管理職能包括建立、刪除、修改表的定義等;
負責分配區域給區域伺服器。
多個Master節點共存,只有一個Master是提供服務的,其他的Master節點處於待命的狀態。當正在工作的Master節點失效時,其他的Master則會接管叢集。
區域伺服器
為區域的訪問提供服務,直接為使用者提供服務;
負責維護區域的合併與分割; 負責資料存持久化。
管理表格,實現讀寫操作。
客戶端直接連線區域伺服器,並通訊獲取HBase中的資料。
Zookeeper
協調者(Zookeeper),保證任何時候叢集中只有一個master, 儲存所有Region的定址入口, 實時監控區域伺服器的狀態,將Region上線和下線的資訊實時通知給Master, 儲存Hbse的schema,有哪些table,table有哪些列族。
通過選舉,叢集中只有一個master處於執行狀態。
Zookeeper負責Region和區域伺服器的註冊。解決分散式環境下資料管理問題:1.統一命名, 2.狀態同步, 3.叢集管理, 4.配置同步
Client
請求發起者, 通過API,包含訪問Hbase的介面,維護著一些cache來加快對Hbase的訪問,比如region的位置資訊。
訪問HBase的介面,並維護cache來加快對HBase的訪問,比如region的位置資訊. 使用HBase RPC機制與HMaster和區域伺服器進行通訊.
•Client與HMaster進行通訊進行管理類操作.
Client與區域伺服器進行資料讀寫類操作
Hbase組建圖
HLog(WAL log): WAL 意為先寫日誌後記錄資料(Write ahead log),用做災難恢復,Hlog記錄資料的所有變更
WAL是HDFS上的一個檔案,寫操作都先將資料寫入日誌後,才會真正更新MemStore,最後寫入HFile中。
區域伺服器失效後,可以從日誌檔案中讀取資料,重做所有的操作,來保證資料的一致性。
日誌檔案會定期刪除舊的檔案(已寫到HFile中的Log可以刪除)
HLog
每個區域伺服器維護一個Hlog,而不是每個Region一個。
HLog是一個普通的Hadoop序列檔案,它的Key是HLogKey物件,HLogKey中記錄了寫入資料的歸屬資訊,包括table和region名字,sequence number和timestamp,
HLog Sequece File的Value是Hbase的鍵值物件,即對應HFile中的鍵值。
鍵值對資料庫
KV:Key-Value(鍵值)儲存模型是Nosql中最基本的資料儲存模型, KV類似於雜湊表,在鍵和值之間建立對映關係,鍵值模型極大的簡化了關係資料模型,具有高效靈活的特點。
鍵值資料庫一致性表現在針對單個鍵的操作包括“獲取”、“設定”、或者“刪除”, 保證“一致性”, 也可以用“最終一致性模型”實現一致性。
其資料型別:
1 資料結構:鍵值模型(Key-Value模型),每行記錄由主鍵和值兩個部分組成,值可以是各種型別的資料
2 資料操作: Get( key )、Set( key, value )、Delete( key )等
3 資料完整性: 針對單個鍵的操作才區別“一致性”。
Redis資料庫
Redis 是Remote Dictionary Server的縮寫,開源的KV資料庫
Redis是KV型別的記憶體資料庫
Redis通過Key-Value的單值不同型別來區分, 支援的資料型別:字串型別(String)、雜湊表型別(Hash)、連結串列型別(List)、集合型別(Set)、有序集合型別(ordered set, zset)
Redis的缺點是資料庫容量受到實體記憶體的限制
Redis可儲存多種資料結構,單個值的最大限制是1GB
用List來做FIFO雙向連結串列可實現輕量級的高效能訊息佇列服務
用Set可做高效能的tag系統等
對存入的KV設定expire時間,通過非同步的方式將資料寫入磁碟,具有快速和資料持久化的特徵
Redis將鍵值儲存在主存中,快速讀寫
Redis支援主從複製。資料讀在slave完成,資料寫入在 master 完成
Redis使用RAM作為記憶體式儲存,用虛擬記憶體來儲存資料
Redis支援建立釋出和訂閱通道
Redis將記憶體中的資料定期儲存到檔案系統中,用於故障恢復
Redis有豐富的SDK支援。所有 Redis 的操作都是原子
Redis的每個資料庫中的所有資料都是Key-Value對,底層的都是二進位制位元組陣列的格式存放。客戶端取的時候需要自己來轉換
Redis鍵值是二進位制安全的,用任何二進位制序列作為key值。空字串也是有效key值
1.String
redis最基本的型別,string型別是二進位制安全的,string可以包含任何資料。
String是最常用的一種資料型別,可應用於普通的key/ value 儲存,具有定時持久化、操作日誌及 Replication等功能。
字串操作包括set、get、decr、incr、mget等, 獲取字串長度、append、設定和獲取字串的某一段內容、設定及獲取字串的某一位(bit)、批量設定一系列字串的內容等。
2.List
List列表即陣列是簡單的字串列表,按照插入順序排序,lpush、rpush、lpop、rpop、lrange等。l和 r表示左和右。
用來實現twitter的關注列表、粉絲列表等、最新訊息排行等功能。
實現為一個雙向連結串列,支援反向查詢和遍歷,使用時要考慮部分額外的記憶體開銷,傳送緩衝佇列等也都是用的這個資料結構。
連結串列
雙端:連結串列節點都有prev和next指標,獲取一個節點前置和後置的演算法複雜度都為O(1)。
無環:list的第一個節點(頭節點)的prev和最後一個節點(尾節點)的next都指向NULL。
帶表頭指標和表尾指標:通過list的head和tail兩個指標,連結串列的頭和尾進行操作。
帶連結串列長度計數器:可以通過len成員來獲取連結串列的節點的個數,複雜度O(1)。
多型:連結串列使用void *指標來儲存value,並且可以通過dup,free,match來操控節點的value值,因此,該連結串列可以儲存任意型別的值。
3.Hash
Hash(雜湊)是一個鍵值對集合,一個 string 型別的 field 和 value 的對映表。常用命令:hget、hset、hgetall等。
例項:使用者資訊包含:ID為key,value包含姓名、年齡、生日、專業等資訊,如果用普通的key/value結構來儲存:
第一種:將使用者ID作為查詢key,其他資訊封裝成一個物件以序列化的方式儲存。
第二種:把使用者資訊物件中所有成員都存成單個key-value對,用使用者ID+對應屬性的名稱作為唯一標識來標示對應屬性值。
4.Set
Redis中的集合是string型別一個無序的、去重的集合, 元素是字串型別。
對外提供的功能是一個列表,set是自動排重的,用set儲存一個列表資料且資料不重複
set 的內部實現是一個 value永遠為null的HashMap,通過計算hash的方式來快速排重的
儲存(sadd)、刪除(srem)、讀取(smembers)、元素是否存在(sismember)、差集運算(sdiff)、交集運算(sinter)、並集運算(sunion)、獲取元素數量(scard)、隨機獲得元素(srandmember)、儲存差集(sdiffstore)、交集(sinterstore)和並集(sunionstore)等。
5.Sorted set/zset
有序集合的操作類似Set集合,有序的、去重的、元素是字串型別、不允許重複的成員,每一個元素都關聯著一個浮點數分值(Score),按照分值從小到大的順序排列集合中的元素。
成員唯一的,但分數(score)可重複。
常用命令:zadd、zrange、zrem、zcard等
通過使用者額外提供一個優先順序(score)的引數來為成員排序,並且是插入有序的,即自動排序。
內部使用HashMap和跳躍表(SkipList)來保證資料的儲存和有序
HashMap裡放的是成員到score的對映,
跳躍表裡存放的是所有的成員,排序依據是HashMap裡存的score
Redis實現原則
資料庫的操作、叢集的設定簡單, Redis內部維護一個db陣列,每個db都是一個數據庫,預設16個數據庫。用select命令來切換資料庫。 儲存效率(memory efficiency)的考慮,可壓縮資料、減少記憶體碎片、快取記憶體和外存的資料交換演算法等問題; 快速響應時間(fast response time)與高吞吐量(high throughput)的折中方案; 單執行緒(single-threaded): 簡化資料結構和演算法的實現,通過非同步IO和pipelining等機制來實現高速的併發訪問。
Redis複製功能
Redis複製主要包括RDB複製和AOF複製,RDB快照方式,AOF通過將傳送到伺服器的寫操作命令記錄下來,形成AOF檔案。 在RDB複製中,每次執行特定的命令(SAVE或BGSAVE)時建立一個新的RDB檔案時,過期的鍵不儲存到新建立的RDB檔案中。載入時,過期鍵就不載入。 當使用AOF,過期鍵刪除之後,程式會向AOF檔案追加一條刪除命令
Redis的儲存管理
Redis是一個記憶體資料庫,記憶體中的資料劃分:
1)資料:資料庫中的資料佔用的記憶體會統計在used_memory
2)程序執行的記憶體:程式碼、常量池等等要佔用記憶體,子程序執行
3)緩衝記憶體
4)記憶體碎片
Redis資料庫的系統結構—叢集
分散式資料處理: 提供在多個Redis間節點間共享資料的程式集。 Redis 叢集的資料分片,引入了 雜湊槽的概念。 叢集有16384個雜湊槽 (hash slot),每個key通過CRC16校驗後對16384取模來決定放置哪個槽,叢集的每個節點負責一部分hash槽
叢集結構
Redis cluster叢集中的每個節點都是平等的關係,每個節點都儲存各自的資料和整個叢集的狀態。每個節點都和其他所有節點連線。 資料存在一個 master 節點,master 和其對應的salve 之間進行資料同步。當讀取資料到對應的 master 。Master掛掉,啟動一個對應的 salve 節點,充當 master 。 客戶端與redis節點直連,連線叢集中任何一個可用節點即可。redis-cluster把所有的物理節點對映到[0-16383]槽上,cluster 負責維護node<->slot<->value。
主從複製
在從節點配置檔案加上從伺服器的IP地址和埠號。通過主伺服器持久化的rdb檔案實現的。主伺服器先匯出記憶體快照檔案,然後將rdb檔案傳給從伺服器,從伺服器根據rdb檔案重建記憶體表。 Redis 支援簡易的主從複製(master-slave replication)功能, 讓從伺服器成為主伺服器的精確複製品。
1)從伺服器,連線到主伺服器, 傳送SYNC
2)主伺服器接受SYNC,fork一個子程序,把記憶體資料儲存為檔案,傳送給從伺服器
3)主伺服器子程序做資料快照時,父程序繼續接收client端寫資料,新據放待發送快取佇列中
4)從伺服器接收記憶體快照,清空記憶體資料,重建記憶體表資料結構
5)主伺服器傳送快取佇列中儲存的子程序快照期間改變的資料給從伺服器,儲存資料一致性
6)主伺服器後續接收的資料,都會通過步驟1建立的連線,把資料傳送到從伺服器
持久化機制
redis記憶體資料庫, 將記憶體中的資料週期性的寫入磁碟或者把操作追加到記錄檔案中---redis的持久化。 redis支援兩種方式的持久化: RDB方式和AOF方式 RDB方式是將記憶體中的資料的快照以二進位制的方式寫入名字為 dump.rdb的檔案中。 AOF方式,AOF 持久化記錄伺服器執行的所有寫操作命令,並在伺服器啟動時,通過重新執行這些命令來還原資料集。
Redis資料庫的API
redis-cli進入shell,可以用命令Config, key 可以獲取配置資訊或鍵值的情況。 對string型別的操作可以用set, get, incr lists列表是連結串列,LPUSH、RPUSH、LRANGE等, 集合set一種無序的集合,sadd、刪除已有元素、取交集、sunion、取差集等。 sorted sets有序集合中的每個元素都關聯一個序號(score),zsets,操作有zrange、zadd、zrevrange、zrangebyscore等等; 雜湊hashes,hashes存的是字串和字串值之間的對映,比如一個使用者要儲存其全名、姓氏、年齡等等,就很適合使用雜湊。