当前位置:   article > 正文

大数据平台--Hive入门1_hive数据开发平台

hive数据开发平台

大数据平台–Hive入门1

一.大数据平台以及ETL介绍

1,ETL简介

ETLExtraction-Transformation-Loading,即数据抽取(Extract)转换(Transform),**装载(Load)**的过程,它是构建数据仓库的重要环节。

ETL是将业务系统的数据经过抽取,清洗转换之后加载到数据仓库的过程,目的是将企业中分散,零乱,标准不统一的数据整合到一起,为企业的决策提供分析依据,ETL是BI项目重要的一个环节,通常情况下,在BI项目中ETL会花掉整个项目的1/3的时间,ETL设计的好坏直接关系到BI项目的成败。

(1)数据抽取:把不同的数据源数据抓取过来,存到某个地方;

(2)数据清洗:过滤那些不符合要求的数据或者修正数据之后再进行抽取

  • 不完整的数据:比如数据里一些应该有的信息缺失,需要补全后再进行抽取;
  • 错误的数据:比如字符串数据后面有一个回车操作,日期格式不正确,日期越界等,需要修正再抽取;
  • 重复的数据:重复的数据记录的所有字段,需要去重。

(3)数据转换:不一致的数据转换,比如同一个供应商在结算系统的编码是XX001,而在CRM中编码是YY001,统一编码,实现由多种方法:

  • 借助ETL工具(如Oracle的OWB,SQL Server的DTS,SQL Server的SSIS服务,Informatic等等)实现;
  • SQL方式实现;
  • ETL工具和SQL相结合------Hive

借助工具可以快速建立起ETL工程,屏蔽了复杂的编码任务,提高了速度,降低了难度,但是缺少灵活性。

SQL的方法是优点是灵活,提高ETL运行效率,但是编码复杂,对技术要求比较高。

ETL和SQL结合综合了前二者的优点,会极大地提高ETL的开发速度和效率。

ELK简介

ELK是三个开源软件的缩写,分别表示:Elasticsearch,Lodstash,Kibana,它们都是开源软件。

新增一个FileBeat,他是一个轻量级的日志收集处理工具(Agent),Filebeat占用资源少,适合于在各个服务器上收集日志后传输给Logastash。

Logstash:

主要是用来日志的收集,分析,过滤日志的工具,支持大量的数据获取方式,一般的工作方式为C/S架构,Client端安装在需要收集日志的主机上,Server端负责将收到的各个节点日志进行过滤修改等操作在一并发往elasticsearch上去。

Kibana也是一个开源,免费的工具,kibana可以为Logstash和Elasticsearch提供日志分析友好的Web界面,可以帮助汇总,分析和搜索重要的日志数据。

Filebeat隶属于Beats,目前Beats包含4种工具:

  • Packetbeat:搜集网络流量数据;

  • Topbeat:搜集系统,进程和文件系统级别的CPU和内存使用情况;

  • Filebeat:搜集文件数据;

  • Winlogbeat:搜集Windows事件日志数据。

2,大数据平台概述

大数据平台架构

在这里插入图片描述

大数据系统数据流向图

在这里插入图片描述

大数据平台架构概述

数据抽取Canal/Sqoop(主要解决数据库数据接入问题),还有大量的数据采用Flume解决方案。

数据存储HDFS(文件存储),HBase(K,V存储),kafka(消息存储)。

调度:采用YARN的统一调度以及Kubernetes的基于容器的管理和调度技术。

计算分析MRHIVEStormSparkKylin以及深度学习平台比如CaffeTensorflow等等(flink)。

应用平台:交互分析sql,多维分析:时间,地域等等。

可视化:数据分析tableau,阿里datavhchartsecharts

数据应用就是指数据的业务。

二.Hive概述

  • Hive是一个基于Hadoop文件系统之上的数据仓库架构,他为数据仓库的管理提供了许多功能:数据ETL(抽取,转换和加载)工具,数据存储管理和大型数据集的查询和分析能力。
  • Hive定义了类SQL语言–Hive QL,HQL允许用户进行和SQL相似的操作,它可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能,还允许开发人员方便地使用Mapper和Reducer操作,可以将SQL语句转换为MapReduce任务运行,这对MapReduce框架来说是一个强有力的支持。

