简体   繁体   English

如果我们有数据库调用,异步处理是否真的有帮助?

[英]Does Asynchronous processing actually help if in case we have database calls into it?

In a server, if I have a async function which will process some database calls and fetch some records from the table. 在服务器中,如果我有一个异步函数,它将处理一些数据库调用并从表中获取一些记录。 If the server receives high number of requests, that database call might actually be blocking and we don't really have a async working there. 如果服务器收到大量请求,则该数据库调用实际上可能正在阻塞,并且我们那里实际上没有异步工作。

  1. When we have some database calls in a server process, does async methods help ? 当我们在服务器进程中进行一些数据库调用时,异步方法有帮助吗?

  2. If not, what are the problems that will arise because of such methods ? 如果没有,这种方法会带来什么问题?

I don't want to customise it to a particular database because then my question will deviate. 我不想将其自定义为特定的数据库,因为那样我的问题就会偏离。 I just want to revolve around asynchronous programming paradigm here. 我只想在这里讨论异步编程范例。 If there are suggestions on some optimised way for the database fetching operation, then its welcome. 如果有关于数据库获取操作的一些优化方法的建议,则欢迎使用。 I would just like to know for a normal fetch for the start. 我只想了解正常的开始操作。

In concurrent applications under load, asynchronous method calling can improve performance and throughput, because the calling thread is freed up to do other work. 在负载下的并发应用程序中,异步方法调用可以提高性能和吞吐量,因为释放了调用线程来执行其他工作。

There are edge cases where it will not help, but if your application spends any significant amount of time doing anything other than waiting for data from the database, you should see some benefit. 在某些情况下,它无济于事,但是如果您的应用程序花费大量时间(除了等待数据库中的数据)来做其他事情,您应该会发现一些好处。 These benefits apply to both server side and GUI applications. 这些好处适用于服务器端和GUI应用程序。

For example, if your application spends 300ms waiting for data, and 300ms processing it, and you are dealing with a large number of simultaneous requests, you could potentially double throughput by using async calls, because each thread requesting data will be freed up instantly, and can then deal with data returned by a previous request. 例如,如果您的应用程序花费300毫秒等待数据并处理300毫秒,并且您正在处理大量同时请求,则使用异步调用可能会使吞吐量翻倍,因为每个请求数据的线程都会立即释放,然后可以处理先前请求返回的数据。

You will rarely see this degree of improvement in practice, because requests do not arrive at nice even intervals, and generally do not each require the same amount of work. 在实践中,您很少会看到这种程度的改进,因为请求不会以均匀的间隔到达,并且通常每个请求所需的工作量都不相同。 The difference should be noticeable though. 区别应该是值得注意的。

However, if you spend 300ms waiting for data, and only spend 10ms processing it, you will not see anywhere near as much improvement. 但是,如果您花300毫秒等待数据,而只花10毫秒来处理数据,那么您将看不到任何改善的地方。

In an environment such as ASP.Net, this is very important as there are a limited number of threads available to process all incoming web requests: If all the threads are waiting on the database server, then no pages are served. 在ASP.Net之类的环境中,这非常重要,因为可以使用有限数量的线程来处理所有传入的Web请求:如果所有线程都在数据库服务器上等待,则将不提供任何页面。

In windows forms applications, using Async calls to fetch data allows the UI to remain responsive while the data is fetched, allowing you to give the user the option of cancelling if they get bored waiting. 在Windows窗体应用程序中,使用Async调用来获取数据可使UI在获取数据时保持响应,从而使用户可以选择在无聊的等待时取消用户。

The obvious downside is that it makes the calling code significantly more complicated. 明显的缺点是,这使调用代码变得更加复杂。

You have two potential problems here, the first can be resolved by using async methods the second can only be resolved by tuning your database. 这里有两个潜在的问题,第一个可以使用异步方法解决,第二个只能通过调整数据库来解决。

Using async methods will allow your clients to perform other processing whilst waiting for your server, ie remain responsive in the case of a UI. 使用异步方法将使您的客户端在等待服务器的同时执行其他处理,即在UI情况下保持响应。

The database locking issue can only be solved by analysing the database under load to see which tables are being locked and which stored procs or processes are causing the locks. 数据库锁定问题只能通过分析负载下的数据库以查看哪些表被锁定以及哪些存储的proc或进程导致了锁定来解决。

You might want to look into in memory caching or other optimisations if you really do have a need for a huge amount of requests. 如果确实确实需要大量请求,则可能要研究内存缓存或其他优化方法。

Using async calls will certianly help your throughput in the situation you're descripting if you have other work for the calling thread to perform. 如果您还有其他工作要执行的调用线程, 在描述的情况下,使用异步调用可以极大地帮助您提高吞吐量。 For example, if Thread 1 handles a request to the server & makes a database call, even if you use a .BeginInvoke(res) followed immediately by .EndInvoke(res) you're still blocking on that call. 例如,如果线程1处理到服务器的请求并进行数据库调用,即使您使用.BeginInvoke(res),紧接着是.EndInvoke(res),您仍会阻止该调用。

To scale properly you need to make sure that Thread 1 has other work to do, perhaps preparing another page request until it's database call is done. 为了适当地扩展,您需要确保线程1还有其他工作要做,也许准备另一个页面请求,直到完成数据库调用为止。 This can be accomplished by using a shared work queue or sequential queues like the pipeline pattern. 这可以通过使用共享工作队列或流水线模式之类的顺序队列来完成。 Check out some of the links in this question for more details about async design patterns and how they can help you get better throughput out of your server. 请查看此问题中的某些链接,以获取有关异步设计模式的更多详细信息,以及它们如何帮助您提高服务器的吞吐量。

Design Patterns [1]: Resources about Asynchronous Programming Design Patterns 设计模式[1]: 关于异步编程设计模式的资源

To keep the answer short: 为了使答案简短:

Using asynchronous processing helps in particular when you have database calls. 使用异步处理特别有帮助当您有数据库调用时。

In a server application you should avoid blocking threads. 在服务器应用程序中,应避免阻塞线程。 If in typical request your server accesses the database, then if you do this synchronously, it means that your threads are blocked waiting for IO most of the time. 如果在典型的请求中您的服务器访问数据库,那么如果您同步进行此操作,则意味着您的线程大部分时间都在等待IO的情况下被阻塞。 When enough threads get blocked, this will introduce a bottle neck on your server and hurt scalability, as no thread-pool threads are available to process new requests, and in addition your CPU may get under-utilized as no threads are available to pick up work to do. 当阻塞了足够多的线程时,这将在您的服务器上造成瓶颈,并损害可伸缩性,因为没有线程池线程可用于处理新请求,此外,由于没有线程可用于拾取,因此您的CPU可能未得到充分利用要做的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM