《NoSQL精粹》讀書摘要

1、Why NoSQL?
  • 關注NoSQL的兩個緣由
    • 應用程序的開發效率(NoSQL簡化了數據交互)
    • 大規模的數據(NoSQL爲集羣環境而設計)
  • NoSQL不是獨立存在的,之後也不會取代關係型數據庫,之後數據庫領域將步入混合持久化(Polyglot Persistence)時代。
  • 關係型數據庫的優勢:
    • 標準化的建模
    • 較爲容易的處理關係
    • 經過事務來處理併發
    • 能夠持久化
  • 關係型數據庫的缺點:
    • 阻抗失諧:關係型數據庫中的存儲結構(模式、表、元組)與應用程序中的數據結構須要轉換。ORM框架能夠解決這個問題,可是會引發性能的降低。
    • 應用程序數據庫(摘綠帽)與集成數據庫(戴綠帽):SOA的興起(內部數據庫與外部通訊服務間的解耦)
    • 集羣化問題:擴展性問題(縱向與橫向)與許可費問題,大數據是一個巨大推進
  • NoSQL的定義:開源分佈式的非關係型數據庫
    • 開源
    • 分佈式
    • 非關係型(無模式)
  • 使用NoSQL的主要緣由:(其餘狀況下,請依然使用關係型數據庫)
    • 數據量大,訪問效率要求高
    • 要解決「阻抗失諧」的問題
 
2、聚合數據模型
  • NoSQL的主要分類
    • 面向聚合(aggregate oriented):來自於DDD
      • 鍵值模型(key-value):聚合對數據庫不透明,只能整個的讀取
      • 文檔模型(document):透明的聚合,能夠看到數據結構,能夠讀取其部分(以結構的限制換取更好的訪問性)
      • 列族模型(column family):「兩級映射」——兩級聚合結構。所以其既「面向行」也「面向列」
    • 非面相聚合:圖數據庫(graph)
  • 聚合的優勢:
    • 在集羣中,使用聚合操做數據比較簡單
    • 聚合也方便應用程序操做數據結構(對程序員更爲友好)
    • 以聚合爲單位的原子操做
    • 下降了數據採集時的須要節點數
  • 聚合的缺點:
    • 多個聚合的操做原子性須要應用代碼來維護,而這經常比較複雜
 
3、數據模型詳解
  • 關係型:若是待處理的數據中存在大量關係,那麼這就意味着須要選用關係型數據庫(但其實圖數據庫在這方面更強)
  • 聚合型:操做單個聚合很方便,可是操做多個聚合時就很笨拙
  • 圖數據庫:
    • 以包含節點和邊的圖構成;
    • 節點簡單,互連結構豐富
    • 圖數據庫中遍歷關係很是迅速,可是關係型數據庫較差
    • 一般運行在單一的服務器上
  • 無模式的數據庫:
    • 其實總包含「隱含模式」
    • 本質上說,無模式數據庫把模式交由訪問其數據的應用程序代碼來處理
    • 若是你發現存儲的數據類型不統一,那麼應優選無模式數據庫
    • 無模式的靈活性僅限於聚合內部
    • 數據遷移對有無模式的數據庫而言都是難點
  • 物化視圖
    • 做用:使基本數據和派生數據對客戶端透明
    • 計算生成物化視圖比較複雜耗時
    • 方式:
      • 一旦有數據變化,當即更新
      • 按期經過批處理操做更新(通常經過Map-Reduce)
    • 能夠將物化視圖在聚合內使用,以便在原子操做內更新
 
