大數據學習過程筆記——第一階段

大數據學習過程筆記

大數據學習視頻網址推薦博客
Hadoop安裝配置說明頁
Hadoop架構介紹

—> CentOS可能會用到的依賴:
yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers
—>linux中一些開發工具的默認地址:
jdk(rpm安裝)的安裝目錄是:/usr/java/jdk1.7
vsftpd(yum安裝)的安裝目錄是:/etc/vsftpd
nginx(make編譯)的安裝目錄是:/usr/local/nginx
cmake(gmake編譯安裝依賴)的版本是:3.6對應低版本的gcc、gcc-c++,這樣才能夠兼容

僞分佈式模式安裝步驟(在一臺主機模擬多主機,其中的每個守護進程都以Java進程的形式運行,其在單機模式的基礎上增加了代碼調試功能,並允許檢查內存使用情況,HDFS輸入輸出以及其他守護進程交互):
安裝請參考文檔

——>首先是配置hadoop-evn.sh文件中的Java路徑
——>主要是修改三個配置文件——>core-site.xml, hdfs-site.xml, mapred-site.xml(並需要更改yarn-site.xml文件)
修改yarn-site.xml時,此處有不同的地方:
  <!-- 指定YARN的老大 (ResourceManager)的地址 -->
  <property>
    <name>yarn.resourcemanager.hostname</name>
    <value>weekend110</value>
  </property>
  <!-- reducer獲取數據方式 -->
  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>
——>格式化文件系統:
沒有將Hadoop的bin目錄添加到/etc/profile情況下,需要cd到Hadoop2.x.x/bin目錄下執行以下命令,否則可以直接執行該命令:
hadoop namenode -format (格式化成功之後,會看到success字樣)
在hadoop-2.x.x/data/dfs/name/current目錄下會看到一些文件即爲元數據

傳智播客Hadoop八天培訓
(總共71個視頻101-807)

Hadoop應用場景:
——>解決問題:
    海量數據的存儲(HDFS)
    海量數據的分析(MapReduce)
    資源管理調度(YARN)
——>Hadoop擅長日誌分析(海量的離線日誌分析)
——>實時的位置數據(實現廣告的推送)

Hadoop對海量數據處理的解決思路:
——>海量數據存儲
——>海量數據計算

Hadoop版本:
——>Apache
——>CDH(Cloudra)
——>HDP

讓普通用戶具備sudo執行權限:
切換到root
然後 vim /etc/sudoers 加入一行
root	ALL=(ALL)	ALL
hadoop    ALL=(ALL)	ALL
讓Linux服務器在啓動時不要啓動圖形界面:
sudo vim /etc/inittab
將啓動級別改成3
id:3:initdefault

HDFS的實現思想:
    1.hdfs是通過分佈式集羣來存儲文件(爲客戶端提供了一個便捷的訪問方式,就是一個虛擬的目錄結構)
    2.文件存儲到hdfs集羣匯中去的時候是被切分成block的
    3.文件的block存放在若干臺datanode節點上
    4.hdfs文件系統中的文件與真實的block之間的映射關係,由namenode管理
    5.每一個block在集羣中會存儲多個副本,好處是可以提高數據的可靠性,還可以提高訪問的吞吐量
遠程拷貝:(以dfss和hadoop02兩臺主機爲例,在dfss主機上進行操作)
scp id_rsa.pub hadoop02:[FilePath]
追加一個文件的內容到另一個文件中去:
cat ../id_rsa.pub >> ./authorized_keys
namenode記錄元數據:
  1.客戶端上傳文件時,NN首先往edits log文件中記錄元數據操作日誌
  2.客戶端開始上傳文件,完成後返回成功信息給NN,NN就在內存中寫入這次上傳操作的新產生的元數據信息
  3.每當editslog寫滿時,需要將這一段時間新的元數據刷到fsimage文件中去
  SecondaryNameNode:將editslog文件合併到fsimage文件中
datanode提供真實的文件數據存儲服務:
  1.文件塊(block):最基本的存儲單位(HDFS默認block大小是128M);
  2.不同於普通文件系統的是,HDFS中,如果一個文件小於一個數據塊的大小,並不佔用整個數據塊存儲空間;
  3.Replication,多副本,默認是三個(hdfs-site.xml的dfs.replication屬性)

====>HDFS讀寫文件過程

讀文件過程:
  1.使用HDFS提供的客戶端開發庫Client,向遠程的Namenode發起RPC請求;
  2.Namenode會視情況返回文件的部分或者全部block列表,對於每個block,Namenode都會返回有該block拷貝的DataNode地址;
  3.客戶端開發庫Client會選取離客戶端最接近的DataNode來讀取block;如果客戶端本身就是DataNode,那麼將從本地直接獲取數據。
  4.讀取完當前block的數據後,關閉與當前的DataNode連接,併爲讀取下一個block尋找最佳的DataNode;
  5.當讀完列表的block後,且文件讀取還沒有結束,客戶端開發庫會繼續向Namenode獲取下一批的block列表。
  6.讀取完一個block都會進行checksum驗證,如果讀取datanode時出現錯誤,客戶端會通知Namenode,然後再從下一個擁有該block拷貝的datanode繼續
寫文件過程:
  1.使用HDFS提供的客戶端開發庫Client,向遠程的Namenode發起RPC請求;
  2.Namenode會檢查要創建的文件是否已經存在,創建者是否有權限進行操作,成功則會爲文件創建一個記錄,否則會讓客戶端拋出異常;
  3.當客戶端開始寫入文件的時候,開發庫會將文件切分成多個packets,並在內部以數據隊列"data queue"的形式管理這些packets,並向Namenode申請新的blocks,獲取用來存儲replicas的合適的datanodes列表,列表的大小根據在Namenode中對replication的設置而定。
  4.開始以pipeline(管道)的形式將packet寫入所有的replicas中。開發庫把packet以流的方式寫入第一個datanode,該datanode把該packet存儲之後,再將其傳遞給在此pipeline中的下一個datanode,直到最後一個datanode,這種寫數據的方式呈流水線的形式。
  5.最後一個datanode成功存儲之後會返回一個ack packet, 在packet裏傳遞至客戶端,在
  客戶端的開發庫內部維護着"ack queue", 成功收到datanode返回的ack packet後會從
  "ack queue"移除相應的packet。
  6.如果傳輸過程中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的pipeline中移除,剩餘的block會繼續剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的datanode,保持replicas設定的數量。
Rack Awareness策略:
  1.第一個block副本放在和client所在的node裏(如果client不在集羣範圍內,則這第一個node是隨機選取的,系統會嘗試不選擇哪些太滿或者太忙的node)。
  2.第二個副本放置在與第一個節點不同的機架中的node中(隨機選擇)。 
  3.第三個副本和第二個在同一個機架,隨機放在不同的node中。
常用管理命令:
hadoop-daemon.sh
hdfs 
hdfs dfs
hdfs dfsadmin
hadoop namenode -format (格式化成功之後,會看到success字樣)

啓動Hadoop過程中遇到的namenode節點啓動失敗的問題:(logs中的namenode日誌中報錯txid啓動錯誤)

——>原因:
Hadoop NN中的元數據包括:
fsimage:包含某個時間點的文件系統的完整狀態
edit logs:包含在最近的fsimage之後進行的每個文件系統更改(文件創建/刪除/修改)

當NN啓動時,Hadoop將加載fsimage並應用所有編輯日誌,同時進行大量的一致性檢查,如果檢查失敗,它將終止。當我們將NN該工作區中的edits_00...0001-00...002刪掉時,然後嘗試sbin/start-dfs.sh,將在日誌中收到edits-logs信息不匹配的日誌並且啓動失敗。
——>解決辦法:
在Hadoop家目錄下執行:./bin/hadoop namenode -recover
在一堆提示後選擇yes, 然後選擇c, 之後日誌內容將會改變
使用單一節點啓動命令: hadoop-daemon.sh start namenode 重新啓動namenode節點
jps查看各節點啓動狀態,即發現namenode節點啓動成功

修改namenode日誌後啓動hadoop時datanode節點啓動失敗的問題:(logs中的datanode日誌中報錯添加文件失敗)

——>原因:
會出現該問題以及上一個問題,是因爲多次對namenode進行format, 每一次format主節點NameNode產生新的clusterID、namespaceID, 於是導致主節點的clusterID、namespaceID、與各個子節點DataNode不一致。當format過後再啓動hadoop, hadoop嘗試創建新的current目錄, 但是由於已存在current目錄, 導致創建失敗, 最終引起DataNode節點的DataNode進程啓動失敗, 從而引起hadoop集羣完全啓動失敗。
——>解決辦法:
重命名原current文件爲current-bak文件(文件名隨意,文件在/hadoop-2.7.7/data/tmp/dfs/data目錄下),再重新啓動hadoop,可以發現datanode節點成功啓動,並且可以順利的上傳文件到節點內。

