黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專(zhuān)注Java教育14年 全國(guó)咨詢(xún)/投訴熱線(xiàn):400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁(yè) 學(xué)習(xí)攻略 Java學(xué)習(xí) java數(shù)據(jù)庫(kù)多線(xiàn)程應(yīng)用程序優(yōu)化數(shù)據(jù)存儲(chǔ)庫(kù)

java數(shù)據(jù)庫(kù)多線(xiàn)程應(yīng)用程序優(yōu)化數(shù)據(jù)存儲(chǔ)庫(kù)

更新時(shí)間:2020-02-07 14:58:22 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2623次


  為Java多線(xiàn)程應(yīng)用程序優(yōu)化數(shù)據(jù)存儲(chǔ)庫(kù)


  數(shù)據(jù)存儲(chǔ)庫(kù)通常是超高要求系統(tǒng)的瓶頸。在這些系統(tǒng)中,正在執(zhí)行的查詢(xún)數(shù)量非常大。DelayedBatchExecutor是一個(gè)用于減少所需查詢(xún)數(shù)量的組件,通過(guò)在Java多線(xiàn)程應(yīng)用程序中對(duì)所需查詢(xún)進(jìn)行批處理。


java數(shù)據(jù)庫(kù)多線(xiàn)程應(yīng)用程序優(yōu)化數(shù)據(jù)存儲(chǔ)庫(kù)


  1個(gè)參數(shù)的n個(gè)查詢(xún)Vs.n個(gè)參數(shù)的1個(gè)查詢(xún)


  假設(shè)有一個(gè)對(duì)關(guān)系數(shù)據(jù)庫(kù)執(zhí)行查詢(xún)的Java應(yīng)用程序,以便在給定其唯一標(biāo)識(shí)符(id)的情況下檢索Product實(shí)體(row)。


  查詢(xún)?nèi)缦滤荆?/p>


  SELECT*FROMPRODUCTWHEREID=<productId>


  現(xiàn)在,檢索n個(gè)Products,有如下兩種方法:


  執(zhí)行1個(gè)參數(shù)的n個(gè)獨(dú)立查詢(xún):


  SELECT*FROMPRODUCTWHEREID=<productId1>


  SELECT*FROMPRODUCTWHEREID=<productId2>


  ...


  SELECT*FROMPRODUCTWHEREID=<productIdn>


  使用IN運(yùn)算符或ORs的串聯(lián),對(duì)n個(gè)參數(shù)執(zhí)行1個(gè)查詢(xún)以便同時(shí)檢索n個(gè)Products


  --ExampleusingINOPERATOR


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


  后者在網(wǎng)絡(luò)流量和數(shù)據(jù)庫(kù)服務(wù)器資源(CPU和磁盤(pán))方面更為有效,因?yàn)椋?/p>


  往返數(shù)據(jù)庫(kù)的次數(shù)為1,而不是n。


  數(shù)據(jù)庫(kù)引擎優(yōu)化了n個(gè)參數(shù)的數(shù)據(jù)遍歷過(guò)程,即每個(gè)表格可能只需要掃描1次,而不是n次。


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


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


  DelayedBatchExecutor


  需要從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù)的Java應(yīng)用程序,如REST微服務(wù)或異步消息處理器,通常以多線(xiàn)程應(yīng)用程序(*1)實(shí)現(xiàn),其中:


  每個(gè)線(xiàn)程在其執(zhí)行的某個(gè)時(shí)刻執(zhí)行相同的查詢(xún)(每個(gè)查詢(xún)具有不同的參數(shù))。


  并發(fā)線(xiàn)程數(shù)很高(每秒數(shù)十或數(shù)百)。


  在這種場(chǎng)景下,數(shù)據(jù)庫(kù)很可能在較短的時(shí)間間隔內(nèi)多次執(zhí)行相同的查詢(xún)。


  如前所述,如果將1個(gè)參數(shù)的n個(gè)查詢(xún)替換為具有n個(gè)參數(shù)的單個(gè)等效查詢(xún),那么則應(yīng)用程序?qū)⑹褂幂^少的數(shù)據(jù)庫(kù)服務(wù)器和網(wǎng)絡(luò)資源。


  好消息是它可以通過(guò)timewindows(時(shí)間窗口)的機(jī)制來(lái)實(shí)現(xiàn),如下所示:


  第一個(gè)嘗試執(zhí)行查詢(xún)的線(xiàn)程會(huì)打開(kāi)一個(gè)時(shí)間窗口,因此其參數(shù)被存儲(chǔ)在一個(gè)列表中,同時(shí)該線(xiàn)程被暫停。在時(shí)間窗口內(nèi)執(zhí)行相同查詢(xún)的其余線(xiàn)程會(huì)將其參數(shù)添加到列表中,并且也會(huì)被暫停。此時(shí),數(shù)據(jù)庫(kù)上未執(zhí)行任何查詢(xún)。


  時(shí)間窗口結(jié)束或列表已滿(mǎn)(先前已定義最大容量限制)后,將使用列表中存儲(chǔ)的所有參數(shù)執(zhí)行單個(gè)查詢(xún)。最后,一旦數(shù)據(jù)庫(kù)提供了該查詢(xún)的結(jié)果,每個(gè)線(xiàn)程將接收相應(yīng)的結(jié)果,同時(shí)所有線(xiàn)程將自動(dòng)恢復(fù)。


  筆者構(gòu)建了一個(gè)簡(jiǎn)單而輕量級(jí)的應(yīng)用機(jī)制(DelayedBatchExecutor),很容易在新的或現(xiàn)有的應(yīng)用程序中使用。它基于Reactor庫(kù),并且為參數(shù)列表使用超時(shí)的Flux緩沖發(fā)布器。


