2_大数据之Hadoop入门

一 大数据概论

1️⃣概念
  大数据是指无法在一定时间范围内用常规的软件工具进行捕捉,管理和处理的数据集合,是需要新处理模式才能具有更强的决策力,洞察发现力和流程优化能力的海量,高增长率和多样化的信息资产.
2️⃣解决的问题
  海量数据的存储和海量数据的分析计算问题.
3️⃣存储单位(按照从小到大的顺序排列)
  单位 : bit<Byte<K<MB<GB<TB<PB<EB<ZB<YB<BB<NB<DB
4️⃣进制换算
  1bit * 8 = 1Byte * 1024 = 1K * 1024 = 1MB * 1024 = 1GB ......
5️⃣大数据特点
1.大量 : 截止目前,人类生产的所有印刷材料的数据量大约200PB,而历史上全人类总共说过的话的数据量大约是5EB.当前,典型个人计算机硬盘的容量为TB量级,而一些大企业的数据量已经接近EB量级;
2. 高速 : 这是大数据区分于传统挖掘的最显著特征.根据IDC的"数字宇宙"的报告,预计到2020年,全球数据使用量将达到35.2ZB.在如此海量的数据面前,处理数据的效率就是企业的生命.
3. 多样 : 这种类型的多样性也让数据被分为结构化数据和非结构化数据.相对于以往便于存储的以数据库,文本为主的结构化数据,非结构化数据越来越多,包括网络日志,音频,视频,图片,地理位置信息等这些多类型的数据对数据的处理能力提出了更高的要求.
4. 低价值密度 : 价值密度的高低与数据总量的大小成反比.比如在一天的监控视频中我们只关心其中某一个时间段所发生的事情,如何快速对有价值的数据"提纯"称为目前大数据背景下待解决的难题.
6️⃣大数据应用场景
1. 物流仓储 :大数据分析系统助力商家精细化运营,提升销量,节约成本.
2. 零售 : 分析用户消费习惯,为用户购买商品提供方便,从而提升商品销量.
3. 旅游 : 深度结合大数据能力与旅游行业需求,共建旅游产业智慧管理,智慧服务和智慧营销的未来.
4. 商品广告推荐 : 给用户推荐可能喜欢的商品.
5. 保险 : 海量数据挖掘及风险预测,助力保险行业精准营销,提升精细化定价能力.
6. 金融 : 多维度体现用户特征,帮助金融机构推荐优质客户,防范欺诈风险.
7. 人工智能 : 无人驾驶,BI等.
8. 其他行业 : 比如房产等.
7️⃣大数据部门常见组织结构(适用于部分企业)


二 Hadoop简介

1️⃣Hadoop是什么?


2️⃣Hadoop发展历史
  Hadoop百度百科
3️⃣Hadoop三大发行版本介绍
 1. Hadoop三大发行版本:ApacheClouderaHortonworks
  Apache版本最原始(最基础)的版本,对于入门学习最好。
  Cloudera在大型互联网企业中用的较多。
  Hortonworks文档较好。
 2. Apache Hadoop
  官网地址:http://hadoop.apache.org/releases.html
  下载地址:https://archive.apache.org/dist/hadoop/common/
 3. Cloudera Hadoop
  官网地址:https://www.cloudera.com/downloads/cdh/5-10-0.html
  下载地址:http://archive-primary.cloudera.com/cdh5/cdh/5/
 4. Hortonworks Hadoop
  官网地址:https://hortonworks.com/products/data-center/hdp/
  下载地址:https://hortonworks.com/downloads/#data-platform
4️⃣Hadoop的优势
5️⃣Hadoop的组成
 1. HDFS架构概述
 2. YARN架构概述
 3. MapReduce架构概述
  MapReduce将计算过程分为两个阶段:MapReduce.
  1)Map阶段并行处理输入数据
  2)Reduce阶段对Map结果进行汇总
6️⃣大数据技术生态体系
 图中涉及的技术名词解释如下:
 1)SqoopSqoop是一款开源的工具,主要用于在HadoopHive与传统的数据库(MySql)间进行数据的传递,可以将一个关系型数据库(例如 :MySQLOracle 等)中的数据导进到HadoopHDFS中,也可以将HDFS的数据导进到关系型数据库中。
 2)FlumeFlumeCloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。
 3)KafkaKafka是一种高吞吐量的分布式发布订阅消息系统,有如下特性:
  (1)通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。
  (2)高吞吐量:即使是非常普通的硬件Kafka也可以支持每秒数百万的消息。
  (3)支持通过Kafka服务器和消费机集群来分区消息。
  (4)支持Hadoop并行数据加载。
 4)StormStorm用于“连续计算”,对数据流做连续查询,在计算时就将结果以流的形式输出给用户。
 5)SparkSpark是当前最流行的开源大数据内存计算框架。可以基于Hadoop上存储的大数据进行计算。
 6)OozieOozie是一个管理Hdoop作业(job)的工作流程调度管理系统。
 7)HbaseHBase是一个分布式的、面向列的开源数据库。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。
 8)HiveHive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
 9)R语言:R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个自由、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。
 10)MahoutApache Mahout是个可扩展的机器学习和数据挖掘库。
 11)ZooKeeperZookeeperGoogleChubby一个开源的实现。它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、 分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
