在大規模 SOA 應用的性能測試中,一個很重要的事就是準備鋪底數據。所謂鋪底數據,即在性能測試之前人工地向數據庫里面存入用來模擬歷史的或用來測試的大量數據。
通過一個進行實際性能測試的樣例,通過對有鋪底數據和沒有鋪底數據兩種情況的測試結果所進行的分析,我們發現,使用鋪底數據進行性能測試,不僅可以幫助測試人員更好地發現應用系統存在的問題,同時也能夠使測試結果更加接近真實生產環境下的結果。
本文假設對某大型 SOA 系統進行性能測試,要保證所有在線用戶能同時在線錄入檔案。測試場景包括創建成員信息、收入及支出信息和提交救援案例的申請等。
在這個系統中,性能測試需要模擬很多人同時在線的情景。通過性能測試工具能模擬任意多的人同時在線,而且要保證系統性能穩定,不論任何時候都要保證系統的請求和響應時間基本保持穩定,不會隨著數據庫數據的增加而變慢?;谶@些問題,我們需要找到一種有效的方式來對系統進行性能測試。在上面的場景中,需要一個長時間穩定的環境,這樣才可以增大數據庫里面的數據量,并構建負載平衡的應用服務器環境。
綜上所述,可以在數據庫里面存入鋪底數據,在服務器端搭建集群服務器。
為什么要準備鋪底數據
那么,我們該如何制作鋪底數據呢?下面我們將詳細地闡述這些問題。
鋪底數據就是我們在做性能測試之前,在數據庫里除數據庫字典表外按照業務邏輯存入的大量的數據。這些數據可以被視為垃圾數據,因為它們對系統的業務邏輯沒有實際影響,但對系統的性能卻有著很大的影響。
我們需要按照實際的情況去生成鋪底數據,而且這一過程要符合實際的生產情況表的數據比例。譬如:有一張表的數據量和另外一張表的倍數關系是 5∶1,那么準備數據的時候不論準備的數據是多少條,也需要保證這兩個表的數據量的倍數是 5∶1。
雖然鋪底數據是垃圾數據,但是它們同樣需要遵守數據庫中數據的依賴關系。比如一對一、一對多的關系等。
我們在性能測試中準備的數據如“性能測試之前在 DB2 里面準備的鋪底數據表”所示。
在性能測試開始之前,我們在 DB2 數據庫里面準備的鋪底數據的總量是10.5 GB。
或許你會問,為什么要準備這些鋪底數據?這些數據不是我們實際生產環境中出現的數據,那為什么要花時間去準備如此大量的數據呢?答案是,系統在有鋪底數據和沒有鋪底數據的情況下,性能會有很大的差異。那么,為什么會出現這種情況呢?
首先,如果沒有那些鋪底數據,那么,本來為一張表建立了一個索引,當系統的數據量很小的時候,數據庫就有可能進行全表掃描,而不是索引掃描,因此,如果沒有鋪底數據的話,有可能會造成系統發生數據庫的死鎖。
如果數據量比較少,數據庫為了優化,有的時候就不用索引掃描,而采用全表掃描,這樣造成整表被鎖,導致死鎖。而數據量大了以后數據庫會進行索引掃描,不會鎖住整個表。
所以,在有些情況下,系統上線時必須要準備一些無用的數據放在表中,讓數據庫不會采用全表掃描。雖然有的時候可以通過改變鎖的策略去解決這個問題,但是如果存在風險,在上線系統中就要避免。
其次,如果數據量很小的話,我們不知道進行一次查詢的時候, SQL 語句究竟是哪種執行路徑方案。數據庫有自動根據 SQL 語句算出一條自認為最優化的路徑的功能,譬如 DB2 的 ACCESS PATH。ACCESS PATH 會隨著數據量多少的變化而變化。一旦系統的體系結構比較龐大,那么,在日積月累中數據量會越來越大。所以要準備一定數量的數據,讓 ACCESS PATH 保持相對穩定。
因為,鋪底數據使得系統性能更加真實,更符合生產環境的真實情況。在數據庫里面存入鋪底數據,系統從一開始上線的時候,就有了一個比較穩定的環境。
如果沒有鋪底數據,那么系統的環境可能隨時都會面臨著不穩定的因素,如性能陡變、數據庫異常、響應時間突然下降等。所以準備鋪底數據,不但對性能測試意義深遠,而且對即將上線的生產環境也是至關重要的。試想在銀行系統中,如果不準備鋪底數據,一旦系統上線的時候發生了問題,那么銀行會損失多少客戶。
準備鋪底數據主要有以下幾個原則:1.數據庫中的數據量只要比內存大上若干倍,結果就差不多了;2.數據在準備的時候,要保持原表的約束關系;3.每張表的數據量要符合真實情況。
準備高性能鋪底數據
以上介紹了鋪底數據的重要性。要知道,準備的每張鋪底數據表要上億條。那么,我們如何快速而真實地準備鋪底數據呢?
如果用簡單的 JDBC 程序插入鋪底數據,性能會很差。而用 JDBC 寫一個程序往數據庫里面插入數據的話,速度會很慢,大概是10萬條一張表,大約需要 20 分鐘。
假設我們需要準備 1 億條數據一張表,就是 10000/10×20/60=333 小時。如果業務邏輯需要準備 20 張表,那我們準備這些數據將需要 333×20=6660 小時=277.5 天。這樣的速度慢得驚人,所以通過 JDBC 準備鋪底數據不行。
顯然,我們需要更高效地產生鋪底數據的方法。筆者所在團隊選擇了如下的方法:找出數據庫之間的表結構關系,并據此把數據翻倍,利用 CPU 的運算能力高效率地生成的數據,并導入數據庫,從而產生出所需的鋪底數據。
如果要準備鋪底數據,那么我們首先就要找到表與表之間的關聯關系。也就是說,我們要清楚數據庫里面主表和附表之間的關系是一對多或多對多,還要知道實際情況中,一張主表的一條記錄大概對應附表的幾條數據。只需要一個大概的規律就可以了,或者取一個中間值。我們可以通過 Rational Data Architect 生成的表結構圖找到表與表之間的關系:準備原始的第一套數據(每張表大概 1000 條數據)。
我們在測試前,應該首先用 Rational Performance Tester 7.0 錄制一個腳本。腳本里面包括要測試的主要用例。譬如:筆者所做的腳本一共包括10個請求,要全部按照順序錄入到 RPT 中。
然后,我們應該重新建立數據庫,使數據庫里面不存在數據。接下來,我們就可以利用上文敘述中錄制好的 Rational Performance Tester 腳本,并循環 1000 次。這樣我們的數據庫里面的一些表里就會有 1000 條數據了。然后,我們在數據庫里面查看哪些表中的數據增加了,然后把這些表里面的數據導出到文本文件里。