java數(shù)據(jù)庫(kù)多線(xiàn)程應(yīng)用程序優(yōu)化數(shù)據(jù)存儲(chǔ)庫(kù)


  運(yùn)用DelayedBatchExecutor的吞吐量和延遲分析


  假設(shè)針對(duì)Products的REST微服務(wù)公開(kāi)了一個(gè)端點(diǎn),用于檢索數(shù)據(jù)庫(kù)中給定的productId的Product數(shù)據(jù)。在沒(méi)有DelayedBatchExecutor的情況下,如果每秒對(duì)端點(diǎn)命中200次,則數(shù)據(jù)庫(kù)每秒執(zhí)行200個(gè)查詢(xún)。如果端點(diǎn)使用的DelayedBatchExecutor配置了50毫秒的時(shí)間窗口且最大容量=10個(gè)參數(shù),數(shù)據(jù)庫(kù)每秒鐘將只執(zhí)行10個(gè)參數(shù)的20個(gè)查詢(xún),代價(jià)是每執(zhí)行一個(gè)線(xiàn)程,最多在50毫秒內(nèi)增加延時(shí)(*2)。


  換句話(huà)說(shuō),為了將延時(shí)增加50毫秒(*2),數(shù)據(jù)庫(kù)每秒接收的查詢(xún)減少了10倍,然而保持了系統(tǒng)的整體吞吐量。還不錯(cuò)!!


  其他有趣的配置:


  窗口時(shí)間=100毫秒,最大容量=20個(gè)參數(shù)→20個(gè)參數(shù)的10個(gè)查詢(xún)(查詢(xún)減少20倍)


  窗口時(shí)間=500毫秒,最大容量=100個(gè)參數(shù)→2個(gè)查詢(xún)100個(gè)參數(shù)(查詢(xún)減少100倍)


  執(zhí)行中的DelayedBatchExecutor


  深入研究Product微服務(wù)示例。假設(shè)對(duì)于每個(gè)傳入的HTTP請(qǐng)求,微服務(wù)的控制器都要求檢索已有id的Product(JavaBean),因此將調(diào)用以下方法:


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


  以下分別是有和沒(méi)有DelayedBatchExecutor的DAO執(zhí)行。


  沒(méi)有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中創(chuàng)建一個(gè)DelayedBatchExecutor實(shí)例,在本例中為delayedBatchExecutorProductById。需要以下三個(gè)參數(shù):


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


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


  將使用參數(shù)列表調(diào)用的方法(詳細(xì)信息見(jiàn)后文)。在此示例中,方法為retrieveProductsByIds


  其次,已經(jīng)重構(gòu)了DAO方法publicProductgetProductById(IntegerproductId),以簡(jiǎn)單調(diào)用delayedBatchExecutorProductById實(shí)例的execute方法。所有的“magic”都是由DelayedBatchExecutor完成的。


  之所以delayedBatchExecutorProductById是DelayedBatchExecutor2<Product,Integer>的實(shí)例,是因?yàn)槠鋏xecute方法返回一個(gè)Product實(shí)例并接收一個(gè)Integer實(shí)例作為其實(shí)際參數(shù)。因此,存在:DelayedBatchExecutor2<Product,Integer>。


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


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


  如果使用的是DelayedBatchExecutor3<Product,Integer,String>,則必須將retrieveProductsByIds設(shè)為L(zhǎng)ist<Product>retrieveProductsByIds(List<Integer>productIdsList,List<String>stringList)


  就是這樣。


  一旦運(yùn)行,執(zhí)行控制器邏輯的并發(fā)線(xiàn)程會(huì)在某時(shí)刻調(diào)用方法getProductById(Integerid),并且此方法將返回對(duì)應(yīng)的Product。并發(fā)線(xiàn)程不知自己已經(jīng)被DelayedBatchExecutor暫停并恢復(fù)了。


  java數(shù)據(jù)庫(kù)多線(xiàn)程應(yīng)用程序優(yōu)化數(shù)據(jù)存儲(chǔ)庫(kù)


       以上就是動(dòng)力節(jié)點(diǎn)Java培訓(xùn)機(jī)構(gòu)小編介紹的“java數(shù)據(jù)庫(kù)多線(xiàn)程應(yīng)用程序優(yōu)化數(shù)據(jù)存儲(chǔ)庫(kù)”的內(nèi)容,希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€(xiàn)咨詢(xún),有專(zhuān)業(yè)老師隨時(shí)為你服務(wù)。


  相關(guān)內(nèi)容


  java多線(xiàn)程的狀態(tài)轉(zhuǎn)換以及基本操作


  常見(jiàn)Java多線(xiàn)程面試題總結(jié)


  Java多線(xiàn)程學(xué)習(xí),深入解析


