关灯
得知互动 门户 互联网+ SEO/SEM 查看内容
3

大数据干货丨最全面得的Hive性能优化

摘要: 1.先容  起首,我们来看看Hadoop的盘算框架特性,在此特性下会衍生哪些题目?数据量大不是题目,数据倾斜是个题目。jobs数比力多的作业运行服从相对比力低,好比纵然有几百行的表,假如屡次关联屡次汇总,产生十几 ...

1.先容

  起首,我们来看看Hadoop的盘算框架特性,在此特性下会衍生哪些题目?

  • 数据量大不是题目,数据倾斜是个题目。
  • jobs数比力多的作业运行服从相对比力低,好比纵然有几百行的表,假如屡次关联屡次汇总,产生十几个jobs,耗时很长。缘由是map reduce作业初始化的时间是比力长的。
  • sum,count,max,min等UDAF,不怕数据倾斜题目,hadoop在map端的汇总归并优化,使数据倾斜不成题目。
  • count(distinct ),在数据量大的环境下,服从较低,假如是多count(distinct )服从更低,由于count(distinct)是按group by 字段分组,按distinct字段排序,一样平常这类分布方式是很倾斜的。举个例子:好比男uv,女uv,像淘宝一天30亿的pv,假如按性别分组,分配2个reduce,每个reduce处置惩罚15亿数据。

  面临这些题目,我们能有哪些有用的优化本领呢?下面列出一些在工作有用可行的优化本领:

  • 好的模子计划事半功倍。
  • 办理数据倾斜题目。
  • 淘汰job数。
  • 设置公道的map reduce的task数,能有用提拔性能。(好比,10w+级别的盘算,用160个reduce,那是相称的浪费,1个充足)。
  • 相识数据分布,本身动手办理数据倾斜题目是个不错的选择。set hive.groupby.skewindata=true;这是通用的算法优化,但算法优化偶然不能顺应特定业务配景,开辟职员相识业务,相识数据,可以通过业务逻辑准确有用的办理数据倾斜题目。
  • 数据量较大的环境下,慎用count(distinct),count(distinct)轻易产生倾斜题目。
  • 对小文件举行归并,是行职苄效的进步调理服从的方法,假设全部的作业设置公道的文件数,对云梯的团体调理服从也会产生积极的正向影响。
  • 优化时把握团体,单个作业最优不如团体最优。

  而接下来,我们心中应当会有一些疑问,影响性能的根源是什么?

2.性能低下的根源

  hive性能优化时,把HiveQL当做M/R步伐来读,即从M/R的运行角度来思量优化性能,从更底层思索怎样优化运算性能,而不但仅范围于逻辑代码的更换层面。

  RAC(Real Application Cluster)真正运用英魂集群就像一辆机动机动的小货车,相应快;Hadoop就像吞吐量巨大的汽船,启动开销大,假如每次只做小数目的输入输出,使用率将会很低。以是用好Hadoop的主要使命是增大每次使命所搭载的数据量。

  Hadoop的焦点本领是parition和sort,因而这也是优化的根本。

  观察Hadoop处置惩罚数据的过程,有几个明显的特性:

  • 数据的大规模并不是负载重点,造成运行压力过大是由于运行数据的倾斜。
  • jobs数比力多的作业运行服从相对比力低,好比纵然有几百行的表,假如屡次关联对此汇总,产生几十个jobs,将会必要30分钟以上的时间且大部门时间被用于作业分配,初始化和数据输出。M/R作业初始化的时间是比力耗时间资源的一个部门。
  • 在利用SUM,COUNT,MAX,MIN等UDAF函数时,不怕数据倾斜题目,Hadoop在Map端的汇总归并优化过,使数据倾斜不成题目。
  • COUNT(DISTINCT)在数据量大的环境下,服从较低,假如多COUNT(DISTINCT)服从更低,由于COUNT(DISTINCT)是按GROUP BY字段分组,按DISTINCT字段排序,一样平常这类分布式方式是很倾斜的;好比:男UV,女UV,淘宝一天30亿的PV,假如按性别分组,分配2个reduce,每个reduce处置惩罚15亿数据。
  • 数据倾斜是导致服从大幅低落的首要缘由,可以接纳多一次 Map/Reduce 的方法, 制止倾斜。

  末了得出的结论是:避实就虚,用 job 数的增添,输入量的增添,占用更多存储空间,充实使用空闲 CPU 等各种方法,分解数据倾斜酿成的造访负担。

