2017-03-24 40 views
1

我有一个Java应用程序从一个Microsoft SQL Server(微软的SQL Server 2008 R2(SP3))申请约2.4万条记录的Microsoft SQL Server - 巨大成绩查询,导致ASYNC_NETWORK_IO等问题

应用罚款运行在所有的主机,除了一个。在该主机上,应用程序能够在某些场合检索数据。但在其他一些情况下,它会挂起。

监视MS Sql服务器指示与查询关联的SPID处于ASYNC_NETWORK_IO等待状态。

在网上有几个链接,谈论它。
https://blogs.msdn.microsoft.com/joesack/2009/01/08/troubleshooting-async_network_io-networkio/

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/6db233d5-8892-4f8a-88c7-b72d0fc59ca9/very-high-asyncnetworkio?forum=sqldatabaseengine

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/1df2cab8-33ca-4870-9daf-ed333a64630c/network-packet-size-and-delay-by-sql-server-sending-data-to-client?forum=sqldatabaseengine

基于上述情况,ASYNC_NETWORK_IO意味着两两件事: 1.应用程序是缓慢处理结果 2.应用之间的网络和DB有一些问题。

对于上面的#1,我们使用tcpdumps进行了分析,发现在查询进入ASYNC_NETWORK_IO状态的情况下,应用程序服务器的tcp连接的窗口大小介于0和小数之间,最终仍然停留在根据更多的分析,大多数情况下也排除了数据库与应用程序之间的防火墙相关的方面。

所以我盯着#2,无法理解什么可能出错。更令人困惑的是,相同的代码已经在类似的数据加载下运行了一年多了。而且它在其他主机上运行也很好。

正在使用的JDBC驱动程序是sqljdbc4-4.0.jar。 默认情况下,它具有自适应缓冲功能,该功能可以减少应用程序资源。 我们使用默认的获取大小128(我认为这不是一个好的)。

因此,我将尝试覆盖默认的自适应缓冲行为,但MS文档建议对大型结果集进行自适应缓冲是很好的做法。

我将更改连接设置以使用selectMethod = cursor。 ,改变它的FETCHSIZE 1024

现在,如果它不工作:

  1. 什么是值得深入研究的问题的某些方面。
  2. 假设它仍然是客户端的问题,还应该检查/更改其他连接设置,网络设置以取得进展?

如果它不工作始终,是什么使得连接设置更改selectMethod的影响=光标

  1. 在应用程序方面?
  2. 数据库端?

更新:我测试的应用程序添加selectMethod =光标到该连接。但是,它会导致与上述相同的问题。

基于与团队中其他管理员的讨论 - 此时问题可能出在jdbc驱动程序或操作系统上(当它试图处理网络上的数据时)。

+0

它可能在该服务器上的内存不足,交换自己的死亡。您正在等待更改'selectMethod = cursor'应该可以解决这个问题,特别是如果您的Java代码不尝试记住所有数据,而是在检索时处理它。 – Andreas

+0

@Andreas - 事实并非如此,因为没有过多的GC活动。有足够的堆大小分配给进程。没有观察到OOM。 – Mavadu

+0

我不是指JVM GC,而是OS交换。如果您向JVM提供的内存超过了操作系统的可用空间,那么它必须交换页面。操作系统内存可能会被其他进程重载,或者如果它是虚拟机,主机内存可能会被其他虚拟机过载。无论哪种方式,内存交换到磁盘,将减缓处理,过度交换基本上会阻止进程,这就是我所说的“交换到死亡”。 – Andreas

回答

0

在与系统管理员,网络管理员和数据库管理员进行了大量讨论后 - 同意在操作系统 - >应用程序堆栈中的某处,未处理来自网络的数据。与此同时,我们测试了一个解决方案,在该解决方案中,我们分解了查询以返回较小的结果。所以我们把它分解成5个查询,每个查询返回约500k条记录。

现在,当我们依次运行这些查询时,我们仍遇到同样的问题。

但是,当我们并行运行查询时,它总是成功的。

鉴于解决方案的工作原理,我们一直没有找到解决问题的根本原因。

另一方面,运行该应用程序的硬件和软件也过时了。它正在运行Red Hat 5.因此,它可能必须采取措施。