小景的Dba之路--壓力測試和Oracle資料庫快取

慵懶的小景發表於2023-11-08

小景最近在做系統查詢介面的壓測相關的工作,其中涉及到了查詢介面的資料庫快取相關的內容,在這裡做一個彙總和思維發散,順便簡單說下自己的心得:

針對系統的查詢介面,首次壓測執行的時候TPS較低,平均響應時間較高,後續的查詢中,TPS和平均相應時間較第一次比有較為明顯的提升,這裡考慮到時Oracle資料庫快取的原因:

 

首先要明確的是,Oracle資料庫查詢中有快取的概念。資料庫管理系統通常會對執行過的查詢結果、執行計劃或者資料頁進行快取,以提高後續相同查詢的效能。

在 Oracle 資料庫中,有幾種常見的快取機制,每種都在不同層次上提高查詢效能:

1. 資料 Buffer Cache(資料塊快取):這是資料庫記憶體中的一個重要部分,用於儲存最常用的資料塊。當資料庫需要讀取資料時,它首先檢查 Buffer Cache,如果資料塊已經在快取中,則不需要再從磁碟讀取,而是直接從記憶體中獲取資料。這減少了磁碟 I/O 操作,提高了資料讀取的速度。

2. Shared Pool(共享池):共享池是另一個重要的記憶體區域,用於儲存 SQL 語句的執行計劃、共享 SQL 區域和其他共享的記憶體結構。當你執行一個 SQL 查詢時,Oracle 會檢查共享池中是否已經有了該查詢的執行計劃。如果有,它可以直接使用共享的執行計劃,而不需要重新生成,提高了查詢的執行效率。

3. Library Cache(庫快取):庫快取是共享池的一個組成部分,其中儲存了 SQL 語句的解析結果和執行計劃。這些資訊的快取減少了 SQL 語句的重新解析和最佳化時間,提高了查詢的效能。

4. Data Dictionary Cache(資料字典快取):資料字典快取儲存了系統後設資料資訊,比如表的結構、索引、許可權等資訊。這些資訊的快取減少了對資料字典的頻繁訪問,提高了系統的效能。

這些快取層次相互協作,以提高查詢的效能和資料庫整體的效率。透過快取常用的資料塊、執行計劃以及後設資料資訊,Oracle 資料庫可以加快查詢的速度,並降低系統對磁碟的 I/O 訪問,從而提高整體效能。

 

那麼上述執行了相同的查詢兩次,第二次查詢的耗時比第一次短可能有多種原因:

1. 資料快取:資料庫中的資料可能在第一次查詢時被載入到快取中。當相同的資料被第二次查詢時,它可能仍然保留在快取中,因此查詢能夠更快地獲取資料,而不需要從磁碟讀取。

底層邏輯:資料庫透過 Buffer Cache 快取經常讀取的資料塊,減少了對磁碟的讀取。如果資料塊在第一次查詢時被讀取到快取中,它會在一段時間內保持在記憶體中,以備再次讀取。第二次查詢時,如果所需的資料仍在 Buffer Cache 中,資料庫不需要再次訪問磁碟,從而提高查詢速度。

2. 執行計劃快取:資料庫可能已經為第一次查詢生成了執行計劃,並將其快取。在第二次查詢時,相同的執行計劃可以被重用,避免了重新生成執行計劃所帶來的開銷。

底層邏輯:當查詢語句被執行時,資料庫會生成執行計劃來決定如何檢索資料。資料庫可以將執行計劃快取起來,以備將來的查詢使用。第二次查詢時,如果相同的執行計劃已經被快取,資料庫不需要重新生成執行計劃,直接使用快取的執行計劃,節省了重新最佳化查詢的時間。

3. 資料 Block 的重複讀取:資料庫中的資料塊可能由多個使用者頻繁讀取。第一次查詢時,資料塊從磁碟載入到快取。第二次查詢時,由於資料塊已經在快取中,其他使用者的查詢可能已經導致資料塊存在於快取中,從而減少了讀取資料塊所需的時間。

底層邏輯:當一個資料塊被多次讀取,它可能會留在資料庫的快取中。這種情況發生在多個查詢都使用相同的資料塊時,比如在多個使用者或查詢之間共享資料塊。如果一個資料塊在第一次查詢中被載入到快取中,並且其他查詢也使用了同一塊資料,它可能會保留在快取中,從而使第二次查詢更快。