3.设置角度优化

  我们知道了性能低下的根源,同样,我们也能够从Hive的设置解读去优化。Hive体系内部已针对差别的查询预设定了优化方法,用户可以通过调解设置举行控制, 以下举例先容部门优化的计谋和优化控制选项。

3.1列裁剪

  Hive 在读数据的时间,可以只读取查询中所必要用到的列,而忽略别的列。 比方,如有以下查询:

SELECT a,b FROM q WHERE e<10;

  在实行此项查询中,Q 表有 5 列(a,b,c,d,e),Hive 只读取查询逻辑中真实必要 的 3 列 a、b、e,而忽略列 c,d;如许做节流了读取开销,中心表存储开销和数据整合开销。

  裁剪所对应的参数项为:hive.optimize.cp=true(默认值为真)

3.2分区裁剪

  可以在查询的过程中淘汰不须要的分区。 比方,如有以下查询:

SELECT * FROM (SELECTT a1,COUNT(1) FROM T GROUP BY a1) subq WHERE subq.prtn=100; #(多余分区) 
SELECT * FROM T1 JOIN (SELECT * FROM T2) subq ON (T1.a1=subq.a2) WHERE subq.prtn=100;

  查询语句若将“subq.prtn=100”条件放入子查询中更为高效,可以淘汰读入的分区 数量。 Hive 主动履行这类裁剪优化。

  分区参数为:hive.optimize.pruner=true(默认值为真)

3.3JOIN操纵

  在编写带有 join 操纵的代码语句时,应当将条目少的表/子查询放在 Join 操纵符的左侧。 由于在 Reduce 阶段,位于 Join 操纵符左侧的表的内容会被加载进内存,载入条目较少的表 可以有用淘汰 OOM(out of memory)即内存溢出。以是对于同一个 key 来说,对应的 value 值小的放前,大的放后,这便是“小表放前”原则。 若一条语句中有多个 Join,依据 Join 的条件雷同与否,有差别的处置惩罚方法。

3.3.1JOIN原则

  在利用写有 Join 操纵的查询语句时有一条原则:应当将条目少的表/子查询放在 Join 操纵符的左侧。缘由是在 Join 操纵的 Reduce 阶段,位于 Join 操纵符左侧的表的内容会被加载进内存,将条目少的表放在左侧,可以有用淘汰发生 OOM 错误的几率。对于一条语句中有多个 Join 的环境,假如 Join 的条件雷同,好比查询:

INSERT OVERWRITE TABLE pv_users 
SELECT pv.pageid, u.age FROM page_view p
JOIN user u ON (pv.userid = u.userid)
JOIN newuser x ON (u.userid = x.userid);
  • 假如 Join 的 key 雷同,不管有多少个表,都会则会归并为一个 Map-Reduce
  • 一个 Map-Reduce 使命,而不是 ‘n’ 个
  • 在做 OUTER JOIN 的时间也是一样

  假如 Join 的条件不雷同,好比:

INSERT OVERWRITE TABLE pv_users 
SELECT pv.pageid, u.age FROM page_view p
JOIN user u ON (pv.userid = u.userid)
JOIN newuser x on (u.age = x.age);

  Map-Reduce 的使命数量和 Join 操纵的数量是对应的,上述查询和以下查询是等价的:

INSERT OVERWRITE TABLE tmptable 
SELECT * FROM page_view p JOIN user u
ON (pv.userid = u.userid);
INSERT OVERWRITE TABLE pv_users
SELECT x.pageid, x.age FROM tmptable x
JOIN newuser y ON (x.age = y.age);

3.4MAP JOIN操纵

  Join 操纵在 Map 阶段完成,不再必要Reduce,条件条件是必要的数据在 Map 的过程中可以访问到。好比查询:

INSERT OVERWRITE TABLE pv_users 
SELECT /*+ MAPJOIN(pv) */ pv.pageid, u.age
FROM page_view pv
JOIN user u ON (pv.userid = u.userid);

  可以在 Map 阶段完成 Join,如图所示:

大数据干货丨最全面得的Hive性能优化

  相干的参数为:

  • hive.join.emit.interval = 1000
  • hive.mapjoin.size.key = 10000
  • hive.mapjoin.cache.numrows = 10000

