大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java學習 java數據庫多線程應用程序優化數據存儲庫

java數據庫多線程應用程序優化數據存儲庫

更新時間:2020-02-07 14:58:22 來源:動力節點 瀏覽2604次


  為Java多線程應用程序優化數據存儲庫


  數據存儲庫通常是超高要求系統的瓶頸。在這些系統中,正在執行的查詢數量非常大。DelayedBatchExecutor是一個用于減少所需查詢數量的組件,通過在Java多線程應用程序中對所需查詢進行批處理。


java數據庫多線程應用程序優化數據存儲庫


  1個參數的n個查詢Vs.n個參數的1個查詢


  假設有一個對關系數據庫執行查詢的Java應用程序,以便在給定其唯一標識符(id)的情況下檢索Product實體(row)。


  查詢如下所示:


  SELECT*FROMPRODUCTWHEREID=<productId>


  現在,檢索n個Products,有如下兩種方法:


  執行1個參數的n個獨立查詢:


  SELECT*FROMPRODUCTWHEREID=<productId1>


  SELECT*FROMPRODUCTWHEREID=<productId2>


  ...


  SELECT*FROMPRODUCTWHEREID=<productIdn>


  使用IN運算符或ORs的串聯,對n個參數執行1個查詢以便同時檢索n個Products


  --ExampleusingINOPERATOR


  SELECT*FROMPRODUCTWHEREIDIN(<productId1>,<productId2>,...,<productIdn>)


  后者在網絡流量和數據庫服務器資源(CPU和磁盤)方面更為有效,因為:


  往返數據庫的次數為1,而不是n。


  數據庫引擎優化了n個參數的數據遍歷過程,即每個表格可能只需要掃描1次,而不是n次。


  這不僅適用于SELECT操作,而且適用于其他操作,例如INSERTs,UPDATEs和DELETEs。實際上,JDBCAPI包括上述操作的批量處理操作。


  同樣的情況也適用于NoSQL存儲庫,其中大多都明確提供BULK操作。


  DelayedBatchExecutor


  需要從數據庫中檢索數據的Java應用程序,如REST微服務或異步消息處理器,通常以多線程應用程序(*1)實現,其中:


  每個線程在其執行的某個時刻執行相同的查詢(每個查詢具有不同的參數)。


  并發線程數很高(每秒數十或數百)。


  在這種場景下,數據庫很可能在較短的時間間隔內多次執行相同的查詢。


  如前所述,如果將1個參數的n個查詢替換為具有n個參數的單個等效查詢,那么則應用程序將使用較少的數據庫服務器和網絡資源。


  好消息是它可以通過timewindows(時間窗口)的機制來實現,如下所示:


  第一個嘗試執行查詢的線程會打開一個時間窗口,因此其參數被存儲在一個列表中,同時該線程被暫停。在時間窗口內執行相同查詢的其余線程會將其參數添加到列表中,并且也會被暫停。此時,數據庫上未執行任何查詢。


  時間窗口結束或列表已滿(先前已定義最大容量限制)后,將使用列表中存儲的所有參數執行單個查詢。最后,一旦數據庫提供了該查詢的結果,每個線程將接收相應的結果,同時所有線程將自動恢復。


  筆者構建了一個簡單而輕量級的應用機制(DelayedBatchExecutor),很容易在新的或現有的應用程序中使用。它基于Reactor庫,并且為參數列表使用超時的Flux緩沖發布器。


