Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
SomeBottle committed Feb 4, 2024
1 parent b53c628 commit 2ddd358
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 71 deletions.
215 changes: 147 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Hadoop + Spark 分布式容器化部署镜像

本镜像基于`bitnami/spark:3.5.0`镜像,系统为`Debian 11`,执行用户为`root`
本镜像基于`bitnami/spark:3.5.0`镜像,系统为`Debian 11`,执行用户为`root`

* [Docker hub](https://hub.docker.com/r/somebottle/haspark)
* [Github: somebottle/haspark](https://github.com/SomeBottle/haspark)

* [DockerHub: somebottle/haspark](https://hub.docker.com/r/somebottle/haspark)

```bash
docker pull somebottle/haspark
Expand All @@ -14,35 +16,33 @@ docker pull somebottle/haspark

如果有增加配置项的需要,欢迎发[Issue](https://github.com/SomeBottle/haspark/issues)亦或者开[Pull request](https://github.com/SomeBottle/haspark/pulls)

## 关于本镜像
## 1. 关于本镜像

* 本镜像配置完成,用docker compose上线容器后,能**自动交换SSH公钥实现节点间SSH免密登录**
* 多节点进程启动同步机制:本镜像依赖于SSH,在进行多个容器上Hadoop组件部署的时候会等待各节点相应进程全启动完毕再进入下一步。
* 本镜像在**WSL**上测试完成。
* 支持 **Hadoop HA(高可用)集群** 的简单部署。
* 本镜像配置完成,用 `docker compose` 部署上线容器后,能**自动交换 SSH 公钥实现节点间 SSH 免密登录**
* 依赖于SSH的多节点进程启动同步机制:本镜像在进行多个容器上Hadoop组件部署的时候,可能会等待各节点相应进程全启动完毕再进入下一步。
在启动**高可用集群**的时候可能需要等待较长的一段时间。
* 本镜像在 **WSL**(Ubuntu22.04LTS) 上测试完成。

## 软件版本
## 2. 软件版本

* Hadoop `3.3.6`
* Spark `3.5.0`
* Zookeeper `3.9.1`

## 默认节点分配

1 master + 2 workers.

> 如果需要修改则需要[编辑多个文件](#修改节点数)进行重新构建。
## 3. 可配置的环境变量

## 可配置的环境变量
环境变量可以[写成一个文件](#62-编写docker-compose配置),和 `docker-compose.yml` 配合使用。

`bitnami/spark`的基础上添加如下环境变量:
`bitnami/spark` 镜像的基础上,本镜像新增如下环境变量:

### 首要配置
### 3.1. 首要配置

| 名称 | 说明 | 默认值 |
| --- | --- | --- |
|`SH_HOSTS` | 集群中所有节点的主机名(**必填**),空格分隔 |

### Hadoop通用配置
### 3.2. Hadoop通用配置

| 名称 | 说明 | 默认值 |
| --- | --- | --- |
Expand All @@ -52,7 +52,7 @@ docker pull somebottle/haspark
| `HADOOP_REDUCE_MEMORY_MB` | 为每个Reduce任务分配的内存量 (以**MiB**为单位) | `1024` |


### Hadoop普通分布式
### 3.3. Hadoop普通分布式

| 名称 | 说明 | 默认值 |
| --- | --- | --- |
Expand All @@ -66,22 +66,22 @@ docker pull somebottle/haspark
| `GN_HDFS_SETUP_ON_STARTUP` | 是否在容器启动时自动启动HDFS各个节点的守护进程 | `"false"` |
| `GN_YARN_SETUP_ON_STARTUP` | 是否在容器启动时自动启动Yarn各个节点的守护进程 | `"false"` |

### Hadoop高可用(HA)分布式
### 3.4. Hadoop高可用(HA)分布式

| 名称 | 说明 | 默认值 |
| --- | --- | --- |
|`HA_HDFS_NAMESERVICE`|HDFS高可用集群的服务名(逻辑地址)| `"hacluster"` |
|`HA_HDFS_SETUP_ON_STARTUP`| 是否在容器启动时自动初始化并启动HDFS | `"false"` |
|`HA_HDFS_SETUP_ON_STARTUP`| 是否部署高可用 HDFS 集群 | `"false"` |
|`HA_NAMENODE_HOSTS`|需要启动NameNode的节点的主机名列表(空格分隔)||
|`HA_JOURNALNODE_HOSTS`|需要启动JournalNode的节点的主机名列表(空格分隔)||
|`HA_DATANODE_HOSTS`|需要启动DataNode的节点的主机名列表(空格分隔)||
|`HA_YARN_SETUP_ON_STARTUP`| 是否在容器启动时自动初始化并启动YARN | `"false"` |
|`HA_YARN_SETUP_ON_STARTUP`| 是否部署高可用 Yarn 集群 | `"false"` |
|`HA_RESOURCEMANAGER_HOSTS`|需要启动ResourceManager的节点的主机名列表(空格分隔)||
|`HA_NODEMANAGER_HOSTS`|需要启动NodeManager的节点的主机名列表(空格分隔)||

## 只读环境变量
## 3.5. 只读环境变量

除了`bitnami/spark`提供的只读环境变量外,本镜像还提供了:
除了 `bitnami/spark` 提供的只读环境变量外,本镜像还提供了:

| 名称 | 说明 |
| --- | --- |
Expand All @@ -93,123 +93,198 @@ docker pull somebottle/haspark
|`HADOOP_HOME` | Hadoop安装目录 |
|`HADOOP_CONF_DIR` | Hadoop配置文件目录 |
|`HADOOP_LOG_DIR` | Hadoop日志目录 |
|`SPARK_CONF_DIR` | Spark配置文件目录 |



## 提供的脚本
## 4. 提供的脚本

### 1. 查询集群各容器的Java进程
### 4.1. 查询集群各容器的Java进程

在命令行执行`jpsall`即可,脚本实际位于`/opt/somebottle/haspark/tools/jpsall`

### 2. Zookeeper集群管理脚本
### 4.2. Zookeeper集群管理脚本

命令行: `zoo <start|stop|status>`

脚本实际位于`/opt/somebottle/haspark/tools/zoo`

### 3. Hadoop集群启停脚本
### 4.3. Hadoop集群启停脚本

命令行:

1. 启动集群中所有节点的相应守护进程: `start-dfs.sh | stop-dfs.sh | start-yarn.sh | stop-yarn.sh | start-all.sh | stop-all.sh`
2. 启动本机的相应守护进程: `start-dfs-local.sh | stop-dfs-local.sh | start-yarn-local.sh | stop-yarn-local.sh | start-all-local.sh | stop-all-local.sh`

### 4. WordCount测试脚本

脚本实际位于`/opt/somebottle/haspark/tools/`中。

### 4.4. WordCount测试脚本

本脚本用于测试Hadoop集群是否能正常工作。

命令行: `test-wordcount.sh`

脚本实际位于`/opt/somebottle/haspark/tools/test-wordcount.sh`
脚本实际位于`/opt/somebottle/haspark/tools/test-wordcount.sh`

## 容器部署
## 5. 容器部署

### 1. 拉取
### 5.1. 拉取

```bash
docker pull somebottle/haspark[:tag]
```

### 2. 编写Docker Compose配置
> [:tag]可选,默认为`latest`
**首次上线**时,会创建几个Docker卷,并且将镜像内格式化过的Namenode数据复制过来。
### 5.2. 编写Docker Compose配置

随后这些Docker卷会保持映射到HDFS的`NameNode``DataNode`目录,实现HDFS数据持久化(除非你移除了这些卷)
要快速部署伪分布式集群,可以使用Docker Compose工具

> Docker Compose Volume配置文档:
> https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose

在某个新目录下建立`docker-compose.yml`

示例配置如下,1 master + 2 worker的分配。

<details>
<summary>展开查看</summary>
<summary>==> 展开查看 <==</summary>

```yaml
待更新...
version: '3'

services:
haspark-main:
image: somebottle/haspark:3.1.0
hostname: shmain
env_file: ./conf.env
environment:
- SPARK_MODE=master
volumes:
- haspark-hdfs-shmain-name:/root/hdfs/name # namenode数据
- haspark-hdfs-shmain-journal:/root/hdfs/journal
- haspark-hdfs-shmain-data:/root/hdfs/data
- ~/docker/spark/share:/opt/share # 三个容器映射到相同的共享目录
ports:
- '8080:8080'
- '8088:8088'
- '4040:4040'
- '8042:8042'
- '9870:9870'
- '19888:19888'
haspark-worker-1:
image: somebottle/haspark:3.1.0
hostname: shworker1
env_file: ./conf.env
environment:
- SPARK_MODE=worker
- SPARK_MASTER_URL=spark://shmain:7077
- SPARK_WORKER_MEMORY=1G
- SPARK_WORKER_CORES=1
volumes:
- ~/docker/spark/share:/opt/share
- haspark-hdfs-worker1-name:/root/hdfs/name # namenode数据
- haspark-hdfs-worker1-journal:/root/hdfs/journal
- haspark-hdfs-worker1-data:/root/hdfs/data # datanode数据
ports:
- '8081:8081'
haspark-worker-2:
image: somebottle/haspark:3.1.0
hostname: shworker2
env_file: ./conf.env
environment:
- SPARK_MODE=worker
- SPARK_MASTER_URL=spark://shmain:7077
- SPARK_WORKER_MEMORY=1G
- SPARK_WORKER_CORES=1
volumes:
- ~/docker/spark/share:/opt/share
- haspark-hdfs-worker2-name:/root/hdfs/name # namenode数据
- haspark-hdfs-worker2-journal:/root/hdfs/journal
- haspark-hdfs-worker2-data:/root/hdfs/data # datanode数据
ports:
- '8082:8081'
- '8089:8088'
- '9871:9870'

volumes:
haspark-hdfs-shmain-name:
haspark-hdfs-shmain-data:
haspark-hdfs-shmain-journal:
haspark-hdfs-worker1-name:
haspark-hdfs-worker1-data:
haspark-hdfs-worker1-journal:
haspark-hdfs-worker2-name:
haspark-hdfs-worker2-data:
haspark-hdfs-worker2-journal:
```
</details>
**当然你也可以直接用本仓库的`docker-compose.yml`配置**
**这其实就是本仓库的[`docker-compose.yml`](./docker-compose.yml),其搭配着[`conf.env`](./conf.env)进行配置**。

* 端口映射相关的配置可以参考[这里](#6-容器内常用端口)。

本仓库的配置使得容器**首次上线**时,会创建几个Docker卷。

### 3. 上线容器
随后这些Docker卷会保持映射到HDFS的`NameNode`和`DataNode`目录(在HA集群下还有`JournalNode`的数据目录),以实现HDFS数据持久化(除非你移除了这些卷)。

> Docker Compose Volume配置文档:
> https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose

`docker-compose.yml`所在目录中执行。
### 5.3. 上线容器

在`docker-compose.yml`所在目录中执行:

```bash
docker compose up -d
docker compose up -d # 守护模式启动
```

### 4. 停止和启动容器
### 5.4. 停止和启动容器

> ⚠️ 建议你在执行这一步前先调用`stop-all.sh`脚本停止Hadoop集群。
> ⚠️ 建议你在执行这一步前先在容器内调用`stop-all.sh`脚本停止Hadoop集群。

`docker-compose.yml`所在目录中执行
在`docker-compose.yml`所在目录中执行

```bash
docker compose stop # 停止容器
docker compose start # 启动容器
```

### 5. 下线容器

> ⚠️ 建议你在执行这一步前先调用`stop-all.sh`脚本停止Hadoop集群。
### 5.5. 下线容器

在`docker-compose.yml`所在目录中执行。

下线容器,保留HDFS数据:
1. 下线容器,保留HDFS数据:

```bash
docker compose down
```
> ⚠️ 建议你在执行这一步前先在容器内调用`stop-all.sh`脚本停止Hadoop集群。

如果你想把HDFS的数据连带清空:
```bash
docker compose down
```

(这个操作会把相关的Docker卷全部移除)
2. 如果你想把HDFS的数据连带清空:

```bash
docker compose down -v # v代表volumes
```
(这个操作会把相关的Docker卷全部移除)

```bash
docker compose down -v # v代表volumes
```

### 5.6. 启动与停止Hadoop

### 6. 启动与停止Hadoop
你可以在集群任意一个节点上执行以下脚本。

按理说容器启动后,**在完成免密登录配置后会自动执行**Hadoop集群启动脚本,如果没有的话你可以手动执行:
Hadoop集群启动脚本

```bash
start-hadoop.sh
start-all.sh
```

Hadoop集群停止脚本:

```bash
stop-hadoop.sh
stop-all.sh
```

## 容器内常用端口
## 6. 容器内常用端口

以下是本镜像创建的容器内部常用端口,你可以选择性地在`docker-compose.yml`中将一些端口映射到宿主机。

Expand All @@ -232,19 +307,19 @@ stop-hadoop.sh
* https://hadoop.apache.org/docs/r3.3.6/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml
* https://hadoop.apache.org/docs/r3.3.6/hadoop-yarn/hadoop-yarn-common/yarn-default.xml

## 数据存储目录
## 7. 数据存储目录

### HDFS
### 7.1. HDFS

* NameNode: `/root/hdfs/name`
* DataNode: `/root/hdfs/data`
* JournalNode: `/root/hdfs/journal`

> -> 建议挂载卷(Volume)到NameNode和DataNode以及JournalNode的目录上,可以保留HDFS的数据。
> -> 尤其在**高可用**集群中,要注意根据NameNode和DataNode所在容器决定挂载规则。
> -> 比如在只有NameNode的节点上可以仅挂载NameNode的卷,但若同时还有DataNode,则也要挂载DataNode的卷。
> -----> 比如在只有NameNode的节点上可以仅挂载NameNode的卷,但若同时还有DataNode,则也要挂载DataNode的卷。

### 日志
### 7.2. 日志
* Hadoop的日志位于`/opt/hadoop/logs`目录。
* 容器启动时初始化的日志位于`/opt/somebottle/haspark/logs`目录,用于调试。

Expand All @@ -262,4 +337,8 @@ stop-hadoop.sh

* [Fencing Method for ZK based HA in Hadoop](https://cornerhadoop.blogspot.com/2017/01/fencing-method-for-zk-based-ha-in-hadoop.html)

* [关于为什么fencing method还要加个无操作(`true`)的备选项](https://community.cloudera.com/t5/Support-Questions/What-s-purpose-of-shell-bin-true-in-HDFS-HA-fencer/m-p/152515/highlight/true#M114982)
* [关于为什么fencing method还要加个无操作(`true`)的备选项](https://community.cloudera.com/t5/Support-Questions/What-s-purpose-of-shell-bin-true-in-HDFS-HA-fencer/m-p/152515/highlight/true#M114982)

## License

Apache License, Version 2.0
Loading

0 comments on commit 2ddd358

Please sign in to comment.