3.5GROUP BY操纵

  举行GROUP BY操纵时必要注重一下几点:

  • Map端部门聚合

  究竟上并不是全部的聚合操纵都必要在reduce部门举行,许多聚合操纵都可以先在Map端举行部门聚合,然后reduce端得出终究效果。

  这里必要修改的参数为:

  hive.map.aggr=true(用于设定是否在 map 端举行聚合,默认值为真) hive.groupby.mapaggr.checkinterval=100000(用于设定 map 端举行聚合操纵的条目数)

  • 稀有据倾斜时举行负载平衡

  此处必要设定 hive.groupby.skewindata,中选项设定为 true 是,天生的查询方案有两 个 MapReduce 使命。在第一个 MapReduce 中,map 的输出效果聚集会随机分布到 reduce 中, 每个 reduce 做部门聚合操纵,并输出效果。如许处置惩罚的效果是,雷同的 Group By Key 有可 能分发到差别的 reduce 中,从而到达负载平衡的目标;第二个 MapReduce 使命再根据预处 理的数据效果按照 Group By Key 分布到 reduce 中(这个过程可以包管雷同的 Group By Key 分布到同一个 reduce 中),末了完成终究的聚合操纵。

3.6归并小文件

  我们知道文件数量小,轻易在文件存储端造成瓶颈,给 HDFS 带来压力,影响处置惩罚服从。对此,可以通过归并Map和Reduce的效果文件来消除如许的影响。

  用于设置归并属性的参数有:

  • 是否归并Map输出文件:hive.merge.mapfiles=true(默认值为真)
  • 是否归并Reduce 端输出文件:hive.merge.mapredfiles=false(默认值为假)
  • 归并文件的巨细:hive.merge.size.per.task=256*1000*1000(默认值为 256000000)

4.步伐角度优化

4.1纯熟利用SQL进步查询

  纯熟地利用 SQL,能写出高服从的查询语句。

  场景:有一张 user 表,为卖家天天收到表,user_id,ds(日期)为 key,属性有主营类目,指标有生意业务金额,生意业务笔数。天天要取前10天的总收入,总笔数,和比来一天的主营类目。   

办理方法 1

  如下所示:常用方法

INSERT OVERWRITE TABLE t1 
SELECT user_id,substr(MAX(CONCAT(ds,cat),9) AS main_cat) FROM users
WHERE ds=20120329 // 20120329 为日期列的值,现实代码中可以用函数表现出当天日期 GROUP BY user_id;

INSERT OVERWRITE TABLE t2
SELECT user_id,sum(qty) AS qty,SUM(amt) AS amt FROM users
WHERE ds BETWEEN 20120301 AND 20120329
GROUP BY user_id

SELECT t1.user_id,t1.main_cat,t2.qty,t2.amt FROM t1
JOIN t2 ON t1.user_id=t2.user_id

  下面给出方法1的思绪,实现步调如下:

  第一步:使用分析函数,取每个 user_id 比来一天的主营类目,存入暂时表 t1。

  第二步:汇总 10 天的总生意业务金额,生意业务笔数,存入暂时表 t2。

  第三步:关联 t1,t2,得到终究的效果。

  办理方法 2

  如下所示:优化方法 

SELECT user_id,substr(MAX(CONCAT(ds,cat)),9) AS main_cat,SUM(qty),SUM(amt) FROM users 
WHERE ds BETWEEN 20120301 AND 20120329
GROUP BY user_id

  在工作中我们总结出:方案 2 的开销即是方案 1 的第二步的开销,性能提拔,由原本的 25 分钟完成,收缩为 10 分钟之内完成。节流了两个暂时表的读写是一个关键缘由,这类方式也实用于 Oracle 中的数据查找工作。

SQL 具有普适性,许多 SQL 通用的优化方案在 Hadoop 分布式盘算方式中也能够到达结果。

4.2无效ID在关联时的数据倾斜题目

  题目:日记中常会出现信息丧失,好比逐日约为 20 亿的全网日记,此中的 user_id 为主 键,在日记网络过程中会丧失,出现主键为 null 的环境,假如取此中的 user_id 和 bmw_users 关联,就会遇到数据倾斜的题目。缘由是 Hive 中,主键为 null 值的项会被当做雷同的 Key 而分配进同一个盘算 Map。

