Java 千万级数据量的入库

处理千万级数据量的入库需要考虑性能、稳定性和可扩展性。以下是一些策略和步骤,用于有效地将大量数据插入数据库:

1. 数据库设计优化

  • 分表策略:如果可能,通过分表(水平分割)来分散数据量,减少单表的压力。
  • 索引优化:确保只有必要的列上有索引,避免在非索引列上进行大量插入操作。

2. 使用PreparedStatement

  • 预编译SQL:使用PreparedStatement来预编译SQL语句,减少数据库编译SQL的时间。
  • 批量插入:利用addBatch()executeBatch()进行批量插入,减少数据库交互次数。

3. 多线程处理

  • 线程池:使用线程池来管理多个插入任务,提高资源利用率和响应速度。
  • 任务分配:将数据集分割成多个批次,每个批次由不同的线程或线程池中的工作线程处理。

4. 事务管理

  • 批量提交:在每个批次的数据插入完毕后,使用事务提交来确保数据的一致性。
  • 避免锁竞争:合理设计事务大小和隔离级别,以减少锁竞争和死锁的可能性。

5. 异步处理

  • 异步写入:如果实时性要求不高,可以使用消息队列等异步机制先缓存数据,后批量处理。

6. 硬件和配置

  • 增加资源:根据需要增加服务器的CPU、内存或存储资源。
  • 数据库配置:调整数据库配置,如连接池大小、缓冲区大小等。

7. 监控和日志

  • 性能监控:监控数据库的性能指标,如响应时间、吞吐量等。
  • 日志记录:记录操作日志,用于问题排查和性能分析。

8. 代码示例

以下是一个简化的Java代码示例,展示如何使用PreparedStatement和多线程进行批量数据插入:

import java.sql.*;
import java.util.concurrent.*;

public class MassiveInsertExample {
    static final String INSERT_SQL = "insert into TR_BASE_PARAM_TYPE(c_type_code,c_type_name,c_leaf,c_parent_code,c_type_class)values (SEQ_RISK_BASE_PARAM_TYPE_CODE.NEXTVAL,?,?,?,?)";


    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        Connection connection = establishConnection();

        // 假设dataList包含千万级数据
        List<List<BaseParamTypePO >> partitionedData = partitionData(); // 每批10000条数据

        for (List<BaseParamTypePO > batch : partitionedData) {
            executor.submit(new InsertTask(connection, batch));
        }

        executor.shutdown();
    }

    static class InsertTask implements Runnable {
        private final Connection connection;
        private final List<BaseParamTypePO > batch;

        InsertTask(Connection connection, List<BaseParamTypePO > batch) {
            this.connection = connection;
            this.batch = batch;
        }

        @Override
        public void run() {
            try (PreparedStatement stmt = connection.prepareStatement(INSERT_SQL)) {
                connection.setAutoCommit(false);
                for (BaseParamTypePO data : batch) {
                    stmt.setString(1, data.col1);
                    stmt.addBatch();
                }
                stmt.executeBatch();
                connection.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 数据库连接建立
    static Connection establishConnection() {
        // 实现数据库连接逻辑
        Connection conn = null;
        try {
            //1、注册驱动
            Class.forName("oracle.jdbc.OracleDriver");
            //2、获取连接
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/orcl","ROOT","123456");
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return conn;
    }

    // 数据分割逻辑
    static List<List<Data>> partitionData(List<Data> dataList, int batchSize) {
        // 实现数据分割逻辑
        BaseParamTypePO baseParamSettingPO = new BaseParamTypePO();
        baseParamSettingPO.setParentCode("1");
        baseParamSettingPO.setTypeClass("1");
        baseParamSettingPO.setTypeName("测试");
        baseParamSettingPO.setLeaf(true);


        List<BaseParamTypePO> baseParamTypePOS = new ArrayList<>();
        List<List<BaseParamTypePO>> baseParamList = new ArrayList<>();
        for (int j = 0; j < 10000; j++) {
            baseParamTypePOS.add(baseParamSettingPO);
        }
        for (int j = 0; j < 1000; j++) {
            baseParamList.add(baseParamTypePOS);
        }

        return baseParamList;
    }

    // 数据对象
    @Getter
	@Setter
	@ToString
    static class BaseParamTypePO {
        private String typeCode;
    	private String typeName;
    	private boolean leaf;
    	private String parentCode;
    	private String typeClass;
    }
}

注意事项

  • 在实际应用中,需要根据具体的业务场景和数据库特性进行调整。
  • 确保在进行大量数据操作时,数据库的备份和恢复策略是可靠的。
  • 考虑到可能的失败情况,实现重试机制或错误数据处理策略。
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Java百万级数据入库,我们可以使用以下方法: 1. 数据库优化:首先,我们需要确保数据库的结构和索引设计得优化且合理,以提高数据入库的速度。可以使用合适的数据库引擎、分区表或者分布式数据库来处理大量数据。 2. 批量插入:使用JDBC或者ORM框架如Hibernate,批量插入数据是提高入库速度的重要手段。通过将多条数据封装为一个批次,减少了与数据库的交互次数,提高了性能。 3. 多线程并发入库:使用多线程并发来进行数据入库,可以充分利用多核处理器,加快入库速度。可以将数据分组,每个线程负责处理一组数据,通过线程池来管理和调度线程。 4. 延迟提交事务:对于大批量的数据入库操作,可以进行延迟提交事务,即将事务的提交操作放置在批量插入的结束后,而不是在每次插入之后立即提交。这样可以减少了频繁的事务开销,提高了性能。 5. 使用批处理工具:可以使用一些批处理工具如Spring Batch来处理大规模数据入库任务。这些工具提供了可靠的任务调度和管理机制,能够有效地处理大量数据。 6. 数据分片:对于特别庞大的数据集,可以考虑将数据进行分片处理,拆分为多个小的数据集进行并发入库。可以根据数据的某些特征,如年份或者地理位置,进行数据分片。 最后,为了保证数据的安全性,我们可以实现数据备份和容灾机制,以避免可能的数据丢失或损坏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值