在这里插入图片描述

Hive体系结构

在这里插入图片描述

用户接口:Client

  • CLI(hive shell),JDBC/ODBC(java访问hive),WEBUI(浏览器访问hive)

元数据:MetaStore

  • 元数据包括:表名,表所属的数据库(默认是default),表的拥有者,列/分区字段,表的类型(是否是外部表,管理表),表的数据所在目录等。
  • 默认存储在自带的derby数据库中,推荐使用采用MySql

Hadoop:使用HDFS进行存储,使用MapReduce进行计算

驱动器(Driver)

1.解析器

  • 将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具完成,比如antlr;对AST进行语法分析,比如表是否存在,字段是否存在,SQL语义是否有误(比如select中被判定为聚合的字段在group by中是否有出现)。

2.编译器:将AST编译成逻辑执行计划;

3.优化器:对逻辑执行计划进行优化;

4.执行器:把逻辑执行计划转换成可以运行的物理计划,对于Hive来说,就是MR/TEZ/Spark;

在这里插入图片描述

  • Hive的数据存储基于Hadoop HDFS
  • Hive没有专门的数据存储格式
  • Hive默认可以直接加载文本文件(TextFile),还支持SequenceFile,RCFile
  • 创建表时,指定Hive的列分隔符和行分隔符,Hive即可解析数据
  • 存储结构主要包括:数据库,文件,表,视图,索引。

三.Hive安装

1.解压安装包

[root@hadoop01 software]# ls
apache-hive-1.2.1-bin.tar.gz  hadoop-2.7.6.tar.gz  jdk-8u211-linux-x64.rpm
[root@hadoop01 software]# tar -zxf apache-hive-1.2.1-bin.tar.gz -C /opt/modules/apache/
[root@hadoop01 software]# ll /opt/modules/apache/
total 8
drwxr-xr-x  8 root  root 4096 Jun  9 09:34 apache-hive-1.2.1-bin
drwxr-xr-x 10 20415  101 4096 Jun  5 13:26 hadoop-2.7.6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.修改配置文件

[root@hadoop01 conf]# cp hive-env.sh.template hive-env.sh
[root@hadoop01 conf]# vi hive-env.sh
  • 1
  • 2
# Set HADOOP_HOME to point to a specific hadoop install directory
HADOOP_HOME=/opt/modules/apache/hadoop-2.7.6

# Hive Configuration Directory can be controlled by:
export HIVE_CONF_DIR=/opt/modules/apache/hive-1.2.1/conf
  • 1
  • 2
  • 3
  • 4
  • 5

3.配置Hive环境变量

[root@hadoop01 hive-1.2.1]# vi /etc/profile
  • 1
export HIVE_HOME=/opt/modules/apache/hive-1.2.1
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin
  • 1
  • 2
[root@hadoop01 hive-1.2.1]# source /etc/profile
  • 1

4.创建Hive数据仓库存放位置和修改配置文件

[root@hadoop01 conf]# cp hive-default.xml.template hive-default.xml
  • 1

在HDFS文件系统上创建如下目录

[root@hadoop01 ~]# hdfs dfs -mkdir /tmp
#如果tmp目录已存在就不需要创建了
[root@hadoop01 ~]# hdfs dfs -mkdir -p /user/hive/warehouse
#修改目录的权限
[root@hadoop01 ~]# hdfs dfs -chmod g+w   /tmp
[root@hadoop01 ~]# hdfs dfs -chmod g+w   /user/hive/warehouse
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5.启动Hive

[root@hadoop01 conf]# hive

Logging initialized using configuration in jar:file:/opt/modules/apache/hive-1.2.1/lib/hive-common-1.2.1.jar!/hive-log4j.properties
hive> 
  • 1
  • 2
  • 3
  • 4

6.hive常用命令

hive> show databases
    > ;