办理方法 1:user_id 为空的不到场关联,子查询过滤 null

SELECT * FROM log a 
JOIN bmw_users b ON a.user_id IS NOT NULL AND a.user_id=b.user_id
UNION All SELECT * FROM log a WHERE a.user_id IS NULL

  办理方法 2 如下所示:函数过滤 null

SELECT * FROM log a LEFT OUTER 
JOIN bmw_users b ON
CASE WHEN a.user_id IS NULL THEN CONCAT(‘dp_hive’,RAND()) ELSE a.user_id END =b.user_id;

  调优效果:本来由于数据倾斜导致运行时长凌驾 1 小时,办理方法 1 运行逐日均匀时长 25 分钟,办理方法 2 运行的逐日均匀时长在 20 分钟摆布。优化结果很显着。

  我们在工作中总结出:办理方法2比办理方法1结果更好,不光IO少了,而且作业数也少了。办理方法1中log读取两次,job 数为2。办理方法2中 job 数是1。这个优化得当无效 id(好比-99、 ‘’,null 等)产生的倾斜题目。把空值的 key 酿成一个字符串加上随机数,就能把倾斜的 数据分到差别的Reduce上,从而办理数据倾斜题目。由于空值不到场关联,纵然分到差别 的 Reduce 上,也不会影响终究的效果。附上 Hadoop 通用关联的实现方法是:关联通过二次排序实现的,关联的列为 partion key,关联的列和表的 tag 构成排序的 group key,根据 pariton key分配Reduce。同一Reduce内根据group key排序。

4.3差别数据范例关联产生的倾斜题目

  题目:差别数据范例 id 的关联会产生数据倾斜题目。

  一张表 s8 的日记,每个商品一条记载,要和商品表关联。但关联却遇到倾斜的题目。 s8 的日记中有 32 为字符串商品 id,也稀有值商品 id,日记中范例是 string 的,但商品中的 数值 id 是 bigint 的。料想题目的缘由是把 s8 的商品 id 转成数值 id 做 hash 来分配 Reduce, 以是字符串 id 的 s8 日记,都到一个 Reduce 上了,办理的方法验证了这个推测。

  办理方法:把数据范例转换成字符串范例

 

SELECT * FROM s8_log a LEFT OUTER 
JOIN r_auction_auctions b ON a.auction_id=CAST(b.auction_id AS STRING)

  调优效果表现:数据表处置惩罚由 1 小时 30 分钟经代码调解后可以在 20 分钟内完成。

4.4使用Hive对UNION ALL优化的特性

  多表 union all 会优化成一个 job。

  题目:好比推广结果表要和商品表关联,结果表中的 auction_id 列既有 32 为字符串商 品 id,也稀有字 id,和商品表关联得到商品的信息。

  办理方法:Hive SQL 性能会比力好

SELECT * FROM effect a 
JOIN
(SELECT auction_id AS auction_id FROM auctions
UNION All
SELECT auction_string_id AS auction_id FROM auctions) b
ON a.auction_id=b.auction_id

  比分别过滤数字 id,字符串 id 然后分别和商品表关联性能要好。

  如许写的利益:1 个 MapReduce 作业,商品表只读一次,推广结果表只读取一次。把 这个 SQL 换成 Map/Reduce 代码的话,Map 的时间,把 a 表的记载打上标签 a,商品表记载 每读取一条,打上标签 b,酿成两个<key,value>对,<(b,数字 id),value>,<(b,字符串 id),value>。

  以是商品表的 HDFS 读取只会是一次。

4.5办理Hive对UNION ALL优化的短板

  Hive 对 union all 的优化的特性:对 union all 优化只范围于非嵌套查询。

  • 清除子查询内的 group by

示例 1:子查询内有 group by

SELECT * FROM 
(SELECT * FROM t1 GROUP BY c1,c2,c3 UNION ALL SELECT * FROM t2 GROUP BY c1,c2,c3)t3
GROUP BY c1,c2,c3

  从业务逻辑上说,子查询内的 GROUP BY 怎么都看显得多余(功能上的多余,除非有 COUNT(DISTINCT)),假如不是由于 Hive Bug 大概性能上的考量(曾出现假如不履行子查询 GROUP BY,数据得不到精确的效果的 Hive Bug)。以是这个 Hive 按履历转换成如下所示:

SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t2)t3 GROUP BY c1,c2,c3 

  调优效果:颠末测试,并未出现 union all 的 Hive Bug,数据是同等的。MapReduce 的 作业数由 3 淘汰到 1。

t1 相称于一个目次,t2 相称于一个目次,对 Map/Reduce 步伐来说,t1,t2 可以作为 Map/Reduce 作业的 mutli inputs。这可以通过一个 Map/Reduce 来办理这个题目。Hadoop 的 盘算框架,不怕数据多,就怕作业数多。

  但假如换成是其他盘算平台如 Oracle,那就不肯定了,由于把大的输入拆成两个输入, 分别排序汇总后 merge(假设两个子排序是并行的话),是有大概性能更优的(好比希尔排 序比冒泡排序的性能更优)。

  • 清除子查询内的 COUNT(DISTINCT),MAX,MIN。
SELECT * FROM 
(SELECT * FROM t1
UNION ALL SELECT c1,c2,c3 COUNT(DISTINCT c4) FROM t2 GROUP BY c1,c2,c3) t3
GROUP BY c1,c2,c3;

  由于子查询里头有 COUNT(DISTINCT)操纵,直接去 GROUP BY 将达不到业务目的。这时候接纳 暂时表清除 COUNT(DISTINCT)作业不光能办理倾斜题目,还能有用淘汰 jobs。

INSERT t4 SELECT c1,c2,c3,c4 FROM t2 GROUP BY c1,c2,c3; 
SELECT c1,c2,c3,SUM(income),SUM(uv) FROM
(SELECT c1,c2,c3,income,0 AS uv FROM t1
UNION ALL
SELECT c1,c2,c3,0 AS income,1 AS uv FROM t2) t3
GROUP BY c1,c2,c3;

  job 数是 2,淘汰一半,而且两次 Map/Reduce 比 COUNT(DISTINCT)服从更高。

调优效果:万万级别的类目表,member 表,与 10 亿级得商品表关联。本来 1963s 的使命颠末调解,1152s 即完成。

  • 清除子查询内的 JOIN
SELECT * FROM 
(SELECT * FROM t1 UNION ALL SELECT * FROM t4 UNION ALL SELECT * FROM t2 JOIN t3 ON t2.id=t3.id) x
GROUP BY c1,c2;

  上面代码运行会有 5 个 jobs。参加先 JOIN 生存暂时表的话 t5,然后 UNION ALL,会酿成 2 个 jobs。

INSERT OVERWRITE TABLE t5 
SELECT * FROM t2 JOIN t3 ON t2.id=t3.id;
SELECT * FROM (t1 UNION ALL t4 UNION ALL t5);

  调优效果表现:针对万万级别的广告位表,由本来 5 个 Job 共 15 分钟,分解为 2 个 job 一个 8-10 分钟,一个3分钟。

4.6GROUP BY替换COUNT(DISTINCT)到达优化结果

  盘算 uv 的时间,常常会用到 COUNT(DISTINCT),但在数据比力倾斜的时间 COUNT(DISTINCT) 会比力慢。这时候可以实验用 GROUP BY 改写代码盘算 uv。

  • 原有代码
INSERT OVERWRITE TABLE s_dw_tanx_adzone_uv PARTITION (ds=20120329) 
SELECT 20120329 AS thedate,adzoneid,COUNT(DISTINCT acookie) AS uv FROM s_ods_log_tanx_pv t WHERE t.ds=20120329 GROUP BY adzoneid

  关于COUNT(DISTINCT)的数据倾斜题目不能一概而论,要依环境而定,下面是我测试的一组数据:

  测试数据:169857条

#统计逐日IP 
CREATE TABLE ip_2014_12_29 AS SELECT COUNT(DISTINCT ip) AS IP FROM logdfs WHERE logdate='2014_12_29';
耗时:24.805 seconds
#统计逐日IP(改造)
CREATE TABLE ip_2014_12_29 AS SELECT COUNT(1) AS IP FROM (SELECT DISTINCT ip from logdfs WHERE logdate='2014_12_29') tmp;
耗时:46.833 seconds

  测试效果表名:显着改造后的语句比之前耗时,这是由于改造后的语句有2个SELECT,多了一个job,如许在数据量小的时间,数据不会存在倾斜题目。

