小菜鸟

java菜鸟号正在起航

YARN 深度解析:分布式资源调度框架,到底在调度什么?

在 Hadoop 1.x 时代,JobTracker 既要管资源分配、又要管任务调度,还要管容错——一个组件扛所有,成了单点瓶颈,而且只支持 MapReduce。

YARN 的出现把 JobTracker 拆了:

  • ResourceManager:管资源(CPU、内存)
  • ApplicationMaster:管应用的执行逻辑
  • NodeManager:管单节点上的资源

拆开之后,每个组件只做一件事,而且任何计算框架(MapReduce、Spark、Flink)都可以跑在 YARN 上——只要实现自己的 ApplicationMaster 就行。

YARN 的四个核心组件

组件 角色 类比
ResourceManager(RM) 全局资源总管 公司总部,管总预算
NodeManager(NM) 单节点资源管家 每个部门的行政,管本部门资源
ApplicationMaster(AM) 单个应用的调度员 项目经理,管自己的项目
Container 资源的容器 工位 + 电脑 + 工时的组合包

它们之间怎么配合?

flowchart TD
    subgraph 集群节点  
        A[ResourceManager<br/>全局资源管理器]  
        B[NodeManager<br/>节点资源管理器]  
        C[NodeManager<br/>节点资源管理器]  
    end  
    subgraph 应用程序  
        D[ApplicationMaster<br/>应用主控]  
        E[Container<br/>资源容器]  
        F[Container<br/>资源容器]  
    end  
    A -- 资源分配 --> B  
    A -- 资源分配 --> C  
    A -- 启动/监控 --> D  
    D -- 申请资源 --> A  
    D -- 管理任务 --> E  
    D -- 管理任务 --> F  
    B -- 提供容器 --> E  
    C -- 提供容器 --> F

不是 RM 直接调度任务,RM 只管分配资源,具体的任务调度由每个应用的 AM 自己管。

一个 MapReduce 作业在 YARN 上怎么跑

第 1 步:提交作业

客户端向 RM 提交作业。RM 为这个作业启动一个 ApplicationMaster(MRAppMaster)。

第 2 步:AM 申请资源

AM 分析作业需要多少个 Map 和 Reduce 任务,向 RM 申请对应数量的 Container。

第 3 步:启动任务

AM 拿到 Container 后,告诉对应的 NM 在这些 Container 里启动 Map/Reduce 任务。

阅读全文 »

MySQL 注释用法详解

在 MySQL 中,注释是提高 SQL 语句可读性的重要手段,可用于解释逻辑、标注功能或临时屏蔽代码。MySQL 支持三种注释方式,适用于不同场景:

单行注释

1. # 开头的注释

  • 语法# 注释内容# 后直接跟注释文字,无需空格)。
  • 适用场景:单行注释,常用于 SQL 语句末尾或单独一行。
-- 示例 1:语句后注释
SELECT * FROM users WHERE status = 1; # 查询状态为1的用户

-- 示例 2:单独一行注释
# 以下语句用于统计今日新增订单
SELECT COUNT(*) FROM orders WHERE create_time >= CURDATE();

2. --开头的注释

  • 语法-- 注释内容(注意 -- 后必须跟至少一个空格,否则会被视为 SQL 语法的一部分)。
  • 适用场景:单行注释,与 # 功能类似,是 SQL 标准的注释方式。
阅读全文 »

MySQL 常用语句大全:从基础操作到系统信息查询

MySQL 提供了丰富的语句用于数据库管理、表操作及系统信息查询。本文整理了日常开发和运维中最常用的语句,涵盖数据库 / 表操作、状态查询、编码设置等场景,帮助快速掌握 MySQL 核心操作。

系统信息查询

1. 查看服务器状态与变量

-- 查看所有系统状态变量(session 级别,当前连接有效)
SHOW STATUS;

-- 查看全局系统状态变量(所有连接共享)
SHOW GLOBAL STATUS;

-- 过滤查询特定状态(如中断的客户端连接数)
SHOW STATUS LIKE 'Aborted_clients';  -- 支持通配符(% 匹配任意字符)
-- 查看所有系统配置变量(如字符集、连接数等)
SHOW VARIABLES;