4. 資料修改:在第一次查詢後,可能沒有對查詢所用到的資料塊進行修改,這樣資料塊可以保持在快取中。因此,第二次查詢時,資料仍在快取中,查詢速度更快。

底層邏輯:當資料塊在查詢後沒有發生變化,它可能會繼續保留在資料庫的快取中。如果資料塊在第一次查詢時被載入到快取中,而在第二次查詢前沒有發生修改,它仍將保留在快取中,使得第二次查詢更快。

5. 系統負載:第一次查詢可能與其他並行操作同時進行,例如其他大型查詢或資料載入過程。這可能會導致系統資源的競爭,從而減慢查詢的執行。第二次查詢時,系統負載減輕,資源更為充足,因此查詢速度更快。

底層邏輯:第一次查詢時,系統可能處於高負載狀態,有可能是有其他大型查詢或者併發操作正在執行,這會使得系統資源分配不均。這可能導致資料庫和伺服器的資源競爭,降低了第一次查詢的速度。在第二次查詢時,如果系統負載較低,資源更為充足,那麼查詢可能會更快。

這些因素都可能影響了相同查詢兩次執行時的耗時差異。資料庫中的快取、併發操作、資料修改以及系統負載等都會對查詢效能產生影響。

 

那麼針對上述可能的原因,系統在做壓力測試的時候,具體怎麼操作才能避開上述的原因呢?小景給出了一些避坑點:

1. 冷啟動環境:在進行壓力測試之前,重啟資料庫以確保快取被清空。這將確保資料庫在測試開始時處於相對清潔的狀態,不會受到之前執行過的查詢、快取或執行計劃的影響。

2. 預熱環境:在進行正式測試之前,預先執行一些基準查詢,以便資料庫快取中有一些熱點資料。這有助於在真正的壓力測試開始之前,建立一些常用資料的快取,模擬真實場景。

3. 使用隔離環境:儘可能在一個相對獨立的環境中進行測試,以避免其他應用或使用者活動對系統負載的干擾。這可以透過使用專門用於測試的資料庫例項或獨立的伺服器進行實現。

4. 多次測試和平均值:進行多次測試並取平均值,而不僅僅是一次測試。因為資料庫的效能在不同時間點可能會有所不同,進行多次測試並取平均值有助於得到更可靠的結果。

5. 監控系統資源:對系統的資源使用情況進行監控,包括 CPU 使用率、記憶體使用情況、磁碟 I/O 等。這有助於識別可能導致效能變化的系統負載。

6. 隔離測試過程:儘可能將不同的測試過程進行隔離,確保不同測試之間不會相互影響,比如在每次測試之間清理快取、重置環境等。

透過這些方法,你可以儘量減少外部因素對測試結果的影響,從而獲得更為準確和可靠的壓力測試結果。

 

上述幾點還都比較好理解,那麼有小夥伴可能會問了,監控系統資源的時候,一般都是看哪幾個指標?有沒有具體的標準?比如,CPU 使用率、記憶體使用情況、磁碟 I/O 等達到了什麼數值的時候,說明系統負載較高?或者系統達到了資源瓶頸?下面小景就詳細說下監控系統資源這點:

1. CPU 使用率:CPU 使用率是非常重要的指標之一。它表示 CPU 的工作負荷,通常以百分比來表示。一般來說,超過 70-80% 的持續 CPU 使用率可能表明系統負載較高,超過 90% 則表示系統可能面臨瓶頸。

2. 記憶體使用情況:監控可用記憶體、使用情況以及交換空間的使用情況。當系統記憶體使用達到接近或超過總記憶體的80%時,可能表明系統記憶體資源緊張,可能導致效能下降。

3. 磁碟 I/O:監控磁碟 I/O 操作,包括讀取和寫入速率。如果磁碟 I/O 達到磁碟的最大容量或磁碟吞吐量達到飽和狀態,可能會成為系統的瓶頸。

4. 網路流量:對於需要大量網路傳輸的系統,監控網路頻寬、網路延遲以及網路連線數。高網路流量可能導致網路擁塞,影響系統效能。

總結:標準或閾值值因系統和環境而異,沒有單一的標準適用於所有情況。通常來說,這些數值的超過並不能直接說明系統一定存在問題,需要綜合考慮其他因素,比如系統負載的特性、硬體規格、應用程式特點等等。

