范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

03Hadoop高可用集群环境搭建

  Hadoop高可用集群环境搭建
  li_zliang
  2021-09-25
  1 高可用简介
  1.1 高可用架构
  1.2 基于 QJM 的共享存储系统的数据同步机制分析
  1.3 NameNode 主备切换
  2 集群规划
  2.1 虚机环境
  2.2 JDK1.8
  2.3 hadoop集群
  2.4 zookeeper集群
  3. 前置配置
  3.1 zookeeper集群
  3.2 安装jdk
  3.3 修改计算机名
  3.4 配置免密登陆
  3.3.1 ssh服务
  3.3.2 生成秘钥
  3.3.3 免密登陆
  3.3.4 登陆验证
  4. 集群搭建
  4.1 安装hadoop(master主机)
  4.2 配置环境变量(master主机,slave从机分发后)
  4.3 新建文件目录(master主机)
  4.4 配置配置文件(master主机)
  4.4.2 配置hadoop-env.sh
  4.4.3 配置yarn-env.sh
  4.4.4 配置core-site.xml
  4.4.5 配置hdfs-site.xml
  4.4.6 配置yarn-site.xml
  4.4.7 配置mapred-site.xml
  4.4.8 配置slaves
  4.5 分发程序(master主机)
  4.6 设置环境变量(slave从机)
  5 关闭防火墙
  6 启动运行
  6.1 启动Zookeeper
  6.2 启动Journalnode
  6.3 初始化NameNode
  6.4 初始化HA状态
  6.5 启动HDFS
  6.6 启动YARN
  6.7 查看集群
  7 二次启动运行
  8 参考资料
  9 问题
  9.1 问题1-启动链接journalnode(端口8485)异常
  1 高可用简介
  Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似,但HDFS NameNode 对数据存储及其一致性的要求比 YARN ResourceManger 高得多,所以它的实现也更加复杂;
  1.1 高可用架构
  Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似,但HDFS NameNode 对数据存储及其一致性的要求比 YARN ResourceManger 高得多,所以它的实现也更加复杂;
  HDFS 高可用架构主要由以下组件所构成:
  Active NameNode 和 Standby NameNode :两台 NameNode 形成互备,一台处于 Active 状态,为主 NameNode,另外一台处于 Standby 状态,为备 NameNode,只有主 NameNode 才能对外提供读写服务。
  主备切换控制器 ZKFailoverController :ZKFailoverController 作为独立的进程运行,对NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换,当然 NameNode目前也支持不依赖于 Zookeeper 的手动主备切换。
  Zookeeper 集群 :为主备切换控制器提供主备选举支持。
  共享存储系统 :共享存储系统是实现 NameNode 的高可用最为关键的部分,共享存储系统保存了NameNode 在运行过程中所产生的 HDFS 的元数据。主 NameNode 和 NameNode 通过共享存储系统实现元数据同步。在进行主备切换的时候,新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务。
  DataNode 节点 :除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主NameNode 和备 NameNode 上报数据块的位置信息。
  1.2 基于 QJM 的共享存储系统的数据同步机制分析
  目前 Hadoop 支持使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作为共享的存储系统,这里以 QJM 集群为例进行说明:Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再从 JournalNode 集群定时同步 EditLog,当 Active NameNode 宕机后, Standby NameNode 在确认元数据完全同步之后就可以对外提供服务。
  需要说明的是向 JournalNode 集群写入 EditLog 是遵循 "过半写入则成功" 的策略,所以你至少要有 3个 JournalNode 节点,当然你也可以继续增加节点数量,但是应该保证节点总数是奇数。同时如果有2N+1 台 JournalNode,那么根据过半写的原则,最多可以容忍有 N 台 JournalNode 节点挂掉。
  1.3 NameNode 主备切换
  NameNode 实现主备切换的流程下图所示:
  1. HealthMonitor 初始化完成之后会启动内部的线程来定时调用对应 NameNode 的HAServiceProtocol RPC 接口的方法,对 NameNode 的健康状态进行检测。
  2. HealthMonitor 如果检测到 NameNode 的健康状态发生变化,会回调 ZKFailoverController 注册的相应方法进行处理。
  3. 如果 ZKFailoverController 判断需要进行主备切换,会首先使用 ActiveStandbyElector 来进行自动的主备选举。
  4. ActiveStandbyElector 与 Zookeeper 进行交互完成自动的主备选举。
  5. ActiveStandbyElector 在主备选举完成后,会回调 ZKFailoverController 的相应方法来通知当前的 NameNode 成为主 NameNode 或备 NameNode。
  6. ZKFailoverController 调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法将NameNode 转换为 Active 状态或 Standby 状态。
  1.4 YARN高可用
  YARN ResourceManager 的高可用与 HDFS NameNode 的高可用类似,但是 ResourceManager 不像NameNode ,没有那么多的元数据信息需要维护,所以它的状态信息可以直接写到 Zookeeper 上,并依赖 Zookeeper 来进行主备选举;
  2 集群规划
  按照高可用的设计目标:需要保证至少有两个 NameNode (一主一备) 和 两个 ResourceManager (一主一备) ,同时为满足"过半写入则成功"的原则,需要至少要有 3 个 JournalNode 节点。这里使用三台主机进行搭建,集群规划如下:
  三台主机名:hadoop-master、hadoop-slave1、hadoop-slave2
  1. 主NameNode:hadoop-master
  2. 备NameNode:hadoop-slave1
  3. 主ResourceManager:hadoop-master
  4. 备ResourceManager:hadoop-slave2
  5. DataNode:三台主机都有
  6. JournalNode:三台主机都有
  7. NodeManager:三台主机都有
  8. Zookeeper:三台主机都有
  2 前提准备
  2.1 虚机环境
  里搭建一个 3 节点的 Hadoop 集群; 我这里准备了三台CentOS 7;用VMware搭建;
  计算机名分别 为hadoop-master、hadoop-slave1、hadoop-slave2;
  2.2 JDK1.8
  hadoop依赖JDK,提前安装好JDK; 三台主机都要安装;
  2.3 hadoop集群
  搭建好hadoop集群,详见《01_Hadoop集群环境搭建(CentOS)》;
  2.4 zookeeper集群
  搭建好zookeeper集群,详见《02_Zookeeper集群环境搭建(CentOS)》;
  3. 前置配置
  3.1 zookeeper集群
  搭建好zookeeper集群,详见《02_Zookeeper集群环境搭建(CentOS)》;
  3.2 安装jdk
  详见《01_Hadoop集群环境搭建(CentOS)》;
  3.3 修改计算机名
  详见《01_Hadoop集群环境搭建(CentOS)》;
  3.4 配置免密登陆
  这里需要注意的是:三台主机互相免密登陆;《01_Hadoop集群环境搭建(CentOS)》中只是配置的master免密访问slave1和slave2;
  3.3.1 ssh服务
  一般服务器上都已安装ssh;
  只要ps -e | grep ssh,有sshd输出即可;
  3.3.2 生成秘钥
  每台主机上使用ssh-keygen命令生成公钥私钥对;
  //生成秘钥
  > ssh-keygen -t rsa -P ""
  //.ssh隐藏,ls是看不到的;
  > cd /root/.ssh
  注:回车后会在/root/.ssh/下生成两个文件:id_rsa和id_rsa.pub这两个文件是成对出现的;
  3.3.3 免密登陆
  第一步:将公钥id_rsa.pub写到 ~/.ssh/authorized_keys授权文件中
  # hadoop-master上执行
  > ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop-master
  # hadoop-slave1上执行
  > ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop-slave1
  # hadoop-slave2上执行
  > ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop-slave2
  第二步:将公钥复制为id_rsa_master.pub 并放到/home下
  # hadoop-master上执行
  > cp ~/.ssh/id_rsa.pub /home/id_rsa_master.pub
  # hadoop-slave1上执行
  > cp ~/.ssh/id_rsa.pub /home/id_rsa_slave1.pub
  # hadoop-slave2上执行
  > cp ~/.ssh/id_rsa.pub /home/id_rsa_slave2.pub
  第三步:将id_rsa_master.pub、id_rsa_slave1.pub、id_rsa_slave2.pub文件取下来,并放到hadoop-master、hadoop-slave1、hadoop-slave2的/root/~ssh目录下;
  先放到/home下,再复制到/root/~ssh下,因为~ssh目录是看不到的
  # hadoop-master上执行
  > cp /home/id_rsa_slave1.pub /root/.ssh/
  > cp /home/id_rsa_slave2.pub /root/.ssh/
  # hadoop-slave1上执行
  > cp /home/id_rsa_master.pub /root/.ssh/
  > cp /home/id_rsa_slave2.pub /root/.ssh/
  # hadoop-slave2上执行
  > cp /home/id_rsa_master.pub /root/.ssh/
  > cp /home/id_rsa_slave1.pub /root/.ssh/
  第四步:将公钥id_rsa_xxxxx.pub写到 ~/.ssh/authorized_keys授权文件中
  # hadoop-master上执行
  > cat ~/.ssh/id_rsa_slave1.pub >> ~/.ssh/authorized_keys
  > cat ~/.ssh/id_rsa_slave2.pub >> ~/.ssh/authorized_keys
  # hadoop-slave1上执行
  > cat ~/.ssh/id_rsa_master.pub >> ~/.ssh/authorized_keys
  > cat ~/.ssh/id_rsa_slave2.pub >> ~/.ssh/authorized_keys
  # hadoop-slave2上执行
  > cat ~/.ssh/id_rsa_master.pub >> ~/.ssh/authorized_keys
  > cat ~/.ssh/id_rsa_slave1.pub >> ~/.ssh/authorized_keys
  3.3.4 登陆验证
  在hadoop-master上操作,分别免密登陆hadoop-slave1和hadoop-slave2;
  > ssh hadoop-slave1
  > exit
  > ssh hadoop-slave2
  > exit
  在hadoop-slave1上操作,分别免密登陆hadoop-master和hadoop-slave2;
  > ssh hadoop-master
  > exit
  > ssh hadoop-slave2
  > exit
  在hadoop-slave2上操作,分别免密登陆hadoop-master和hadoop-slave1;
  > ssh hadoop-master
  > exit
  > ssh hadoop-slave1
  > exit
  4. 集群搭建
  4.1 安装hadoop(master主机)
  详见《01_Hadoop集群环境搭建(CentOS)》;
  4.2 配置环境变量(master主机,slave从机分发后)
  详见《01_Hadoop集群环境搭建(CentOS)》;
  4.3 新建文件目录(master主机)
  详见《01_Hadoop集群环境搭建(CentOS)》;
  4.4 配置配置文件(master主机)
  4.4.1 查看配置
  详见《01_Hadoop集群环境搭建(CentOS)》;
  4.4.2 配置hadoop-env.sh
  修改JAVA_HOME
  # 指定JDK的安装位置
  # export JAVA_HOME=$JAVA_HOME
  export JAVA_HOME=/usr/local/java/jdk1.8.0_301
  4.4.3 配置yarn-env.sh
  修改JAVA_HOME
  # 指定JDK的安装位置
  # export JAVA_HOME=/home/y/libexec/jdk1.6.0/
  export JAVA_HOME=/usr/local/java/jdk1.8.0_301
  4.4.4 配置core-site.xml
  注意,实际配置时,将中文注释都去掉,否则在后续初始化时出现编码异常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);
  fs.defaultFS
  hdfs://hadoop-master:8020
  
  hadoop.tmp.dir
  /usr/local/hadoop/hadoop-2.10.1/hdfs/tmp
  
  ha.zookeeper.quorum
  hadoop-master:2181,hadoop-slave1:2181,hadoop-slave2:2181
  
  ha.zookeeper.session-timeout.ms
  10000
        4.4.5 配置hdfs-site.xml   注意,实际配置时,将中文注释都去掉,否则在后续初始化时出现编码异常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);   dfs.replication   3
     dfs.namenode.name.dir   /usr/local/hadoop/hadoop-2.10.1/hdfs/name   true      dfs.datanode.data.dir   /usr/local/hadoop/hadoop-2.10.1/hdfs/data   true      dfs.datanode.edits.dir   /usr/local/hadoop/hadoop-2.10.1/hdfs/edits   true      dfs.nameservices   mycluster      dfs.ha.namenodes.mycluster   nn1,nn2      dfs.namenode.rpc-address.mycluster.nn1   hadoop-master:8020      dfs.namenode.rpc-address.mycluster.nn2   hadoop-slave1:8020      dfs.namenode.http-address.mycluster.nn1   hadoop-master:50070      dfs.namenode.http-address.mycluster.nn2   hadoop-slave1:50070      dfs.namenode.shared.edits.dir   qjournal://hadoop-master:8485;hadoop-slave1:8485;hadoop-slave2:8485/mycluster      dfs.journalnode.edits.dir   /usr/local/hadoop/hadoop-2.10.1/journalnode/data      dfs.ha.fencing.methods   sshfence      dfs.ha.fencing.ssh.private-key-files   /root/.ssh/id_rsa      dfs.ha.fencing.ssh.connect-timeout   30000
     dfs.client.failover.proxy.provider.mycluster   org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider      dfs.ha.automatic-failover.enabled   true         4.4.6 配置yarn-site.xml   注意,实际配置时,将中文注释都去掉,否则在后续初始化时出现编码异常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);   yarn.log-aggregation-enable   true      yarn.log-aggregation.retain-seconds   86400
     yarn.resourcemanager.ha.enabled   true      yarn.resourcemanager.cluster-id   my-yarn-cluster      yarn.resourcemanager.ha.rm-ids   rm1,rm2      yarn.resourcemanager.hostname.rm1   hadoop-slave1      yarn.resourcemanager.hostname.rm2   hadoop-slave2      yarn.resourcemanager.webapp.address.rm1   hadoop-slave1:8088      yarn.resourcemanager.webapp.address.rm2   hadoop-slave2:8088      yarn.resourcemanager.zk-address   hadoop-master:2181,hadoop-slave1:2181,hadoop-slave2:2181      yarn.resourcemanager.recovery.enabled   true      yarn.resourcemanager.store.class   org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore      yarn.nodemanager.aux-services   mapreduce_shuffle      yarn.nodemanager.auxservices.mapreduce.shuffle.class   org.apache.hadoop.mapred.ShuffleHandler         4.4.7 配置mapred-site.xml   复制mapred-site.xml.template文件,并命名为mapred-site.xml;   cp mapred-site.xml.template mapred-site.xml   配置mapred-site.xml:   注意,实际配置时,将中文注释都去掉,否则在后续初始化时出现编码异常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);   mapreduce.framework.name   yarn         4.4.8 配置slaves   配置所有从属节点的主机名或 IP 地址,每行一个。所有从属节点上的 DataNode 服务和NodeManager 服务都会被启动;   把原本的localhost删掉,改为:   hadoop-master   hadoop-slave1   hadoop-slave2   4.5 分发程序(master主机)   将 Hadoop 安装包分发到其他两台服务器;   # hadoop-slave1 和 hadoop-slave2分别创建目录   > mkdir /usr/local/hadoop/   # 将安装包分发到hadoop-slave1   > scp -r /usr/local/hadoop/hadoop-2.10.1 hadoop-slave1:/usr/local/hadoop/   # 将安装包分发到hadoop-slave2   > scp -r /usr/local/hadoop/hadoop-2.10.1 hadoop-slave2:/usr/local/hadoop/   # 总之从机的hadoop_home路径与主机保持一致;   # 修改配置后重新分发,比如修改主机配置文件后   scp -r /usr/local/hadoop/hadoop-2.10.1/etc/hadoop/* hadoop-slave1:/usr/local/hadoop/hadoop-2.10.1/etc/hadoop/   scp -r /usr/local/hadoop/hadoop-2.10.1/etc/hadoop/* hadoop-slave2:/usr/local/hadoop/hadoop-2.10.1/etc/hadoop/   4.6 设置环境变量(slave从机)   在hadoop-slave1和hadoop-slave2设置 Hadoop 的环境变量;同4.2;   5 关闭防火墙   关闭三个主机的防火墙:   > systemctl stop firewalld.service   > systemctl disable firewalld.service   > systemctl status firewalld.service   6 启动运行   6.1 启动Zookeeper   分别到三台服务器上启动 ZooKeeper 服务:   > cd $ZOOKEEPER_HOME/bin   > ./zkServer.sh start   6.2 启动Journalnode   分别到三台服务器的的 ${HADOOP_HOME}/sbin 目录下,启动 journalnode 进程:   > cd ${HADOOP_HOME}/sbin   > ./hadoop-daemon.sh start journalnode   6.3 初始化NameNode   首次启动需要进行初始化,初始化成功不再初始化;   在hadoop-master 上执行 namenode 初始化命令:   > hdfs namenode -format   注意如果出现编码异常,则说明配置文件中有中文字符;主机、从机的配置文件都去掉中文注释;   重新初始化:删除$HADOOP_HOME/hdfs/name、data、tmp的内容,以及$HADOOP_HOME/logs,然后再次format;   执行初始化命令后,需要将 NameNode 元数据目录的内容,复制到其他未格式化的 NameNode 上。元数据存储目录就是我们在 hdfs-site.xml 中使用 dfs.namenode.name.dir 属性指定的目录。这里我们需要将其复制到 hadoop-slave1 上:   > scp -r /usr/local/hadoop/hadoop-2.10.1/hdfs/name hadoop-slave1:/usr/local/hadoop/hadoop-2.10.1/hdfs/   6.4 初始化HA状态   在任意一台 NameNode 上使用以下命令来初始化 ZooKeeper 中的 HA 状态:   > hdfs zkfc -formatZK   6.5 启动HDFS   进入到 hadoop-master 的 ${HADOOP_HOME}/sbin 目录下,启动 HDFS;   此时 hadoop-slave1 和 hadoop-slave2 上的 NameNode 服务,和三台服务器上的 DataNode 服务都会被启动:   > cd ${HADOOP_HOME}/sbin   > ./start-dfs.sh   6.6 启动YARN   进入到 hadoop-slave1 的 ${HADOOP_HOME}/sbin 目录下,启动 YARN;   此时 hadoop-slave2 上的ResourceManager 服务,和三台服务器上的 NodeManager 服务都会被启动:   > cd ${HADOOP_HOME}/sbin   > ./start-yarn.sh   需要注意的是,这个时候 hadoop-slave2 上的 ResourceManager 服务通常是没有启动的,需要到hadoop-slave2 上手动启动:   > cd ${HADOOP_HOME}/sbin   > ./yarn-daemon.sh start resourcemanager   6.7 查看集群   在每台服务器上使用 jps 命令查看服务进程:   在本机(windows)配置hosts:   192.168.25.100 hadoop-master   192.168.25.102 hadoop-slave1   192.168.25.103 hadoop-slave2   查看HDFS Web-UI 界面(节点管理GUI),端口为 50070   http://hadoop-master:50070   http://hadoop-slave1:50070   hadoop-master 上的 NameNode 处于可用状态:   hadoop-slave1 上的 NameNode 则处于备用状态:   同时界面上也有 Journal Manager 的相关信息:   查看 Yarn Web-UI界面(资源管理GUI),端口为 8088 :   http://hadoop-slave1:8088   http://hadoop-slave2:8088   hadoop-slave1 上的 ResourceManager 处于可用状态:   hadoop-slave2 上的 ResourceManager 则处于备用状态:   7 二次启动运行   上面的集群初次启动涉及到一些必要初始化操作,所以过程略显繁琐。但是集群一旦搭建好后,想要再次启用它是比较方便的,步骤如下   1. 分别到三台服务器上启动 ZooKeeper 服务:   > cd $ZOOKEEPER_HOME/bin   > ./zkServer.sh start   2. 在 hadoop-master 启动 HDFS,此时会启动所有与 HDFS 高可用相关的服务,包括 NameNode,DataNode 和 JournalNode:   > cd ${HADOOP_HOME}/sbin   > ./stop-dfs.sh   > ./start-dfs.sh   3. 在 hadoop-slave1 启动 YARN:   > cd ${HADOOP_HOME}/sbin   > ./stop-yarn.sh   > ./start-yarn.sh   4. hadoop-slave2 上的 ResourceManager 服务通常还是没有启动的,需要手动启动:   > cd ${HADOOP_HOME}/sbin   > ./yarn-daemon.sh stop resourcemanager   > ./yarn-daemon.sh start resourcemanager   8 参考资料   以上搭建步骤主要参考自官方文档:   HDFS High Availability Using the Quorum Journal Manager   ResourceManager High Availability   9 问题   9.1 问题1-启动链接journalnode(端口8485)异常   启动hadoop时,出现Call From hadoop-master/192.168.25.100 to hadoop-master:8485 failed on connection exception: java.net.ConnectException: 拒绝连接;   答:   默认情况下namenode启动10s(maxRetries=10, sleepTime=1000)后journalnode还没有启动,就会报上述错误。   由于部署好ha后,首次启动我是分步启动的,没有遇到该问题;之后启动,大约70%情况下会有该问题,30%左右的启动是正常的,究其原因,我想70%的时候journalnode启动比较慢,另有个别时候是启动比较快;   修改core-site.xml中的ipc参数:仅对于这种由于服务没有启动完成造成连接超时的问题,都可以调整core-site.xml中的ipc参数来解决;   ipc.client.connect.max.retries   100
  Indicates the number of retries a client will make to establish a server connection.      ipc.client.connect.retry.interval   10000
  Indicates the number of milliseconds a client will wait for before retrying to establish a server connection.      9.2 问题2: Namenode写Journalnode超时   解决问题1后,启动服务再次出现下述错误:   FATAL org.apache.hadoop.hdfs.server.namenode.FSEditLog: Error: flush failed for required journal (JournalAndStream(mgr=QJM to [192.168.5.100:8486, 192.168.5.102:8486, 192.168.5.103:8486], stream=QuorumOutputStream starting at txid 2947))java.io.IOException: Timed out waiting 20000ms for a quorum of nodes to respond.   答:   修改hdfs-site.xml中的ipc参数:在namenode对应的配置文件中调大写journanode超时参数(默认是20000ms)   < property >   dfs.qj ourn a l.start-segment.timeout.ms   90000 l ue>   < /propert y >   < property >   dfs.qj ourn a l.select-input-streams.timeout.msme>   90000 l ue>   < /propert y >   < property >   dfs.qj ourn a l.write-txns.timeout.ms   90000 l ue>   < /propert y >   修改core-site.xml   ipc.client.connect.timeout   90000
  