7️⃣推荐系统框架图


三 Hadoop运行环境搭建

1️⃣虚拟机环境初始化

  1. 克隆虚拟机
  2. 修改克隆虚拟机的静态IP
  3. 修改主机名
  4. 关闭防火墙
  5. 创建一般用户
  6. 配置一般用户具有root权限
  7. 在/opt目录下创建文件夹
     ① 在/opt目录下创建module、software文件夹
     ② 修改module、software文件夹的所有者及组
#!/bin/bash

#环境初始化脚本
#读取用户输入
read -t 10 -p "Enter your user name in 10 seconds " username
read -t 10 -p "Enter your folder name in 10 seconds " foldernameone
read -t 10 -p "Enter your folder name in 10 seconds " foldernametwo
read -t 10 -p "Enter your starting value in 10 seconds " minvalue
read -t 10 -p "Enter your end value in 10 seconds " maxvalue
read -t 10 -p "Enter your ip number in 10 seconds " ip


#关闭防火墙
echo "关闭防火墙"
service iptables stop
chkconfig iptables off

#创建一个一般用户
echo "创建一般用户"
useradd $username
echo "123456" | passwd $username --stdin

#创建目录
echo "创建目录"
mkdir /opt/$foldernameone /opt/$foldernametwo
chown $username:$username /opt/$foldernameone /opt/$foldernametwo

#加入Sudoers
echo "加入Sudoers"
sed -i "/^root/a $username ALL=(ALL)       NOPASSWD: ALL" /etc/sudoers


lan=`ifconfig | grep Bcast | cut -d . -f 3`
#改Host
echo "修改hosts"
for ((i=$minvalue;i<$maxvalue;i++))
do
    echo "192.168.$lan.$i hadoop$i" >> /etc/hosts
done

#改网卡
echo "修改网卡"
cat <<EOF >/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.$lan.$ip
PREFIX=24
GATEWAY=192.168.$lan.2
DNS1=192.168.$lan.2
NAME=eth0
EOF

#改主机名
echo "修改主机"
sed -i "s/HOSTNAME=.*/HOSTNAME=hadoop$ip/g" /etc/sysconfig/network

#改网卡脚本
echo "修改网卡"
sed -i '/eth0/d' /etc/udev/rules.d/70-persistent-net.rules 
sed -i 's/eth1/eth0/g' /etc/udev/rules.d/70-persistent-net.rules

#重启使配置生效
reboot

2️⃣安装JDK

  1. 查询是否安装JDKrpm -qa | grep java
  2. 卸载系统自带JDKrpm -e software_name
  3. 下载JDK到指定目录/opt/sofrware
  4. 解压JDK到指定目录/opt/module目录下tar -zxvf software_name -C /opt/module
  5. 配置JDK环境变量
     5.1 获取JDK路径pwd
     5.2 打开/etc/profile文件
     5.3 在profile文件末尾添加JDK路径
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin
  1. 保存退出:wq
  2. 重新加载配置文件使修改生效source /etc/profile
  3. 测试JDK是否安装成功java -version
  4. 如果以上步骤没有问题第8步不能正常使用则重启尝试

3️⃣安装Hadoop

  1. 下载Hadoop到/opt/software目录此处版本为2.7.2
  2. 进入到Hadoop安装包路径下cd /opt/software/
  3. 解压安装文件到/opt/module下tar -zxvf software_name -C /opt/module
  4. 配置Hadoop环境变量
     4.1 获取Hadoop安装路径 pwd
     4.2 打开/etc/profile文件 vim /etc/profile
     4.3 在profile文件末尾添加环境变量
#HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-2.7.2
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
  1. 保存后退出 :wq
  2. 重新加载配置文件使修改生效source /etc/profile
  3. 测试是否安装成功hadoop version
  4. 如果以上步骤没有问题第7步不能正常使用则重启尝试

4️⃣Hadoop目录结构

  1. 查看Hadoop目录结构
