51cto趙強HADOOP學習(八)

weixin_33797791發表於2017-12-14

使用Sqoop匯入關係型資料庫中的資料

資料的交換和整合

使用Sqoop進行HDFS和RDBMS資料的交換
什麼是Sqoop?
SQL-to-HDFS工具
利用JDBC連結關係型資料庫
Sqoop的獲取(偽分佈)
#mkdir tools
#cd tools
#tar -zxvf sqoop-1.4.5.bin__hadoop-0.23.tar.gz -C ~/training/
#cd ~/training
# cd sqoop-1.4.5.bin__hadoop-0.23/
# pwd
/root/training/sqoop-1.4.5.bin__hadoop-0.23
#vi ~/.bash_profile
export SQOOP_HOME=/root/training/sqoop-1.4.5.bin__hadoop-0.23

export PATH=$SQOOP_HOME/bin:$PATH
#source ~/.bash_profile

匯入Oracle資料庫表中指定的列

#sqoop import --connect jdbc:oracle:thin:@ip:1521:orcl --username scott --password tiger --table emp --columns 'empno,ename,sal' -m 1
#hdfs dfs -ls /

匯入Oracle資料庫表中指定的列,並且指定分隔符和HDFS的路徑

#sqoop import --connect jdbc:oracle:thin:@ip:1521:orcl --username scott --password tiger --table emp --columns 'empno,ename,sal' -m 1 --target-dir '/sqoop/data1' --fields-terminated-by '**'
#hdfs dfs -lsr /sqoop/data1

匯入Oracle資料庫表中的資料,並使用query語句

#sqoop import --connect jdbc:oracle:thin:@ip:1521:orcl --username scott --password tiger --query 'select * from emp where deptno=10 and $CONDITINOS' -m 1 --target-dir '/sqoop/data2'

使用Apache Flume採集資料

什麼是Flume?

-Apache Flume是Cloudera提供的一個高可用的,高可靠的,分散式的海量日誌採集、聚合和傳輸的系統,Flume支援在日誌系統中定製各類資料傳送方,用於收集資料;同時Flume提供對資料進行簡單處理,並寫到各種資料接受方(可定製)的能力

cd tools
tar -zxvf apache-flume-1.6.0-bin.tar.gz -C ~/training/
cd ~/training
cd apache-flume-1.6.0-bin/
cd conf
mv flume-env.sh.template flume-env.sh
vi flume-env.sh
export JAVA_HOME=/root/training/jdk1.8.0_144 
cd ..
mkdir /root/training/mylogs
mkdir myagent
cd myagent
vi a3.conf
#bin/flume-ng agent -n a3 -f myagent/a3.conf -c conf -Dflume.root.logger=INFO,console
#定義agent名,source、sink的名稱
a3.sources = r1
a3.channels =c1
a3.sinks = k1

#具體定義source
a3.sources.r1.type = spooldir
a3.sources.r1.spoolDir = /root/training/mylogs

#具體定義channel
a3.channels.c1.type = memory
a3.channels.c1.capacity = 1000
a3.channels.c1.transactionCapacity = 100

#具體定義sink
a3.sinks.k1.type = logger

#組裝source、channel、sink
a3.sources.r1.channels = c1a3.sinks.k1.channel = c1
a3.sinks.k1.channel = c1
#cd ..
#bin/flume-ng agent -n a3 -f myagent/a3.conf -c conf -Dflume.root.logger=INFO,console
cd training
vi a.txt
mv a.txt mylogs/
~/training/apache-flume-1.6.0-bin/
cd myagentls
vi a4.conf
#定義agent名,source、sink的名稱
a4.sources = r1
a4.channels =c1
a4.sinks = k1

#具體定義source
a4.sources.r1.type = spooldir
a4.sources.r1.spoolDir = /root/training/mylogs

#具體定義channel
a4.channels.c1.type = memory
a4.channels.c1.capacity = 1000
a4.channels.c1.transactionCapacity = 100