OPPO的万物互联系统发布,不同品牌不同设备也能无界协同大家知道,以鸿蒙为代表的万物智联系统,被认为是面向5GAI大数据的下一代操作系统,万物互联多端协同是其典型特征。目前,华为鸿蒙小米妙享均已朝着这个方向探索和实践。昨天下午,OPPO37岁老詹VS37岁邓肯,谁更强?对比各项数据,才发现有人被低估了詹姆斯和邓肯,都是前锋位置上的天花板,尽管球风各异,但在巅峰时期都有着绝对的统治力,也都是联盟少有的常青树球员,那同样是37岁的高龄,詹姆斯和邓肯,谁的表现更胜一筹?詹姆斯37岁,粤夜粤精彩广东广州,游客夜游广州塔,一览羊城最美夜景。广东潮州,华灯初上的潮州古城车水马龙,十分热闹。广东珠海,珠海海韵城大剧院文旅综合体夜晚灯光璀璨。广东清远,夜幕降临后的南岸公园,一名网衔草筑巢菡萏上栖息河北河间昔日坑塘成鸟类天堂图为在河北河间瀛州水系公园,一只翠鸟在菡萏上栖息。周国敬摄图为在河北河间瀛州水系公园,一只苇莺在荷花上啁啾。周国敬摄图为在河北河间瀛州水系公园,灰翅浮鸥在衔草筑巢。周国敬摄图为在河世界上最大的天坑,竟然藏在重庆市的这个郊县,你来玩过吗?这里是刘小顺的旅行和生活研究所。相信很多朋友出去旅游,都喜欢欣赏大自然鬼斧神工的景观,比如自然形成的天坑奇景,就往往让人流连忘返。顾名思义,所谓的天坑,就是指发育在喀斯特地区的一种百里荒露营俏起来8月24日傍晚,百里荒景区露营地灯火通明。远眺宜昌城区,高楼林立灯火辉煌,磨基山至喜长江大桥葛洲坝等标志性建筑清晰可见。近年来,百里荒旅游度假区充分利用天然凉机,全力打造宜昌首个高诺诗诺画诺尔盖极目黄河九曲第一湾诺诗诺画诺尔盖极目黄河九曲第一湾在我国青藏高原东部边缘,川甘青三省交界的阿坝州北部群山环抱之中,有一片富饶而美丽的高原草甸湿地诺尔盖大草原。它是我国仅次于呼伦贝尔的第二大草原,一年江西喝酒怪象,有人喝四特酒,有人喝李渡酒,但更偏爱这3款江西是我国所有省份中存在感较弱的一个省份,提起江西你可能没有特别深的印象,但是你一定知道落霞与孤鹜齐飞,秋水共长天一色的滕王阁,横看成岭侧成峰,远近高低各不同的庐山,以及蒿溪黛瓦翠行业人员暗示好消息,解决卡脖子是否曙光初现?导读最近中国信息业,电子行业,光刻机,芯片行业的某些行业人员似乎有些不同寻常,他们频频暗示好消息,解决卡脖子的问题是否曙光初现?自从美国加大了在科技技术行业的限制,很多人都关注到卡湖南电信携手中兴通讯完成2。1GHz8TR5GNR首商用覆盖优势明显为贯彻落实国家加快5G等新型基础设施建设要求,持续加强5G网络覆盖的广度和深度,打造高质量5G精品网,湖南电信联合中兴通讯在常德电信分公司完成首个2。1GHz8TR5GNR商用试点安徽人游安徽红游九华沉浸式体验红色文化九华山为皖南腹地北部的主入口,西南为皖赣边境,北临长江,西望大别山,且又紧临皖赣南区和鄂豫皖根据地,在早期革命时期,特别是在抗日战争和解放战争时期,战略地位突出,九华山已发展成为皖