小菜鸟

java菜鸟号正在起航

Hibernate 核心配置文件(hibernate.cfg.xml)详解

hibernate.cfg.xml 是 Hibernate 的核心配置文件,负责定义数据库连接信息、框架行为参数、映射文件路径等关键配置,是 Hibernate 与数据库交互的 “总开关”。本文将逐段解析配置文件的核心参数,帮助理解各配置项的作用与最佳实践。

配置文件结构与约束

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 所有配置项都在这里 -->
    </session-factory>
</hibernate-configuration>
  • DOCTYPE 约束:指定配置文件的 DTD 规范(版本 3.0),确保配置格式合法;
  • 根标签<hibernate-configuration> 是根标签,内部仅包含一个 <session-factory> 标签,对应 Hibernate 的 SessionFactory 实例(一个数据库连接源)。

核心配置参数详解

1. 数据库连接配置(必须配置)

用于指定 Hibernate 连接数据库的基本信息,与 JDBC 连接参数对应:

阅读全文 »

数据库连接池:原理、优势与实现详解

在传统 JDBC 编程中,每次次次操作数据库都需要通过 DriverManager 创建新连接,使用后再关闭。这种方式存在严重的性能问题 —— 连接的创建和关闭涉及 TCP 握手、认证等开销,频繁操作会显著降低系统性能。数据库连接池(Connection Pool)通过预先创建并管理一定数量的连接,实现连接复用,从根本上解决了这一问题。本文将详细讲解连接池的原理、优势及核心实现。

数据库连接池的核心原理

连接池的本质是一个连接缓冲池,其核心思想是:

  1. 预先创建连接:系统初始化时,在连接池中创建一定数量的数据库连接(Connection 对象)。
  2. 复用连接:当业务需要操作数据库时,从池中获取连接,使用完毕后不关闭连接,而是将其归还池内供下次复用。
  3. 动态管理:连接池根据负载自动调整连接数量(如空闲连接过多时销毁部分连接,请求高峰时临时创建新连接)。

传统方式 vs 连接池方式

  • 传统方式创建连接 → 使用 → 关闭连接(每次操作都有创建 / 关闭开销)。
  • 连接池方式从池获取连接 → 使用 → 归还连接(连接可重复使用,避免重复创建 / 关闭)。

连接池的核心优势

  1. 资源复用
    连接被重复使用,避免了频繁创建和关闭连接的性能开销(尤其是数据库服务器与应用服务器不在同一台机器时,可减少网络交互成本)。
  2. 提升响应速度
    连接预先创建,业务请求时可直接从池内获取,无需等待连接建立,缩短了请求处理时间。
  3. 防止资源耗尽
    连接池可限制最大连接数,避免某一应用独占所有数据库资源(如无限制创建连接可能导致数据库崩溃)。
  4. 统一连接管理
    连接池提供连接超时回收、空闲检测等机制,避免传统方式中因忘记关闭连接导致的资源泄露。

JDBC 连接池规范:DataSource 接口

JDBC 定义了 javax.sql.DataSource 接口作为连接池的标准,该接口屏蔽了连接池的实现细节,为用户提供统一的连接获取方式。核心方法:

阅读全文 »

HDFS 常用配置详解:哪些参数该调、调到多少、为什么

HDFS 的默认配置能跑,但不一定是最优的。

不同场景对 HDFS 的要求不一样——日志采集要吞吐,核心数据要可靠,小集群和大集群的配置也不一样。盲目照搬默认值,要么资源浪费,要么性能不够。

一、数据可靠性相关配置

1. dfs.replication副本数,决定数据丢不丢

  • 作用:设置 HDFS 数据块的默认副本数,确保数据可靠性;

  • 默认值:3

  • 配置示例

    <property>  
      <name>dfs.replication</name>  
      <value>3</value>  
    </property>
  • 优化建议

    • 生产环境建议保持 3 副本,确保数据容错性;
    • 冷数据或测试环境可降至 2 副本,节省存储资源;
    • 单节点集群必须设为 1(否则无法写入数据)。

2. dfs.client.block.write.replace-datanode-on-failure.replication

  • 作用:写入数据时,若某个 DataNode 失败,是否继续写入剩余副本;

  • 默认值:0(失败后不继续写入)

  • 配置示例

    <property>  
        <name>dfs.client.block.write.replace-datanode-on-failure.replication</name>  
        <value>2</value>  
      </property>
  • 适用场景

    • 数据节点数为 3 时,设为 2 可容忍 1 个节点故障,避免写入失败;
    • 高并发写入场景(如 Spark 批量写入)建议启用,提升写入成功率。

性能相关配置

1. dfs.blocksize 块大小,影响元数据压力和任务并行度

阅读全文 »

HDFS 读写流程:客户端、NameNode、DataNode 之间怎么配合