#定義攔截器,為訊息新增時間戳
a4.sources.r1.interceptors = i1
a4.sources.r1.interceptors.i1.type = org.apache.flume.interceptor.TimestampInterceptor$Builder


#具體定義sink
a4.sinks.k1.type = hdfs
a4.sinks.k1.hdfs.path = hdfs:192.168.56.102:9000/flume/%Y%m%d
a4.sinks.k1.hdfs.filePrefix = events-
a4.sinks.k1.hdfs.fileType = DataStream
#不按照條數生成檔案
a4.sinks.k1.hdfs.rollCount = 0
#HDFS上的問價能達到128M時生成一個檔案
a4.sinks.k1.hdfs.rollSize = 134217728
#HFDS上的檔案達到60秒生成一個檔案
a4.sinks.k1.hdfs.rollInterval = 60

#組裝source、channel、sink
a4.sources.r1.channels =c1
a4.sinks.k1.channel = c1
cd ..
bin/flume-ng agent -n a4 -f myagent/a4.conf -c conf -Dflume.root.logger=INFO,console

ls mylogs
vi a.txt
mv a.txt mylogs/
ls mylogs
hdfs dfs -ls
vi a.txt
mv a.txt mylogs
hdfs dfs -ls /
hdfs dfs -lsr /flume
hdfs dfs -cat 

HDFS與Apache Kafka

什麼是Apache Kafka?

Apache Kafka是分散式釋出-訂閱訊息系統。它最初由LinkedIn公司開發,之後成為Apache專案的一部分。Kafka是一種快速、可擴充套件的、設計內在就是分散式的,分割槽的和可複製的提交日誌服務
9291012-bc646e26dde4b95b.png
image.png

啟動zookeeper叢集

#cd tools
# tar -zxvf kafka_2.9.2-0.8.1.1.tgz -C ~/training/
#cd ~/training
# cd kafka_2.9.2-0.8.1.1/
# mkdir -p logs/broker1
# mkdir -p logs/broker2
cd logs/broker1
#pwd
/root/training/kafka_2.9.2-0.8.1.1/logs/broker1
#cd ../../config
# vi server.properties 
log.dirs=/root/training/kafka_2.9.2-0.8.1.1/logs/broker1
zookeeper.connect=192.168.56.11:2181,192.168.56.12:2181,192.168.56.13:2181
# cp server.properties server1.properties
#vi server1.properties 
broker.id=1
port=9093
#cd ..
#jps
# bin/kafka-server-start.sh config/server.properties &
# bin/kafka-server-start.sh config/server2.properties &
# vi config/server1.properties 
log.dirs=/root/training/kafka_2.9.2-0.8.1.1/logs/broker2
# bin/kafka-server-start.sh config/server2.properties &
#jps
17413 Jps
17240 Kafka
17374 Kafka
# bin/kafka-topics.sh --create --zookeeper 192.168.56.11:2181 --replication-factor 1 --partitions 3 --topic mydemo2

複製一個,當前的命名為消費者,另一個命名為生產者

9291012-4510bc9d22b5bd87.png
image.png

生產者

# cd training/kafka_2.9.2-0.8.1/
# ls bin/
# bin/kafka-console-producer.sh --broker-list 192.168.56.102:9092 --topic mydemo2

消費者

# bin/kafka-console-consumer.sh --zookeeper 192.168.56.11:2181 --topic mydemo2

生產者

HelloWorld
9291012-e7caf380615cc75c.png
image.png

9291012-3c7e7547b19beeab.png
image.png

Apache Kafka與Hadoop HDFS的整合

對於一個實時訂閱的系統來說,可以通過Kafka將實時處理和監控的資料載入到Hadoop的HDFS中,或者NoSQL資料庫中,或者資料倉儲中。

Kafka提供了Hadoop Producer和Consumer用於整合Hadoop

9291012-d12355ae7edebaa2.png
image.png

KafkaHDFSConsumer.java

package demo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector;


/*
 * 完成兩件事情:
 * 1、作為Kafka的消費者讀取Topic中的資訊
 * 2、將資訊寫入HDFS
 */

