从数百万个光纤(而不是数千个线程)中查询数据库
jOOQ是在Java中執(zhí)行SQL的好方法, Quasar光纖帶來(lái)了大大提高的并發(fā)性
我們很高興在平行宇宙的 Fabio Tudone的jOOQ博客上宣布另一個(gè)非常有趣的來(lái)賓帖子。
Parallel Universe開(kāi)發(fā)了一個(gè)開(kāi)源堆棧,使開(kāi)發(fā)人員可以輕松地在JVM上對(duì)極端的并發(fā)應(yīng)用程序進(jìn)行編碼。 使用Parallel Universe堆棧,您可以構(gòu)建與現(xiàn)代硬件協(xié)調(diào)工作的軟件,而不是動(dòng)every動(dòng)腦,同時(shí)保持您的編程語(yǔ)言和簡(jiǎn)單,熟悉的編程風(fēng)格。
Fabio Tudone作為Comsat項(xiàng)目的一部分,開(kāi)發(fā)和維護(hù)Quasar集成模塊。 在加入Parallel Universe團(tuán)隊(duì)之前,他曾參與并領(lǐng)導(dǎo)了基于云的企業(yè)內(nèi)容治理平臺(tái)的開(kāi)發(fā)工作數(shù)年,并且他在整個(gè)職業(yè)生涯中一直在編寫JVM軟件。 他的興趣包括Dev和DevOps實(shí)踐,可伸縮性,并發(fā)和功能編程以及運(yùn)行時(shí)平臺(tái)。 他自然好奇,喜歡探索,他喜歡從人,地方和文化中收集知識(shí)和理解。 他還對(duì)意識(shí)實(shí)踐感興趣,喜歡寫各種各樣的東西。
Quasar作為Comsat項(xiàng)目的一部分,具有JDBC和jOOQ的集成,因此讓我們來(lái)看看它的內(nèi)部。
JDBC,jOOQ和Quasar
comsat-jdbc提供了JDBC API的光纖阻塞包裝程序,因此您可以在光纖而不是常規(guī)Java線程中使用連接。
為什么要這么做? 因?yàn)楣饫w是輕量級(jí)線程,并且與正在運(yùn)行的JVM中的線程相比 ,您可以擁有更多的光纖。 “更多”意味著我們要說(shuō)的是數(shù)百萬(wàn)人,而不是數(shù)千人。
這意味著在等待JDBC執(zhí)行時(shí),您的系統(tǒng)中有更多的并行能力來(lái)并行執(zhí)行其他操作,無(wú)論是并發(fā)/并行計(jì)算(例如在高度可靠的類Quasar Erlang類actor系統(tǒng)中 交換actor消息 )阻止I / O(例如, 服務(wù) Web 請(qǐng)求 , 調(diào)用微服務(wù) ,通過(guò)光纖NIO讀取文件或訪問(wèn)其他啟用了光纖的數(shù)據(jù)源(如MongoDB ))。
如果您的數(shù)據(jù)庫(kù)能忍受它,而更多的常規(guī)線程不會(huì)使您的系統(tǒng)崩潰(甚至),您甚至可以增加光纖JDBC池(請(qǐng)參閱附加點(diǎn):后面的等待線 )并發(fā)送更多并發(fā)的jOOQ命令。
由于jOOQ使用JDBC連接訪問(wèn)數(shù)據(jù)庫(kù),因此在光纖上運(yùn)行jOOQ就像引入comsat-jooq依賴項(xiàng)并將啟用光纖的JDBC連接傳遞到j(luò)OOQ上下文一樣簡(jiǎn)單:
import java.sql.Connection; import static org.jooq.impl.DSL.*;// ...Connecton conn = FiberDataSource.wrap(dataSource).getConnection(); DSLContext create = DSL.using(connection);// ...當(dāng)然,您也可以將ConnectionProvider配置為從FiberDataSource提取連接。
從這一刻起,您可以使用常規(guī)的jOOQ,所有操作都將在光纖阻塞模式下發(fā)生,而不是在線程阻塞下發(fā)生。 而已。
不,真的, 絕對(duì)沒(méi)有其他東西了:您將繼續(xù)使用出色的jOOQ,僅使用效率更高的光纖而不是線程。 Quasar是一個(gè)好公民,不會(huì)強(qiáng)迫您使用新的API(特別是當(dāng)原始API很好時(shí),這很好)。
由于JVM 目前不支持可用于實(shí)現(xiàn)輕量級(jí)線程的本機(jī)綠色線程或延續(xù) ,因此Quasar通過(guò)字節(jié)碼檢測(cè)實(shí)現(xiàn)了延續(xù)(以及它們之上的光纖)。 這可以在編譯時(shí)完成,但是使用Quasar的代理通常更方便(尤其是在檢測(cè)第三方庫(kù)時(shí)),因此這是一個(gè)基于Dropwizard的Gradle示例項(xiàng)目 ,其中還包括Quasar代理設(shè)置(不要忘了Capsule ,這是一種非常出色的Java部署工具,可滿足各種需求,這無(wú)疑使使用Quasar和代理變得輕而易舉。 該示例未使用所有jOOQ功能,而是屬于SQL構(gòu)建用例 (用于查詢和CRUD),但是建議您更改它以適合您的需求。 without-comsat分支包含一個(gè)線程阻止版本,因此您可以比較并查看與Comsat版本的(最小)差異。
排隊(duì)等候在哪里?
您可能現(xiàn)在想知道:好的,但是JDBC是一個(gè)線程阻塞 API,Quasar如何將其轉(zhuǎn)換為光纖 阻塞 API? 因?yàn)镴DBC沒(méi)有異步模式,所以Quasar在后臺(tái)使用了一個(gè)線程池,光纖在該線程池中調(diào)度JDBC操作,并且在JDBC操作完成后將其解凍并計(jì)劃恢復(fù)(請(qǐng)查看Quasar的集成模式以了解更多信息)信息)。
是的,這是討厭的等待行 :等待線程池執(zhí)行的JDBC命令。 盡管您并未將數(shù)據(jù)庫(kù)并行性提高到超過(guò)JDBC線程池的大小,但是即使您仍在使用簡(jiǎn)單且熟悉的阻塞API,也不會(huì)損害光纖。 您仍然可以擁有數(shù)百萬(wàn)的纖維。
是否可以改善總體狀況? 沒(méi)有標(biāo)準(zhǔn)的異步Java RDBMS API,我們將無(wú)能為力。 但是,如果數(shù)據(jù)庫(kù)是您的瓶頸,那么這可能根本不重要。 關(guān)于此主題有很多不錯(cuò)的文章和討論 ,該論據(jù)等于確定您要將等待線移至何處。
獎(jiǎng)勵(lì):巧妙的jOOQ集成
目前,Quasar需要開(kāi)發(fā)人員(或集成商)告訴它要進(jìn)行檢測(cè)的內(nèi)容,盡管正在進(jìn)行自動(dòng)檢測(cè)(此功能取決于Java 9之前不會(huì)發(fā)布的一些較小的JRE更改)。 如果您可以方便地更改源代碼(或已編譯的類),則足以使用@Suspendable注釋方法或讓它們throws SuspendExecution ,但是對(duì)于庫(kù)通常不是這種情況。 但是可以在META-INF/suspendables和META-INF/suspendable-supers中分別列出具有要檢測(cè)的固定名稱的方法,分別用于可以具有可掛起實(shí)現(xiàn)的具體方法和抽象/接口方法。
如果有很多(或涉及代碼生成),則可以編寫SuspendableClassifier隨集成一起提供,并在Quasar的SPI中注冊(cè)它以提供其他檢測(cè)邏輯(請(qǐng)參閱jOOQs )。 SuspendableClassifier的工作是在檢測(cè)階段檢查有關(guān)運(yùn)行時(shí)類路徑中每個(gè)方法的簽名信息,并確定該方法是否可掛起,是否可以掛起,是否可以實(shí)現(xiàn)或不確定。 (其他一些分類器稍后可能會(huì)說(shuō)“可懸浮”或“可懸浮-超級(jí)”)。
總結(jié)一下
好吧……只需要在高效纖維上享受出色的jOOQ!
翻譯自: https://www.javacodegeeks.com/2015/06/querying-your-database-from-millions-of-fibers-rather-than-thousands-of-threads.html
總結(jié)
以上是生活随笔為你收集整理的从数百万个光纤(而不是数千个线程)中查询数据库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: FPGA设计心得(5)Aurora 例子
- 下一篇: ejb 2.0 3.0_EJB 3.1全