上傳文件報錯,未能識別hdfs文件系統(Wrong FS: hdfs://hadoop20:9000/word.txt, expected: file:///):

解決辦法有兩種:
1.直接通過在代碼,在conf中設置默認文件系統
2.直接將hadoop文件配置中的core-site.xml和hdfs-site.xml文件拷貝到項目的src文件目錄下,代碼在運行的時候就會先讀取core-site.xml文件中的配置信息。
NameNode職責:
1.維護元數據信息
2.維護hdfs目錄樹
3.響應客戶端請求

Hadoop中的RPC框架實現機制:
RPC框架實現機制

hdfs中下載數據的源代碼解析:
HDFS下載數據源碼分析過程

hdfs中打開數據流的源代碼解析:
HDFS打開輸入流源碼分析過程


MapReduce編程:
每個map都要繼承Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
在上述Mapper類的4個泛型中,前兩個是指定mapper輸入數據的類型,KEYIN是輸入的key的類型, VALUEIN是輸入的value的類型;
map和reduce的數據輸入輸出是以 key-value對的形式封裝的
默認情況下,框架傳遞給我們的mapper的輸入數據中,key是要處理的文本中一行的起始偏移量,這一行的內容作爲value
——>Hadoop中特有的數據類型:(因爲數據在不同節點之間進行通信的時候需要對數據進行序列化處理,而jdk自帶的數據類型在進行序列化處理的時候會添加一些冗餘的信息,這對海量數據的處理非常不友好,所以Hadoop自定義了一些數據類型以消除序列化冗餘所帶來的影響)
如:
Long -> LongWritable
String -> Text等等

MR程序的幾種提交運行模式:

本地模式運行:
1.在Windows中的eclipse裏直接運行main方法,就會將job提交給本地執行器localjobRunner執行
    ————輸入輸出數據可以放在本地路徑下(D:/xx/xx/)
    ————輸入輸出數據也可以放在hdfs中(hdfs://hadoop:9000/xx/xx/)
2.在Linux的eclipse裏直接運行main方法,但是不要添加yarn相關的配置,也會提交給localjobRunner執行
    ————輸入輸出數據可以放在本地路徑下(/home/hadoop/Desktop/xx/xx/)
    ————輸入輸出數據也可以放在hdfs中(hdfs://hadoop:9000/xx/xx/)
集羣模式運行:
1.將工程打成jar包,上傳到服務器,然後用hadoop命令提交 hadoop jar your.jar package.WCRunner(main方法所在類)
2.在Linux的eclipse中直接運行main方法,也可以提交到集羣中去運行,但是,必須採取以下措施:
    ————在工程src目錄下加入mapred-site.xml和yarn-site.xml
    ————將工程打成jar包(your.jar), 同時在main方法中添加一個conf的配置參數 conf.set("mapreduce.job.jar", "your.jar")

3.在Windows的eclipse中直接運行main方法,也可以提交給集羣中運行,但是因爲平臺不兼容,需要做很多的設置:
    ————要在Windows中存放一份hadoop的安裝包(解壓好的)
    ————要將其中的lib和bin目錄替換成根據你的Windows版本重新編譯出的文件
    ————再配置系統環境變量 HADOOP_HOME 和 PATH
    ————修改YarnRunner這個類的源碼
Yarn的通用性意義:
使得Hadoop框架的可擴展性大大增強(在HDFS文件系統的加持下,通過yarn對各種運算框架進行任務分配及管理,如MP的海量批處理、Spark的迭代處理以及Storm的實時流處理,各種計算框架只需要實現yarn框架中的AppMaster接口即可完成擴展)

Yarn提交Job的源碼分析:
在這裏插入圖片描述


Hadoop中的序列化機制:
.....
——>在實際編碼過程中,可以通過實現Writable接口或者是WritableComprable接口來完成IO流的序列化與反序列化
hadoop自定義排序實現:
——>在序列化的基礎上,封裝的數據對象可以通過實現Comprable接口來實現最終的排序
hadoop自定義分組實現(例如將全國的號碼分成各個省的號碼分別進行處理):
默認是根據key的hash 值進行分組
1.自定義過程中是通過將分組字典加載在緩存中,以map的形式實現,在加載類(該類繼承了Hadoop中的Partitioner類,重寫getPartition來返回一條數據的組號)的時候,static變量只初始化一次於緩存內,這樣可以通過該邏輯來確定最終的分組
2.默認是隻生成1個reduce任務,可以通過job.setNumReduce(tasks)來指定Reducer任務數量,從而對應各個分組進行任務處理。

1.map task的併發數量是由切片的數量決定的,有多少個切片,就啓動多少個map task
2.切片是一個邏輯的概念,指的就是文件中數據的偏移量範圍
3.切片的具體大小應該根據所處理的文件的大小來調整
shuffle機制(分組與排序以及各種緩存機制):

綜合上述幾個點就構成了mapreduce的組件全貌(包括InputFormat和OutputFormat):

textinputformat對切片規劃的源碼分析:

Hadoop權威指南——>內容詳細,但是實戰性的內容不多,主要是從技術機制上進行分析(即理論)
老師提到有一本關於Hadoop源碼分析的書,可能會與實戰有關

——>關於多個job在同一個main中提交的做法是不提倡的,解決辦法可以在shell腳本中指定若干job先後在任務中進行提交運行。
zookeeper高可用:
提供少量的數據的存儲和管理(即一些狀態信息,非業務信息)
提供對數據節點的監聽器功能
——>是什麼: 分佈式應用服務組件
——>爲什麼: 1.大部分分佈式應用需要一個主控、協調器或控制器來管理物理分佈的子進程(如資源、任務分配等)
2.大部分應用需要開發私有的協調程序,缺乏一個通用的機制
3.協調程序的反覆變謝謝誒浪費,且難以形成通用、伸縮性好的協調器
4.ZooKeeper提供通用的分佈式鎖服務,用以協調分佈式應用
——>怎麼用:
1.ZooKeeper的安裝和配置(集羣模式):
創建myid文件,server.1機器的內容爲:1,server.2機器的內容爲:2,server.3機器的內容爲:3
2.在conf目錄下創建一個配置文件zoo.cfg,
tickTime=2000
dataDir=/xxx/xxx/zookeeper/data
dataLogDir=/xxx/xxx/zookeeper/dataLog
clientPort=2181
initLimit=5
syncLimit=2
server.1=server1:2888:3888
server.2=server2:2888:3888
server.3=server3:2888:3888
3.將配置好的zk拷貝到其他節點:
    scp -r xx/xx/zookeeper3.x.x/ hostname:xx/xx/
    scp -r xx/xx/zookeeper3.x.x/ hostname:xx/xx/
4.注意:在其他節點上一定要修改myid的內容(見步驟1)
5. /bin/zkServer.sh start啓動zookeeper
配置Linux虛擬機靜態IP:
...
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=yes
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
...
zookeeper集羣啓動過程中遇到的問題:
1.啓動zookeeper之後,查看狀態,顯示爲ERROR,說明集羣機器數量沒有達到標準或者是各機器之間沒有識別到各自的存在:
(在啓動每臺機器的時候,可以通過命令./zkServer.sh start-foreground來啓動,這樣在啓動以及後續的過程中就能實時查看到集羣中的各機器在啓動過程中拋出的錯誤,這樣就可以根據出現的錯誤解決問題)
2.在掛起客戶機並重新開啓後,查看狀態,QuorumPeerMain沒有開啓,並且也無法重新開啓,在關閉佔用2181端口的進程之後,重啓zookeeper後,查看狀態,顯示Follwer,並且其他兩臺機器一臺顯示Follwer一臺顯示Leader,但是一段時間後再觀察狀態,ERROR又出現了...,之後重啓集羣中的各機器(使用上面的命令),恩,奇蹟又出現了,有點捉摸不透。
3.關於zookeeper的初始配置:
重命名conf/下的zoo.sample.cfg爲zoo.cfg,並編輯修改其中的內容(更改其中的dataDir路徑並在最後添加server.?=hostname:2888:3888,其中?是自定義的機器編號,需要和接下來在data/下新建的myid中的內容一致,2888是指首選通信端口,3888即爲次選端口)
在data/下新建myid文件,並向其中寫入機器對應的編號
zookeeper應用場景:
1.統一命名服務:
2.配置管理:
——>Dubbo(阿里開源框架)
3.集羣管理:Zookeeper不僅能夠維護當前的集羣中機器的服務狀態,而且能夠選出一個“總管”,讓這個總管來管理集羣(即Leader Election)
4.共享鎖
Zookeeper提供了一套很好的分佈式集羣管理的機制,就是它這種基於層次型的目錄樹的數據結構,並對樹中的節點進行有效管理,從而可以設計出多種多樣的分佈式的數據管理模型 。
NameNode高可用方案(HA)要點1:
hdfs中的Namenode只有一個,雖然有SecondaryNamenode提供保障,但是高可用性還是不能實現,所以就需要考慮提供另外一臺Namenode節點

Hadoop-HA機制的配置文件:(共需啓動7臺機器來組成高可用HA的Hadoop集羣)
1. NameNode   zkfc
2. NameNode   zkfc
3. resourcemanager
4. resourcemanager
5. ZooKeeper  journalnode   datanode  nodemanager
6. ZooKeeper  journalnode   datanode  nodemanager
7. ZooKeeper  journalnode   datanode  nodemanager


集羣規劃:
  主機名       IP                安裝的軟件                     運行的進程
  hadoop    192.168.79.139  jdk、hadoop、zookeeper、nginx、....  DataNode、NodeManager、JournalNode、QuorumPeerMain
  hadoop02  192.168.79.138  jdk、hadoop、zookeeper              DataNode、NodeManager、JournalNode、QuorumPeerMain
  hadoop03  192.168.79.140  jdk、hadoop、zookeeper              DataNode、NodeManager、JournalNode、QuorumPeerMain
  hadoop04  192.168.79.128  jdk、hadoop                        NameNode、DFSZKFailoverController(zkfc)  
  hadoop05  192.168.79.129  jdk、hadoop                        NameNode、DFSZKFailoverController(zkfc)
  hadoop06  192.168.79.130  jdk、hadoop                        ResourceManager
  hadoop07  192.168.79.131  jdk、hadoop                        ResourceManager
說明:
  1.在hadoop2.0中通常由兩個NameNode組成,一個處於active狀態,另一個處於standby狀態。Active NameNode對外提供服務...
  hadoop2.0官方提供了兩種HDFS HA的解決方案,一種是NFS,一種是QJM,這裏我們使用簡單的QJM。在該方案中...
  這裏還配置了一個zookeeper集羣,用於ZKFC(DFSZKFailoverController)故障轉移,當Active NameNode掛掉了,會自動切換到Standby NameNode節點....
  2.hadoop-2.2.0中依然存在一個問題,就是ResourceManager只有一個,存在單點故障,hadoop2.4.1解決了這個問題,
集羣配置:
1.安裝、配置環境變量
...(基礎配置)
2.修改hadoop配置文件:
->修改core-site.xml
  <configuration>
    <!--指定hdfs的nameservice爲ns1-->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://ns1/</value>
    </property>
    <!--指定hadoop臨時目錄-->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/xxxx/software/hadoop-2.7.7/data/tmp</value>
    </property>
    <!--指定zookeeper地址-->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>hadoop:2181,hadoop02:2181,hadoop03:2181</value>
    </property>
  </configuration>

->修改hdfs-site.xml
  <configuration>
      <!--指定hdfs的nameservice爲ns1,需要和core-site.xml中保持一致-->
      <property>
          <name>dfs.nameservices</name>
          <value>ns1</value>
      </property>
      <!--ns1下面有兩個NameNode,分別是nn1,nn2-->
      <property>
          <name>dfs.ha.namenodes.ns1</name>
          <value>nn1,nn2</value>
      </property>
      <!--nn1的RPC通信地址-->
      <property>
          <name>dfs.namenode.rpc-address.ns1.nn1</name>
          <value>hadoop04:9000</value>
      </property>
      <!--nn1的http通信地址-->
      <property>
          <name>dfs.namenode.http-address.ns1.nn1</name>
          <value>hadoop04:50070</value>
      </property>
      <!--nn2的RPC通信地址-->
      <property>
          <name>dfs.namenode.rpc-address.ns1.nn2</name>
          <value>hadoop05:9000</value>
      </property>
      <!--nn2的http通信地址-->
      <property>
          <name>dfs.namenode.http-address.ns1.nn2</name>
          <value>hadoop05:50070</value>
      </property>
      <!--指定NameNode的元數據在JournalNode上的存放位置。其value有兩種,一種是NFS,一種是qjournal
        qjournal集羣中會保存很多個ns的元數據,所以每一對NN所對應的元數據存放在相應的目錄下->/ns1
      -->
      <property>
          <name>dfs.namenode.shared.edits.dir</name>
          <value>qjournal://hadoop:8485;hadoop02:8485;hadoop03:8485/ns1</value>
      </property>
      <!--指定JournalNode在本地磁盤存放數據的位置-->
      <property>
          <name>dfs.journalnode.edits.dir</name>
          <value>/home/xxxx/software/hadoop-2.7.7/journaldata</value>
      </property>
      <!--開啓NameNode失敗自動切換-->
      <property>
          <name>dfs.ha.automatic-failover.enabled</name>
          <value>true</value>
      </property>
      <!--配置失敗自動切換實現方式-->
      <property>
          <name>dfs.client.failover.proxy.provider.ns1</name>
          <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
      </property>
      <!--配置隔離機制方法,多個機制用換行分割,即每個機制暫用一行-->
      <property>
          <name>dfs.ha.fencing.methods</name>
          <value>
            sshfence
            shell(/xxx/xxx/xx.sh或者是/bin/true (系統自帶的?))
          </value>
      </property>
      <!--使用sshfence隔離機制時需要ssh免登陸-->
      <property>
          <name>dfs.ha.fencing.ssh.private-key-files</name>
          <value>~/.ssh/id_rsa</value>
      </property>
      <!--配置sshfence隔離機制超時時間-->
      <property>
          <name>dfs.ha.fencing.ssh.connect-timeout</name>
          <value>30000</value>
      </property>
  </configuration>

->修改mapred-site.xml
<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>

->修改yarn-site.xml
<configuration>
    <!-- 開啓RM高可用 -->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
    <!-- 指定RM的cluster id。 value的值是自定義的-->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>yrc</value>
    </property>
    <!-- 指定RM的名字 -->
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>
    <!-- 分別指定RM的地址 -->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>hadoop06</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>hadoop07</value>
    </property>
    <!-- 指定zk集羣地址 -->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>hadoop:2181,hadoop02:2181,hadoop03:2181</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
</configuration>

集羣之間配置無密登錄:
->爲了不會發生混亂,先清除之前配置的ssh文件,之後重新生成
->ssh-keygen -t rsa 生成rsa加密文件
->ssh-copy-id hostname (複製rsa公鑰到指定機器上,從而實現無密登錄,中間要輸入yes)
->驗證ssh登錄是否需要密碼
——>普通用戶ssh到另一臺電腦上:
最初嘗試:ssh hostname;可能是沒有指定username的原因,會出現未能識別正確密碼的情況,並報錯Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
試試:ssh username@hostname;輸入密碼後能夠正常登錄,所以有了下面的解決方案(原因是在沒有指定連接的用戶名的情況下,它會默認使用當前的用戶名,所以會錯誤)
方便起見:可以使用映射關係,即在.ssh文件下創建config配置文件,配置如下:
[hadoop04@hadoop04 home]$ cat ~/.ssh/config 
Host    hadoop
user    hadoop
Host    hadoop02
user    hadoop02
Host    hadoop03
user    hadoop03
Host    hadoop05
user    hadoop05

其中
Host  hostname
user  username

將配置好的hadoop拷貝到其他節點:
  scp -r /hadoop/ hadoop02:/
  scp -r /hadoop/ hadoop03:/
  scp -r /hadoop//hadoop-2.7.7/ hadoop04:/hadoop03/
  scp -r /hadoop//hadoop-2.7.7/ hadoop05:/hadoop03/
  scp -r /hadoop//hadoop-2.7.7/ hadoop06:/hadoop03/
  scp -r /hadoop//hadoop-2.7.7/ hadoop07:/hadoop03/
###注意:嚴格按照下面的步驟
——>啓動zookeeper集羣(分別在hadoop、hadoop02、hadoop03上啓動zk)
  cd /home/hadoop03/software/zookeeper-3.4.9/bin/
  ./zkServer.sh start
  #查看狀態:一個leader,兩個follower
  ./zkServer.sh status
——>啓動journalnode(分別在hadoop、hadoop02、hadoop03上執行)
  cd /home/hadoop03/software/hadoop-2.7.7
  sbin/hadoop-daemon.sh start journalnode
  #運行jps命令檢驗,hadoop、hadoop02、hadoop03上多了JournalNode進程
——>格式化HDFS
  #在hadoop04(機器根據集羣搭建指定的該機器功能來選擇)上執行命令
  hdfs namenode -format
  #格式化後會在根據core-site.xml中的hadoop.tmp.dir配置生成個文件,這裏配置的是/hadoop03/software/hadoop-2.7.7/tmp,然後將/hadoop/hadoop-2.7.7/tmp拷貝到hadoop05的/hadoop/hadoop-2.7.7/下。
  ##也可以這樣,建議hdfs namenode --bootstrapStandby
——>格式化ZKFC(在hadoop04上執行即可)
  hdfs zkfc -formatZK
——>啓動HDFS(在hadoop04上執行)
  sbin/start-dfs.sh
——>啓動YARN(#####注意#####:是在hadoop06上執行start-yarn.sh(單獨在hadoop07上啓動yarn,執行命令yarn-daemon.sh start resourcemanager),把namenode和resourcemanager分開是因爲性能問題,...,執行sbin/start-yarn.sh即可進行啓動)

到此,hadoop-2.7.7配置完畢,可以統計瀏覽器訪問
hdfs指定tmp目錄中內容簡介:
——>執行hadoop格式化指令後,會在指定的tmp目錄下生成dfs目錄(/data、/name、/namesencondary)
/data: 是DataNode節點存儲數據塊的目錄
/namesencondary: 對於集羣是沒用的,它只在僞分佈式模式時纔會出現,所以不用關心
/name: 該目錄存儲Namenode元數據信息,格式化後,啓動hdfs前,在/name/current/目錄下,會生成一個最初的fsimage_0000000和類似的文件(關於fsimage和eidits在前面已經介紹過了)
——>格式化的危險:
當執行格式化之後,相當於把tmp下的內容清掉,以前的數據將不存在,另外重新更新了clusterID,該clusterID表示的是當前namenode的標識,如果它變了,那原本連接該Namenode的DataNode將找不到它,當然可以將新的clusterID更新到每個datanode裏,即可重新連接。
——>啓動後:
啓動hdfs後,首先會在/name下生成一個in_use.lock,這個文件的作用可以防止同一臺服務器上啓動多個Namenode,避免管理紊亂。
——>查看元數據文件:
不能直接打開,都是亂碼,需要輸入下面的命令才能查看
hdfs oev -i edits_0000001 -o edits.xml
hdfs oiv -i fsimage_00000012 -o fsimage.xml -p XML


datanode:
03: clusterID=CID-c7630be5-7d43-4f92-98f2-f1d01b1b57f1
02: clusterID=CID-c7630be5-7d43-4f92-98f2-f1d01b1b57f1
01: clusterID=CID-b0b743f4-6489-41be-9839-bd1bce40ad7f

03: datanodeUuid=ed19b20d-0162-4068-89c1-92839f877a99
02: datanodeUuid=ed19b20d-0162-4068-89c1-92839f877a99
01: datanodeUuid=0a02f0a2-a903-4657-a18a-15f5459edbd7

namenode:
04: clusterID=CID-b0b743f4-6489-41be-9839-bd1bce40ad7f
05: clusterID=CID-b0b743f4-6489-41be-9839-bd1bce40ad7f

04: namespaceID=47811340
05: namespaceID=47811340

04: blockpoolID=BP-1966791895-192.168.79.128-1560673371040
05: blockpoolID=BP-1966791895-192.168.79.128-1560673371040

集羣搭建到上傳文件到集羣的hdfs系統過程中遇到的問題:
1.啓動集羣過程中總是出現DataNode節點啓動失敗或者是Namenode節點啓動失敗的狀況

——>查看日誌:FileNotFundException找不到相關文件(Namenode節點在啓動時,會從fsimage文件中讀取相關元數據,但是過程中更改了其中一個DataNode的配置,所以DataNode與元數據不符,就出現找不到文件的錯誤,從而造成節點啓動失敗).從而導致節點啓動失敗
——>解決方案:
目前只知道暴力的解決辦法:即刪除hadoop集羣中的各DataNode和Namenode節點下的data/目錄下的tmp文件夾(備份),之後重新在Namenode節點對集羣中的各節點進行格式化。接下來的步驟還需要嚴格按照集羣啓動步驟進行啓動,最後可以看到成功啓動各節點。

2.mkdir: Permission denied: user=hadoop, access=WRITE, inode="/":hadoop04:supergroup:drwxr-xr-x

(相關描述:在DataNode節點上向hdfs系統上傳一個文件,但是Namenode節點存在權限問題導致DataNode節點上傳文件不成功)
——>可以大致確定原因是權限相關問題,網上有建議在hdfs-site.xml文件中添加permission.enabled=true相關配置的;也有sudo -u username hadoop fs -operation ***進行操作的。
——>解決方案:
第一種會涉及到重啓集羣,比較麻煩;
第二種在不同機器上執行該命令,會出現識別不了用戶名的錯誤提示
所以就需要在Namenode節點上使用方法二更改用戶權限( sudo -u hadoop04 /home/hadoop03/software/hadoop-2.7.7/bin/hadoop fs -chmod 777 /)
——>hdfs-HA測試未進行實踐(主要是對高可用的實踐驗證)
——>hdfs動態增加節點和副本數量管理
->命令行中查看和管理Namenode狀態:
hdfs haadmin
hdfs haadmin -transitionToStandby nn1
(由於自動狀態管理已經開啓,而且手動管理可能會造成其他狀態,所以系統拒絕此命令,但可以通過下面命令進行強制狀態轉換)
hdfs haadmin -transitionToStandby nn1 --forcemanual
hdfs haadmin -transitionToActive nn2 --forcemanual(Namenode節點2轉換成活躍狀態)
->hadoop DataNode節點超時時間設置:
DataNode進程死亡或者網絡故障造成DataNode無法與Namenode通信,
Namenode不會立即把該節點判定爲死亡,要經過一段時間,這段時間暫稱作超時時長
HDFS默認的超時時長爲10分鐘+30秒。如果定義超時時間爲timeout,則超時時長的計算公式爲:
  timeout = 2*heartbeat.recheck.interval+10*dfs.heartbeat.interval
  而默認的heartbeat.recheck.interval 大小爲5分鐘,dfs.heartbeat.interval默認爲3秒
  需要注意的是hdfs-site.xml配置文件中的
  heartbeat.recheck.interval的單位爲毫秒,
  dfs.heartbeat.interval的單位爲秒。

  所以,舉個例子,如果heartbeat.recheck.interval設置爲5000(毫秒),dfs.heartbeat.interval設置爲3(秒,默認)
  hdfs-site.xml中的參數設置格式:
  <property>
    <name>heartbeat.recheck.interval</name>
    <value>2000</value>
  </property>
  <property>
    <name>dfs.heartbeat.interval</name>
    <value>1</value>
  </property>
->HDFS冗餘數據塊的自動刪除:
在日常維護hadoop集羣的過程中發現這樣一種情況:
  某個節點由於網絡故障或者DataNode進程死亡,被NameNode判定爲死亡:
  HDFS馬上自動開始數據塊的容錯拷貝;
  當該節點重新添加到集羣中時,由於該節點上的數據其實並沒有損壞,
  所以造成HDFS上某些block的備份數超過了設定的備份數。
  通過觀察發現,這些多餘的數據塊經過很長的一段時間纔會被完全刪除掉,
  那麼這個時間取決於什麼呢?
  該時間的長短跟數據塊報告的間隔時間有關。
  DataNode會定期將當前該節點上所有的BLOCK信息報告給NameNode,
  參數dfs.blockreport.intervalMsec就是控制這個報告間隔的參數。
  hdfs-site.xml文件中有一個參數:
  <property>
    <name>dfs.blockreport.intervalMsec</name>
    <value>10000</value>
    <description>Determines block reproting interval in millseconds</description>
  </property>
  其中3600000爲默認設置,3600000毫秒,即1個小時,也就是說,塊報告的時間間隔爲1個小時,所以經過了很長時間
需要再克隆一臺虛擬機,並重新配置,最後再測試關閉一臺DataNode後Namenodeu關於Live Nodes和Dead Nodes的統計,之後開啓新機器,查看各節點數量,再恢復剛關閉的DataNode,再次查看各節點數量。
——>放翁:
->大公司的流水線——>技術的狹隘
->大部分人需要得到的是沉默的肯定,而不是明確的表態
->主動改變一切,找到自己的特點,沒有問題的時候最可怕,不同階段追求不同的收穫,先聽再說,永遠都要清楚自己想要的是什麼。
->怎麼看待開源:有時候國內的公司的開源,其實更貼合“曬代碼”,只有自己參與了,一旦自己不用就over。多把設計細節和代碼片段分析說明作詳細了就好了,
->如何學習技術?
不用着急什麼都學,珍惜每一次不同工作的機會,挖深做細,幾年以後回過頭來原來自己積攢了那麼多!xml解析分成幾種模式,各種解析的優劣?http 1.1協議中的Header中的緩存設置,返回頭裏面的trunked什麼用途?分佈式計算關鍵問題是什麼(調度,協同,數據交互)?應用壓力測試瓶頸如何評定,導致瓶頸的代碼所屬操作可能分成哪幾類? …… 要留下更多疑問背後的答案,而不僅僅是那一點代碼,那一些入門文檔。

重新啓動掛起狀態的虛擬機時突然出現遠程連接不上其中一臺虛擬機的情況:

試了幾遍連接不上的情況,則直接通過虛擬機客戶端登錄虛擬機,ifconfig查看網絡,發現IP地址不再顯示(可能是網卡出了問題),嘗試重啓network服務,但是出現Bring up interface eth0: Error: Connection activation failed: Device not managed by NetworkManager or available的錯誤
—>解決方案(依次執行以下命令):
service NetworkManager stop        #停止NetworkManager服務
chkconfig NetworkManager off       #關閉NetworkManager隨系統啓動
service network restart            #重啓網絡服務
chkconfig network on               #網絡服務設爲開機自啓動
——>hive入門:
->hive元數據庫MySQL方式安裝配置:
  配置hive-site.xml文件:
  <property>
    <name>javax.jdo.option.ConnectURL</name>
    <value>jdbc:mysql://hadoop04:3306/hive?createDatabaseIfNotExist=true</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectUserName</name>
    <value>root</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectPassword</name>
    <value>123456</value>
  </property>
——>關於虛擬機不定期自動更改IP地址的解決方案:
網上有很多種方法,但按照其中的幾種解決方案執行之後,發現,有時候ping不同外網(未識別的ping),有時候SecureRT無法遠程連接虛擬機。我的做法是將/etc/sysconfig/network-scripts/ifcfg-eth0中的BOOTPROTO="static"直接設置成static,並在下面添加IP地址、網關(務必保證和編輯虛擬機網絡中的網關保持一致)以及子網和DNS的相關設置。
重啓網絡服務之後發現IP地址重新設置爲設置中的IP地址,至於後來是否會變,我就不去研究原理了,等待時間來驗證。

——>centOs6.x安裝MySQL筆記:
->根據Linux版本下載對應的MySQL版本(red hat類型5.7版本的MySQL,下載下來的是.tar壓縮文件,解壓的時候使用參數-xvf即可)
->依次通過rpm -ivh命令安裝common、libs、libs-compact、client、server文件(在此之前需要查看系統內默認安裝的老版本的MySQL是否存在,若存在需要卸載,一般情況下使用rpm -e即可,若提示相關依賴不能進行卸載,則使用rpm -e --nodeps進行強制卸載)
->安裝完成之後需要更改用戶密碼等信息
->需要通過sudo service mysqld stop命令停止MySQL
->一般情況下執行mysqld --skip-grant-tables &命令之後即可直接通過mysql命令進入MySQL
->若還是無法直接通過命令mysql進入MySQL,則可以指定用戶名進行登錄(mysqld --user=root --skip-grant-tables &)
->進入數據庫之後,通過以下命令修改用戶名以及密碼:
mysql5.7以下版本:UPDATE mysql.user SET Password=PASSWORD('123456') where USER='root';
mysql5.7版本:UPDATE mysql.user SET authentication_string=PASSWORD('123456') where USER='root';
刷新權限:flush privileges;
退出重登(中間需要開啓mysqld服務)mysql:exit或quit
->關於解決Navicat 報錯:1130-host ... is not allowed to connect to this MySql server,MySQL不允許從遠程訪問的方法:
1.改表法
可能是你的帳號不允許從遠程登陸,只能在localhost。這個時候只要在localhost的那臺電腦,登入mysql後,更改 "mysql" 數據庫裏的 "user" 表裏的 "host" 項,從"localhost"改稱"%"
mysql -u root -pvmwaremysql>use mysql;
mysql>update user set host = '%' where user = 'root'
mysql>select host, user from user;
2.授權法:...

Navicat破解(win10,mac同理)

Navicat Premium歷史版本下載地址:
http://download.navicat.com/download/navicat9_premium_cs.exe
http://download.navicat.com/download/navicat100_premium_cs.exe
http://download.navicat.com/download/navicat110_premium_cs_x86.exe
http://download.navicat.com/download/navicat110_premium_cs_x64.exe
http://download.navicat.com/download/navicat120_premium_cs_x86.exe
http://download.navicat.com/download/navicat120_premium_cs_x64.exe
http://download.navicat.com/download/navicat121_premium_cs_x86.exe
http://download.navicat.com/download/navicat121_premium_cs_x64.exe

GitHub上下載破解工具
GitHub:https://github.com/DoubleLabyrinth/navicat-keygen/releases

.\navicat-patcher.exe ".....\Navicat Premium 12" PrivateKey.pem
(Input index)> 1
(Input index)> 1
(range:0 ~ 15, default: 12)> 12
Serial number:
NAVH-2YAT-7JC7-2ZAX
Your name: trb331617
Your organization: trb331617
Input request code in Base64:
手動激活後,複製出現的code到這裏
Activation Code:
回車後,此處生成的code即爲手動激活碼。

IntelliJ系列破解

Idea付費版安裝破解+Pycharm付費版安裝破解:修改hosts文件(將0.0.0.0 account.jetbrains.com添加到hosts文件最後)+激活碼鏈接(http://idea.lanyus.com/),即可成功激活。

關於Navicat更多破解信息可以查看破解工具下載


->安裝hive的時候,可能是由於hive-site.xml文件配置錯誤,導致在不同目下啓動hive時都會在該目錄下新建一個metastore_db的文件夾用於存儲數據庫文件,刪除hive之後,重新解壓並配置hive-site.xml文件,出現Hivemetastore之類的錯誤可能是由於hive在lib庫中沒有找到mysql-connector-xxx.jar數據庫連接文件(添加即可)。
——>hive HQL(常用語法介紹):
set hive.cli.print.header=true;

CREATE TABLE page_view(viewTime INT, userid BIGINT, page_url STRING, referrer_url STRING, ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001'
STORED AS SEQUENCEFILE;    //TEXTFILE

//create & load(導數據)
create table tab_ip(id int, name string, ip string, country string)
row format delimited
fields terminated by ','
stored as textfile;
load data local inpath '/home/hadoop/ip.txt' into table tab_ext;

//external(該方法鍵的表的數據所使用的文件不是必須位於指定的hdfs文件夾下面,這樣就不會干擾業務系統調用該文件了,因爲manage_table在load文件系統hdfs上的文件時直接將該文件移動到對應的文件夾下了)
CREATE EXTERNAL TABLE tab_ip_ext(id INT, name STRING, ip STRING, country STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION '/external/hive';
->在drop table的時候,MANAGE_TABLE在刪除之後,其hdfs中的文件也會隨之而刪除;EXTERNAL_TABLE在刪除之後,其hdfs中的文件仍然存在,系統只是刪除了其元數據而已。

//CTAS    用於創建一些臨時表存儲中間結果
CREATE TABLE tab_ip_ctas 
AS 
SELECT id new_id, name new_name, ip new_ip, country new_country
FROM tab_ip_ext
SORT BY new_id;

//insert from select    用於向臨時表中追加中間結果數據
create table tab_ip_like like tab_ip;

insert overwrite table tab_ip_like
    select * from tab_ip;

//CLUSTER <--相對高級一點,你可以放在有精力的時候去學習>
create table tab_ip_cluster(id int, name string, ip string, country string)
clustered by(id) into 3 buckets;

load data local inpath '/home/hadoop/ip.txt' overwrite into table tab_ip_cluster;
set hive.enforce.bucketing=true;
insert into table tab_ip_cluster select * from tab_ip;
select * from tab_ip_cluster tablesample(bucket 2 out of 3 on id);

//PARTITION
create table tab_ip_part(id int, name string, ip string, country string)
    partitioned by (part_flag string)
    row format delimited fields terminated by ',';

load data local inpath '/home/hadoop03/software/hivetestdata/ip.txt' overwrite into table tab_ip_part
    partition(part_flag='part1');

load data local inpath '/home/hadoop03/ip_part2.txt' overwrite into table tab_ip_part
    partition(part_flag='part2');

select * from tab_ip_part where part_flag='part2';
select count(*) from tab_ip_part where part_flag='part2';

alert table tab_ip change id id_alter string;
ALTER TABLE tab_cts ADD PARTITION (partCol = 'dt') location '/external/hive/dt';

show partitions tab_ip_part;


//write to hdfs
insert overwrite local directory '/home/hadoop/hivetemp/test.txt' select * from tab_ip_part where part_flag='part1';
insert overwrite directory '/hiveout.txt' select * from tab_ip_part where part_flag='part1';

//cli shell
hive -$ -e 'select country, count(*) from tab_ext' > /home/hadoop/hivetemp/e.txt
有了這種執行機制,就使得我們可以利用腳本語言(bash shell, python)進行hql語句的批量執行

select * from tab_ext sort by id desc limit 5;

select a.ip, b.book from tab_ext a join tab_ip_book b on(a.name==b.name);



//array
create table tab_array(a array<int>, b array<string>)
row format delimited
fields terminated by '\t'
collection items terminated by ',';

示例數據
tobenbrone,laihama,woshishei    13866987898,13287654321
abc,iloveou,itcat    13866987898,13287654321

select a[0] from tab_array;
select * from tab_array where array_contains(b, 'word');
insert into table tab_array select array(0), array(name, ip) from tab_ext t;

//map
create table tab_map(name string, info map<string, string>)
row format delimited
fields terminated by '\t'
collection items terminated by ';'
map keys terminated by ':';

示例數據
fengjie    age:10;size:36A;addr:usa
furong    age:20;size:39C;addr:beijing;weight:180KG

load data local inpath '/home/hadoop/hivetemp/tab_map.txt' overwrite into table tab_map;
insert into table tab_map select name, map('name', name, 'ip', ip) from tab_ext;

//struct
create table tab_struct(name string, info struct<age:int, tel:string,addr:string>)
row format delimited
fields terminated by '\t'
collection items terminated by ','

load data local inpath '/home/hadoop/hivetemp/tab_st.txt' overwrite into table tab_struct;
insert into table tab_struct select name, named_struct('age', id, 'tel', name, 'addr', country) from tab_ext;

//UDF 用戶自定義函數
select if(id=1, first, no-first), name from tab_ext;

hive>add jar /home/hadoop/myudf.jar
hive>CREATE TEMPORARY FUNCTION my_lower AS 'org.dht.Lower';
select my_upper(name) from tab_ext;
->啓動mysql時遇到的問題(ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)):
->啓動mysqld時總是失敗:
->解決辦法:查看/var/lib/mysql文件夾下的文件,可以看到文件mysql.sock的用戶名和用戶組都是mysql,
執行命令chown -R mysql:mysql /var/lib/mysql
執行命令service mysqld restart
之後mysqld服務重啓成功
再執行命令mysql -uroot -p 就可以成功進入數據庫
0000101    iphone6plus    64G    6888
0000102    xiaominote     64G    2388
0000103    iphone5s     64G    4388
0000104    mi4     64G    2388
0000105    mi3     64G    2388
0000106    meizu     64G    1388
0000107    huawei     64G    3388
0000108    zhongxing     64G    788


create table t_order(id int, name string, rongliang string, price double)
row format delimited            #表示一行就是一條記錄
fields terminated by '\t'
==>2019.7.19(ios系統設置代理方法):
——>ios系統搜索Outline App下載安裝

安裝完成進入App之後,需要輸入accesskey:
->access-key生成方法:
首先需要把配置內容拼接在一起:
    ss://method:password@hostname:port
eg: ss://aes-256-gcm:p*****[email protected].***:****
將[method:password]部分通過Base64編碼轉換後得到:
    ss://[email protected].***:****

複製上面得到的access,進入Outline App後,App自動識別粘貼板的內容,點擊進入連接即可
跳過Day06-05-hql語法及自定義函數(31'31'')等關於hql和hbase相關的課程簡介
——>Storm

->Storm的基本概念:
Topologies:拓撲,俗稱一個任務
Spouts:拓撲的消息源
Bolts:拓撲的處理邏輯單元
tuple:消息元組 Spouts和Bolts以及Bolts和Bolts之間傳遞信息的數據格式
Streams: 流
Tasks: 任務處理單元(實例)
Executor: 工作線程
Workers: 工作進程
Configuration: topology的配置
->Storm安裝手冊:
1.安裝一個zookeeper集羣
2.上傳storm的安裝包,解壓
3.修改配置文件storm.yaml

#所使用的zookeeper集羣主機
storm.zookeeper.servers:
     - "hadoop"
     - "hadoop02"
     - "hadoop03"

#Nimbus所在的主機名
nimbus.host: "hadoop"

supervisor.slots.ports #slot(工作槽位)就是一個worker進程,一個進程佔一個端口
-6701
-6702
-6703
-6704
-6705

啓動storm
在nimbus主機上
nohup ./storm nimbus 1>/dev/null 2>&1 & (啓動storm)
nohup ./storm ui 1>/dev/null 2>&1 &     (啓動storm的ui界面)

在supervisor主機上
nohup ./storm supervisor 1>/dev/null 2>&1 &
storm編程規範及demo編寫:(其中的類RandomWorldSpout、UpperBolt、ShuffixBolt都是繼承自接口自定義的與業務相關的類)
  Topologybuilder builder = new Topologybuilder();
  //將spout組件設置到topology中去
  //指定該組件有四個executor來執行
  //四個executor運行8個tasks
  builder.setSpout("randomspout", new RandomWorldSpout(), 4).setNumTasks(8);
  //將大寫轉換bolt組件設置到topology,並且指定它接收randomspout組件的消息
  builder.setBolt("upperbolt", new UpperBolt(), 4).shuffleGrouping("randomspout");
  //將添加後綴的bolt組件設置到topology,並且指定它接收upperbolt組件的消息
  builder.setBolt("suffixbolt", new SuffixBolt(), 4).shuffleGrouping("upperbolt");
  //用builder來創建一個topology
  StormTopology topology = builder.createTopology();

  //配置一些topology在集羣上運行時的參數
  Config conf = new Config();
  //指定集羣中有運行四個槽位,即四個worker
  conf.setNumWorkers(4);
  ....

  //將這個topology提交給storm集羣運行
  StormSubmitter.submitTopology("demotopo", conf, topology);
->Storm中的Stream groupings:
  定義一個topology的關鍵一步是定義每個bolt接收什麼樣的流作爲輸入;
  stream grouping就是用來定義一個stream應該如何分配數據給bolts;
  Storm裏面有7中類型的stream grouping:
    ->Shuffle Grouping——隨機分組,隨機派發stream裏面的tuple,保證每個bolt接收到的tuple數量大致相同。
    ->Fields Grouping——按字段分組,比如按userid來分組,具有同樣的userid的tuple會被分到相同的Bolts裏的一個task,而不同的userid則會被分配到不同的bolts裏的task
    ->All Grouping-廣播發送
    ->Global Grouping-全局分組
    ->Non Grouping-不分組
    ->Direct Grouping-直接分組
    ->Local or shuffle grouping
->Storm 與 Hadoop的對比:
  ->Topology與Mapreduce的一個關鍵區別是:一個Mapreduce job最終會結束,而一個topology永遠 會運行(除非你手動kill掉)
  ->Nimbus與ResourceManager:在Storm集羣裏面有兩種節點:控制節點和工作節點。控制節點上面運行一個叫Nimbus後臺程序,它的作用類似Hadoop裏的Jobtracker。Nimbus負責在集羣裏分發代碼,分配計算任務給機器,並且監控狀態。
  ->Supervisor與NodeManager:每一個工作節點上面運行一個叫做Supervisor的節點。Supervisor會監聽分配給它那臺機器的工作,根據需要啓動/關閉工作進程。每個工作進程執行一個topology的一個子集;一個運行的topology由運行在很多機器上的很多工作進程組成
->Storm中的Nimbus和Supervisor:
  Nimbus和Supervisor之間的所有協調工作都是通過Zookeeper集羣完成的。
  Nimbus進程和Supervisor進程都是快速失敗(fail-fast)和無狀態的。所有的狀態要麼在zookeeper裏面,要麼在本地磁盤。
  即你可以kill -9 來殺死Nimbus和Supervisor進程,然後再重啓它們,就好像什麼都沒有發生過。這個設計使得Storm異常的穩定。
->Storm常用命令:
  ./storm list (列出當前正在執行的topology, 即任務)
  ./storm kill 【拓撲名稱】 停止Topologies

->Storm深入學習:
  分佈式共享鎖的實現
  事務topology的實現機制及開發模式
  在具體場景中的跟其他框架的整合(flume、activeMQ、kafka(分佈式消息隊列系統)、redis、hbase、mysql cluster)
——>Kafka

->kafka基本概念:
  Fast: 非常快,單個Kafka broker每秒能夠讀寫數百兆字節從數千臺客戶端,
  Scalable: 可擴展,容量不夠之後,可以通過增加機器來解決
  Durable: 消息可以持久化到硬盤上
  Distributed by Design

  kafka是一個分佈式的消息緩存系統
  kafka集羣中的服務器都叫做broker
  kafka有兩類客戶端,一類叫producer(消息生產者),一類叫做consumer(消費者),客戶端和broker服務器之間採用tcp協議連接
  kafka中不同業務系統的消息可以通過topic進行區分,而且每一個消息topic都會被分區,以分擔消息讀寫的負載
  每一個分區都可以有多個副本,以防止數據的丟失
  某一個分區中的數據如果需要更新,都必須通過該分區所有副本中的leader進行更新
  消費者可以分組,比如有兩個消費者組A和B,共同消費一個topic: order_info, A和B所消費的消息不會重複,比如:order_info中有100個消息,每個消息有一個id, 編號從0-99,那麼,如果A組消費0-49號,B組就消費50-99號
  消費者在具體消費某個topic中的消息時,可以指定起始偏移量(宕機後,可以從指定地方讀起)

  ->kafka快速入門實際操作(基於獨立的zookeeper集羣環境下,多機器 現在最新版本的kafka 執行命令中用--bootstrap-server代替了--zookeeper是什麼意思):
    ->啓動zookeeper集羣和kafka集羣:(在kafka根目錄下,在後臺運行時,需要在命令後加1>/dev/null 2>&1 &)
      ./bin/kafka-server-start.sh ./config/server.properties
    ->創建topic:(3個副本數,一個分區,topic名稱是youshuo_test_topic)
      ./bin/kafka-topics.sh --create --zookeeper hadoop:2181 --replication-factor 3 --partitions 1 --topic test01
    ->查看topic列表:
      ./bin/kafka-topics.sh --list --zookeeper hadoop:2181
      hadoopTopic2
      test01
      youshuo_test_topic
    ->創建生產者:
      ./bin/kafka-console-producer.sh --broker-list hadoop:9092 --topic test01
    ->創建消費者:
      ./bin/kafka-console-consumer.sh --zookeeper hadoop:9092 --topic test01 --from-beginning
    ->查看某個話題狀態信息 :
      ./bin/kafka-topics.sh --describe --zookeeper hadoop:2181 --topic test01
->kafka客戶端編程:
//生產者
public class ProducerDemo {
  public static void main(String[] args) {
    Properties props = new Properties();
    props.put("zk.connect", "hadoop:2181,hadoop02:2181,hadoop03:2181");
    props.put("metadata.broker.list", "hadoop:9092,hadoop02:9092,hadoop03:9092");
    props.put("serializer.class", "kafka.serializer.StringEncoder");
    ProducerConfig config = new ProducerConfig(props);
    Producer<String, String> producer = new Producer<String, String>(config);
   
    //發送業務消息
    //讀取文件 讀取內存數據庫 讀socket端口
    for (int i = 1; i <= 1000; i++) {
      producer.send(new KeyedMessage<String, String>("Hey ", "i said i love you for " + i + "times"));
      Thread.sleep(500);
    }
  }
}
//消費者
public class ConsumerDemo {
  private static final String topic = "order";
  private static final Integer threads = 1;

  public static void main(String[] args) {
    Properties props = new Properties();
    props.put("zk.connect", "hadoop:2181,hadoop02:2181,hadoop03:2181");
    props.put("group.id", "1111");
    props.put("auto.offset.reset", "smallest");

    ConsumerConfig = config = new ConsumerConfig(props);
    ConsumerConnector consumer = Consumer.createJavaConsumerConnector(config);
    Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
    topicCountMap.put("test01", 1); //param1: topicName; param2: threads
    topicCountMap.put("test02", 10);
    Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = consumer.createMessageStreams(topicCountMap);
    List<KafkaStream<byte[], byte[]>> streams = consumerMap.get(topic);

    for (final KafkaStream<byte[], byte[]> KafkaStream : streams) {
      new Thread(new Runnable() {
        @Override
        public void run() {
          for(MessageAndMetadata<byte[], byte[]> mm : kafkaStream) {
            String msg = new String(mm.message);
            sout(msg);
          }
        }
      }).start();
    }
  }
}

flink中國github社區

  ->flink介紹
    bound (bound、unbound)
    state (stateful、)
    time (Event Time、Processing Time)
    API
  ->flink基本概念:有狀態流式處理引擎的基石
    有狀態流式處理
    有狀態流式處理的挑戰
      狀態容錯(State Fault Tolerance)
      狀態維護(State Managerment)
      Event-time處理(Event-time Processing)
      狀態保存與遷移(Savepoints and Job Migration)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章