【Hive安装配置全攻略】:打造高性能Hadoop环境的10个关键步骤
发布时间: 2024-10-26 01:51:51 阅读量: 4 订阅数: 8
![【Hive安装配置全攻略】:打造高性能Hadoop环境的10个关键步骤](https://img-blog.csdnimg.cn/a3c1cffa9da5424c9b7f2ed834816873.png)
# 1. Hive简介及其在Hadoop生态系统中的地位
Hadoop作为大数据处理的基石,为存储和处理PB级别的数据提供了解决方案。随着数据量的激增和分析需求的多样化,传统MapReduce编程模型的复杂性和开发效率的低下逐渐显现出不足。为了解决这一问题,Hive应运而生。
Hive是一个构建在Hadoop之上的数据仓库工具,它提供了类SQL查询语言HiveQL,允许熟悉SQL的开发者轻松查询和管理大数据。Hive将HiveQL语句转换为MapReduce任务,然后执行这些任务以处理数据。
在Hadoop生态系统中,Hive扮演着至关重要的角色,它桥接了传统BI(商业智能)工具和底层Hadoop技术之间的鸿沟,使得数据分析师可以利用熟悉的SQL技能在Hadoop上执行复杂的数据分析任务。通过Hive,企业能够更加快速和高效地从海量数据中提取价值,为决策提供支持。随着大数据的发展和演进,Hive的地位和作用愈发重要,成为Hadoop生态系统中的关键组件之一。
# 2. Hive的安装前准备工作
### 2.1 理解Hive的系统要求
在开始安装Hive之前,我们必须确保系统满足基本的硬件和软件要求。这是保证Hive稳定运行和高效执行查询的基础。
#### 2.1.1 硬件需求
Hive作为一个构建在Hadoop之上的数据仓库工具,其硬件需求与Hadoop集群的硬件需求相当。但Hive是用于数据仓库的查询和分析,而不是存储,所以对硬件的要求不是非常严格。
- **CPU**: 至少需要双核处理器,推荐使用更快的多核处理器来提升查询性能。
- **内存**: 最小需要1GB的RAM,但为了获得更好的性能,建议配置至少4GB或更多内存。
- **存储**: 硬盘空间需求取决于Hive表的大小和数量。一般而言,需要足够的存储空间来存放数据和执行查询所需的临时文件。
- **网络**: 稳定的网络连接是必须的,因为Hive可能会在不同的节点之间移动数据进行计算。
#### 2.1.2 软件依赖
在安装Hive之前,需要确保系统中安装了所有必要的软件依赖。
- **操作系统**: Hive支持运行在大多数Linux发行版上,比如Ubuntu、CentOS或RedHat。
- **Java**: Hive需要Java运行环境,具体版本取决于Hive的版本。例如,Hive 3.x版本需要Java 8或更高版本。
- **Hadoop**: Hive依赖于Hadoop来处理存储和计算。确保安装并正确配置了Hadoop环境,包括HDFS和MapReduce。
- **其他库**: 根据使用情况,可能还需要安装如zlib、libstdc++等库。
### 2.2 配置Java环境
Hive对Java环境有依赖,Java环境的配置是安装Hive前的一个重要步骤。
#### 2.2.1 安装Java
安装Java最直接的方式是下载相应的压缩包并解压。以下是安装Oracle Java 8的步骤:
```bash
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" ***
```
#### 2.2.2 配置JAVA_HOME环境变量
配置Java环境变量`JAVA_HOME`是确保Hive能够正确识别Java安装位置的关键步骤。可以在用户的家目录下的`.bashrc`文件中添加以下内容:
```bash
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
export PATH=$JAVA_HOME/bin:$PATH
```
之后,运行`source .bashrc`使配置生效。
### 2.3 安装并配置Hadoop环境
Hadoop是Hive运行的基础,必须首先确保Hadoop环境已经搭建并且能够正常运行。
#### 2.3.1 Hadoop的安装步骤
安装Hadoop的详细步骤可能因发行版而异,但基本流程如下:
1. 下载Hadoop。
2. 解压到指定目录。
3. 配置Hadoop环境变量。
4. 配置核心配置文件,如`hdfs-site.xml`和`core-site.xml`。
#### 2.3.2 Hadoop的核心配置文件解析
在安装Hive之前,我们需要配置Hadoop的核心配置文件。以下是核心配置文件的简要说明:
- `core-site.xml`: 包含了Hadoop的核心配置,如HDFS的默认文件系统和I/O的配置。
- `hdfs-site.xml`: 包含了HDFS的配置信息,如副本数量和HDFS的存储空间。
- `mapred-site.xml`: 配置MapReduce作业的运行参数。
- `yarn-site.xml`: 配置YARN的资源管理器,包括资源分配、调度器和容器运行时环境。
配置Hadoop集群能够确保Hive在执行查询时可以正确地与HDFS和YARN交互。
通过本章节的介绍,我们已经了解了安装Hive之前需要做的准备工作,包括硬件和软件需求的理解、Java环境的安装和配置、以及Hadoop环境的安装和配置。这些准备工作是安装Hive之前的必要步骤,为后续的Hive安装和使用打下了坚实的基础。
# 3. Hive安装流程详解
在大数据领域,Hive扮演了数据仓库的角色,使得用户能够使用类SQL语言处理存储在Hadoop文件系统中的大规模数据集。为了使Hive能够正常工作,正确的安装和配置步骤至关重要。本章节将详细介绍Hive的安装流程,从下载与安装Hive开始,逐步覆盖配置Hive环境以及初始化和启动Hive的必要步骤。
## 3.1 下载与安装Hive
### 3.1.1 选择合适的Hive版本
在开始安装Hive之前,首先需要决定使用哪个版本。Hive的版本分为稳定版和快照版。稳定版适合生产环境,因为它们通过了全面的测试并提供稳定性保证。快照版则适合开发者或测试环境,以便尽早地尝试新特性和改进。
下载Hive之前,请访问官方网站或其在GitHub上的存储库,并检查各个版本的发布说明,了解每个版本的新增特性、修复的bug和已知的兼容性问题。
### 3.1.2 安装步骤和验证
下载完合适的Hive版本后,按照以下步骤进行安装和验证。
```bash
# 解压下载的Hive压缩包
tar -xvzf apache-hive-<version>-bin.tar.gz
# 进入解压后的Hive目录
cd apache-hive-<version>-bin
# 验证安装
bin/hive --version
```
上述命令会显示Hive的版本信息。如果一切正常,Hive安装成功。
## 3.2 配置Hive环境
### 3.2.1 编辑hive-site.xml配置文件
Hive使用`hive-site.xml`文件来定义特定于Hive的配置设置。我们需要编辑此文件来设置数据仓库的存储位置、JDBC连接信息等。
```xml
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost/metastore</value>
<description>连接到数据库的JDBC URL</description>
</property>
<!-- 其他配置项 -->
</configuration>
```
### 3.2.2 配置Metastore
Metastore是Hive的元数据存储库,用于存储关于表结构、字段信息和分区等数据。在Hive中进行任何操作之前,都需要正确配置Metastore。
```sh
# 使用内置的Derby数据库
bin/schematool -initSchema -dbType derby
# 使用MySQL数据库作为Metastore(需要先配置相应的JDBC驱动和URL)
bin/schematool -initSchema -dbType mysql
```
## 3.3 初始化和启动Hive
### 3.3.1 初始化数据库
在首次运行Hive之前,需要初始化Metastore数据库。
```sh
bin/schematool -initSchema -dbType mysql
```
如果之前已经使用Derby作为Metastore的数据库,可以使用以下命令进行转换。
```sh
bin/schematool -convertTo <mysql | derby>
```
### 3.3.2 启动和连接Hive
现在,我们已经完成了Hive的安装和配置,可以启动Hive并进行连接测试。
```sh
bin/hive
```
如果一切顺利,终端上将显示Hive命令行界面,您可以开始创建表和查询数据了。
为了方便读者理解和操作,以下是Hive安装流程的表格总结。
| 步骤 | 描述 | 命令示例或说明 |
|------------|--------------------------------------------------------------------------------------|-----------------------------------------|
| 下载Hive | 访问官方网站或GitHub存储库,下载所需版本的Hive压缩包。 | `wget ***<version>/apache-hive-<version>-bin.tar.gz` |
| 解压Hive | 使用tar命令解压下载的Hive压缩包。 | `tar -xvzf apache-hive-<version>-bin.tar.gz` |
| 配置环境变量 | 将Hive的bin目录添加到PATH环境变量。 | `export PATH=$PATH:<hive-install-dir>/bin` |
| 初始化Metastore | 根据所选数据库类型初始化Metastore数据库。MySQL需要提供JDBC URL和用户名密码。 | `bin/schematool -initSchema -dbType mysql` |
| 启动Hive | 运行Hive命令行界面。 | `bin/hive` |
以上表格列出了Hive安装的关键步骤,为读者提供了一个快速参考指南。
在安装Hive时,可能需要根据实际使用场景进行不同的配置。对于生产环境,推荐配置一个外部的Metastore,并使用外部数据库(如MySQL或PostgreSQL)来存储Hive的元数据。这样做的好处是Hive服务和元数据存储分离,便于维护和扩展。
# 4. Hive的高级配置和性能优化
## 4.1 配置Hive的执行引擎
### 4.1.1 Tez和Spark执行引擎的选择
选择合适的执行引擎是优化Hive性能的重要一步。Hive可以使用多种执行引擎,包括MapReduce、Tez和Spark。MapReduce是Hadoop最初使用的工作负载管理器,但因其执行效率较低,通常在处理复杂查询时性能不如Tez和Spark。
Tez是基于MapReduce构建的,优化了任务间的依赖关系,减少了不必要的磁盘I/O操作,大幅提升了查询性能。Tez特别适合执行包含多个阶段的复杂查询。
Spark执行引擎则完全绕过了Hadoop的MapReduce层,通过内存计算提高了效率,尤其适合于需要迭代计算的任务。在处理大数据量和复杂计算时,Spark通常能提供更快的响应时间。
根据应用场景和数据规模的不同,可以选择最适合的执行引擎。对于批处理场景,Tez往往能提供更好的性能。而在需要实时处理或者迭代计算的场景,Spark可能是更好的选择。
### 4.1.2 配置执行引擎的参数优化
配置执行引擎的参数优化对于提升Hive性能至关重要。每种执行引擎都有自己的配置参数,以满足不同的性能需求。
对于Tez,可以通过调整`hive.tez.container.size`参数来控制Tez容器的内存大小,这对于处理大量数据的查询尤为重要。`hive.tez.java.opts`参数则用来指定Java堆大小,它影响了Tez任务的性能。
对于Spark,参数`spark.executor.memory`影响了执行器的内存大小,而`spark.executor.cores`则定义了执行器使用的CPU核心数量。合理配置这些参数可以充分利用集群资源,提高查询效率。
在实际操作中,你需要根据集群资源和工作负载进行调优,有时还需要配合执行计划的查看来调整参数,达到最佳性能。
### 4.2 性能优化技巧
#### 4.2.1 分区和桶策略的使用
分区和桶是Hive用来提高查询效率的两种策略。分区是将表中的数据按照某列或多列的值分散存储在不同的目录下,查询时Hive只会读取相关的分区,从而减少不必要的数据扫描。
桶策略则是将数据进一步分散存储在多个文件中,可以用来实现数据的随机采样。通过`CLUSTERED BY`和`DISTRIBUTED BY`语句,可以在创建表时或之后对数据进行桶化。
在使用分区和桶策略时,合理的分区键和桶的数量选择非常关键。分区键的选择应避免数据倾斜,而桶的数量则需要根据数据量大小和集群的处理能力进行权衡。
#### 4.2.2 索引和存储格式的选择
索引可以加快查询速度,尤其是对于数据量庞大的表。Hive支持多种类型的索引,例如位图索引、Bloom Filter和Compact索引等。每种索引都有其特定的使用场景,例如位图索引适合于基数较低的列。
存储格式的选择也对性能有影响。Hive支持多种存储格式,包括TextFile、SequenceFile、Parquet和ORC等。ORC格式因其高度压缩和列式存储的特性,在读写效率上往往优于其他格式,尤其适合大数据量的分析。
选择合适的索引和存储格式,需要根据查询类型、数据特性以及对压缩率和读写速度的要求进行综合考量。
### 4.3 监控和故障排除
#### 4.3.1 日志文件分析
日志文件是Hive性能监控和故障排除的宝贵资源。通过分析Hive的服务器日志、客户端日志和Hadoop的YARN日志,可以找到查询执行的瓶颈和错误原因。
服务器日志提供了关于查询执行的详细信息,例如任务执行的时间、资源使用情况以及作业失败的原因。客户端日志则可以帮助定位用户操作或配置问题。
在分析日志时,特别要注意错误信息、警告信息和时间戳。错误信息有助于快速定位问题,而警告信息和时间戳则可以帮助你了解在何时何地发生了问题。
#### 4.3.2 常见问题的解决方法
Hive在使用过程中可能会遇到各种问题,常见的问题包括数据倾斜、低效的查询计划、资源不足等。
数据倾斜问题通常需要通过调整表的分区策略、增加更多的桶或者使用倾斜连接来解决。低效的查询计划则需要通过查看执行计划并根据实际情况调整表的存储格式或索引。
资源不足的问题,如内存不足或CPU限制,可以通过增加任务的资源请求或者优化查询计划来解决。另外,适当调整执行引擎的参数也有助于解决资源问题。
在处理这些问题时,Hive社区提供了大量的工具和文档资源。利用这些资源进行故障排除,可以有效解决Hive使用中遇到的问题。
# 5. Hive数据仓库的操作实践
## 5.1 数据定义语言(DDL)的使用
### 5.1.1 创建和修改表结构
在Hive中,数据定义语言(DDL)是一种用于定义数据结构的语言,如表、分区和桶。创建表是使用DDL中最常见的任务之一。
```sql
CREATE TABLE IF NOT EXISTS employees (
id INT,
name STRING,
salary FLOAT,
department STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
```
在上述示例中,我们创建了一个名为`employees`的新表,它包含四个字段:`id`, `name`, `salary`, 和`department`。这些字段分别被定义为整型(INT)、字符串(STRING)、浮点型(FLOAT)和字符串类型(STRING)。此表使用逗号作为字段分隔符,并以文本格式存储。
表创建后,可能会出现需要修改表结构的情况。例如,要向`employees`表中添加一个新字段`age`:
```sql
ALTER TABLE employees ADD COLUMNS (age INT);
```
此语句将向现有表添加一个新的整型字段`age`。Hive的DDL还支持修改字段的数据类型、重命名字段以及删除字段,使结构修改变得灵活。
### 5.1.2 管理分区和桶
分区(Partitioning)和桶(Buckets)是Hive优化查询性能的关键特性。分区允许将数据组织在不同的部分中,通常根据某些经常用于查询条件的字段。而桶则是将数据进一步细分为多个文件。
假设我们需要根据`department`字段对`employees`表进行分区:
```sql
ALTER TABLE employees PARTITION BY (department);
```
如果数据已经被加载到表中,可以通过`MSCK REPAIR TABLE`命令让Hive识别已经存在的分区:
```sql
MSCK REPAIR TABLE employees;
```
对于桶操作,可以使用以下命令对数据进行分桶处理:
```sql
SET hive.enforce.bucketing = true;
SET mapreduce.job.reduces = 4;
INSERT OVERWRITE TABLE employees SELECT * FROM employees TABLESAMPLE(BUCKET 4 OUT OF 4 ON id) SORT BY id;
```
上述命令中,`hive.enforce.bucketing`参数启用桶强制。`mapreduce.job.reduces`设置执行MapReduce任务时的Reducer数量,这个值通常应该是桶数的倍数。`TABLESAMPLE`操作用于选择特定的样本桶,这里是从4个桶中抽取所有数据,并根据`id`字段排序。
通过DDL管理和优化表结构,我们可以有效地组织和查询大量数据。接下来将探讨如何使用数据操作语言(DML)来执行实际的数据操作。
## 5.2 数据操作语言(DML)实践
### 5.2.1 加载数据到Hive表
Hive中的数据操作语言(DML)涉及数据的加载、查询和更新。加载数据是数据仓库中常见的操作之一。以下是向Hive表中加载数据的示例:
```bash
hadoop fs -put /user/data/employees.csv /user/hive/warehouse/employees;
```
在这个示例中,我们使用Hadoop的`fs`命令将本地文件系统中的`employees.csv`文件上传到了HDFS中的`/user/hive/warehouse/employees`路径,Hive默认将表数据存储在此位置。
加载数据后,需要将数据加载(或装载)到Hive表中,这通常通过HiveQL完成:
```sql
LOAD DATA INPATH '/user/data/employees.csv' INTO TABLE employees;
```
此命令将HDFS中指定位置的文件加载到`employees`表中。如果Hive表和数据文件存储在同一个路径下,则可以省略`INPATH`关键字。
### 5.2.2 查询数据和聚合操作
在数据仓库中,执行数据查询是实现数据分析和生成报告的关键。HiveQL提供了强大的查询功能,几乎可以执行所有SQL-92标准的查询。
对于简单的数据查询,可以如下操作:
```sql
SELECT name, salary FROM employees WHERE department = 'Engineering';
```
该查询将从`employees`表中提取工程师部门的所有员工姓名和薪水。
更复杂的查询可能需要使用聚合函数,例如计算平均薪水:
```sql
SELECT department, AVG(salary) AS average_salary FROM employees GROUP BY department;
```
该语句计算每个部门的平均薪水,并按部门分组。
Hive还支持使用窗口函数进行更高级的数据分析。这里是一个使用窗口函数`ROW_NUMBER()`的例子,用于为每个部门的员工按薪水排序编号:
```sql
SELECT id, name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rank
FROM employees;
```
查询执行后,每个部门的员工将根据薪水降序排列,并获得一个基于此顺序的排名。
通过使用HiveQL的DML,可以轻松地实现数据加载、查询和聚合操作,这些操作是数据仓库实现数据处理和分析的基础。
## 5.3 数据仓库的最佳实践
### 5.3.1 数据模型设计
设计高效的数据模型是构建数据仓库时一个关键步骤。良好的数据模型不仅简化了数据管理,而且还可以提升查询性能。
在Hive中,数据模型设计通常涉及星型模式和雪花模式,这两种模式都是数据仓库设计中常用的维度建模方法。
星型模式使用一个或多个事实表(通常是大型表格,存储大量的度量数据)和一些维度表(存储有助于分析事实数据的描述信息)。星型模式特别适合于OLAP分析。
```mermaid
graph TD;
事实表 --连接--> 维度表A;
事实表 --连接--> 维度表B;
事实表 --连接--> 维度表C;
维度表A --与--> 维度表B;
维度表B --与--> 维度表C;
```
雪花模式是星型模式的一个变种,其中维度表进一步规范化为更小的表。这些表通过外键关联,形成一个类似雪花的结构。
```mermaid
graph TD;
事实表 --连接--> 维度表;
维度表 --连接--> 维度表细分;
维度表细分 --连接--> 维度表细分之细分;
```
### 5.3.2 数据处理和ETL流程
ETL(Extract, Transform, Load)是数据仓库的核心概念之一。Hive提供了一系列工具来实现ETL流程。
数据提取(Extract)是从各种数据源中导入数据到Hive中。Hive支持多种数据格式,如文本文件、JSON、CSV以及Parquet和ORC列式存储格式。
数据转换(Transform)涉及到数据清洗、格式化和聚合等操作。HiveQL提供了强大的数据转换能力,可以使用用户定义函数(UDF)和窗口函数来完成复杂的数据转换。
数据加载(Load)是将清洗和转换后的数据加载到目标表。数据加载可以通过HiveQL的`INSERT OVERWRITE TABLE`或`INSERT INTO TABLE`命令来实现。
在Hive中实现ETL流程通常涉及编写HiveQL脚本,这些脚本可以作为Hadoop作业提交执行。在某些情况下,可以使用更复杂的工具如Apache NiFi或Apache Airflow来管理Hive的ETL流程。
通过遵循这些最佳实践,可以有效地管理和优化Hive数据仓库,以便更高效地进行数据处理、分析和报告。
# 6. Hive在大数据环境中的扩展应用
## 6.1 Hive与Hadoop生态系统组件的集成
随着Hadoop生态系统的发展,Hive作为其核心组件之一,不仅自身性能得到提升,其与其他组件的集成也越发紧密。通过与Hadoop生态系统中的其他组件集成,Hive能够更好地处理大规模数据集,实现更加高效的数据仓库架构。
### 6.1.1 与HBase集成
HBase是一个开源的、非关系型、分布式数据库,它能够为Hive提供强大的实时读写能力。集成HBase与Hive主要有以下两个方面的优势:
1. **数据存储能力扩展**:HBase作为一个列式存储数据库,可以在保持对海量数据快速读写的同时,支持超大表结构。Hive可以利用HBase的存储能力来存储某些特定的数据集,尤其是那些需要高效实时访问的动态数据集。
2. **实时查询能力增强**:通过Hive-HBase集成,Hive能够利用HBase的快速检索能力来执行高效的实时查询,这对于需要实时反馈结果的业务场景尤为重要。
### 6.1.2 与Oozie工作流集成
Oozie是Hadoop的一个用于工作流调度的子系统,能够处理Hadoop作业的执行。将Hive与Oozie集成,可以实现复杂数据处理流程的自动化,提高数据处理效率。主要集成方法如下:
1. **工作流设计**:通过Oozie工作流设计,可以将Hive查询任务编排到整个数据处理流程中。例如,可以在数据清洗、转换和加载(ETL)任务之后,立即执行Hive查询以获取实时的分析结果。
2. **任务调度和监控**:Oozie提供了强大的任务调度和监控能力,可以按照预定的时间表执行Hive作业,并且实时监控任务的执行状态。这对于维护大规模数据处理的稳定性和可靠性至关重要。
## 6.2 构建高效的数据仓库架构
在大数据环境中,构建一个高效的数据仓库架构是处理和分析海量数据的关键。Hive在其中扮演着重要角色,无论是通过其自身的优化,还是与其他组件的结合,都能够为构建高效数据仓库架构提供支持。
### 6.2.1 数据仓库的扩展设计模式
Hive支持多种扩展设计模式来优化数据仓库架构:
1. **星型模式和雪花模式**:这两种模式都是数据仓库中常见的维度建模方法,可以将数据组织成易于分析的结构,便于实现高效的查询。
2. **分层架构**:通过将数据分为操作数据层、数据仓库层和数据集市层,Hive可以帮助实现数据的多级存储和处理,以及更细致的数据访问控制。
### 6.2.2 使用Hive构建数据湖
数据湖是一种数据存储策略,旨在存储大量的原始数据,包括结构化、半结构化和非结构化数据。Hive可以被用来构建和查询数据湖:
1. **数据存储**:Hive表可以存储在HDFS上,从而实现数据湖的存储需求。Hive通过外部表的概念,可以方便地访问存储在HDFS上各种格式的数据。
2. **数据查询和分析**:Hive提供了一种结构化查询语言,能够对存储在数据湖中的数据执行复杂的查询和分析任务。这使得对原始数据的快速分析成为可能。
## 6.3 安全和治理
在数据仓库的部署和使用过程中,数据安全和治理是不容忽视的部分。Hive也在不断完善其安全机制和元数据治理功能,以适应日益严格的合规要求和安全需求。
### 6.3.1 Hive的数据安全策略
为了保护数据不被非法访问,Hive提供了多种安全措施:
1. **权限管理**:Hive支持基于角色的访问控制(RBAC),可以对不同的用户和组进行精细的权限分配。
2. **数据加密**:为了保障数据传输和存储的安全,Hive支持与Hadoop生态系统的安全组件(如Kerberos)集成,实现数据的加密传输和存储。
### 6.3.2 元数据管理和治理
元数据管理是数据治理的一个重要组成部分。Hive提供了元数据管理工具,方便用户管理Hive环境中的数据结构、数据血缘等信息:
1. **元数据存储**:Hive将元数据存储在关系型数据库中,如MySQL、Derby等,并提供了便捷的接口来查看和维护这些元数据。
2. **数据血缘追踪**:数据血缘是指数据的来源和去向,Hive通过元数据管理,可以帮助用户追踪数据在整个生命周期中的处理过程,这对维护数据质量和进行故障排除非常重要。
通过上述的集成应用、架构构建和安全治理,Hive在大数据环境中不仅能够有效地存储、处理和分析数据,还能够提供强有力的安全和治理支持,为企业的数据驱动决策提供坚实的后盾。
0
0