public class KafkaHDFSConsumer extends Thread{
    
    //指定具體topic名稱
    private String topic;
    
    public KafkaHDFSConsumer(String topic) {
        this.topic = topic;
        
    }
    
    public void run() {
        //構造一個consumer的物件
        ConsumerConnector consumer = createConsumer();
        
        //構造一個Map物件,代表topic
        Map<String,Integer> topicCountMap = new HashMap<String,Integer>();
        topicCountMap.put(this.topic, 1);
        
        //構造一個輸入流
        Map<String,List<KafkaStream<byte[],byte[]>>> messageStreams = consumer.createMessageStreams(topicCountMap);
        
        //獲取每次接收到的具體資料
        KafkaStream<byte[],byte[]> stream = messageStreams.get(this.topic).get(0);
        
        ConsumerIterator<byte[],byte[]> iterator = stream.iterator();
        while(iterator.hasNext()) {
            String message = new String(iterator.next().message());
            //列印
            System.out.println("接收訊息:" + message);
            
            //將訊息寫入HDFS
            try {
                HDFSUtils.sendMessageToHDFS("/kafka/data1.txt", message);
            }catch (Exception e) {
                e.printStackTrace();
            }
            
        }
        
    }

    //建立一個Consumer
    private ConsumerConnector createConsumer() {
        Properties prop = new Properties();
        prop.put("zookeeper.connect", "192.168.56.11:2181,192.168.56.12:2181,19.168.56.13:2181");
        
        //申明一個消費組
        prop.put("group.id", "group1");
        
        return Consumer.createJavaConsumerConnector(new ConsumerConfig(prop));
    }

    public static void main(String[] args) {
        new KafkaHDFSConsumer("mydemo").start();
    

    }

}

HDFSUtils

package demo;

import java.io.OutputStream;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class HDFSUtils {
    
    //定義一個檔案系統的物件
    private static FileSystem fs;
    
    static {
        Configuration conf = new Configuration();
        conf.set("dfs.client.block.write.replace-datanode-on-failure.policy", "NEVER");
        conf.set("dfs.client.block.write.replace-datanode-on-failure.enable", "true");
        
        try {
            fs = FileSystem.get(new URI("hdfs://192.168.56.102:9000"),conf);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void sendMessageToHDFS(String filename,String data) throws Exception{
        OutputStream out = null;
        
        if(!fs.exists(new Path(filename))) {
            //建立檔案
            out = fs.create(new Path(filename));
        }else {
            //如果存在,則追加
            out = fs.append(new Path(filename));
        }
        
        //將資料寫入HDFS
        out.write(data.getBytes());
        out.close();
        
    }

}

#bin/kafka-console-producer.sh --broker-list 192.168.56.102:9092 --topic mydemo2

管理和監控MapReduce任務

yarn application -list  //檢視正在執行的任務
yarn application -list -appState<State>  //檢視叢集中某個狀態的所有任務
yarn application -status <application_ID>  //檢視單個任務的狀態資訊

Yarn的資源管理和排程

資源池

使用者提交的作業將會放進一個能夠公平共享資源的Pool(池)中。
系統資源不會與某個具體的池繫結
資源池可以預先定義:也可以在提交任務的時候,動態指定資源池的名稱
資源池及其子集,在fair-scheduler.xml中定義

三種方式:

FIFO:基於佇列的FIFO排程器(MapReduce 1.0)

Capacity Scheduler:容器排程器

Fair Scheduler:公平排程器
為所有的應用分配公平的資源(對公平的定義可以通過引數來設定)
9291012-9f1618ce48ba422e.png
image.png

9291012-4eaf94ae5b43ee88.png
image.png

配置Fair Scheduler

Fair Scheduler的配置選項包括兩部分

其中一部分在yarn-site.xml中,主要用於配置排程器級別的引數
另外一部分在一個自定義配置檔案(預設是fair-scheduler.xml)中,主要用於配置各個佇列的資源量、權重等資訊

相關文章