標籤:
劉勇 Email: [email protected]
本部落格記錄作者在工作與研究中所經曆的點滴,一方面給自己的工作與生活留下印記,另一方面若是能對大家有所協助,則幸甚至哉矣!
簡介
鑒於高頻中心庫task部分佔用機器較多,為節省成本,調研資料庫或緩衝。在資料庫選型之MySQL(二)中,在固態硬碟本地訪問MySQL可以滿足其10000次/s操作的需求,由於實際環境中存在多個品種(多進程、多線程訪問資料庫)的業務需求,因此,本文採用多線程在固態硬碟本地訪問MySQL展開測試,以期對高頻中心庫後期架構調整提供實踐參考。需要指出,本文作者對該種節省成本的解決方案是不贊成的。
測試環境
硬體環境
10.1.120.34:Intel Core I5-4590, 主頻:3.30G, 記憶體:16G, 有固態硬碟
軟體環境:
10.1.120.34: Cent OS 6.5, MySQL 5.6.26 (社區版)
效能測試
針對高頻生產的應用需求,本文構造高頻中心庫系統的資料結構,採用多線程類比業務需求對本地節點MySQL進行寫入操作,分別儲存資料總量為60K、100K、600K條資料,對其速率進行測試。需要指出,由於常見I/O訪問的瓶頸主要受限於寫入測試,本文只針對寫入操作進行測試,暫不考慮讀取操作或者混合讀寫方式,若寫入操作不滿足要求,其它操作無需測試。
因為10.1.120.34上採用固態硬碟作為儲存介質,其安裝有MySQL,根據應用情境,分別從10、20、30個線程並發訪問MySQL 展開測試。
測試整個結果見圖-1:
圖-1 完整測試結果
10個線程
從10個線程執行交易處理,需要指出,交易處理資料量固定為1000,以下多線程情況與之類同,不再贅述,10個線程的平均速率見表-1。
表-1 10個線程下每個線程平均訪問MySQL測試結果
節點 |
資料庫IP |
資料量(K) |
平均寫入速率(條/s) |
| 本地節點 |
10.1.120.34 |
60 |
4085 |
| 本地節點 |
10.1.120.34 |
100 |
4607 |
| 本地節點 |
10.1.120.34 |
600 |
3021 |
20個線程
從20個線程執行交易處理,20個線程的平均速率見表-2。
表-2 20個線程下每個線程平均訪問MySQL測試結果
節點 |
資料庫IP |
資料量(K) |
平均寫入速率(條/s) |
| 本地節點 |
10.1.120.34 |
60 |
1945 |
| 本地節點 |
10.1.120.34 |
100 |
2149 |
| 本地節點 |
10.1.120.34 |
600 |
1525 |
30個線程
從30個線程執行交易處理,30個線程的平均速率見表-3。
表-3 30個線程下每個線程平均訪問MySQL測試結果
節點 |
資料庫IP |
資料量(K) |
平均寫入速率(條/s) |
| 本地節點 |
10.1.120.34 |
60 |
1266 |
| 本地節點 |
10.1.120.34 |
100 |
1461 |
| 本地節點 |
10.1.120.34 |
600 |
879 |
小結
從表1-3可知:1)隨著線程數目增加,線程平均寫入速率會減小,而且還很明顯;2)隨著訪問的資料量的增加,以10萬條至60萬條為例,每個線程平均訪問其速率下降也很明顯。
本文測試結果對高頻中心庫後續架構調整提供有一些實踐參考,若以平均速率乘以線程個數來衡量,則該高頻生產情形是滿足需求的,但是若出現不平衡狀況,則為節省成本採用將資料在固態硬碟本地入庫落地來生產,然後輔以redis作為緩衝來緩解訪問系統訪問壓力的解決方案,本文作者是不贊成這種該方案的,希望對有類似業務需求的朋友有所協助。
附錄:
測試部分程式原始碼:
1 public static void main(String[] args) { 2 3 Transaction [] ts = new Transaction[ThreadTest.MAX]; 4 Test []test = new Test[ThreadTest.MAX]; 5 int symbol = 100000; 6 for (int i = 0; i < ts.length; i++) { 7 ts[i] = new Transaction(null, 8 "", 9 "",10 "010000",11 new BigDecimal(15.857).setScale(3, RoundingMode.HALF_UP),12 new BigDecimal(18.550).setScale(3, RoundingMode.HALF_UP),13 new BigDecimal(13.147).setScale(3, RoundingMode.HALF_UP),14 new BigDecimal(16.383).setScale(3, RoundingMode.HALF_UP),15 new BigDecimal(0.151).setScale(3, RoundingMode.HALF_UP),16 new BigDecimal(1.550).setScale(3, RoundingMode.HALF_UP),17 new BigDecimal(5000000).setScale(3, RoundingMode.HALF_UP),18 new BigDecimal(500000000).setScale(3, RoundingMode.HALF_UP),19 System.currentTimeMillis(),20 "SSE");21 test[i] = new Test();22 23 }24 25 26 RunThread[] thread = new RunThread[ThreadTest.MAX]; 27 for (int i = 0; i < thread.length; i++) {28 test[i].initMySQL();29 thread[i] = new RunThread(ts[i], symbol, test[i]);30 symbol += ThreadTest.NUM*1000;31 }32 33 for (int i = 0; i < thread.length; i++)34 thread[i].start();35 36 while (true) {37 try {38 Thread.sleep(1000);39 } catch (InterruptedException e) {40 e.printStackTrace();41 test[0].down();42 }43 }44 45 }View Code
資料庫選型之MySQL(三)