4、分佈式模型
  • 橫向擴展易於縱向擴展
  • 數據分佈:
    • 複製(replication)
      • 主從式(master-salve)
      • 對等式(peer-to-peer)
    • 分片(sharding)
    • 這兩種方式正交,能夠同時使用
  • 單一服務器
    • 單一服務器便可以SQL也能夠NoSQL
    • 在不需分佈數據時,應老是選擇「單一服務器」方案
  • 分片
    • 將不一樣的數據放在不一樣的數據庫服務器上
    • 讀、寫性能均可以提高
    • 會下降數據庫的錯誤恢復能力(由於須要維護更多的數據庫服務器了)
    • 優化方式:
      • 地理空間上應將數據庫靠近訪問者
      • 負載均衡
      • 自動分片技術(大部分NoSQL提供,其將應用代碼與數據庫分片功能解耦)
  • 主從複製
    • 能夠將系統視爲帶有「即時備份」功能的「單服務器存儲方案」
    • 優勢:
      • 經過新增從節點能夠方便的進行水平擴展,能夠處理更多的讀請求,並保證讀請求都被引導至從節點
      • 能夠加強讀操做的故障恢復能力
        • 主節點出錯了,從節點依然能夠提供讀服務
        • 擁有與主節點相同內容的從節點能夠很快的被指派爲新的主節點,代替故障的原主節點
      • 減小了寫操做的衝突機率
    • 缺點:
      • 數據的不一致性
      • 主節點是性能瓶頸
  • 對等複製
    • 優勢
      • 全部的節點均可以讀寫
      • 易於擴展
      • 不存在性能瓶頸節點
    • 缺點:
      • 數據一致性問題
  • 解決寫入操做衝突的兩種極端解決思路:
    • 老是去協調節點間的關係,確保不發生衝突,只需保證各大部分副本的一致性,
    • 容許節點間的衝突,但嘗試合併這些衝突的寫入操做
  • 分片+複製
    • 對等複製+分片
    • 將分片存放在必定數量(複製因子)的對等節點中
 
5、一致性
  • 須要理解並權衡
    • 強一致性(strong consistency):時時一致
    • 最終一致性(eventual consistency):有不一致的時間窗,但最後一致
  • 更新一致性
    • 問題:寫衝突(write-write conflict)
    • 經常使用解決方式:
      • 先決條件:處理更新操做的順序必須一致
        • 順序一致性(sequential consistency)
      • 悲觀方式:避免發生衝突
        • 寫入鎖
        • 會大幅下降系統的響應能力
        • 容易產生死鎖
      • 樂觀方式:發生衝突,再解決衝突
        • 條件更新
        • 保存全部的更新,標註出衝突,併合並衝突
  • 讀取一致性
    • 問題:讀寫衝突(read-write conflict)/讀取不一致(logical consistency)
    • NoSQL對事物的支持:
      • 面向聚合:支持「原子更新」,但不支持多個聚合構成的事物
      • 圖數據庫:支持
    • 不一致窗口:數據邏輯不一致的時間長度
    • 複製一致性:不一樣副本中數據的一致性
    • 一般能夠指定單個請求所需的一致性級別,合理地下降部分請求的一致性級別能夠提升性能
    • 照原樣讀出所寫內容的一致性(read-your-writes consistency)
      • 會話一致性
        • 黏性會話
          • 將讀寫綁定至某一個節點
          • 會下降負載均衡器的效能
        • 版本戳
  • 放寬「一致性」約束
    • 制定合理的隔離級別,合理地放寬一致性要求
    • CAP理論
      • 一致性(Consistency)
      • 可用性(Availability)
      • 分區耐受性(Partition tolerance)
      • 常見錯誤理解:
        • 咱們只能同時知足其中兩個方面
        • 實際上:當系統可能會遇到「分區」情況時,咱們須要在「一致性」和「可用性」之間進行權衡;這並非一個二選一問題。
    • 有時能夠適當放寬一致性,容許衝突的發生,並經過領域知識指導下的應用程序代碼來解決衝突,以換取更好的併發能力。
    • NoSQL倡導的BASE理論:
      • 基本可用(Basically Available)
      • 柔性狀態(Soft State)
      • 最終一致性(Eventual consistency)
      • 本質上大可能是一致性與時延的取捨
  • 放寬「持久性」約束
    • 非持久性寫入操做
      • 例如,Redis先寫入內存,而後再按期的寫入硬盤
    • 複製持久性
      • 在複製過程當中,寫節點失效,就會形成數據的丟失
      • 須要權衡對複製質量的保證仍是數據庫的響應速度
  • 仲裁(避免衝突的方式)
    • 寫入仲裁
      • 在對等式分佈模型下:
        • W>N/2
        • W:寫節點數
        • N:複製因子
      • 在主從式分佈模型下:
        • 從主節點
    • 讀取仲裁
      • 在對等式分佈模型下:
        • R+W>N
        • R:讀節點數
      • 在主從式分佈模型下:
        • 從主節點
    • 仍是須要根據實際狀況來肯定具體的仲裁方式
 