ll /opt/module/hadoop-2.7.2
总用量 52
drwxr-xr-x. 2 xxx xxx  4096 5月  22 2017 bin
drwxr-xr-x. 3 xxx xxx  4096 5月  22 2017 etc
drwxr-xr-x. 2 xxx xxx  4096 5月  22 2017 include
drwxr-xr-x. 3 xxx xxx  4096 5月  22 2017 lib
drwxr-xr-x. 2 xxx xxx  4096 5月  22 2017 libexec
-rw-r--r--. 1 xxx xxx 15429 5月  22 2017 LICENSE.txt
-rw-r--r--. 1 xxx xxx   101 5月  22 2017 NOTICE.txt
-rw-r--r--. 1 xxx xxx  1366 5月  22 2017 README.txt
drwxr-xr-x. 2 xxx xxx  4096 5月  22 2017 sbin
drwxr-xr-x. 4 xxx xxx  4096 5月  22 2017 share
  1. 重要目录简介
    (1)bin目录:存放对Hadoop相关服务(HDFS,YARN)进行操作的脚本;
    (2)etc目录:Hadoop的配置文件目录,存放Hadoop的配置文件;
    (3)lib目录:存放Hadoop的本地库(对数据进行压缩解压缩功能);
    (4)sbin目录:存放启动或停止Hadoop相关服务的脚本;
    (5)share目录:存放Hadoop的依赖jar包、文档、和官方案例;

四 Hadoop运行模式

Hadoop运行模式包括 : 本地模式 伪分布式模式以及完全分布式模式.
Hadoop官方网站 : http://hadoop.apache.org

1️⃣本地运行模式

  1. 官方Grep案例
    ① 在hadoop-2.7.2文件下面创建一个input文件夹
mkdir input

 ② 将hadoopxml配置文件复制到input

