如何为Java多线程应用程序优化数据存储库

技术如何为Java多线程应用程序优化数据存储库本篇文章为大家展示了如何为Java多线程应用程序优化数据存储库,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。数据存储库通常是超高要求

本文向您展示了如何为Java多线程应用程序优化数据存储库。内容简洁易懂,一定会让你大放异彩。希望通过这篇文章的详细介绍,你能有所收获。

数据仓库通常是超需求系统的瓶颈。在这些系统中,正在执行的查询数量非常大。DelayedBatchExecutor是一个用于减少所需查询数量的组件,通过批处理Java多线程应用程序中所需的查询。

1个参数的n个查询Vs. n个参数的1个查询

假设有一个Java应用程序查询关系数据库来检索给定其唯一标识符(id)的产品实体(行)。

查询如下:

从产品中选择*其中标识=

现在,有两种方法可以检索n个产品:

使用1个参数执行n个独立的查询:

选择* fromproductwhreid=选择* fromproductwhreid=.select * fromproductwhreid=使用IN运算符或ORs的串联对n个参数执行查询,以同时检索n个产品。

-示例操作符从产品中选择*(,)后者在网络流量和数据库服务器资源(CPU和磁盘)方面更有效,因为:

往返数据库的次数是1,而不是n。

数据库引擎优化了n个参数的数据遍历过程,即每个表可能只需要扫描一次,而不是n次。

这不仅适用于SELECT操作,也适用于其他操作,如INSERTs、UPDATEs和DELETEs。实际上,JDBC API包含上述操作的批处理操作。

这同样适用于NoSQL存储库,其中大多数都明确提供了BULK操作。

DelayedBatchExecutor

需要从数据库中检索数据的Java应用程序,如REST微服务或异步消息处理器,通常被实现为多线程应用程序(*1),其中:

每个线程在其执行的特定时间执行相同的查询(每个查询有不同的参数)。

并发线程的数量非常高(每秒数十或数百个)。

在这种情况下,数据库可能会在短时间间隔内多次执行相同的查询。

如前所述,如果带有一个参数的n个查询被带有n个参数的单个等效查询替换,应用程序将使用更少的数据库服务器和网络资源。

好消息是,它可以通过时间窗口机制来实现,如下所示:

第一个试图执行查询的线程会打开一个时间窗口,因此它的参数会存储在一个列表中,并且该线程会被挂起。在时间窗口内执行相同查询的其余线程会将其参数添加到列表中,并且也会被挂起。此时,不会对数据库执行任何查询。

时间窗口结束或列表已满(最大容量限制已在前面定义)后,将使用列表中存储的所有参数执行单个查询。最后,一旦数据库提供了查询的结果,每个线程都会收到相应的结果,所有线程都会自动恢复。

作者构建了一个简单且轻量级的应用程序机制(DelayedBatchExecutor),可以很容易地在新的或现有的应用程序中使用。它基于反应器库,并使用超时的通量缓冲发布器作为参数列表。

运用DelayedBatchExecutor的吞吐量和延迟分析

假设产品的REST微服务公开了一个端点来检索数据库中给定产品标识的产品数据。如果没有DelayedBatchExecutor,如果端点每秒被命中200次,数据库每秒将执行200个查询。如果端点使用的DelayedBatchExecutor配置为50毫秒的时间窗口,并且最大容量为10个参数,则数据库将仅每秒执行一次。

行10个参数的20个查询,代价是每执行一个线程,最多在50毫秒内增加延时(*2)。

换句话说,为了将延时增加50毫秒(* 2),数据库每秒接收的查询减少了10倍,然而保持了系统的整体吞吐量。还不错!!

其他有趣的配置:

  • 窗口时间= 100毫秒,最大容量= 20个参数→20个参数的10个查询(查询减少20倍)

  • 窗口时间= 500毫秒,最大容量= 100个参数→2个查询100个参数(查询减少100倍)

执行中的DelayedBatchExecutor

深入研究Product微服务示例。假设对于每个传入的HTTP请求,微服务的控制器都要求检索已有id的Product(Java  Bean),因此将调用以下方法:

DAO组件(ProductDAO)的public Product getProductById(IntegerproductId) .

以下分别是有和没有 DelayedBatchExecutor的DAO执行。

没有 DelayedBatchExecutor