OK
default
Time taken: 0.788 seconds, Fetched: 1 row(s)
hive> use default;
OK
Time taken: 0.051 seconds
hive> show tables;
OK
Time taken: 0.044 seconds
#创建数据库
hive> create database test01;
OK
Time taken: 0.099 seconds
hive> show databases;
OK
default
test01
Time taken: 0.012 seconds, Fetched: 2 row(s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这里插入图片描述

四.hive客户端基础语句

hive数据类型

  • 数值型:tinyint,smallint,int(常用),bigint,
  • 字符型:char,varchar,string(常用)
  • 时间型:date,timestamp,
  • 其他型:boolean,
  • 复杂型:arrays(下标从0开始),maps(K,V),structs,union

hive创建表

create table ta_test01(
	id int,
	name string,
);
---------------------------------------------------------------------------------------------------
hive> create table ta_test(
    > id int,
    > name string
    > );
OK
Time taken: 0.288 seconds
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述

加载数据
创建数据
[root@hadoop01 ~]# cd datas
[root@hadoop01 datas]# vi test
  • 1
  • 2
1	nike
2	mark
3	jerry
4	lucy
5	zhuzhu
  • 1
  • 2
  • 3
  • 4
  • 5
load data local inpath '/root/datas/test' into table ta_test;
  • 1
加载数据
hive> load data local inpath '/root/datas/test' into table ta_test;
Loading data to table test01.ta_test
Table test01.ta_test stats: [numFiles=1, totalSize=38]
OK
Time taken: 1.362 seconds
  • 1
  • 2
  • 3
  • 4
  • 5
查询数据
select * from ta_test;
  • 1
hive> select * from ta_test;
OK
NULL	NULL
NULL	NULL
NULL	NULL
NULL	NULL
NULL	NULL
Time taken: 0.619 seconds, Fetched: 5 row(s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

注意:Hive必须指定行分隔符列分隔符

如果数据的分割符与表的分割符不一致就会解析数据失败;

指定分隔符(默认的分割符是:\001(^A)):ctrl+v,ctrl+a
vi test
  • 1
1^Anike
2^Amark
3^Ajerry
4^Alucy
5^Azhuzhu
  • 1
  • 2
  • 3
  • 4
  • 5

加载数据,查看数据

hive> load data local inpath '/root/datas/test' into table ta_test;
Loading data to table test01.ta_test
Table test01.ta_test stats: [numFiles=2, totalSize=76]
OK
Time taken: 0.479 seconds
hive> select * from ta_test;
OK
NULL	NULL
NULL	NULL
NULL	NULL
NULL	NULL
NULL	NULL
1	nike
2	mark
3	jerry
4	lucy
5	zhuzhu
Time taken: 0.053 seconds, Fetched: 10 row(s)
hive> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

分割符:"\t"、","、" "、“A"、"B”、…

指定分隔符
#数据以制表符分割
create table ta_test01(
	id int,
	name string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";
  • 1
  • 2
  • 3
  • 4
  • 5

创建数据

vi test01
---------------------------------------------------------------------------------------------------
1       zhuzhu
2       nike
3       mike
4       jack
5       lucy
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

创建表

hive> create table ta_test01(
    > id int,
    > name string
    > )ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";
OK
Time taken: 0.161 second
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

加载数据,查看数据

hive> load data local inpath '/root/datas/test01' into table ta_test01;
Loading data to table test01.ta_test01
Table test01.ta_test01 stats: [numFiles=1, totalSize=37]
OK
Time taken: 0.257 seconds
hive> select * from ta_test01;
OK
1	zhuzhu
2	nike
3	mike
4	jack
5	lucy
Time taken: 0.081 seconds, Fetched: 5 row(s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

五.修改元数据存储的数据库

如果使用默认的derby数据库,发现不能同时开启多个hive shell客户端,需要修改hive元数据存储的数据库。

hive支持的元数据存储的数据库有derby,mssql,mysql,oracle,postgres

采用MySql数据库

1.在线安装MySql数据库
#查看系统是否安装mysql
[root@hadoop01 upgrade]# rpm -qa|grep mysql
mysql-libs-5.1.71-1.el6.x86_64
#卸载已有的mysql数据库
[root@hadoop01 upgrade]# rpm -e --nodeps mysql-libs-5.1.71-1.el6.x86_64
#yum安装MySql
[root@hadoop01 upgrade]# yum -y install mysql-server
#启动MySql
[root@hadoop01 upgrade]# service mysqld start
#设置mysql的root用户密码
[root@hadoop01 upgrade]# mysqladmin -u root password '971102
#登陆mysql
[root@hadoop01 upgrade]# mysql -uroot -p971102
#设置远程登陆权限
mysql> grant all privileges on *.* to 'root'@'%' identified by '971102' with grant option;
mysql> flush privileges;
[root@hadoop01 upgrade]# service mysqld restart
#设置MySql服务开机自启动
[root@hadoop01 upgrade]# chkconfig mysqld on
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

MySQL的安装信息:

  • 执行的脚本:/usr/bin/mysql
  • 文件存储的路径:/var/lib/mysql
  • mysql配置文件:/etc/my.conf
2.配置hive-site.xml
vi hive-site.xml
  • 1
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!--连接数据库的url-->
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://hadoop01:3306/metastore_db?createDatabaseIfNotExist=true</value>
    <description>JDBC connect string for a JDBC metastore</description>
  </property>
<!--连接数据库的驱动-->
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    <description>Driver class name for a JDBC metastore</description>
  </property>
<!--连接数据库的用户名-->
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
    <description>Username to use against metastore database</description>
  </property>
<!--连接数据库的密码-->
  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>971102</value>
    <description>password to use against metastore database</description>
  </property>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

3.将数据库驱动jar包放到hive的lib目录下

[root@hadoop01 hive-1.2.1]# ls lib|grep mysql
mysql-connector-java-5.1.27-bin.jar
  • 1
  • 2

4.开启Hive

[root@hadoop01 hive-1.2.1]# hive

Logging initialized using configuration in jar:file:/opt/modules/apache/hive-1.2.1/lib/hive-common-1.2.1.jar!/hive-log4j.properties
hive> 
#如果遇到报错不能启动hive shell,则在mysql中开启允许你的主机名登陆mysql
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

在MySql的metastore_db数据库中:

  • DBS:存储hive的所有数据库信息;
  • TBLS:存储hive的所有数据表信息。
hive> create table test01(
    > id int,
    > name string);
OK
Time taken: 0.259 seconds
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

hive> create database db_test01;
OK
Time taken: 0.047 seconds
hive> create table test02(
    > id int,
    > name varchar(20));
OK
Time taken: 0.066 seconds
hive> use db_test01;
OK
Time taken: 0.023 seconds
hive> create table test01(
    > id int,
    > name string,
    > age int);
OK
Time taken: 0.063 seconds
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述

在这里插入图片描述

六.Hive操作命令

描述表信息:

  • desc table_name;

  • hive> desc test01;
    OK
    id                  	int                 	                    
    name                	string              	                    
    Time taken: 0.133 seconds, Fetched: 2 row(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • desc extended table_name;

  • hive> desc extended test01;
    OK
    id                  	int                 	                    
    name                	string              	                    
    	 	 
    Detailed Table Information	Table(tableName:test01, dbName:default, owner:root, createTime:1560062424, lastAccessTime:0, retention:0, sd:StorageDescriptor(cols:[FieldSchema(name:id, type:int, comment:null), FieldSchema(name:name, type:string, comment:null)], location:hdfs://hadoop01:8020/user/hive/warehouse/test01, inputFormat:org.apache.hadoop.mapred.TextInputFormat, outputFormat:org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat, compressed:false, numBuckets:-1, serdeInfo:SerDeInfo(name:null, serializationLib:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, parameters:{serialization.format=1}), bucketCols:[], sortCols:[], parameters:{}, skewedInfo:SkewedInfo(skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}), storedAsSubDirectories:false), partitionKeys:[], parameters:{transient_lastDdlTime=1560062424}, viewOriginalText:null, viewExpandedText:null, tableType:MANAGED_TABLE)	
    Time taken: 0.085 seconds, Fetched: 4 row(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • desc formatted table_name;

  • hive> desc formatted test01;
    OK
    # col_name            	data_type           	comment             
    	 	 
    id                  	int                 	                    
    name                	string              	                    
    	 	 
    # Detailed Table Information	 	 
    Database:           	default             	 
    Owner:              	root                	 
    CreateTime:         	Sun Jun 09 14:40:24 CST 2019	 
    LastAccessTime:     	UNKNOWN             	 
    Protect Mode:       	None                	 
    Retention:          	0                   	 
    Location:           	hdfs://hadoop01:8020/user/hive/warehouse/test01	 
    Table Type:         	MANAGED_TABLE       	 
    Table Parameters:	 	 
    	transient_lastDdlTime	1560062424          
    	 	 
    # Storage Information	 	 
    SerDe Library:      	org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe	 
    InputFormat:        	org.apache.hadoop.mapred.TextInputFormat	 
    OutputFormat:       	org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat	 
    Compressed:         	No                  	 
    Num Buckets:        	-1                  	 
    Bucket Columns:     	[]                  	 
    Sort Columns:       	[]                  	 
    Storage Desc Params:	 	 
    	serialization.format	1                   
    Time taken: 0.096 seconds, Fetched: 27 row(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

修改表

  • alter table table_name01 rename to table_name02(修改表名)

  • hive> show tables;
    OK
    hadoop01
    hadoop02
    Time taken: 0.752 seconds, Fetched: 2 row(s)
    hive> alter table hadoop01 rename to ha01;
    OK
    Time taken: 0.249 seconds
    hive> alter table hadoop02 rename to ha02;
    OK
    Time taken: 0.118 seconds
    hive> show tables;
    OK
    ha01
    ha02
    Time taken: 0.028 seconds, Fetched: 2 row(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • alter table t_name add columns (c_name1 c_type1,c_name2 c_type2,…);(新增列)

  • hive> desc ha01;
    OK
    id                  	int                 	                    
    name                	string              	                    
    Time taken: 0.109 seconds, Fetched: 2 row(s)
    hive> alter table ha01 add columns (age int,gender string);
    OK
    Time taken: 0.185 seconds
    hive> desc ha01;
    OK
    id                  	int                 	                    
    name                	string              	                    
    age                 	int                 	                    
    gender              	string              	                    
    Time taken: 0.088 seconds, Fetched: 4 row(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • alter table t_name add columns (c_name1 c_type1 comment ‘注释’,c_name2 c_type2,…);(新增列并给列加上注释)

  • alter table t_name CHANGE col_old_name col_new_name col_type;(修改列)

  • hive> desc ha01;
    OK
    id                  	int                 	                    
    name                	string              	                    
    age                 	int                 	                    
    gender              	string              	                    
    Time taken: 0.088 seconds, Fetched: 4 row(s)
    hive> alter table ha01 CHANGE gender sex varchar(4);
    OK
    Time taken: 0.135 seconds
    hive> desc ha01;
    OK
    id                  	int                 	                    
    name                	string              	                    
    age                 	int                 	                    
    sex                 	varchar(4)          	                    
    Time taken: 0.076 seconds, Fetched: 4 row(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • alter table t_name CHANGE col_old_name col_new_name col_type after col_name02;(修改列并将该列放置到某一列的后面)

  • alter table t_name CHANGE col_old_name col_new_name col_type first;(修改列并将该列放置在第一列)

  • alter table t_name REPLACE COLUMNS (col_name1 com_type1 [comment ‘注释’],col_name1 com_type1 [comment ‘注释’], …)(替换列,不能指定替换,将表完全替换)

  • TRUNCATE TABLE t_name;(清空表数据)

  • DROP TABLE t_name;(删除表)

  • DROP DATABASE db_name;(删除数据库)

  • DROP DATABASE db_name CASCADE;(强制删除表)

  • show functions;(查看Hive自带的函数)

  • desc function f_name;(查看函数的描述信息)

  • hive> desc function count;
    OK
    count(*) - Returns the total number of retrieved rows, including rows containing NULL values.
    count(expr) - Returns the number of rows for which the supplied expression is non-NULL.
    count(DISTINCT expr[, expr...]) - Returns the number of rows for which the supplied expression(s) are unique and non-NULL.
    Time taken: 0.013 seconds, Fetched: 3 row(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • desc function extended f_name;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/800629
推荐阅读
相关标签
  

闽ICP备14008679号