cp etc/hadoop/*.xml input

 ③ 执行share目录下的MapReduce程序

bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar grep input output 'dfs[a-z.]+'

 ④ 查看输出结果

cat output/*
  1. 官方WordCount案例
    ① 在hadoop-2.7.2文件下面创建一个wcinput文件夹
mkdir wcinput

 ② 在wcinput文件下创建一个wc.input文件

touch wc.input

 ③ 编辑wc.input文件

vim wc.input
# 在文件中输入如下内容
hadoop yarn
hadoop mapreduce
test
test
# : wq 保存退出

 ④ 回到Hadoop目录/opt/module/hadoop-2.7.2
 ⑤ 执行程序

hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount wcinput wcoutput

 ⑥ 查看结果

cat wcoutput/part-r-00000
# 以下为输出内容
test 2
hadoop  2
mapreduce       1
yarn    1

2️⃣伪分布式运行模式

  1. 启动HDFS并运行MapReduce程序
  1. 分析
    (1)配置集群
    (2)启动、测试集群增、删、查
    (3)执行WordCount案例
  2. 执行步骤
    (1)配置集群
     (a)配置:hadoop-env.sh
      Linux系统中获取JDK的安装路径:echo $JAVA_HOME
      修改路径:export JAVA_HOME=/opt/module/jdk1.8.0_144
     (b)配置:core-site.xml
     (c)配置:hdfs-site.xml

    (2)启动集群
     (a)格式化NameNode(第一次启动时格式化,以后就不要总格式化): bin/hdfs namenode -format
     (b)启动NameNode : sbin/hadoop-daemon.sh start namenode
     (c)启动DataNode : sbin/hadoop-daemon.sh start datanode
    (3)查看集群
     (a)查看是否启动成功 : jps(注意:jpsJDK中的命令,不是Linux命令。不安装JDK不能使用jps)
     (b)web端查看HDFS文件系统 : http://hadoop101:50070/dfshealth.html%23tab-overview注意:如果不能查看,看如下帖子处理http://www.cnblogs.com/zlslch/p/6604189.html
     (c)查看产生的Log日志
      当前目录:/opt/module/hadoop-2.7.2/logs
     (d)思考:为什么不能一直格式化NameNode,格式化NameNode,要注意什么?
      注意:格式化NameNode,会产生新的集群id,导致NameNode和DataNode的集群id不一致,集群找不到已往数据。所以,格式NameNode时,一定要先删除data数据和log日志,然后再格式化NameNode。
    (4)操作集群
     (a)在HDFS文件系统上创建一个input文件夹 : bin/hdfs dfs -mkdir -p /user/xxx/input
     (b)将测试文件内容上传到文件系统上 : bin/hdfs dfs -put wcinput/wc.input
     (c)查看上传的文件是否正确 : bin/hdfs dfs -ls /user/xxx/input/ bin/hdfs dfs -cat /user/xxx/ input/wc.input
     (d)运行MapReduce程序 : bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/xxx/input/ /user/xxx/output
     (e)查看输出结果 : bin/hdfs dfs -cat /user/xxx/output/*
  1. 启动YARN并运行MapReduce程序
  1. 分析
    (1)配置集群在YARN上运行MR
    (2)启动、测试集群增、删、查
    (3)在YARN上执行WordCount案例
  2. 执行步骤
    (1)配置集群
     (a)配置yarn-env.sh配置一下JAVA_HOME : export JAVA_HOME=/opt/module/jdk1.8.0_144
     (b)配置yarn-site.xml
     (c)配置:mapred-env.sh配置一下JAVA_HOME : export JAVA_HOME=/opt/module/jdk1.8.0_144
     (d)配置: (对mapred-site.xml.template重新命名为) mapred-site.xml
mv mapred-site.xml.template mapred-site.xml
vim mapred-site.xml
<!-- 指定MR运行在YARN上 -->
<property>
     <name>mapreduce.framework.name</name>
     <value>yarn</value>
</property>

(2)启动集群
 (a)启动前必须保证NameNodeDataNode已经启动
 (b)启动ResourceManager : sbin/yarn-daemon.sh start resourcemanager
 (c)启动NodeManager : sbin/yarn-daemon.sh start nodemanager
(3)集群操作
 (a)YARN的浏览器页面查看 : http://hadoop101:8088/cluster

 (b)删除文件系统上的output文件 : bin/hdfs dfs -rm -R /user/xxx/output
 (c)执行MapReduce程序 bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/xxx/input /user/xxx/output
 (d)查看运行结果 : bin/hdfs dfs -cat /user/xxx/output/*

  1. 配置历史服务器 : 为了查看程序的历史运行情况,需要配置一下历史服务器。具体配置步骤如下
  1. 配置mapred-site.xml : vim mapred-site.xml
# 在该文件里面增加如下配置
<!-- 历史服务器端地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop101:10020</value>
</property>
<!-- 历史服务器web端地址 -->
<property>
   <name>mapreduce.jobhistory.webapp.address</name>
   <value>hadoop101:19888</value>
</property>
  1. 启动历史服务器 : sbin/mr-jobhistory-daemon.sh start historyserver
  2. 查看历史服务器是否启动 : jps
  3. 查看JobHistory : http://hadoop101:19888/jobhistory
  1. 配置日志的聚集
    日志聚集概念:应用运行完成以后,将程序运行日志信息上传到HDFS系统上。
    日志聚集功能好处:可以方便的查看到程序运行详情,方便开发调试。
    注意:开启日志聚集功能,需要重新启动NodeManager 、ResourceManager和HistoryManager。
    开启日志聚集功能具体步骤如下:
  1. 配置yarn-site.xml : vim yarn-site.xml
# 在该文件里面增加如下配置。
<!-- 日志聚集功能使能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>

<!-- 日志保留时间设置7天 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
  1. 关闭NodeManagerResourceManagerHistoryServer
sbin/yarn-daemon.sh stop resourcemanager
sbin/yarn-daemon.sh stop nodemanager
sbin/mr-jobhistory-daemon.sh stop historyserver
  1. 启动NodeManagerResourceManagerHistoryServer
sbin/yarn-daemon.sh start resourcemanager
sbin/yarn-daemon.sh start nodemanager
sbin/mr-jobhistory-daemon.sh start historyserver
  1. 删除HDFS上已经存在的输出文件 : bin/hdfs dfs -rm -R /user/xxx/output
  2. 执行WordCount程序 : hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/xxx/input /user/xxx/output
  3. 查看日志 : http://hadoop101:19888/jobhistory
  1. 配置文件说明
    Hadoop配置文件分两类:默认配置文件和自定义配置文件,只有用户想修改某一默认配置值时,才需要修改自定义配置文件,更改相应属性值。

(1)默认配置文件:

(2)自定义配置文件:
  core-site.xmlhdfs-site.xmlyarn-site.xmlmapred-site.xml四个配置文件存放在$HADOOP_HOME/etc/hadoop这个路径上,用户可以根据项目需求重新进行修改配置。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 当前,整个互联网正在从IT时代向DT时代演进,大数据技术也正在助力企业和公众敲开DT世界大门。当今“大数据”一词的...
    吴瑞文阅读 1,459评论 1 11
  • IBM、Oracle、SAP、甚至Microsoft等几乎所有的大型软件提供商都采用了Hadoop。然而,当你已经...
    丨程序之道丨阅读 716评论 0 1
  • 数据管理比以往更加复杂,到处都是大数据,包括每个人的想法以及不同的形式:广告 , 社交图谱,信息流 ,推荐 ,市场...
    abel_cao阅读 857评论 0 7
  • 生活中我们总会经历这样或那样的不开心的事。特别是当我们长大成人后,烦躁的事情越来越多,感觉每天都有做不完的...
    荣我静静阅读 277评论 0 4
  • 在今天我终于读完了这本书,好久没有一本书能让我静下心来把它读完了。读到这本书的结尾,我真的很感动,眼眶都湿润了,我...
    MU心阅读 1,787评论 1 1