简体   繁体   English

使用多线程读取和一个线程写入内存数据库

[英]Using multiple threads to read and one thread to write to an in-memory database

I currently am working on a spring application which uses an in-memory database.我目前正在开发一个使用内存数据库的 spring 应用程序。 The application receives many orders via MQ and it checks if the orders exists in the db or not.该应用程序通过 MQ 接收许多订单,并检查订单是否存在于数据库中。 If it doesnt exist then after processing the order (business logic) it saves it to the db.如果它不存在,则在处理订单(业务逻辑)后将其保存到数据库中。 Currently I am using a single thread to to handle these orders (read operation to check if already exist in db + business logic).目前我正在使用单个线程来处理这些订单(读取操作以检查数据库+业务逻辑中是否已经存在)。 Only when I want to save the order to the db (write operation) I hand off the task to another thread.只有当我想将订单保存到数据库(写操作)时,我才将任务交给另一个线程。 So while the db is being checked to see if Order n + 10 exists already, another thread might be saving Order n to the db.因此,当正在检查数据库以查看Order n + 10是否已经存在时,另一个线程可能正在将Order n保存到数据库中。 When I increase the incoming rate for the orders I notice that certain read operations take a very long amount of time.当我增加订单的传入速率时,我注意到某些读取操作需要很长时间。 I am wondering what could be the reason for this?我想知道这可能是什么原因? Right now 2 threads are interacting with the db现在有 2 个线程正在与数据库交互

  1. thread 1 (read operation + business logic)线程1(读操作+业务逻辑)
  2. thread 2 (write operation)线程2(写操作)

I have already created indexes.我已经创建了索引。 Do I need to make sure both threads create a new session instead of using the current session?我是否需要确保两个线程都创建一个新的 session 而不是使用当前的 session? Can write and read happen concurrently?写入和读取可以同时发生吗? I am planning to increase the number of reader threads so i can process the orders faster.我计划增加读者线程的数量,以便我可以更快地处理订单。 Its alright to insert the orders into db with some delay.可以延迟将订单插入数据库。 Also Order is a hibernate entity.此外, Order是一个 hibernate 实体。

Below is the code for reading from db下面是从数据库读取的代码

    @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
    public Order findByOrderId(String Id, boolean isDeleted) {
        Session session = Objects.requireNonNull(getSessionFactory()).openSession();
        final List<Order> resultList = session
            .createQuery("from Order o where o.Id = :Id and isDeleted = :isDeleted", Order.class)
            .setParameter("Id", Id)
            .setParameter("isDeleted", isDeleted)
            .list();
        session.close();

        if (resultList.isEmpty()) {
            return null;
        }
        return (resultList.get(0));
    }

What changes can I make to my hibernate/JDBC properties for better performance?我可以对我的休眠/JDBC 属性进行哪些更改以获得更好的性能?

There is no one single answer to improve the performance as it depends on a lot of factors.提高性能没有一个单一的答案,因为它取决于很多因素。 Having insights into the following factors will help us to understand why there is a performance bottleneck.深入了解以下因素将有助于我们理解为什么会出现性能瓶颈。

  1. Checking the thread pool settings for the spring boot application检查 spring 引导应用程序的线程池设置
  2. Checking the amount of CPU/Threads that are available on the server on which the spring boot app is running.检查运行 spring 启动应用程序的服务器上可用的 CPU/线程数量。

As the read operations are taking a lot of time, there are certain parameters that we need to look into to answer this由于read操作需要花费大量时间,因此我们需要研究某些参数来回答这个问题

  1. For hibernate, the number of round trips that we are making to fetch the data from the database.对于 hibernate,我们从数据库中获取数据的往返次数。

  2. The amount of data being fetched in each call from the database and amount of time it takes in transforming the data.每次调用从数据库中获取的数据量以及转换数据所花费的时间。

  3. The Hibernate connection pool settings as we need to check the total number of open connections to the database. Hibernate连接池设置为我们需要检查打开的数据库连接总数。

  4. If the data is in a sharded database, then we need to check the amount of time it takes in fetching the data from multiple shards.如果数据在分片数据库中,那么我们需要检查从多个分片中获取数据所花费的时间。

As mentioned above, we need to look at multiple areas to check where we have the performance bottleneck.如上所述,我们需要查看多个区域来检查我们的性能瓶颈在哪里。

Please also note that spawning a lot of threads will not help always as a lot of time is spent by the executor service in context switching and many threads are simply waiting for their turn to get executed.另请注意,生成大量线程并不总是有帮助,因为executor service在上下文切换中花费了大量时间,许多线程只是在等待轮到它们执行。

I would recommend you to go through the article by Vlad Mihalcea https://vladmihalcea.com/hibernate-performance-tuning-tips/ where he explains all these things in detail.我会通过Vlad Mihalcea https://vladmihalcea.com/hibernate-performance-tuning-tips/的文章向您推荐 go,他在其中详细解释了所有这些事情。

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

相关问题 Java - 使用多个线程读取/写入内存映射缓冲区(MappedByteBuffer) - Java - Using multiple threads to read/write to memory mapped buffers (MappedByteBuffer) 如何在一个线程中读取SocketChannel,并从n个线程写入? - How to read SocketChannel in one thread, and write from n threads? 使用 @DataJpaTest 的测试未使用嵌入式内存数据库 - Tests with @DataJpaTest are not using embedded in-memory database 多个线程如何通过使用Java中的同一连接来写入数据库? - How can multiple Threads write to the database by using the same connection in java? java - 通过在java中使用相同的连接,多个线程读取到数据库中的同一个表? - multiple Threads read to the same table in database by using the same connection in java? 使用内存数据库在 Spring Boot 中进行集成测试 - Integration test in Spring Boot using in-memory database 使用Java类在内存数据库中添加数据? - add data in in-memory database using Java Classes? 使用DBUnit在内存数据库中创建表时出错 - Error in creating table in in-memory database using DBUnit 结合使用内存数据库和Hibernate教程如何执行? - Using In-memory Database With Hibernate tutorial how to execute? 如何使用Derby创建内存数据库表? - How to create an in-memory database table using Derby?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM