關係型數據庫工做原理-快速緩存(翻譯自Coding-Geek文章)

本文翻譯自Coding-Geek文章:《 How does a relational database work》。算法

原文連接:http://coding-geek.com/how-databases-work/#Buffer-Replacement_strategies數據庫

先翻譯快速緩存章節。興許有時間再翻譯其餘章節。緩存

翻譯內容在原文的文件夾:
markdown

這裏寫圖片描寫敘述

1、數據管理器

這裏寫圖片描寫敘述

數據查詢器運行查詢操做,從數據表中獲取數據。它向Data Manger發送請求,獲取數據。當中存在2個問題:

  1. 關係型數據使用事物模型。當數據庫在運行改動操做時,不能運行查詢操做。避免查詢出髒數據。

  2. 數據提取是最慢的數據庫操做,因爲數據要從磁盤上讀取。

    所以,數據庫必需要有一個很是強大的數據緩存系統。網絡

本章。咱們將看一下關係數據是怎樣解決這兩個問題的。數據結構

咱們不會探討數據庫是怎樣從磁盤載入數據的。這個不是本文的重點(受篇幅所限,不展開分析)。post

2、快速緩存器

這裏寫圖片描寫敘述

正如我以前所言。數據庫的性能瓶頸是I/O。

爲了提高性能,現代數據庫都使用了快速緩存。性能

數據查詢器從Cache Manger中獲取數據。而不是直接從磁盤文件裏讀取數據。google

Cache Manger管理着一片內存區域。叫緩存池。 直接從內存獲取數據,使得訪問數據庫的性能日新月異。.net

但是,很是難評估使用快速緩存的重要性有多大,這取決於你要作什麼樣的數據庫操做。

  • 順序訪問 VS 隨機訪問。

  • 讀操做 VS 寫操做。

以及數據庫使用的是什麼樣的磁盤

  • 7.2k/10k/15k rpm HDD
  • SSD
  • RAID 1/5/…

但是,我敢說使用內存快速緩存比不適用緩存直接從磁盤讀數據快100到10萬倍。
這也致使另一個問題(所有的數據庫都有這個問題……), 快速緩存器需要在查詢器訪問數據以前預取數據,不然查詢器需要掛起,等待快速緩存器把數據從磁盤載入到內存先。

3、緩存數據預取

問題的核心就在「數據預取」。

數據查詢器清楚需要哪些數據,因爲它瞭解每一次查詢操做的詳細要求,也清楚數據庫表的存儲結構。數據預取的基本邏輯是這種:

  1. 數據查詢器在獲取第一批數據時通知Cache Manger提早載入第二批數據到緩存中。
  2. 數據查詢器在獲取第二批數據時通知Cache Manger提早載入第三批數據,而第一批數據可以從緩存中移除了。

  3. …….

Cache Manger存儲所有的數據在緩存池中。

爲了肯定緩存池中數據是否正在被使用,Cache Manger需要維護一些關於這些數據的額外信息(被稱之爲鎖的東西)。

但有時。數據查詢器不清楚下一步需要什麼數據,或者數據庫沒有提供指定預取哪些數據的功能。取而代之,數據庫提供的是隨機預取功能(好比,查詢了數據1,2,3後,它因爲你可能還需要7,8,9,提早把7,8,9載入到緩存中)或者順序緩存功能(運行一次查詢後。將磁盤上查詢數據臨近的其餘數據也預取到緩存中)。

爲了評估Cache Manger預期機制工做的效果。現代數據庫系統提供一個指標度量:緩存命中率。緩存命中率描寫敘述查詢器從緩存中拿到數據的概率(在不需要讀磁盤文件的狀況下)。

說明:糟糕的緩存命中率。並不老是意味Cache工做得很差。不少其餘信息可參考Oracle說明文檔。

但是,快速緩存內存大小是受限的。緩存內容需要不斷吐故納新。緩存數據的載入和移除都需要消耗磁盤I/O和網絡I/O資源。

假設某個查詢操做要經常運行,緩存數據頻繁的載入和移除是很是低效的。爲了解決問題。現代數據庫都使用了一些緩存置換策略。

4、緩存置換策略

大多數現代數據庫緩存置換策略都使用LRU算法,至少SQL Server, MySQL, Oracle and DB2是這種。

1. LRU

LRU的意思是非近期當前使用。這個算法的是基於這樣一種假設:近期使用過的數據,在未來被再次使用的機率很是大,需要駐留在緩存中。反之,非近期當前使用的數據可移除。

這裏寫圖片描寫敘述

爲了方便理解,咱們假設緩存中的數據未被加鎖(所以可被移除)。

舉個樣例說明它的工做原理。這個簡單的演示樣例中緩存池能容納3個數據。

  1. Cache Manger使用數據1後。將1放入緩存。

  2. Cache Manger使用數據4後,將4放入緩存。
  3. Cache Manger使用數據3後。將3放入緩存。

  4. Cache Manger使用數據9後。將9放入緩存。

    因爲緩存已滿,需要先移除一條數據。移除哪一條?
    依據LRU原則,1是最遠當前使用的數據,移除1後增長9。

  5. Cache Manger使用數據4後放入緩存,4變成了近期被使用過的數據。調整順序。

  6. Cache Manger使用數據1後放入緩存,1變成了近期被使用過的數據。3被移除。
  7. ……

算法OK。但有一些限制,假設讀取的是一張大表呢? 換言之。讀取的表數據太大,超過了緩存空間的大小。使用該算法將清除緩存以前所有的數據,即便新載入上來的這張大表數據僅僅會使用一次就再也不使用。

2. 算法改進

爲解決問題。一些數據庫管理系統加了一些特殊規則。好比:Oracle規則說明:

對於超級大表的讀取,直接從磁盤文件裏讀取數據。避免是用快速緩存。對於中型表。可以從磁盤文件直接讀也可以用緩存。假設使用緩存應該把讀取的數據放到LRU列表末尾(這樣,新增長緩存數據時將先把該表的數據移除)。

LRU算法有高級版本號,叫LRU-K。好比SQL Server使用的LRU-K, K=2。

K表明的是考慮近期時間段,數據訪問的次數。
前面的樣例是LRU-K算法最簡單的樣例。僅僅考慮一次訪問。K = 1。LRU-K的原理例如如下:

  1. 記錄數據的近期訪問次數(最多記錄K次)。
  2. 依據數據訪問次數,設置一個權值。近期訪問次數越多的權值越大。
  3. 當一批新的數據載入到緩存中時,權值大的數據不會被移除,即便該數據是很是早就載入到緩存中的。

  4. 假設數據長時間未被再使用,權值會逐漸減小。

權值的計算是很是耗資源的。這也是爲何 SQL Server使用K=2的緣由。這種設置方式。投入產出比較高。

想更深刻的瞭解LRU算法,可以參考一下算法文檔(文檔google)。

3. 其餘算法

另外一些其餘算法策略,用於管理快速緩存器。

  • 2Q(類似LRU-K算法)
  • CLOCK(類似LRU-K算法)
  • MRU(用得比較多的算法。邏輯類似LRU。用的是另外一套規則)
  • LRFU(近期、最頻繁使用算法)
  • ……

一些數據庫贊成你使用除默認算法外的其餘算法。多種方式可選。

5、寫緩存器

前討論的最多的是讀緩存器。它在數據使用以前將其提早載入到內存。數據庫中還存在一種寫緩存器,它將屢次操做改動的數據存儲累計起來,一次寫到磁盤文件。減小對磁盤IO的頻繁訪問(數據庫瓶頸在I/O)。

謹記,快速緩存中存儲的是分頁數據而不是人們直觀印象中的行數據。假設緩存中的某一頁數據被改動了,尚未保存到磁盤上,這頁被稱爲「髒頁」。有多種策略算法能評估髒頁數據寫到磁盤上的最佳時機,而這也和事物強相關(事務是下一章節將展開的內容)。

已翻譯的《How does a relational database work》其餘章節連接:
1. 關係型數據庫工做原理-時間複雜度:http://blog.csdn.net/ylforever/article/details/51205332
2. 關係型數據庫工做原理-歸併排序:http://blog.csdn.net/ylforever/article/details/51216916
3. 關係型數據庫工做原理-數據結構:http://blog.csdn.net/ylforever/article/details/51278954
4. 關係型數據庫工做原理-快速緩存:http://blog.csdn.net/ylforever/article/details/50990121
5. 關係型數據庫工做原理-事務管理(一):http://blog.csdn.net/ylforever/article/details/51048945
6. 關係型數據庫工做原理-事務管理(二):http://blog.csdn.net/ylforever/article/details/51082294

相關文章
相關標籤/搜索