提交申請(qǐng)后,顧問(wèn)老師會(huì)電話(huà)與您溝通安排學(xué)習(xí)

  • 全國(guó)校區(qū) 2025-05-15 搶座中
  • 全國(guó)校區(qū) 2025-06-05 搶座中
  • 全國(guó)校區(qū) 2025-06-26 搶座中
免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 亚洲伊人久久综合一区二区 | 国产成人乱码一区二区三区在线 | 国产成人精品免费视频大全软件 | 就草草在线观看视频 | 欧美性video 欧美性video高清精品 | 国产一区2区3区 | a级毛片黄色 | 久久美女性网 | 亚洲国产日韩无在线播放 | 国内福利视频 | 久热这里只有精品视频6 | 午夜在线视频免费观看 | 在线午夜影院 | 国产高清免费在线观看 | 一本大道香蕉大无线视频 | 成人在线播放av | 成人网18免费网 | 亚洲视频欧洲视频 | 狠狠色狠狠色综合久久第一次 | 视频一区二区欧美日韩在线 | 男女激情视频网站 | 99视频在线看观免费 | 午夜a视频| 国产小视频免费观看 | 色网站在线播放 | 永久免费视频 | 欧美精品亚洲网站 | 日韩高清一区二区三区五区七区 | 在线视频一本 | 久草综合在线视频 | 日韩亚洲人成网站 | 第一区免费在线观看 | 亚洲欧洲视频在线观看 | 欧美成视频在线观看 | 国产成人精品亚洲77美色 | 午夜激情影视 | 免费的三级网站 | 国产精品综合久成人 | 美国十次色 | 成人网18免费软件 | 黄色国产在线观看 |