public classProductDAO {  public Product getProductById(Integer id) {  Product product= ...// execute the query SELECT * FROM PRODUCT WHERE ID=  // using your favourite API: JDBC, JPA, Hibernate...  return product;  }  ...  }

有DelayedBatchExecutor

// Singleton  publicclass ProductDAO {  DelayedBatchExecutor2 delayedBatchExecutorProductById =  DelayedBatchExecutor.define(Duration.ofMillis(50), 10, this::retrieveProductsByIds);  public Product getProductById(Integer id) {  Product product = delayedBatchExecutorProductById.execute(id);  return product;  }  private List retrieveProductsByIds(List idList) {  List productList = ...// execute query:SELECT * FROM PRODUCT WHERE ID IN (idList.get(0), ..., idList.get(n));  // using your favourite API: JDBC, JPA, Hibernate...  // The positions of the elements of the list to return must match the ones in the parameters list.  // For instance, the first Product of the list to be returned must be the one with  // the Id in the first position of productIdsList and so on...  // NOTE: null could be used as value, meaning that no Product exist for the given productId  return productList;  }  ...  }

首先,必须在DAO中创建一个DelayedBatchExecutor实例,在本例中为  delayedBatchExecutorProductById。需要以下三个参数:

  • 时间窗口(在此示例中为50毫秒)

  • 参数列表的最大容量(在此示例中为10个参数)

  • 将使用参数列表调用的方法(详细信息见后文)。在此示例中,方法为retrieveProductsByIds

其次,已经重构了DAO方法 publicProduct getProductById(Integer  productId),以简单调用delayedBatchExecutorProductById 实例的execute 方法。所有的“magic”都是由  DelayedBatchExecutor完成的。

之所以delayedBatchExecutorProductById是DelayedBatchExecutor2

如果execute方法需要接收两个参数(例如,一个 Integer和一个String)并返回Product实例,则定义为  DelayedBatchExecutor3

最终,retrieveProductsByIds方法必须返回List并接收List作为参数。

如果使用的是 DelayedBatchExecutor3

就是这样。

一旦运行,执行控制器逻辑的并发线程会在某时刻调用方法 getProductById(Integerid)  ,并且此方法将返回对应的Product。并发线程不知自己已经被 DelayedBatchExecutor暂停并恢复了。

由数据存储库延伸的“题外话”

尽管本文与数据存储库有关,但  DelayedBatchExecutor也可以用在其他地方,例如:对REST进行微服务请求。再说,用1个参数启动n个GET请求要比使用n个参数启动1个GET昂贵得多。

DelayedBatchExecutor的优化

笔者创建了  DelayedBatchExecutor并使用了一段时间,有效地解决了个人项目中并发线程启动的多个查询的执行问题。因此相信它对其他人可能也有用处,所以决定将其公开。

话虽如此,DelayedBatchExecutor改进和功能扩展的空间还很大。最有趣的是能够根据执行的特定条件动态更改DelayedBatchExecutor参数(窗口时间和最大容量)的功能,以便在利用带有n个参数的查询时很大程度地减少延时。

上述内容就是如何为Java多线程应用程序优化数据存储库,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/125342.html

(0)

相关推荐

  • 如何使用Winrm.vbs绕过应用白名单执行任意未签名代码

    技术如何使用Winrm.vbs绕过应用白名单执行任意未签名代码这篇文章给大家分享的是有关如何使用Winrm.vbs绕过应用白名单执行任意未签名代码的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

    攻略 2021年11月1日
  • 怎样用Python爬取京东的价格和标题及评价等商品情况

    技术怎样用Python爬取京东的价格和标题及评价等商品情况这篇文章将为大家详细讲解有关怎样用Python爬取京东的价格和标题及评价等商品情况,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知

    攻略 2021年10月26日
  • 化妆品牌子大全,日本有哪些好用的化妆品牌

    技术化妆品牌子大全,日本有哪些好用的化妆品牌日本女生从初中开始很多就开始化妆了化妆品牌子大全,所以整体国家的化妆品还是发展的很不错的,毕竟需求大嘛,而且从贵妇到大众品牌一应俱全,很多大集团都会出不同价位的品牌,以满足不同

    生活 2021年11月1日
  • LINQ查询的目的与实现手段是什么

    技术LINQ查询的目的与实现手段是什么这期内容当中小编将会给大家带来有关LINQ查询的目的与实现手段是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。LINQ查询从数据源中找到合适的

    攻略 2021年11月24日
  • 服务器哪些因素会影响SEO香港服务器租用

    技术服务器哪些因素会影响SEO香港服务器租用大多数SEO专家认为,在决定为给定搜索查询显示哪些网站时,搜索引擎会考虑多个因素。其中之一是用于托管您的网站的服务器,在这里,我们将以香港服务器为例讨论服务器的选择会对您的搜索

    礼包 2021年10月26日
  • ETL架构中的子系统有哪些

    技术ETL架构中的子系统有哪些这篇文章主要讲解了“ETL架构中的子系统有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ETL架构中的子系统有哪些”吧!三个简单的字母,

    攻略 2021年11月9日