java數據庫多線程應用程序優化數據存儲庫


  運用DelayedBatchExecutor的吞吐量和延遲分析


  假設針對Products的REST微服務公開了一個端點,用于檢索數據庫中給定的productId的Product數據。在沒有DelayedBatchExecutor的情況下,如果每秒對端點命中200次,則數據庫每秒執行200個查詢。如果端點使用的DelayedBatchExecutor配置了50毫秒的時間窗口且最大容量=10個參數,數據庫每秒鐘將只執行10個參數的20個查詢,代價是每執行一個線程,最多在50毫秒內增加延時(*2)。


  換句話說,為了將延時增加50毫秒(*2),數據庫每秒接收的查詢減少了10倍,然而保持了系統的整體吞吐量。還不錯?。?/p>


  其他有趣的配置:


  窗口時間=100毫秒,最大容量=20個參數→20個參數的10個查詢(查詢減少20倍)


  窗口時間=500毫秒,最大容量=100個參數→2個查詢100個參數(查詢減少100倍)


  執行中的DelayedBatchExecutor


  深入研究Product微服務示例。假設對于每個傳入的HTTP請求,微服務的控制器都要求檢索已有id的Product(JavaBean),因此將調用以下方法:


  DAO組件(ProductDAO)的publicProductgetProductById(IntegerproductId).


  以下分別是有和沒有DelayedBatchExecutor的DAO執行。


  沒有DelayedBatchExecutor


  publicclassProductDAO{


  publicProductgetProductById(Integerid){


  Productproduct=...//executethequerySELECT*FROMPRODUCTWHEREID=<id>


  //usingyourfavouriteAPI:JDBC,JPA,Hibernate...


  returnproduct;


  }


  ...


  }


  有DelayedBatchExecutor


  //Singleton


  publicclassProductDAO{


  DelayedBatchExecutor2<Product,Integer>delayedBatchExecutorProductById=


  DelayedBatchExecutor.define(Duration.ofMillis(50),10,this::retrieveProductsByIds);


  publicProductgetProductById(Integerid){


  Productproduct=delayedBatchExecutorProductById.execute(id);


  returnproduct;


  }


  privateList<Product>retrieveProductsByIds(List<Integer>idList){


  List<Product>productList=...//executequery:SELECT*FROMPRODUCTWHEREIDIN(idList.get(0),...,idList.get(n));


  //usingyourfavouriteAPI:JDBC,JPA,Hibernate...


  //Thepositionsoftheelementsofthelisttoreturnmustmatchtheonesintheparameterslist.


  //Forinstance,thefirstProductofthelisttobereturnedmustbetheonewith


  //theIdinthefirstpositionofproductIdsListandsoon...


  //NOTE:nullcouldbeusedasvalue,meaningthatnoProductexistforthegivenproductId


  returnproductList;


  }


  ...


  }


  首先,必須在DAO中創建一個DelayedBatchExecutor實例,在本例中為delayedBatchExecutorProductById。需要以下三個參數:


  時間窗口(在此示例中為50毫秒)


  參數列表的最大容量(在此示例中為10個參數)


  將使用參數列表調用的方法(詳細信息見后文)。在此示例中,方法為retrieveProductsByIds


  其次,已經重構了DAO方法publicProductgetProductById(IntegerproductId),以簡單調用delayedBatchExecutorProductById實例的execute方法。所有的“magic”都是由DelayedBatchExecutor完成的。


  之所以delayedBatchExecutorProductById是DelayedBatchExecutor2<Product,Integer>的實例,是因為其execute方法返回一個Product實例并接收一個Integer實例作為其實際參數。因此,存在:DelayedBatchExecutor2<Product,Integer>。


  如果execute方法需要接收兩個參數(例如,一個Integer和一個String)并返回Product實例,則定義為DelayedBatchExecutor3<Product,Integer,String>等。


  最終,retrieveProductsByIds方法必須返回List<Product>并接收List<Integer>作為參數。


  如果使用的是DelayedBatchExecutor3<Product,Integer,String>,則必須將retrieveProductsByIds設為List<Product>retrieveProductsByIds(List<Integer>productIdsList,List<String>stringList)


  就是這樣。


  一旦運行,執行控制器邏輯的并發線程會在某時刻調用方法getProductById(Integerid),并且此方法將返回對應的Product。并發線程不知自己已經被DelayedBatchExecutor暫停并恢復了。


  java數據庫多線程應用程序優化數據存儲庫


       以上就是動力節點Java培訓機構小編介紹的“java數據庫多線程應用程序優化數據存儲庫”的內容,希望對大家有幫助,如有疑問,請在線咨詢,有專業老師隨時為你服務。


  相關內容


  java多線程的狀態轉換以及基本操作


  常見Java多線程面試題總結


  Java多線程學習,深入解析


提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 天天干干干干 | 国产欧美另类久久久品 | 五月婷婷激情综合网 | 久久精品久 | 日韩国产精品视频 | 久久www免费人成_看 | 四虎国产精品视频免费看 | 小h片在线播放 | 偷偷操网站 | 亚洲rv国产rv日本rv | 国产中文字幕亚洲 | 国产精品成人免费观看 | 精品久久久久久乐 | 日韩成人高清 | 热久久国产精品 | 狠狠躁日日躁人人爽 | 国产精品图片 | 久久www免费人成精品 | 爱操影院 | 久久久久久久国产a∨ | 女性牲交一级毛片 | 中文字幕色综合久久 | 久久久久久久久久久96av | 99热久久这里只有精品7 | 久久国产香蕉 | 爱爱夜夜爽成人夜夜爽 | 免费不卡视频 | 黄色毛片视频网站 | 国产精品久久久久久久久岛 | 国产精品久久久久久福利 | 夜色视频一区二区三区 | 四虎澳门永久8848在线影院 | 天堂日韩 | 性欧美video另类hd亚洲人 | 在线播放性xxx欧美 在线播放亚洲 | 性做久久久久久久免费看 | 四虎成人精品国产一区a | 天天摸日日碰天天看免费 | 国产欧美日韩精品高清二区综合区 | 亚洲欧美自拍一区 | 天天操夜夜操免费视频 |