HDFS 的读写流程,本质上是三个角色配合完成一件事:

  • 客户端:我要读/写数据
  • NameNode:告诉我”数据在哪”或”数据该存哪”
  • DataNode:真正干活的——存数据或给数据

整个流程的核心逻辑是:NameNode 管”位置”,DataNode 管”数据”,客户端不经过 NameNode 直接跟 DataNode 传数据。

写入流程:数据怎么进 HDFS

写入的核心机制叫 流水线复制(Pipeline Replication)——客户端把数据发给第一个 DataNode,第一个转发给第二个,第二个转发给第三个,像流水线一样。

写入流程时序图

sequenceDiagram  
    participant Client  
    participant NN[NameNode]  
    participant DN1[DataNode 1]  
    participant DN2[DataNode 2]  
    participant DN3[DataNode 3]  

    Client->>NN: 创建文件请求(/user/data.txt)  
    NN->>Client: 确认创建,返回文件句柄  
    Client->>NN: 请求分配第一个数据块  
    NN->>Client: 分配块 ID(blk_123),返回 DataNode 列表(DN1→DN2→DN3)  
    Client->>DN1: 建立写入流水线(blk_123)  
    DN1->>DN2: 建立连接  
    DN2->>DN3: 建立连接  
    Client->>DN1: 流式写入数据(64KB 数据包)  
    DN1->>DN2: 转发数据  
    DN2->>DN3: 转发数据  
    DN3->>DN2: 确认接收  
    DN2->>DN1: 确认接收  
    DN1->>Client: 确认接收  
    loop 直至所有数据写入  
        Client->>DN1: 发送下一个数据包  
        DN1->>DN2: 转发  
        DN2->>DN3: 转发  
        DN3->>DN2: 确认  
        DN2->>DN1: 确认  
        DN1->>Client: 确认  
    end  
    Client->>NN: 关闭文件请求  
    NN->>Client: 确认关闭,持久化元数据
分步拆解:

第一步:客户端问 NameNode——“我要写文件”

客户端发送创建文件请求,NameNode 检查权限和路径合法性,在元数据中创建文件节点。此时不分配块,只是占个位置。

第二步:客户端申请块——NameNode 分配位置

客户端开始写数据时,向 NameNode 申请一个新的数据块。NameNode 按机架感知策略选出一组 DataNode(默认 3 个),返回给客户端。

第三步:建立流水线——客户端连 DN1,DN1 连 DN2,DN2 连 DN3

客户端收到 DataNode 列表后,依次建立连接形成一条链。这保证了数据按固定顺序流动。

第四步:数据流式写入——客户端 → DN1 → DN2 → DN3

数据以 64KB 数据包的形式从客户端流向 DN1,DN1 边收边转给 DN2,DN2 边收边转给 DN3。每个数据包发完后,确认信息从 DN3 反向传回客户端。

第五步:关闭文件——NameNode 记下块的位置

客户端写完所有数据后,通知 NameNode 关闭文件。NameNode 把块的 ID 和位置信息持久化到 Edits。

关键设计点:

  • 数据流和确认流分开:数据正向流,确认反向流,提高吞吐
  • NameNode 不参与数据传输:只负责分配位置,避免成为瓶颈
  • 管道中任何节点失败:客户端会关闭当前管道,用剩下的节点重建管道继续写
阅读全文 »

JDBC 事务操作详解:ACID 与隔离级别实践

事务是数据库操作的基本单元,确保多个数据库操作要么全部成功,要么全部失败,从而保证数据的一致性。JDBC 提供了完整的事务控制 API,支持事务的提交、回滚及隔离级别的设置。本文将从事务的核心特性(ACID)出发,详解 JDBC 事务操作的实现、隔离级别及并发问题的解决。

事务的核心特性(ACID)

事务必须满足四大特性,即 ACID

特性 定义 示例场景
原子性(Atomicity) 事务是不可分割的最小单位,操作要么全执行,要么全不执行。 转账时,“扣款” 和 “收款” 必须同时成功,若一方失败则全部回滚。
一致性(Consistency) 事务执行前后,数据库从一个一致性状态切换到另一个一致性状态。 转账前 A 有 100 元、B 有 200 元,转账后 A+B 仍为 300 元(总额不变)。
隔离性(Isolation) 多个事务并发执行时,彼此互不干扰,结果等同于串行执行。 事务 T1 读取数据时,事务 T2 的未提交修改不会影响 T1 的结果。
持久性(Durability) 事务提交后,对数据的修改永久生效,即使系统崩溃也不会丢失。 提交转账后,即使数据库重启,A 和 B 的余额仍保持更新后的值。

JDBC 事务操作的核心 API

JDBC 通过 Connection 接口控制事务,默认情况下,每条 SQL 语句都是一个独立事务(自动提交)。如需手动管理事务,需通过以下方法:

阅读全文 »
0%