6、版本戳
  • 商業事務vs系統事務
    • 商業事務:針對用戶而言從,整個交互流程
    • 系統事務:用戶提交後,對系統而言的事務
    • 問題:商業事務和系統事務之間,存在較大的時間窗
    • 解決方式:離線併發技術
      • 樂觀離線鎖(條件更新的一種):compare-and-set(CAS操做)
      • 經過比較商業事務開始執行時的版本戳與系統事務開始執行時的版本戳,來檢驗信息是否發生了變化,以肯定是否須要進行更新操做
  • 常見的版本戳類型:
    • 計數器
      • 易於比較
      • 可是須要一個主服務器用來生成並保證不一樣版本的計數器值不會重複
    • GUID(Globally Unique Identifier),全局惟一標識符:
      • 任何人均可以生成
      • 可是數值較大,並且難以直接比較
    • 根據資源內容生成Hash碼
      • 足夠大時,能夠惟一標識
      • 任何人均可以生成
      • Hash值是肯定的
      • 可是冗長且沒法直接比較
    • 上一次更新的時間戳
      • 短小,易於生成
      • 能夠直接比較
      • 可是不一樣服務器之間的時鐘必須同步,不然很容易形成數據損毀
      • 且時間戳的精度很難肯定:太低,沒法區分;太高,須要頻繁的更新
    • 複合版本戳(composite stamp)
      • 運用多種手法
  • 在多節點環境中生成版本戳
    • 單服務器或主從式複製模型:
      • 基本的版本戳方案就足夠了:計數器
      • 時間戳也能夠,但不如計數器好
    • 多個主節點時:
      • 每一個節點維護一份版本戳記錄(version stamp history)
      • 經過判斷「祖先」記錄來肯定新舊關係;如互不爲祖先,則檢測爲衝突
    • 對等式複製模型
      • 數組式版本戳(vector stamp)
      • 維護一個數組記錄全部節點的版本,例如[server01:1, server02:4, server03:5]
      • 如缺失某些值,則視爲0,例如視server04:0
      • 這樣便於新增節點
  • 版本戳僅能檢測衝突,而不能解決衝突,衝突的解決依賴於領域知識
 
7、Map-Reduce
  • 分散-彙集(Scatter-Gather)模式的一種形式
  • 將部分計算邏輯放於數據庫服務器上
  • 輸入值是某個集合,輸出值是鍵值對的集合
  • 主要包括如下函數
    • Mapper
    • Combiner
    • Reducer
  • 一般會要求Mapper Combinable,既Mapper同時做爲Combiner使用
  • 一般會使用管道及過濾器(Pipes-and-filters)來組合處理
  • 增量式Map-Reduce: 一般須要保存部分中間結果,以備下次使用
  • 經典實現:Hadoop
    • Pig:專用語言
    • Hive:類SQL語言
 
8、常見NoSQL實現
  • 鍵值
    • Memcached
    • Redis
    • Riak
  • 文檔
    • CouchDB
    • MongoDB
  • 列族
    • HBase
    • Cassandra
    • Amazon SimpleDB
    • Neo4J
    • HyperGraphDB
相關文章
相關標籤/搜索