5.优化总结

  优化时,把hive sql当做mapreduce步伐来读,会成心想不到的惊喜。明白hadoop的焦点本领,是hive优化的根本。这是这一年来,项目组全部成员名贵的履历总结。

  • 恒久观察hadoop处置惩罚数据的过程,有几个明显的特性:
  1. 不怕数据多,就怕数据倾斜。
  2. 对jobs数比力多的作业运行服从相对比力低,好比纵然有几百行的表,假如屡次关联屡次汇总,产生十几个jobs,没半小时是跑不完的。map reduce作业初始化的时间是比力长的。
  3. 对sum,count来说,不存在数据倾斜题目。
  4. 对count(distinct ),服从较低,数据量一多,准出题目,假如是多count(distinct )服从更低。
  • 优化可以从几个方面动手:
  1. 好的模子计划事半功倍。
  2. 办理数据倾斜题目。
  3. 淘汰job数。
  4. 设置公道的map reduce的task数,能有用提拔性能。(好比,10w+级别的盘算,用160个reduce,那是相称的浪费,1个充足)。
  5. 本身动手写sql办理数据倾斜题目是个不错的选择。set hive.groupby.skewindata=true;这是通用的算法优化,但算法优化老是漠视业务,风俗性提供通用的办理方法。 Etl开辟职员更相识业务,更相识数据,以是通过业务逻辑办理倾斜的方法每每更准确,更有用。
  6. 对count(distinct)接纳漠视的方法,尤其数据大的时间很轻易产生倾斜题目,不抱幸运生理。本身动手,丰衣足食。
  7. 对小文件举行归并,是行职苄效的进步调理服从的方法,假设我们的作业设置公道的文件数,对云梯的团体调理服从也会产生积极的影响。

  优化时把握团体,单个作业最优不如团体最优。

6.优化的常用本领

  首要由三个属性来决定:

  • hive.exec.reducers.bytes.per.reducer #这个参数控制一个job会有多少个reducer来处置惩罚,依据的是输入文件的总巨细。默认1GB。
  • hive.exec.reducers.max #这个参数控制最大的reducer的数目, 假如 input / bytes per reduce > max 则会启动这个参数所指定的reduce个数。 这个并不会影响mapre.reduce.tasks参数的设置。默认的max是999。
  • mapred.reduce.tasks #这个参数假如指定了,hive就不会用它的estimation函数来主动盘算reduce的个数,而是用这个参数来启动reducer。默认是-1。

6.1参数设置的影响

  假如reduce太少:假如数据量很大,会导致这个reduce非常的慢,从而导致这个使命不能完毕,也有大概会OOM 2、假如reduce太多: 产生的小文件太多,归并起来代价太高,namenode的内存占用也会增大。假如我们不指定mapred.reduce.tasks, hive会主动盘算必要多少个reducer。

末了

小编这里有还一份大数据的学习文档可以避免费分享给各人。此中包罗:Zookeeper、spark、hadoop、hbase、RabbitMQ、Cassandra 分布式缓存、数据构造等等

由于平台文章篇幅限定,细节内容过多,以是只把部门知识点截图出来大略的先容,每个末节点内里都有更细化的内容!

资料免费获取方式:关注我 + 转发文章,背景私信【资料】即可免费获取

大数据干货丨最全面得的Hive性能优化

大数据干货丨最全面得的Hive性能优化

大数据干货丨最全面得的Hive性能优化

大数据干货丨最全面得的Hive性能优化


路过

雷人

握手

鲜花

鸡蛋

说点什么...

已有3条评论

最新评论...

错过的期待2020-9-26 04:20引用

转发了

家驹死党2020-9-26 04:00引用

转发了

天天看海2020-9-26 03:40引用

转发了

查看全部评论(3)

本文作者
2020-9-26 03:20
  • 0
    粉丝
  • 7354
    阅读
  • 3
    回复

关注帮客优品

扫描关注,了解最新资讯

联系人:叶先生
Q Q:956130084
EMAIL:956130084@qq.com
地址:中国·武汉
热门评论
排行榜

关注我们:微信订阅号

官方微信

APP下载

全国服务Q Q:

956130084

中国·湖北

Email:956130084@qq.com

Copyright   ©2015-2022  站长技术交流论坛|互联网技术交流平台Powered by©Discuz!技术支持:得知网络  

鄂公网安备 42018502006730号

  ( 鄂ICP备15006301号-5 )