關鍵是瞭解系統的基線效能和常規行為,透過觀察系統在正常情況下的指標,然後對照測試期間的數值變化來評估系統的效能和負載情況。如果在測試期間出現異常,例如指標異常高或異常低,可能意味著系統在承受壓力時出現了瓶頸。

 

那麼可能又有小夥伴會問了,上述第三點所說的網路通訊,怎麼判斷應用伺服器和資料庫伺服器之間的通訊是優秀還是良好,還是不好呢?具體是怎麼操作?小景給出了一些自己的建議:

1. Ping測試:使用 `ping` 命令測試應用伺服器和資料庫伺服器之間的網路連線。較低的延遲和較少的丟包率通常是良好通訊的指標。命令格式為:`ping <資料庫伺服器IP>`。替換 <資料庫伺服器IP> 為你資料庫伺服器的實際 IP 地址。這條命令會傳送 ICMP 請求到目標伺服器並接收 ICMP 響應,從而可以評估到達目標伺服器的延遲和丟包率。較高的延遲和較高的丟包率可能表明網路連線存在問題。

2. 網路監控工具:使用網路監控工具來實時監控應用伺服器和資料庫伺服器之間的網路流量、延遲和丟包率。工具如Wireshark、tcpdump等,能夠提供詳細的網路資料包資訊。透過分析資料包,可以確定通訊中是否存在異常或潛在問題。

3. 傳輸速率iperf 是一個網路效能測試工具,它可以測量網路頻寬和吞吐量。首先,你需要在應用伺服器和資料庫伺服器上分別安裝 iperf。使用工具如`iperf`來測試應用伺服器和資料庫伺服器之間的頻寬和傳輸速率。這可以幫助你確定網路的最大吞吐量。`iperf` 可以在伺服器之間進行速率測試。命令格式為:`iperf -c <資料庫伺服器IP>`。

這條命令會向資料庫伺服器傳送 TCP 資料包,以測試應用伺服器到資料庫伺服器之間的頻寬和傳輸速率。在資料庫伺服器上需要執行 iperf 服務端來接受連線。如果資料庫伺服器上沒有安裝 iperf,你需要在資料庫伺服器上執行以下命令安裝 iperf 服務端:

sudo apt-get install iperf

sudo yum install iperf

安裝完畢後,在資料庫伺服器上執行以下命令來執行 iperf 服務端:

  iperf -s

這將啟動 iperf 服務端以接收來自應用伺服器的連線,並進行網路頻寬測試。

4. 應用程式響應時間:在進行壓力測試時,觀察應用程式的響應時間,尤其是與資料庫通訊相關的操作。較長的響應時間可能是網路通訊問題的表現。

      • 監控工具:使用監控工具,比如 New Relic、AppDynamics 等,這些工具提供實時監控應用程式的效能、響應時間、請求處理等資訊。

      • 自定義監控指令碼:編寫自定義指令碼來模擬使用者請求並記錄應用程式的響應時間。你可以使用類似 curlab(Apache Benchmark)這樣的命令列工具,以及程式語言(如Python、Java)來執行請求並記錄響應時間。

5. 系統日誌和監控工具:審查系統的日誌記錄和使用監控工具(如Nagios、Zabbix等)來檢視網路介面的使用情況、錯誤資訊、頻寬利用率等。異常或錯誤的日誌資訊可能提示著網路通訊方面的問題。

      • 系統日誌:系統日誌位於 /var/log 或類似的位置。不同的系統日誌記錄了網路、應用程式、資料庫和系統事件。你可以檢視日誌檔案(如 syslogmessagesdmesg)來檢查網路連線、錯誤、警告或其他與通訊相關的資訊。

      • 監控工具:使用專門的監控工具,比如 Nagios、Zabbix、ELK Stack 等,來監控系統日誌和事件。這些工具可以自動分析和報警,幫助你更好地瞭解系統的狀態和問題。

這些方法可以幫助你評估應用伺服器和資料庫伺服器之間的通訊質量。透過監控網路延遲、丟包率、頻寬利用率和響應時間,可以更全面地瞭解通訊情況,以及是否存在網路通訊方面的瓶頸或問題。

 

最後,希望小景的這篇文章可以幫助您解決實際工作中的問題,有什麼問題可以評論區或者關注我的微信公眾號來交流。

 

 

相關文章