-- 查看全局配置变量
SHOW GLOBAL VARIABLES LIKE 'max_connections';  -- 查看最大连接数

2. 版本与环境信息

阅读全文 »

Struts2 访问 Web 资源的两种方式详解

在 Struts2 框架中,Web 资源(如HttpServletRequestHttpSessionServletContext等)的访问方式分为与 Servlet API 解耦与 Servlet API 耦合两种。两种方式各有适用场景,下面详细解析其实现方式与使用场景。

与 Servlet API 解耦的方式

这种方式通过 Struts2 封装的 API 访问 Web 资源,不直接依赖 Servlet 原生类,便于进行单元测试,适合大多数业务场景。

1. 使用 ActionContext(核心方式)

ActionContext是 Struts2 的上下文对象,封装了当前请求的所有信息,可通过它间接访问 Web 资源对应的 Map 对象。

核心方法与示例:
import com.opensymphony.xwork2.ActionContext;
import java.util.Map;

public class UserAction {
    public String execute() {
        // 获取ActionContext实例(单例,与当前请求绑定)
        ActionContext actionContext = ActionContext.getContext();

        // 1. 获取application域(对应ServletContext)
        Map<String, Object> applicationMap = actionContext.getApplication();
        applicationMap.put("appKey", "全局应用数据"); // 存储数据
        Object appValue = applicationMap.get("appKey"); // 获取数据

        // 2. 获取session域
        Map<String, Object> sessionMap = actionContext.getSession();
        sessionMap.put("userName", "张三"); // 存储用户会话数据
        Object user = sessionMap.get("userName");

        // 3. 获取request域(需通过"request"键获取,Struts2未直接提供getRequest()方法)
        Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");
        requestMap.put("msg", "请求数据");
        Object msg = requestMap.get("msg");

        // 4. 获取请求参数(封装为Map,键是参数名,值是参数值数组)
        Map<String, Object> params = actionContext.getParameters();
        String[] ids = (String[]) params.get("id"); // 适用于多值参数
        String name = (String) params.get("name"); // 单值参数

        return "success";
    }
}
特点:
阅读全文 »

Hadoop 序列化:为什么不用 Java 自带 Serializable?

在分布式系统里,数据要在节点之间网络传输,也要落盘存储。序列化就是干这个的——把内存里的对象变成字节流,到了目的地再还原回来。

Java 自带 Serializable,那 Hadoop 为什么还要搞一套自己的序列化?

因为 Java 原生的序列化太重了——它会把类的元数据(类名、父类信息、字段签名等)也序列化进去,字节流体积大、速度慢。 在海量数据场景下,这种开销是灾难性的。

Hadoop 的 Writable 接口是轻量级序列化的解决方案:只序列化数据本身,不附带任何元数据。 收方和发方约定好”数据的顺序和类型是什么”,然后直接读、直接写。

Writable 长什么样?

Writable 接口就两个方法:

public interface Writable {
    void write(DataOutput out) throws IOException;   // 对象 → 字节流
    void readFields(DataInput in) throws IOException; // 字节流 → 对象
}

对比 Java Serializable:

Java Serializable Hadoop Writable
序列化内容 数据 + 类元数据 仅数据
字节流大小
速度
实现复杂度 自动(implements 就行) 手写 write/readFields
跨语言支持 不支持 不支持

所以 Writable 是”用开发者的少量手写代码,换取生产环境的大量性能提升”。

常用 Writable 类型

Hadoop 封装了常用 Java 类型的 Writable 版本:

Java 类型 Writable 类型 备注
int IntWritable 4 字节
long LongWritable 8 字节
float FloatWritable 4 字节
double DoubleWritable 8 字节
boolean BooleanWritable 1 字节
String Text UTF-8 变长编码
byte[] BytesWritable 字节数组
null NullWritable 占位,不占空间

MapReduce 的 Key/Value 必须实现 Writable(或 WritableComparable)。

自定义 Writable:手写一个 UserInfo

假设你要在 MapReduce 里传递用户信息:

阅读全文 »
0%