<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>is-land</title>
 <link href="s/atom.xml" rel="self"/>
 <link href="s"/>
 <updated>2018-04-26T07:38:10+00:00</updated>
 <id>s</id>
 <author>
   <name>is-land</name>
   <email></email>
 </author>

 
 <entry>
   <title>30天系列 Day 29-End Of 30 Days Series</title>
   <link href="s/bigdata/2018/01/01/30days-series-29-end-of-hadoop-ecosystem"/>
   <updated>2018-01-01T16:00:00+00:00</updated>
   <id>s/bigdata/2018/01/01/30days-series-29-end-of-hadoop-ecosystem</id>
   <content type="html">&lt;p&gt;30 天系列到了尾聲，最後來談談Hadoop Ecosystem的未來。
Hadoop剛發表的時候影響整個檔案系統的生態，以往在單一機器無法處理或是儲存有所限制的使用情境都因Hadoop得以解決。&lt;/p&gt;

&lt;p&gt;但由於MapReduce的應用程式對於開發者而言較不友善，且以運算速度的角度來看，對於已經習慣&lt;strong&gt;毫秒等級&lt;/strong&gt;內反應的使用者來說，MapReduce還是有很大的改善空間。所以當Spark發表後，在短時間內就受到高度注目，使用人數也急速攀升。&lt;/p&gt;

&lt;p&gt;很多人的問題是，”Hadoop 會不會被 Spark所取代呢？”，這要看以哪個角度來看這件事情。Spark是個運用記憶體計算的運算框架(Framework)而MapReduce在運算過程中會不斷地將各Map的運算結果儲存在硬碟內，硬碟IO相較於使用記憶體會花費較多的時間，所以&lt;strong&gt;Spark在運算方面基本上是勝過MapReduce&lt;/strong&gt;。Saprk唯一無法勝過Hadoop的大概就是儲存系統了吧！因為Saprk是個運算框架而不具備儲存功能。&lt;/p&gt;

&lt;p&gt;Hadoop社群這幾年也朝向這方面努力，先後整合&lt;a href=&quot;https://web.mit.edu/kerberos/&quot;&gt;Kerberos&lt;/a&gt;與&lt;a href=&quot;https://sentry.apache.org&quot;&gt;Sentry&lt;/a&gt;，彌補了authentication與authorization權限的不足，除了讓使用者資料受到保護以外，也可以達成Multi-tenancy的功能。&lt;/p&gt;

&lt;p&gt;倘若Hadoop未來可以讓HDFS的功能更加強大、安全與穩定，其周邊的Ecosystem也會更加欣欣向榮，尤其是首當其衝的HBase。&lt;/p&gt;

&lt;p&gt;如果你是個熱血開發者，想讓整個Hadoop Ecosystem更加好用，又或者覺得”這ＸＸＸ功能怎麼這麼難用，如果是OOOO這樣做會更好啊”，社群們需要你的加入！！&lt;/p&gt;

&lt;p&gt;可以到各個Mailing list:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hadoop.apache.org/general_lists.html&quot;&gt;Hadoop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hbase.apache.org/mail-lists.html&quot;&gt;HBase&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hive.apache.org/mailing_lists.html&quot;&gt;Hive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://spark.apache.org/community.html&quot;&gt;Spark&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;或是&lt;a href=&quot;https://issues.apache.org/jira/browse/PHOENIX-4506?jql=project%20in%20(SPARK%2C%20HBASE%2C%20HADOOP%2C%20HIVE)&quot;&gt;Jira&lt;/a&gt;參與並討論各個project的開發與討論，讓社群了解使用者的心聲，或遮直接參與開發討論是更好的！&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 28-Use Case Of Hadoop Ecosystem</title>
   <link href="s/bigdata/2017/12/31/30days-series-28-usecase-of-hadoop-ecosystem"/>
   <updated>2017-12-31T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/31/30days-series-28-usecase-of-hadoop-ecosystem</id>
   <content type="html">&lt;p&gt;介紹完Hadoop Ecosystem的Hadoop、HBase、Spark、Hive後，想必大家對這些工具有更近一步的了解。
接下來要介紹幾個這些工具的使用情境，讓大家可以更了解使用時機。&lt;/p&gt;

&lt;h2 id=&quot;純檔案模式&quot;&gt;純檔案模式&lt;/h2&gt;

&lt;p&gt;假設大量的原始資料都是以檔案形式存放，而且不會修改原始檔案，並且會需要使用這些檔案進行運算，這樣很適合使用Hadoop。
Hadoop的 HDFS、Yarn 與 MapReduce 符合這些使用情境，而且Hadoop的HA機制可以降低機器故障時，造成整個叢集無法使用情況。
副本(replication)機制可以降低機器故障時，不會發生資料遺失的窘境。&lt;/p&gt;

&lt;p&gt;以副本數預設值3來說，除非很衰剛好故障的電腦都是某檔案的同block，否則HDFS是可以確保資料的可用性！
建議副本數應視叢集機器數量調整，當機器少於三台時建議將副本數調整成等於datanode的數量，而高於三台時，可以依比例調整。
例如，100台機器的叢集，可以將副本數調整成10，這樣至少可以確保同個檔案在其他9台的block損壞時，檔案還是可用的。但是這樣硬碟的容量就會升高，可用的空間就會降低，這就要看使用者如何取捨。&lt;/p&gt;

&lt;p&gt;使用Hadoop存放檔案並需要對檔案進行運算或是萃取資料時，可以針對不同類型的使用者搭配不同運算工具來達到最好的使用模式。
如果你是：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1.不會寫程式與不懂SQL語法。&lt;/li&gt;
  &lt;li&gt;2.不會撰寫程式，會使用SQL語法。&lt;/li&gt;
  &lt;li&gt;3.會撰寫Java或是Scala，會使用SQL語法。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;第一類的使用者，如果自己本身是資料科學家，建議與第二類或是第三類人員進行討論並委託開發，將想研究的資料透過程式視覺化後再進行研究。&lt;/p&gt;

&lt;p&gt;第二類的使用者，懂的使用SQL則可以透過Hive CLI來查詢想觀察的資料，如果查詢邏輯過於複雜導致MapReduce的運算時間過長，則可以使用Hive On Spark的功能來加快運算效能。&lt;/p&gt;

&lt;p&gt;第三類的使用者，彈性又更大了，除了可以使用第二類使用者的方式外，還可以透過撰寫程式碼，撰寫Spark RDD或者Spark SQL
來讀取HDFS的檔案進行資料分析，或者透過JDBC呼叫hiveserver2來執行SQL語法，查詢預先定義好的Hive table的資料。&lt;/p&gt;

&lt;h2 id=&quot;資料庫模式&quot;&gt;資料庫模式&lt;/h2&gt;

&lt;p&gt;很多人都會有個疑問：”巨量資料以檔案格式存放比較好還是存入類似RDB的儲存架構內呢？”。
首先思考一件事情，資料會不會有經常性修改的需求？又或者需不需要 Random accesses功能？
如果需要，那可以考慮將資料存放在HBase，透過預先設計好的Row key，除了加快資料查詢的速度外，也可以避免資料歪斜以平衡HBase叢集的資源使用。&lt;/p&gt;

&lt;p&gt;與&lt;strong&gt;純檔案模式&lt;/strong&gt;一樣分為三類使用者：&lt;/p&gt;

&lt;p&gt;第一類使用者一樣只能透過與第二、第三類使用者溝通，幫忙把自己要的資料取出後開始解讀，如果能朝向第二、第三類的使用者邁進，那是最好的！&lt;/p&gt;

&lt;p&gt;第二類使用者一樣可以透過使用Hive預先對HBase建立好的external table後進行查詢，但是當資料量過大也會花費更多時間，一樣可以使用 Hive On Spark的功能來加速，不過有可能會因為map數量過多而造成HBase RPC請求過多而發生timeout exception。或者也可以使用前面介紹過的HareDB HBase Clint，具有Web的使用者介面，讓使用者不必著寫程式可以直接執行SQL查詢，而且免安裝一鍵即可使用。&lt;/p&gt;

&lt;p&gt;第三類使用者與檔案模式相同，彈性一樣很大，除了透過JDBC呼叫hiveserver2來執行SQL語法，查詢預先定義好的Hive 上的 HBase external table的資料，也可以使用HBase 的 &lt;a href=&quot;https://hbase.apache.org/book.html#spark&quot;&gt;Spark Module&lt;/a&gt;來撰寫RDD。又或是透過Apache Phoenix提供的Api，在透過Phoenix建置好的table上進行資料查詢。&lt;/p&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;不同的使用者，有不同的使用方式與情境，只有用了對的方法與工具才能讓自己在分析資料時能夠如虎添翼，
如何用對的工具與法方就要透過瞭解工具的特性才能知道，工欲善其事，必先利其器。
希望大家都可以在自己能力範圍內找到適合自己的工具。&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 27-Apache Hive Server On Spark簡介</title>
   <link href="s/bigdata/2017/12/30/30days-series-27-introduction-of-apache-hive-on-spark"/>
   <updated>2017-12-30T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/30/30days-series-27-introduction-of-apache-hive-on-spark</id>
   <content type="html">&lt;p&gt;使用複雜的Hive SQL語法查詢時，預設狀況下是使用MapReduce來進行運算。自從Apache Spark出現之後，MapReduce已經有逐漸被取代的跡象。
Apache Hive在1.1版本推出Hive On Spark功能，透過Spark高效能計算速度的優點，讓使用者有更好的使用者體驗。&lt;/p&gt;

&lt;h2 id=&quot;前置作業&quot;&gt;前置作業&lt;/h2&gt;

&lt;p&gt;一般而言，大家會想說&lt;code class=&quot;highlighter-rouge&quot;&gt;Hive On Spark&lt;/code&gt;，那我只要到Apache Spark網站下載build好的jar檔案，放入Hive的安裝環境下這應應該就可以跑了吧！
沒錯！理論上是這樣，但是&lt;strong&gt;代志恩洗憨人想A嫁擬甘單&lt;/strong&gt;，Apache Spark有個功能整合Hive，可以讓Spark Application以RDD或者
是Spark SQL的方式讀取Hive table，Apache Spark官網提供的pre-build Spark檔案，已經包含Hive的相關dependency檔案。&lt;/p&gt;

&lt;p&gt;如果在Hive上使用官網下載的Spark jar檔來使用Hive On Spark的功能，這樣是會發生Jar衝突的錯誤訊息的！所以必須重新打包Apache Spark 的source code，並將Hive的dependency排除。&lt;/p&gt;

&lt;h3 id=&quot;build-apache-without-hive&quot;&gt;Build Apache Without Hive&lt;/h3&gt;

&lt;p&gt;重新打包Spark source code可以透過三種方式：&lt;code class=&quot;highlighter-rouge&quot;&gt;SBT&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;Maven&lt;/code&gt;或者是&lt;code class=&quot;highlighter-rouge&quot;&gt;make-distribution.sh&lt;/code&gt;。
使用SBT或是Maven這兩種方法打包出來的spark-assembly檔案會比較大，在部署上會花費較多時間，故建議使用&lt;strong&gt;make-distribution.sh&lt;/strong&gt;。
這裡也只示範如何使用make-distribution.sh來打包。首先請到官方網站下載&lt;a href=&quot;https://www.apache.org/dyn/closer.lua/spark/spark-2.1.2/spark-2.1.2.tgz&quot;&gt;Spark 2.1.2的原始碼&lt;/a&gt;，並執行下列語法：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#make-distribution.sh&lt;/span&gt;
.&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SPARK_HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/dev/make-distribution.sh &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hadoop2-without-hive&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--tgz&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;-Pyarn,hadoop-provided,hadoop-2.7&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;由於前面介紹Hadoop時，是使用Hadoop 2.7.3版本，因此打包時也使用hadoop-2.7的參數。&lt;/p&gt;

&lt;h2 id=&quot;設定hive&quot;&gt;設定Hive&lt;/h2&gt;

&lt;p&gt;這裡使用Hive 2.1.1版本，只要將打包好的spark-assembly檔案放入&lt;code class=&quot;highlighter-rouge&quot;&gt;$HIVE_HOME/lib&lt;/code&gt;內即可。Hive 2.2.0(含)之後的版本，Hive只支援Spark 2.0及之後的新版本，詳細安裝方式可參考&lt;a href=&quot;https://cwiki.apache.org/confluence/display/Hive/Hive+on+Spark%3A+Getting+Started#HiveonSpark:GettingStarted-ConfiguringHive&quot;&gt;Hive官方網站&lt;/a&gt;。&lt;/p&gt;

&lt;h2 id=&quot;啟動hive-on-spark&quot;&gt;啟動Hive On Spark&lt;/h2&gt;

&lt;p&gt;進入Hive CLI後輸入下面的設定，即可啟用Hive On Spark:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#進入Hive CEL&lt;/span&gt;
hive

&lt;span class=&quot;c&quot;&gt;#設定使用spark engine&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;hive.execution.engine&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;spark&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;接下來就可以進行查詢，而原本使用MapReduce進行運算的Hive SQL語法也會變成Spark進行運算，可以在如果是使用yarn當作運算資源管理系統，可以透過&lt;code class=&quot;highlighter-rouge&quot;&gt;http://{hostname}:8088&lt;/code&gt;觀察Hive送出的application。&lt;/p&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;簡介完了Hive On Spark，Hive篇章也到了最後。接下來兩天要來介紹，目前這些Hadoop ecosystem 整合應用的use case。&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 26-Apache Hive Server 簡介</title>
   <link href="s/bigdata/2017/12/29/30days-series-26-introduction-of-apache-hive-server2"/>
   <updated>2017-12-29T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/29/30days-series-26-introduction-of-apache-hive-server2</id>
   <content type="html">&lt;p&gt;前面有介紹Hive的安裝方式，想必大家也了解並且知道怎麼使用Hive SQL來對HDFS進行查詢。&lt;/p&gt;

&lt;p&gt;Hive可以是作為一個Client工具，而且同時只能讓一個使用者進行操作，如果要讓多個使用者同時使用呢？那就多安裝幾台嗎？
但是Hive Client無法讓應用程式透過JDBC的方式，接受應用程式的request。那這種應用場景該如何在Hive上面使用呢？&lt;/p&gt;

&lt;p&gt;Hive 提供了一種service讓使用者可以透過JDBC driver，接收應用程式發出的SQL語法請求(request)並且回傳對HDFS查詢後的結果給應用程式，這個service就稱之為&lt;strong&gt;HiveServer&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;HiveServer是基於&lt;a href=&quot;http://thrift.apache.org/&quot;&gt;Apache Thrift&lt;/a&gt;專案所建置出來的一個服務，所以也稱之為Thrift server，支援多種語言透過JDBC呼叫使用，包含：&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;Java&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;Node&lt;/code&gt;與&lt;code class=&quot;highlighter-rouge&quot;&gt;Ruby&lt;/code&gt;。
後來為了解決HiveServer 無法處理多個使用者同時查詢的問題(即使修改原始碼也無法解決)，進而發展出了新一代的HiveServer，同樣是以Thrift server為基礎所建置出來的服務。
為了避免造成混亂，原有的HiveServer就被稱為&lt;code class=&quot;highlighter-rouge&quot;&gt;HiveServer1&lt;/code&gt;或是&lt;code class=&quot;highlighter-rouge&quot;&gt;Thrift server&lt;/code&gt;，而新一代的HiveServer就稱之為&lt;code class=&quot;highlighter-rouge&quot;&gt;HiveServer2&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;HiverServer2於 hive 0.11.0版本推出，並且建議使用者使用。而在 hive 1.0.0版本，則正式移除HiveServer1。
若使用者剛開始使用Hive，強烈建議開始使用HiveServer2，除了可讓多人同時使用外，也會有社群的持續支援維護原始碼，還可以透過HiveServer2才有的Web UI來監控狀態。&lt;/p&gt;

&lt;h2 id=&quot;start-hiveserver2&quot;&gt;Start HiveServer2&lt;/h2&gt;

&lt;p&gt;接下來要介紹如何設定並啟動HiveServer2，假設已經下載並設定好&lt;code class=&quot;highlighter-rouge&quot;&gt;HIVE_HOME&lt;/code&gt;與&lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt;等環境變數。&lt;/p&gt;

&lt;p&gt;如果只想快速體驗HiveServer2，不用額外的設定即可透過下列指令啟動：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hive &lt;span class=&quot;nt&quot;&gt;--service&lt;/span&gt; hiveserver2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;或是透過&lt;code class=&quot;highlighter-rouge&quot;&gt;-H&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;--help&lt;/code&gt;來查看可用的指令&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hive &lt;span class=&quot;nt&quot;&gt;--service&lt;/span&gt; hiveserver2 &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt;
Starting HiveServer2
usage: hiveserver2
 &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt;,--help                        Print &lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;information
    &lt;span class=&quot;nt&quot;&gt;--hiveconf&lt;/span&gt; &amp;lt;&lt;span class=&quot;nv&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;value&amp;gt;   Use value &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;given property
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;–hiveconf 常用的設定有：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hive.server2.thrift.min.worker.threads: 最低可連線的數量，預設是5個連線數。
hive.server2.thrift.max.worker.threads: 最多可連線的數量，預設500個連線數。
hive.server2.thrift.port              : HiveServer2所使用的TCP port號碼，預設是10000.
hive.server2.thrift.bind.host         : HiveServer2所使用的TCP host name，預設是localhost
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;上列設定黨除了在啟動HiveServer2時直接使用，也可以寫入&lt;code class=&quot;highlighter-rouge&quot;&gt;hive-site.xml&lt;/code&gt;檔案內。
可以查看&lt;a href=&quot;https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties#ConfigurationProperties-HiveServer2&quot;&gt;Apache Hive官網文件&lt;/a&gt;查看更多的參數說明。&lt;/p&gt;

&lt;h2 id=&quot;啟動-web-ui-for-hiveserver2&quot;&gt;啟動 Web UI for HiveServer2&lt;/h2&gt;

&lt;p&gt;如果需要使用HiveServer2的Web UI，需要將下列的設定加入&lt;code class=&quot;highlighter-rouge&quot;&gt;hive-site.xml&lt;/code&gt;，或是啟動時加在 –hiveconf 指令內：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;hive.server2.webui.host
    &lt;ul&gt;
      &lt;li&gt;HiveServer2的Web UI所使用的hostname，預設是0.0.0.0&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;hive.server2.webui.port
    &lt;ul&gt;
      &lt;li&gt;HiveServer2的Web UI所使用的port，預設是10002&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;成功啟動後，可以在瀏覽器網址列輸入:http://{hive.server2.webui.host}:{hive.server2.webui.port}後，即可看到下列的畫面：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/mathsigit/blog_page/gh-pages/img/30_days/hs2-webui.png&quot; alt=&quot;hs2-webui.png&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;看完了Hive Server的介紹後，應該對Hive Server有更近一步的了解。接下來要來看Apache Hive如何透過當紅炸子雞- Apache Spark執行Hive SQL。&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 25 - Apache Hive 與 HBase 整合應用介紹</title>
   <link href="s/bigdata/2017/12/27/30days-series-25-introduction-of-apache-hive-and-hbase"/>
   <updated>2017-12-27T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/27/30days-series-25-introduction-of-apache-hive-and-hbase</id>
   <content type="html">&lt;p&gt;今天要來介紹如何透過使用Hive來對HBase table進行查詢。由前面的HBase篇章已經知道HBase本身是沒有提供SQL查詢的介面與功能，
只能依賴其他的工具，例如 Phoenix 或是本篇要介紹的 Hive。&lt;/p&gt;

&lt;p&gt;而由於 Hive 可以使用Hive CLI且安裝簡易，不用啟動service就可以使用，所以受到不少使用者使用，接下來就來介紹Hive如何與HBase整合吧！&lt;/p&gt;

&lt;h2 id=&quot;整合設定&quot;&gt;整合設定&lt;/h2&gt;

&lt;p&gt;開始之前要注意一件事情：&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Hive 1.x版本目前只支援HBase 0.98.x與之前的版本。而HBase 1.x之後的版本，請使用Hive 2.x之後的版本。
假設你想在Hive 1.x使用HBase 1.x，那就要自行重新編譯Hive的原始碼。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;好的，假設我們已經有一個HBase叢集，且下載&lt;a href=&quot;http://apache.stu.edu.tw/hive/hive-2.1.1/&quot;&gt;Hive 2.1.1&lt;/a&gt;版本，Hive CLI環境也已經設定完成，接著只要在進行修改&lt;code class=&quot;highlighter-rouge&quot;&gt;hive-site.xml&lt;/code&gt;，即可透過Hive CLI使用SQL語法對HBase進行操作。&lt;/p&gt;

&lt;p&gt;開啟&lt;code class=&quot;highlighter-rouge&quot;&gt;hive-site.xml&lt;/code&gt;並加入下面的設定值：&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;hbase.zookeeper.quorum&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;{zookeeper host}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;使用HBase內建的zookeeper則指定為HBase master的hostname，若是使用外部且多台zookeeper，請用,分隔。
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;hive.aux.jars.path&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;${HIVE_HOME}/lib/hive-hbase-handler-2.1.1.jar,
           ${HIVE_HOME}lib/hbase-server-1.1.1.jar,
           ${HIVE_HOME}/lib/zookeeper-3.4.6.jar,
           ${HIVE_HOME}/lib/guava-14.0.1.jar
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;設定完畢後，重新啟動Hive CLI即可開始透過 SQL 操作HBase Table啦！&lt;/p&gt;

&lt;h2 id=&quot;建立資料表&quot;&gt;建立資料表&lt;/h2&gt;

&lt;p&gt;其實Hive與HBase整合非常簡單與方便，下面會介紹兩種使用情境，透過Hive CLI建立HBase table的語法，分別是：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;透過Hive新增HBase table。&lt;/li&gt;
  &lt;li&gt;透過Hive如何查詢已經存在的HBase table。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;透過hive新增hbase-table&quot;&gt;透過Hive新增HBase table&lt;/h3&gt;

&lt;p&gt;假設HBase上面尚未有任何table，我們可以使用Hive SQL來建立一個&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#啟動hive&lt;/span&gt;
hive
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;輸入下面語法：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CREATE TABLE new_hbase_table&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;key int, value string&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
STORED BY &lt;span class=&quot;s1&quot;&gt;'org.apache.hadoop.hive.hbase.HBaseStorageHandler'&lt;/span&gt;
WITH SERDEPROPERTIES &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hbase.columns.mapping&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;:key,cf1:val&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
TBLPROPERTIES &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hbase.table.name&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;new_table&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;hbase.mapred.output.outputtable&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;new_table&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#說明&lt;/span&gt;
hbase.columns.mapping           : 欄位對應。必須與hive table的順序相對應。例如：key對應到:key，value對應到cf:value，id對應到cf:id。
hbase.table.name                : HBase table name。若沒有指定，預設hive table name會與hbase table name相同。
hbase.mapred.output.outputtable : HBase table name，非必要設定。若需要在Hive使用insert的指令，則需要指定。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;完成後可以使用&lt;code class=&quot;highlighter-rouge&quot;&gt;hbase shell&lt;/code&gt;進入查詢，此時可以發現new_table已經被建立，要注意的是，透過這個語法所建立的HBase table，當在Hive CLI使用drop table指令時，HBase table同時會被刪除。&lt;/p&gt;

&lt;h3 id=&quot;透過hive如何查詢已經存在的hbase-table&quot;&gt;透過Hive如何查詢已經存在的HBase table&lt;/h3&gt;

&lt;p&gt;只要進入Hive CLI後，對已經存在的HBase table 建立Hive external table，定義欄位與型別即可。&lt;/p&gt;

&lt;p&gt;假設我們有一個HBase table &lt;code class=&quot;highlighter-rouge&quot;&gt;hbase_table&lt;/code&gt;，並且使用&lt;code class=&quot;highlighter-rouge&quot;&gt;hbase shell&lt;/code&gt;的&lt;code class=&quot;highlighter-rouge&quot;&gt;put&lt;/code&gt;指令新增資料:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;put &lt;span class=&quot;s1&quot;&gt;'hbase_table'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'rk_1'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'cf:value'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'65535'&lt;/span&gt;
put &lt;span class=&quot;s1&quot;&gt;'hbase_table'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'rk_2'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'cf:value'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'111'&lt;/span&gt;
put &lt;span class=&quot;s1&quot;&gt;'hbase_table'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'rk_3'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'cf:value'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'9487'&lt;/span&gt;
put &lt;span class=&quot;s1&quot;&gt;'hbase_table'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'rk_3'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'cf:id'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'John'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以看出來這個HBase table的擁有column family: &lt;code class=&quot;highlighter-rouge&quot;&gt;cf&lt;/code&gt;。接下來在Hive CLI內使用下面的指令：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#啟動hive&lt;/span&gt;
hive
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#Create Hive table on HBase&lt;/span&gt;
create external table hbase_table&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;key string, value string, id string&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
stored by &lt;span class=&quot;s1&quot;&gt;'org.apache.hadoop.hive.hbase.hbasestoragehandler'&lt;/span&gt;
with serdeproperties &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hbase.columns.mapping&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;:key,cf:value,cf:id&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; tblproperties &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hbase.table.name&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hbase_table&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hbase.mapred.output.outputtable&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hbase_table&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;當hive table建立完畢，該資料表會長成這樣：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;key&lt;/th&gt;
      &lt;th&gt;id&lt;/th&gt;
      &lt;th&gt;value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;rk_1&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;65535&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;rk_2&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;111&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;rk_3&lt;/td&gt;
      &lt;td&gt;John&lt;/td&gt;
      &lt;td&gt;9487&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;透過&lt;code class=&quot;highlighter-rouge&quot;&gt;create external table&lt;/code&gt;指令建立的hive table，當使用drop table指令時，原本的HBase table是不會被刪除的。&lt;/p&gt;

&lt;h2 id=&quot;使用&quot;&gt;使用&lt;/h2&gt;

&lt;p&gt;當hive table建立完成後，我們就可以透過hive sql語法來對HBase進行操作，語法使用可以參考”Apache Hive SQL 基礎教學”這一篇文章。要注意的是，透過hive sql對HBase進行查詢時，若是使用join語法，會觸發mapreduce的job執行，當HBase資料量龐大region數量很多時，mapreduce運作時會開啟大量map與HBase進行溝通，此時HBase會受到大量的RPC連線，有機會影響到HBase其他的AP的運作，甚至導致HBase regionserver shutdown ，請務必小心使用。&lt;/p&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;看完了Hive 與 HBase的整合應用教學，接下來要來介紹如何使用hiveserver2囉。&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 24 - Apache Hive SQL 基礎教學</title>
   <link href="s/bigdata/2017/12/27/30days-series-24-introduction-of-apache-hive-sql"/>
   <updated>2017-12-27T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/27/30days-series-24-introduction-of-apache-hive-sql</id>
   <content type="html">&lt;p&gt;今天要來介紹Hive SQL語法基礎教學。大部分的人使用情境會是這樣：建立一個table，新增資料，進行查詢、更新資料，必要時刪除table。&lt;/p&gt;

&lt;p&gt;首先我們必須進入Hive CLI互動式介面。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hive
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;建立資料表&quot;&gt;建立資料表&lt;/h2&gt;

&lt;p&gt;假設我們在HDFS路徑&lt;code class=&quot;highlighter-rouge&quot;&gt;hdfs://{hostname}:9000/tmp/person&lt;/code&gt;上有一個CSV檔案&lt;code class=&quot;highlighter-rouge&quot;&gt;person.csv&lt;/code&gt;，資料格式如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-csv&quot;&gt;Mike,Jason,+88612345678,33
Hive,Apache,+88615465788,27
Spark,Apache,+88612348775,19
HBase,Apache,+88655788444,22
Hadoop,Apache,+88987654323,34
Tomcat,Apache,+88611004322,35
...
Mary,Jean,+88612345678,60
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;一共四個欄位，分別是:&lt;code class=&quot;highlighter-rouge&quot;&gt;名&lt;/code&gt;，&lt;code class=&quot;highlighter-rouge&quot;&gt;姓&lt;/code&gt;，&lt;code class=&quot;highlighter-rouge&quot;&gt;電話&lt;/code&gt;，&lt;code class=&quot;highlighter-rouge&quot;&gt;年齡&lt;/code&gt;。接下來用下面的語法來建立hive table。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#新增資料表&lt;/span&gt;
create table person &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;first_name String,sec_name String,tel String,age int&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#由HDFS讀取檔案&lt;/span&gt;
load data inpath &lt;span class=&quot;s1&quot;&gt;'/tmp/person/person.csv'&lt;/span&gt; into table person&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;但是上面的語法在進行刪除資料表時會發生一個情形，就是連同在HDFS上的原始檔案會一並被刪除，如果想保存原始檔案，可以使用下面的語法進行新增table。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;create external table person &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;first_name String,sec_name String,tel String,age int&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; ROW FORMAT DELIMITED FIELDS TERMINATED BY &lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt; LINES TERMINATED BY &lt;span class=&quot;s1&quot;&gt;'\n'&lt;/span&gt; LOCATION &lt;span class=&quot;s1&quot;&gt;'/person'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#說明:&lt;/span&gt;
ROW FORMAT DELIMITED FIELDS TERMINATED BY: 欄位的分隔符號，CSV預設為&lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt;
LINES TERMINATED BY                      : 每個row的換行符號，CSV為&lt;span class=&quot;s1&quot;&gt;'\n'&lt;/span&gt;
LOCATION                                 : HDFS檔案存放路徑
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;使用external語法建立table，當刪除table時原始資料檔就會被保留下來了！&lt;/p&gt;

&lt;h2 id=&quot;顯示資料表定義內容&quot;&gt;顯示資料表定義內容&lt;/h2&gt;

&lt;p&gt;既然建立了資料表，如果想了解table schema，該如何查詢呢？可以使用下面指令：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;describe person&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;刪除資料表&quot;&gt;刪除資料表&lt;/h2&gt;

&lt;p&gt;雖然用到的機會不多，但是還是要介紹一下:D&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;drop table &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;exist person purge&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#說明&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;exist: 這個非必填項目，但建議使用避免輸入錯誤的table時回傳錯誤訊息。
purge   : 如果沒有使用，table不會馬上被刪除，而是會被放入類似HDFS的垃圾桶機制一樣，等時間到才會移除。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;查詢資料select&quot;&gt;查詢資料(select)&lt;/h2&gt;

&lt;p&gt;基本的SQL是一定有的，另外包含&lt;code class=&quot;highlighter-rouge&quot;&gt;join&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;group by&lt;/code&gt;等等。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#取出所有欄位&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; from person&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#指定顯示欄位&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;select &lt;/span&gt;first_name, sec_name, tel, age from person&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#使用where&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; from person where age &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; 30 or &lt;span class=&quot;nv&quot;&gt;sec_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Apache'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;新增資料insert&quot;&gt;新增資料(insert)&lt;/h2&gt;

&lt;p&gt;Hive的insert並不會將新資料append到原始檔案內，而是建立一個新檔案。此語法於Hive 0.14版本後開始支援。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;insert into table person values
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Jack'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'Dawson'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'125'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;,
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Rose'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'DeWitt Bukater'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'122'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;刪除資料delete&quot;&gt;刪除資料(delete)&lt;/h2&gt;

&lt;p&gt;此語法於Hive 0.14版本後開始支援。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#刪除first_name等於Mike的資料&lt;/span&gt;
delete from person where first_name &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Mike'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#刪除年齡小於20&lt;/span&gt;
delete from person where age &amp;lt; 20&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;更新資料update&quot;&gt;更新資料(update)&lt;/h2&gt;

&lt;p&gt;此語法於Hive 0.14版本後開始支援。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;update person &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;age &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 18, tel &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt; where first_name &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Hive'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;本篇只針對基本用法進行說明，Hive的SQL無論是DDL或是DML功能眾多，如有需要可至&lt;a href=&quot;https://cwiki.apache.org/confluence/display/Hive/LanguageManual&quot;&gt;官方文件&lt;/a&gt;查看。看完了SQL基礎教學，接下來我們就要來看Apache Hive 與 HBase的介紹囉。&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 23-Apache Hive 安裝教學</title>
   <link href="s/bigdata/2017/12/26/30days-series-23-installation-of-apache-hive"/>
   <updated>2017-12-26T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/26/30days-series-23-installation-of-apache-hive</id>
   <content type="html">&lt;p&gt;今天要介紹 Hadoop Ecosystem 中火力威猛的Data Warehouse工具 - Apache Hive 的安裝教學。&lt;/p&gt;

&lt;p&gt;前面有提到Apache Hive主要是透過對儲存在HDFS上的結構化資料定義Schema後，以SQL佐以Schema來查詢”&lt;strong&gt;檔案&lt;/strong&gt;“。
而Apache Hive 的 Schema需要某個儲存裝置來存放這些資料，通常是使用RDB，如果沒有任何的RDB service也可以使用Hive內建的 embedded DB(Derby)。&lt;/p&gt;

&lt;h2 id=&quot;事前準備&quot;&gt;事前準備&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;安裝Java
    &lt;ul&gt;
      &lt;li&gt;建議使用Java 1.8以上。基本上Hive 1.2之後的版本只支援Java 1.7以上的版本。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;一個Hadoop叢集，版本至少要2.x以上。
    &lt;ul&gt;
      &lt;li&gt;如果有根據前面的教學安裝，現在應該會有一個 Hadoop 2.7.3 的叢集可以使用。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Mysql(非必要)。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;hive安裝教學&quot;&gt;Hive安裝教學&lt;/h2&gt;

&lt;p&gt;下載Hive 編譯好的檔案，可由&lt;a href=&quot;http://apache.stu.edu.tw/hive/&quot;&gt;Hive官方的連結&lt;/a&gt;下載。本篇教學會使用1.2.2版本。
下載完畢使用下面指令進行解壓縮：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-xzvf&lt;/span&gt; apache-hive-1.2.2-bin.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;解壓縮完畢後，編輯&lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt;設定HIVE_HOME環境變數。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HIVE_HOME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/path/to/your/hive
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HIVE_HOME&lt;/span&gt;/bin:&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;設定&lt;code class=&quot;highlighter-rouge&quot;&gt;hive-site.xml&lt;/code&gt;檔案：&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;fs.default.name&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;hdfs://{hostname}:9000&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;For YARN this configuration variable is called fs.defaultFS.&lt;span class=&quot;nt&quot;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;備註：&lt;code class=&quot;highlighter-rouge&quot;&gt;{hostname}&lt;/code&gt;為主機名稱，請依照自己的Hadoop Namenode所在的hostname修改。&lt;/p&gt;

&lt;p&gt;設定完畢後，就可以啟動Hive CLI來與HDFS互動囉！&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hive
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;metastore-設定&quot;&gt;Metastore 設定&lt;/h2&gt;

&lt;p&gt;前面有介紹Hive可以將Schema儲存在RDB上，假設我們有一個mysql db，只要在&lt;code class=&quot;highlighter-rouge&quot;&gt;hive-site.xml&lt;/code&gt;增加連線資訊的設定，就可以讓Schema儲存到我們指定的RDB內了，但必須先在mysql內建立Hive metastore的RDB schema，可以使用Hive內建script來建立：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#使用root角色匯入schema，如果沒有root角色權限，請使用有權限之使用者。&lt;/span&gt;
mysql &lt;span class=&quot;nt&quot;&gt;-uroot&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;CREATE DATABASE IF NOT EXISTS metastore_db&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HIVE_HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/scripts/metastore/upgrade/mysql
mysql &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; root metastore_db&amp;lt;hive-schema-1.2.0.mysql.sql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;匯入完畢，接著增加下列設定到&lt;code class=&quot;highlighter-rouge&quot;&gt;hive-site.xml&lt;/code&gt;：&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;javax.jdo.option.ConnectionURL&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;jdbc:mysql://{hostname}/metastore_db&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;javax.jdo.option.ConnectionDriverName&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;com.mysql.jdbc.Driver&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;javax.jdo.option.ConnectionUserName&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;root&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;javax.jdo.option.ConnectionPassword&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;123456&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;備註：&lt;code class=&quot;highlighter-rouge&quot;&gt;{hostname}&lt;/code&gt;為主機名稱，請依照自己的mysql所在的hostname修改。&lt;/p&gt;

&lt;p&gt;接下來要到mysql官方網站下載&lt;a href=&quot;https://dev.mysql.com/downloads/connector/j/&quot;&gt;mysql JDBC connector&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;好的！這樣就設定完成了！Hive CLI僅提供單機運作，如果想以server形式透過JDBC讓多人同時連線進來操作，可以透過啟動&lt;code class=&quot;highlighter-rouge&quot;&gt;hiveserver2&lt;/code&gt; service讓多人同時連線操作。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#啟動hiveserver2&lt;/span&gt;
hive &lt;span class=&quot;nt&quot;&gt;--service&lt;/span&gt; hiveserver2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 22-Apache Hive 簡介</title>
   <link href="s/bigdata/2017/12/25/30days-series-22-introduction-of-apache-hive"/>
   <updated>2017-12-25T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/25/30days-series-22-introduction-of-apache-hive</id>
   <content type="html">&lt;h1 id=&quot;apache-hive&quot;&gt;Apache Hive&lt;/h1&gt;

&lt;p&gt;Apache Hive 的資料倉儲(Data Warehouse)系統，是一個便於使用SQL語法對巨量資料集進行操作的工具。可以對已經存在的資料定義結構(Schema)後，以該資料結構進行SQL語法的查詢，並且提供command line 工具以及 JDBC driver，讓使用者可以連線到Hive所提供的 service進行資料操作。&lt;/p&gt;

&lt;p&gt;Apache Hive 剛開始開發時只是Apache Hadoop的子專案，後來獨立出來就成為了Apache 的top project，其受歡迎的程度可想而知。&lt;/p&gt;

&lt;p&gt;Apache Hive可以視為client工具，卻又需要依賴Hadoop運作，具有下列的優點：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;可以透過SQL來探索資料，做到extract/transform/load (ETL)、報表與資料分析等等，資料倉儲的工作。&lt;/li&gt;
  &lt;li&gt;可加強對於已格式化資料的結構(Schema)。&lt;/li&gt;
  &lt;li&gt;可直接讀取存放在Apache HDFS或是Apache HBase等資料儲存系統的資料。&lt;/li&gt;
  &lt;li&gt;可透過Apache Tez、Apache Spark或是MapReduce來進行查詢。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hive 的SQL語法符合&lt;a href=&quot;https://cwiki.apache.org/confluence/display/Hive/Apache+Hive+SQL+Conformance&quot;&gt;標準SQL&lt;/a&gt;，包含最新的SQL-2003與SQL-2011。標準SQL語法會因為Hive版本而有所不同，可以看下列的連結：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://cwiki.apache.org/confluence/display/Hive/Supported+Features%3A+Apache+Hive+2.1&quot;&gt;Apache Hive 2.1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cwiki.apache.org/confluence/display/Hive/Supported+Features%3A+Apache+Hive+2.3&quot;&gt;Apache Hive 2.3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hive除了內建的SQL function以外(如 max，avg等等)也可以自定義使用者函式(user defined functions (UDFs))或者user defined aggregates (UDAFs)與user defined table functions (UDTFs)。&lt;/p&gt;

&lt;p&gt;假設資料儲存在HDFS，可透過Hive建立meta後以SQL語法進行查詢，其支援的檔案格式可以是CSV/TSV，或者Apache Parquet、Apache ORC等等，甚至可以自行實作支援的資料格式，詳情可以查看&lt;a href=&quot;https://cwiki.apache.org/confluence/display/Hive/DeveloperGuide#DeveloperGuide-FileFormats&quot;&gt;開發者手冊&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;在接下來的篇章會介紹下列有關Apache Hive的項目：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Apache Hive 安裝與設定&lt;/li&gt;
  &lt;li&gt;Apache Hive SQL基礎教學&lt;/li&gt;
  &lt;li&gt;Apache Hive 與 HBase&lt;/li&gt;
  &lt;li&gt;Hiveserver2&lt;/li&gt;
  &lt;li&gt;Apache Hive On Spark&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 21-Apache Spark Streaming 簡介</title>
   <link href="s/bigdata/2017/12/24/30days-series-21-introduction-of-spark-streaming"/>
   <updated>2017-12-24T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/24/30days-series-21-introduction-of-spark-streaming</id>
   <content type="html">&lt;h1 id=&quot;spark-streaming&quot;&gt;Spark Streaming&lt;/h1&gt;

&lt;p&gt;Spark streaming是以Spark核心API擴充出來的一個模組，他在處理資料串流(streaming)上具有可擴充性、高吞吐量、高容錯性特點。可以從Kafka，Flume，Kinesis或TCP等許多來源介接資料，也可以透過Spark API的map，reduce，join和window等函數進行複雜的運算來處理資料。最後再將運算結果送到檔案系統(如HDFS)、資料庫或是即時的監控系統，也可以將資料餵給機器學系的系統，進行即時的運算。&lt;/p&gt;

&lt;p&gt;Spark streaming提供了一個高層級的抽象層，稱之為discretized stream(DStream)，意指連續的資料串流。DStream可以通過Kafka，Flume和Kinesis等資料來源來建立，也可以通過在其他DStream的API來新增。在Spark streaming中，一個DStream即為一種有順序的RDD。&lt;/p&gt;

&lt;p&gt;目前Spark streaming可以使用Scala，Java或Python（Spark 1.2開始支援）撰寫應用程式。&lt;/p&gt;

&lt;p&gt;現在就來看個範例程式吧！下列的程式碼是在Spark 2.1.2執行。&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.spark._&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.spark.streaming._&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SparkConf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setMaster&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;local[2]&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setAppName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;NetworkWordCount&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ssc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StreamingContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Seconds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//建立一個DStream來表示來自TCP的data source，指定為主機名（例如localhost）和port（例如9999）。&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ssc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;socketTextStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9999&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 以空白切開每行的字串&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 計算每批資料的文字數量&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pairs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wordCounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pairs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;reduceByKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 印出DStreamPrint到console視窗&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;wordCounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ssc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// 開始計算&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ssc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;awaitTermination&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 等待資料傳送到command視窗&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;如果已經從官方網站下載Spark，上列的程式碼已經被編譯並放入裡面，可以透過下面的指令以local模式來啟動這個Saprk streaming的程式：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bin/run-example streaming.NetworkWordCount localhost 9999
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;啟動之後我們需要一個tcp的server來傳入資料，可以使用&lt;code class=&quot;highlighter-rouge&quot;&gt;nc&lt;/code&gt;這個工具來偽裝一個tcp伺服器輸入資料，開啟另一個command視窗來使用下來指令：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nc &lt;span class=&quot;nt&quot;&gt;-lk&lt;/span&gt; 9999
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;啟動後，可以在裡面輸入資料，這樣另一個Spark streaming的視窗就會顯示由tpc server傳入的文字。&lt;/p&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;看完的入門的Spark streaming，Spark的簡介也告一段落了，如果想看更進階的使用方法，可以到&lt;a href=&quot;https://spark.apache.org/streaming/&quot;&gt;Apache Spark官方網站&lt;/a&gt;查看文件，官方文件蠻齊全的，如有問題也可以到&lt;a href=&quot;https://spark.apache.org/community.html&quot;&gt;Spark 社群&lt;/a&gt;討論，或者在者邊留言。&lt;/p&gt;

&lt;p&gt;接下來，我們要邁入最後的篇章Apache Hive。&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 20-Apache Spark SQL 簡介</title>
   <link href="s/bigdata/2017/12/23/30days-series-20-introduction-of-spark-sql"/>
   <updated>2017-12-23T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/23/30days-series-20-introduction-of-spark-sql</id>
   <content type="html">&lt;h1 id=&quot;spark-sql&quot;&gt;Spark SQL&lt;/h1&gt;

&lt;p&gt;Spark SQL是Spark用來執行SQL語法查詢的一種功能，也支援HiveQL查詢語法，可透過Spark application 撰寫程式對使用Hive建立的Table進行查詢，可以透過&lt;code class=&quot;highlighter-rouge&quot;&gt;.{$SPARK_HOME}/bin/spark-sql&lt;/code&gt;在command模式或透過hiverserver2使用JDBC/ODBC來查詢Hive table。&lt;/p&gt;

&lt;h1 id=&quot;dataframe&quot;&gt;DataFrame&lt;/h1&gt;

&lt;p&gt;使用Spark SQL回傳的物件類型是DataFrame，是一種用來命名欄位的分散式資料集合。
它的概念有點像優化版本的RDB table，可以接受更多的資料來源建立DataFrame，例如結構化的的檔案(CSV)、Hive Table、外部資料庫或是Spark RDD。與RDD一樣，DataFrame目前有支援下列的語言：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Scala&lt;/li&gt;
  &lt;li&gt;Java&lt;/li&gt;
  &lt;li&gt;Python&lt;/li&gt;
  &lt;li&gt;R&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;dataset&quot;&gt;DataSet&lt;/h1&gt;

&lt;p&gt;DataSet在Spark 1.6版本所提出，想藉由Spark SQL的優化引擎來強化RDD的優勢，可以想像成是加強版的DataFrame。DataSet提供強型別(strong type)與lambda functions。其中強型別的好處是在編譯時就可以發現資料型態是否正確而提出警告，有別於傳統RDD必須要在執行期(runtime)才能發現，可以儘早改善錯誤。&lt;/p&gt;

&lt;h1 id=&quot;sample-code&quot;&gt;Sample Code&lt;/h1&gt;

&lt;p&gt;現在開始來示範一個sample code進行操作Spark SQL，下面程式碼是以spark 2.1.2所撰寫。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;import org.apache.spark.sql.SparkSession
import spark.implicits._

/*
 * SparkSession在Spark 2.0提出，未來計畫取代SparkContext。
 * SparkSession包含了Saprk SQL、Streaming等等元件的進入點，並且支援查詢Hive包含HiveQL或UDF等等。
 */
val spark = SparkSession
  .builder()
  .appName(&quot;Spark SQL basic example&quot;)
  .config(&quot;spark.some.config.option&quot;, &quot;some-value&quot;)
  .getOrCreate()

//建立一個DataFrame
val df = spark.read.json(&quot;examples/src/main/resources/people.json&quot;)

// 顯示DataFrame資料內容：
df.show()
// +----+-------+
// | age|   name|
// +----+-------+
// |null|Michael|
// |  30|   Andy|
// |  19| Justin|
// +----+-------+

// 印出DataFrame的schema結構
df.printSchema()
// root
// |-- age: long (nullable = true)
// |-- name: string (nullable = true)

// 只顯示&quot;name&quot;欄位
df.select(&quot;name&quot;).show()
// +-------+
// |   name|
// +-------+
// |Michael|
// |   Andy|
// | Justin|
// +-------+

// 選出&quot;name&quot;、&quot;age&quot;，並且將age欄位的值+1
df.select($&quot;name&quot;, $&quot;age&quot; + 1).show()
// +-------+---------+
// |   name|(age + 1)|
// +-------+---------+
// |Michael|     null|
// |   Andy|       31|
// | Justin|       20|
// +-------+---------+

// 選出age欄位值大於25的資料
df.filter($&quot;age&quot; &amp;gt; 25).show()
// +---+----+
// |age|name|
// +---+----+
// | 30|Andy|
// +---+----+

// 以name分群並計算數量
df.groupBy(&quot;age&quot;).count().show()
// +----+-----+
// | age|count|
// +----+-----+
// |  19|    1|
// |null|    1|
// |  30|    1|
// +----+-----+


//使用Spark SQL進行查詢
// 首先註冊一個DataFrame當作SQL語法會用到的暫存veiw：&quot;employee&quot;
df.createOrReplaceTempView(&quot;employee&quot;)

val sqlDF = spark.sql(&quot;SELECT * FROM employee&quot;)
sqlDF.show()
// +----+-------+
// | age|   name|
// +----+-------+
// |null|Michael|
// |  30|   Andy|
// |  19| Justin|
// +----+-------+

//使用DataSet
// 注意： case class 在 Scala 2.10 最多只支援22個欄位，請注意這個限制。
case class Person(name: String, age: Long)

// 將case clasee 進行編碼後再轉換成DataSet
val caseClassDS = Seq(Person(&quot;Andy&quot;, 32)).toDS()
caseClassDS.show()
// +----+---+
// |name|age|
// +----+---+
// |Andy| 32|
// +----+---+

// DataFrames 可以透過指定case class轉換成DataSet。
val path = &quot;examples/src/main/resources/people.json&quot;
val peopleDS = spark.read.json(path).as[Person]
peopleDS.show()
// +----+-------+
// | age|   name|
// +----+-------+
// |null|Michael|
// |  30|   Andy|
// |  19| Justin|
// +----+-------+
&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;介紹完了基本的Spark SQL與DataDrame、DataSet後，應該可以更了解Spark SQL對於查詢結構化的資料是相當便利的，那如果想對HBase使用Spark SQL呢？沒問題的！經過HBase社群的努力，也開發出了支援Spark的模組，詳情可以到&lt;a href=&quot;https://hbase.apache.org/book.html#spark&quot;&gt;HBase and Spark&lt;/a&gt;來查看更詳細的內容！&lt;/p&gt;

&lt;p&gt;看完了Spark SQL，接下來就要來介紹Spark Stream囉！&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 19-Apache Spark Submit 簡介</title>
   <link href="s/bigdata/2017/12/22/30days-series-19-introduction-of-spark-shell"/>
   <updated>2017-12-22T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/22/30days-series-19-introduction-of-spark-shell</id>
   <content type="html">&lt;h1 id=&quot;spark-submit&quot;&gt;Spark Submit&lt;/h1&gt;

&lt;p&gt;Spark submit 是Spark用來送出程式到叢集執行的script。目前支援的叢集平台/模式有下列幾種：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Standalone- Spark Standalone 模式&lt;/li&gt;
  &lt;li&gt;Apache Mesos&lt;/li&gt;
  &lt;li&gt;Hadoop YARN&lt;/li&gt;
  &lt;li&gt;Kubernetes- 目前在Spark 2.2以上開始支援，目前還在測試階段。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;打包程式吧&quot;&gt;打包程式吧！&lt;/h2&gt;

&lt;p&gt;為了讓&lt;code class=&quot;highlighter-rouge&quot;&gt;spark-submit&lt;/code&gt;的script可以順利將程式碼送出執行，除了Python以外，Scala、Java都需要將程式碼編譯並打包成jar，可以使用 Sbt 或是 Maven 來幫忙進行複雜的 dependency 管理與打包。&lt;/p&gt;

&lt;p&gt;如果是Python，使用spark-submit時需要使用&lt;code class=&quot;highlighter-rouge&quot;&gt;--py-files&lt;/code&gt;指定要執行的.py、.zip或是.egg檔案。建議若是要執行的python檔案有一個以上，可以將他們打包成.zip或是.egg後再送出。&lt;/p&gt;

&lt;h2 id=&quot;spark-submit-usage&quot;&gt;Spark Submit Usage&lt;/h2&gt;

&lt;p&gt;接下來看一下spark-submit的指令與參數：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bin/spark-submit &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--class&lt;/span&gt; &amp;lt;main-class&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--master&lt;/span&gt; &amp;lt;master-url&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--deploy-mode&lt;/span&gt; &amp;lt;deploy-mode&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--conf&lt;/span&gt; &amp;lt;key&amp;gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;lt;value&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &amp;lt;application-jar&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;application-arguments]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;參數說明：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;–class: 主程式的進入點，例如:org.apache.spark.examples.SparkPi。&lt;/li&gt;
  &lt;li&gt;–master: 要執行Spark程式叢集/平台的master url，下面會介紹目前可使用的格式。&lt;/li&gt;
  &lt;li&gt;–deploy-mode: 程式的driver要在哪邊執行。&lt;code class=&quot;highlighter-rouge&quot;&gt;client&lt;/code&gt; 或是 &lt;code class=&quot;highlighter-rouge&quot;&gt;cluster&lt;/code&gt;，預設為&lt;code class=&quot;highlighter-rouge&quot;&gt;client&lt;/code&gt;。假設程式是不需要回傳值，可以使用cluster，如果需要回傳計算結果，那需要使用client，這樣執行spark-submit的視窗才能顯示計算結果。需要注意的是，目前spark standalone&lt;strong&gt;不支援&lt;/strong&gt;在Python程式使用cluster模式來進行。&lt;/li&gt;
  &lt;li&gt;–conf: 各種Spark參數設定都可以用key=value的格式傳入&lt;/li&gt;
  &lt;li&gt;application-jar: 要執行的spark程式(jar)路徑。檔案路徑可以放在HDFS、 本機路徑或是某個http url，但必須帶入指定路徑讓spark-submit可以辨識：&lt;code class=&quot;highlighter-rouge&quot;&gt;hdfs://&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;file://&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;http://&lt;/code&gt;。如果是python檔案，這個參數需要以&lt;code class=&quot;highlighter-rouge&quot;&gt; --py-files&lt;/code&gt;替換。&lt;/li&gt;
  &lt;li&gt;application-arguments: 傳遞參數讓主程式使用。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Master URLs:&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Master URL&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;說明&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;local&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;使用單一執行緒(thread)在本機執行&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;local[K]&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;使用K個執行緒(thread)在本機執行。理想狀況上可以設定單一機器cpu core數量的上限。&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;local[*]&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;使用與本機cpu core數量相同的執行緒(thread)在本機執行。&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;spark://HOST:PORT&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;連接到Spark Standalone叢集的master node，預設PORT為7070。&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;mesos://HOST:PORT&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;連接到Apache Mesos叢集上運行，預設PORT為5050。&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;yarn&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;連接到Hadoop YARN的叢集進行運算。首先會根據&lt;code class=&quot;highlighter-rouge&quot;&gt;HADOOP_CONF_DIR&lt;/code&gt;或&lt;code class=&quot;highlighter-rouge&quot;&gt;YARN_CONF_DIR&lt;/code&gt;路徑內的設定檔知道yarn叢集的位址(可以搭配Day 4 Hadoop安裝篇章來複習)，再判斷–deploy-mode是client或是cluster模式來運作。&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;接下來看一些spark-submit的範例：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Execute SparkPi locally with 6 cores&lt;/span&gt;
./bin/spark-submit &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--class&lt;/span&gt; org.apache.spark.examples.SparkPi &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--master&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;6] &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  /path/to/spark-examples.jar &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Execute on a YARN cluster, and jar path is on HDFS&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HADOOP_CONF_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;XXX
./bin/spark-submit &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--class&lt;/span&gt; org.apache.spark.examples.SparkPi &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--master&lt;/span&gt; yarn &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--deploy-mode&lt;/span&gt; cluster &lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# can be client for client mode&lt;/span&gt;
  hdfs://path/to/spark-examples.jar &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Execute Python application on Spark standalone&lt;/span&gt;
./bin/spark-submit &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--master&lt;/span&gt; spark://172.124.161.138:7077 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  examples/src/main/python/pi.py &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;看完了spark-submit的介紹後，想必對執行Spark的應用程式的指令有更近一步了瞭解。接下來要來介紹Spark的另一個重要模組&lt;code class=&quot;highlighter-rouge&quot;&gt;Spark Sql&lt;/code&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 18-Apache Spark API</title>
   <link href="s/bigdata/2017/12/21/30days-series-18-introduction-of-spark-api"/>
   <updated>2017-12-21T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/21/30days-series-18-introduction-of-spark-api</id>
   <content type="html">&lt;h1 id=&quot;spark-hello-world-api&quot;&gt;Spark Hello World API&lt;/h1&gt;

&lt;p&gt;今天要來介紹如何撰寫一段簡單的Spark Hello World API程式碼。&lt;/p&gt;

&lt;p&gt;接下來的範例要以python為例。使用python來進行spark submit的好處是不用打包成jar檔，  &lt;br /&gt;
但如果有使用到其他的第三方library，進行spark submit時需要將檔案同時上傳。&lt;/p&gt;

&lt;p&gt;首先先打開一個空白文件 (如果有使用IDE會更棒！建議搭配使用 IntelliJ )，並命名成&lt;code class=&quot;highlighter-rouge&quot;&gt;helloworld.py&lt;/code&gt;。&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pyspark&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SparkContext&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;computeStatsForCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;countPerPartitions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partitions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;totalNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;countPerPartitions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;partitions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxsize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;rdd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parallelize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;totalNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partitions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rdd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SparkContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;appName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello Spark&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello Spark Demo. Compute the mean and variance of a collection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;computeStatsForCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;gt;&amp;gt;&amp;gt; Results: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;Mean: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]));&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;Variance: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]));&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;接下來只要使用spark submit指令就可以在local執行我們的程式囉！&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./spark-submit &lt;span class=&quot;nt&quot;&gt;--master&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;helloworld.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;運作的過程及結果：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Using Spark&lt;span class=&quot;s1&quot;&gt;'s default log4j profile: org/apache/spark/log4j-defaults.properties
17/12/22 18:56:46 INFO SparkContext: Running Spark version 2.1.2
17/12/22 18:56:47 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
17/12/22 18:56:47 INFO SecurityManager: Changing view acls to: stana
17/12/22 18:56:47 INFO SecurityManager: Changing modify acls to: stana
17/12/22 18:56:47 INFO SecurityManager: Changing view acls groups to:
17/12/22 18:56:47 INFO SecurityManager: Changing modify acls groups to:
17/12/22 18:56:47 INFO SecurityManager: SecurityManager: authentication disabled; ui acls disabled; users  with view permissions: Set(stana); groups with view permissions: Set(); users  with modify permissions: Set(stana); groups with modify permissions: Set()
17/12/22 18:56:48 INFO Utils: Successfully started service '&lt;/span&gt;sparkDriver&lt;span class=&quot;s1&quot;&gt;' on port 63573.
17/12/22 18:56:48 INFO SparkEnv: Registering MapOutputTracker
17/12/22 18:56:48 INFO SparkEnv: Registering BlockManagerMaster
17/12/22 18:56:48 INFO BlockManagerMasterEndpoint: Using org.apache.spark.storage.DefaultTopologyMapper for getting topology information
17/12/22 18:56:48 INFO BlockManagerMasterEndpoint: BlockManagerMasterEndpoint up
17/12/22 18:56:48 INFO DiskBlockManager: Created local directory at /private/var/folders/90/_z_w8bmd0k3gsv4y03clngfw0000gn/T/blockmgr-8e76e493-de86-4167-a3ab-cde2f0d62c6a
17/12/22 18:56:48 INFO MemoryStore: MemoryStore started with capacity 366.3 MB
17/12/22 18:56:48 INFO SparkEnv: Registering OutputCommitCoordinator
17/12/22 18:56:49 INFO Utils: Successfully started service '&lt;/span&gt;SparkUI&lt;span class=&quot;s1&quot;&gt;' on port 4040.
17/12/22 18:56:49 INFO SparkUI: Bound SparkUI to 0.0.0.0, and started at http://10.1.1.123:4040
17/12/22 18:56:49 INFO SparkContext: Added file file:/Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py at file:/Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py with timestamp 1513940209546
17/12/22 18:56:49 INFO Utils: Copying /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py to /private/var/folders/90/_z_w8bmd0k3gsv4y03clngfw0000gn/T/spark-2884e48f-df26-40ef-bc34-2e5cb9f03d1e/userFiles-3859a0da-0a04-4aa8-af98-7fe78b4dcfef/helloworld.py
17/12/22 18:56:49 INFO Executor: Starting executor ID driver on host localhost
17/12/22 18:56:49 INFO Utils: Successfully started service '&lt;/span&gt;org.apache.spark.network.netty.NettyBlockTransferService&lt;span class=&quot;s1&quot;&gt;' on port 63574.
17/12/22 18:56:49 INFO NettyBlockTransferService: Server created on 10.1.1.123:63574
17/12/22 18:56:49 INFO BlockManager: Using org.apache.spark.storage.RandomBlockReplicationPolicy for block replication policy
17/12/22 18:56:49 INFO BlockManagerMaster: Registering BlockManager BlockManagerId(driver, 10.1.1.123, 63574, None)
17/12/22 18:56:49 INFO BlockManagerMasterEndpoint: Registering block manager 10.1.1.123:63574 with 366.3 MB RAM, BlockManagerId(driver, 10.1.1.123, 63574, None)
17/12/22 18:56:49 INFO BlockManagerMaster: Registered BlockManager BlockManagerId(driver, 10.1.1.123, 63574, None)
17/12/22 18:56:49 INFO BlockManager: Initialized BlockManager: BlockManagerId(driver, 10.1.1.123, 63574, None)
Hello Spark Demo. Compute the mean and variance of a collection
17/12/22 18:56:50 INFO SparkContext: Starting job: mean at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7
17/12/22 18:56:50 INFO DAGScheduler: Got job 0 (mean at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7) with 5 output partitions
17/12/22 18:56:50 INFO DAGScheduler: Final stage: ResultStage 0 (mean at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7)
17/12/22 18:56:50 INFO DAGScheduler: Parents of final stage: List()
17/12/22 18:56:50 INFO DAGScheduler: Missing parents: List()
17/12/22 18:56:50 INFO DAGScheduler: Submitting ResultStage 0 (PythonRDD[1] at mean at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7), which has no missing parents
17/12/22 18:56:51 INFO MemoryStore: Block broadcast_0 stored as values in memory (estimated size 4.5 KB, free 366.3 MB)
17/12/22 18:56:51 INFO MemoryStore: Block broadcast_0_piece0 stored as bytes in memory (estimated size 2.9 KB, free 366.3 MB)
17/12/22 18:56:51 INFO BlockManagerInfo: Added broadcast_0_piece0 in memory on 10.1.1.123:63574 (size: 2.9 KB, free: 366.3 MB)
17/12/22 18:56:51 INFO SparkContext: Created broadcast 0 from broadcast at DAGScheduler.scala:996
17/12/22 18:56:51 INFO DAGScheduler: Submitting 5 missing tasks from ResultStage 0 (PythonRDD[1] at mean at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7)
17/12/22 18:56:51 INFO TaskSchedulerImpl: Adding task set 0.0 with 5 tasks
17/12/22 18:56:51 WARN TaskSetManager: Stage 0 contains a task of very large size (364 KB). The maximum recommended task size is 100 KB.
17/12/22 18:56:51 INFO TaskSetManager: Starting task 0.0 in stage 0.0 (TID 0, localhost, executor driver, partition 0, PROCESS_LOCAL, 373371 bytes)
17/12/22 18:56:51 INFO Executor: Running task 0.0 in stage 0.0 (TID 0)
17/12/22 18:56:51 INFO Executor: Fetching file:/Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py with timestamp 1513940209546
17/12/22 18:56:51 INFO Utils: /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py has been previously copied to /private/var/folders/90/_z_w8bmd0k3gsv4y03clngfw0000gn/T/spark-2884e48f-df26-40ef-bc34-2e5cb9f03d1e/userFiles-3859a0da-0a04-4aa8-af98-7fe78b4dcfef/helloworld.py
17/12/22 18:56:52 INFO PythonRunner: Times: total = 1335, boot = 398, init = 18, finish = 919
17/12/22 18:56:52 INFO Executor: Finished task 0.0 in stage 0.0 (TID 0). 1880 bytes result sent to driver
17/12/22 18:56:52 INFO TaskSetManager: Starting task 1.0 in stage 0.0 (TID 1, localhost, executor driver, partition 1, PROCESS_LOCAL, 509839 bytes)
17/12/22 18:56:52 INFO Executor: Running task 1.0 in stage 0.0 (TID 1)
17/12/22 18:56:52 INFO TaskSetManager: Finished task 0.0 in stage 0.0 (TID 0) in 1566 ms on localhost (executor driver) (1/5)
17/12/22 18:56:53 INFO PythonRunner: Times: total = 935, boot = -21, init = 22, finish = 934
17/12/22 18:56:53 INFO Executor: Finished task 1.0 in stage 0.0 (TID 1). 1793 bytes result sent to driver
17/12/22 18:56:53 INFO TaskSetManager: Starting task 2.0 in stage 0.0 (TID 2, localhost, executor driver, partition 2, PROCESS_LOCAL, 509839 bytes)
17/12/22 18:56:53 INFO Executor: Running task 2.0 in stage 0.0 (TID 2)
17/12/22 18:56:53 INFO TaskSetManager: Finished task 1.0 in stage 0.0 (TID 1) in 955 ms on localhost (executor driver) (2/5)
17/12/22 18:56:54 INFO PythonRunner: Times: total = 937, boot = -4, init = 5, finish = 936
17/12/22 18:56:54 INFO Executor: Finished task 2.0 in stage 0.0 (TID 2). 1793 bytes result sent to driver
17/12/22 18:56:54 INFO TaskSetManager: Starting task 3.0 in stage 0.0 (TID 3, localhost, executor driver, partition 3, PROCESS_LOCAL, 509839 bytes)
17/12/22 18:56:54 INFO Executor: Running task 3.0 in stage 0.0 (TID 3)
17/12/22 18:56:54 INFO TaskSetManager: Finished task 2.0 in stage 0.0 (TID 2) in 953 ms on localhost (executor driver) (3/5)
17/12/22 18:56:55 INFO PythonRunner: Times: total = 931, boot = -6, init = 7, finish = 930
17/12/22 18:56:55 INFO Executor: Finished task 3.0 in stage 0.0 (TID 3). 1880 bytes result sent to driver
17/12/22 18:56:55 INFO TaskSetManager: Starting task 4.0 in stage 0.0 (TID 4, localhost, executor driver, partition 4, PROCESS_LOCAL, 506157 bytes)
17/12/22 18:56:55 INFO Executor: Running task 4.0 in stage 0.0 (TID 4)
17/12/22 18:56:55 INFO TaskSetManager: Finished task 3.0 in stage 0.0 (TID 3) in 947 ms on localhost (executor driver) (4/5)
17/12/22 18:56:56 INFO PythonRunner: Times: total = 921, boot = -2, init = 3, finish = 920
17/12/22 18:56:56 INFO Executor: Finished task 4.0 in stage 0.0 (TID 4). 1793 bytes result sent to driver
17/12/22 18:56:56 INFO TaskSetManager: Finished task 4.0 in stage 0.0 (TID 4) in 935 ms on localhost (executor driver) (5/5)
17/12/22 18:56:56 INFO TaskSchedulerImpl: Removed TaskSet 0.0, whose tasks have all completed, from pool
17/12/22 18:56:56 INFO DAGScheduler: ResultStage 0 (mean at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7) finished in 5.362 s
17/12/22 18:56:56 INFO DAGScheduler: Job 0 finished: mean at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7, took 5.809938 s
17/12/22 18:56:56 INFO SparkContext: Starting job: variance at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7
17/12/22 18:56:56 INFO DAGScheduler: Got job 1 (variance at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7) with 5 output partitions
17/12/22 18:56:56 INFO DAGScheduler: Final stage: ResultStage 1 (variance at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7)
17/12/22 18:56:56 INFO DAGScheduler: Parents of final stage: List()
17/12/22 18:56:56 INFO DAGScheduler: Missing parents: List()
17/12/22 18:56:56 INFO DAGScheduler: Submitting ResultStage 1 (PythonRDD[2] at variance at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7), which has no missing parents
17/12/22 18:56:56 INFO MemoryStore: Block broadcast_1 stored as values in memory (estimated size 4.5 KB, free 366.3 MB)
17/12/22 18:56:56 INFO MemoryStore: Block broadcast_1_piece0 stored as bytes in memory (estimated size 2.9 KB, free 366.3 MB)
17/12/22 18:56:56 INFO BlockManagerInfo: Added broadcast_1_piece0 in memory on 10.1.1.123:63574 (size: 2.9 KB, free: 366.3 MB)
17/12/22 18:56:56 INFO SparkContext: Created broadcast 1 from broadcast at DAGScheduler.scala:996
17/12/22 18:56:56 INFO DAGScheduler: Submitting 5 missing tasks from ResultStage 1 (PythonRDD[2] at variance at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7)
17/12/22 18:56:56 INFO TaskSchedulerImpl: Adding task set 1.0 with 5 tasks
17/12/22 18:56:56 WARN TaskSetManager: Stage 1 contains a task of very large size (364 KB). The maximum recommended task size is 100 KB.
17/12/22 18:56:56 INFO TaskSetManager: Starting task 0.0 in stage 1.0 (TID 5, localhost, executor driver, partition 0, PROCESS_LOCAL, 373375 bytes)
17/12/22 18:56:56 INFO Executor: Running task 0.0 in stage 1.0 (TID 5)
17/12/22 18:56:57 INFO PythonRunner: Times: total = 906, boot = -74, init = 75, finish = 905
17/12/22 18:56:57 INFO Executor: Finished task 0.0 in stage 1.0 (TID 5). 1866 bytes result sent to driver
17/12/22 18:56:57 INFO TaskSetManager: Starting task 1.0 in stage 1.0 (TID 6, localhost, executor driver, partition 1, PROCESS_LOCAL, 509843 bytes)
17/12/22 18:56:57 INFO Executor: Running task 1.0 in stage 1.0 (TID 6)
17/12/22 18:56:57 INFO TaskSetManager: Finished task 0.0 in stage 1.0 (TID 5) in 925 ms on localhost (executor driver) (1/5)
17/12/22 18:56:58 INFO PythonRunner: Times: total = 927, boot = -1, init = 2, finish = 926
17/12/22 18:56:58 INFO Executor: Finished task 1.0 in stage 1.0 (TID 6). 1880 bytes result sent to driver
17/12/22 18:56:58 INFO TaskSetManager: Starting task 2.0 in stage 1.0 (TID 7, localhost, executor driver, partition 2, PROCESS_LOCAL, 509843 bytes)
17/12/22 18:56:58 INFO Executor: Running task 2.0 in stage 1.0 (TID 7)
17/12/22 18:56:58 INFO TaskSetManager: Finished task 1.0 in stage 1.0 (TID 6) in 937 ms on localhost (executor driver) (2/5)
17/12/22 18:56:59 INFO PythonRunner: Times: total = 927, boot = -1, init = 2, finish = 926
17/12/22 18:56:59 INFO Executor: Finished task 2.0 in stage 1.0 (TID 7). 1793 bytes result sent to driver
17/12/22 18:56:59 INFO TaskSetManager: Starting task 3.0 in stage 1.0 (TID 8, localhost, executor driver, partition 3, PROCESS_LOCAL, 509843 bytes)
17/12/22 18:56:59 INFO Executor: Running task 3.0 in stage 1.0 (TID 8)
17/12/22 18:56:59 INFO TaskSetManager: Finished task 2.0 in stage 1.0 (TID 7) in 936 ms on localhost (executor driver) (3/5)
17/12/22 18:57:00 INFO PythonRunner: Times: total = 929, boot = 1, init = 0, finish = 928
17/12/22 18:57:00 INFO Executor: Finished task 3.0 in stage 1.0 (TID 8). 1793 bytes result sent to driver
17/12/22 18:57:00 INFO TaskSetManager: Starting task 4.0 in stage 1.0 (TID 9, localhost, executor driver, partition 4, PROCESS_LOCAL, 506161 bytes)
17/12/22 18:57:00 INFO Executor: Running task 4.0 in stage 1.0 (TID 9)
17/12/22 18:57:00 INFO TaskSetManager: Finished task 3.0 in stage 1.0 (TID 8) in 938 ms on localhost (executor driver) (4/5)
17/12/22 18:57:01 INFO PythonRunner: Times: total = 926, boot = 0, init = 0, finish = 926
17/12/22 18:57:01 INFO Executor: Finished task 4.0 in stage 1.0 (TID 9). 1793 bytes result sent to driver
17/12/22 18:57:01 INFO TaskSetManager: Finished task 4.0 in stage 1.0 (TID 9) in 933 ms on localhost (executor driver) (5/5)
17/12/22 18:57:01 INFO TaskSchedulerImpl: Removed TaskSet 1.0, whose tasks have all completed, from pool
17/12/22 18:57:01 INFO DAGScheduler: ResultStage 1 (variance at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7) finished in 4.664 s
17/12/22 18:57:01 INFO DAGScheduler: Job 1 finished: variance at /Volumes/Sdhd/Downloads/spark-2.1.2-bin-hadoop2.7/bin/helloworld.py:7, took 4.677022 s
&amp;gt;&amp;gt;&amp;gt; Results:
&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;Mean: 249999.5
&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;Variance: 20833333333.2
17/12/22 18:57:01 INFO SparkUI: Stopped Spark web UI at http://10.1.1.123:4040
17/12/22 18:57:01 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!
17/12/22 18:57:01 INFO MemoryStore: MemoryStore cleared
17/12/22 18:57:01 INFO BlockManager: BlockManager stopped
17/12/22 18:57:01 INFO BlockManagerMaster: BlockManagerMaster stopped
17/12/22 18:57:01 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!
17/12/22 18:57:01 INFO SparkContext: Successfully stopped SparkContext
17/12/22 18:57:02 INFO ShutdownHookManager: Shutdown hook called
17/12/22 18:57:02 INFO ShutdownHookManager: Deleting directory /private/var/folders/90/_z_w8bmd0k3gsv4y03clngfw0000gn/T/spark-2884e48f-df26-40ef-bc34-2e5cb9f03d1e/pyspark-7a2eb92b-ea5a-47b4-9595-f5bc069fe579
17/12/22 18:57:02 INFO ShutdownHookManager: Deleting directory /private/var/folders/90/_z_w8bmd0k3gsv4y03clngfw0000gn/T/spark-2884e48f-df26-40ef-bc34-2e5cb9f03d1e
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;大家可以看到這段文字：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; Results:
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;Mean: 249999.5
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;Variance: 20833333333.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;就是我們在程式裡面印出來的文字。&lt;/p&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;這段程式碼是使用 spark submit 來進行運作，如果對spark submit不了解沒關係，接下來我們就要來介紹它了！&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 17-Apache Spark Shell 簡介</title>
   <link href="s/bigdata/2017/12/20/30days-series-17-introduction-of-spark-shell"/>
   <updated>2017-12-20T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/20/30days-series-17-introduction-of-spark-shell</id>
   <content type="html">&lt;h1 id=&quot;spark-shell&quot;&gt;Spark Shell&lt;/h1&gt;

&lt;p&gt;Spark Shell是一個互動介面，提供使用者一個簡單的方式學習Spark API，可以使用Scala或是Python。
要如何運作呢？&lt;/p&gt;

&lt;p&gt;首先到官方網站下載Spark，作者這裡使用的Spark 2.1.2 Pre-build for Hadoop 2.7，表示支援Hadoop 2.7或以上到版本。&lt;/p&gt;

&lt;p&gt;接著執行下列的語法：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#若環境變數沒有設定SPARK_HOME，請自行移動至Spark 目錄下。&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$SPARK_HOME&lt;/span&gt;
./bin/spark-shell
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以看到下面的歡迎畫面：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Using Sparks default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to &lt;span class=&quot;s2&quot;&gt;&quot;WARN&quot;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
To adjust logging level use sc.setLogLevel&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;newLevel&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; For SparkR, use setLogLevel&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;newLevel&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
17/12/21 14:58:18 WARN NativeCodeLoader: Unable to load native-hadoop library &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;your platform...
using builtin-java classes where applicable
Spark context Web UI available at http://10.1.1.123:4040
Spark context available as &lt;span class=&quot;s2&quot;&gt;&quot;sc&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;master &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, app id &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; local-1513839499523&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
Spark session available as &lt;span class=&quot;s2&quot;&gt;&quot;spark&quot;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _&lt;span class=&quot;se&quot;&gt;\ \/&lt;/span&gt; _ &lt;span class=&quot;se&quot;&gt;\/&lt;/span&gt; _ |/ __/  |_/
   /___/ .__/&lt;span class=&quot;se&quot;&gt;\_&lt;/span&gt;,_/_/ /_/&lt;span class=&quot;se&quot;&gt;\_\ &lt;/span&gt;  version 2.1.2
      /_/

Using Scala version 2.11.8 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Java HotSpot&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;TM&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 64-Bit Server VM, Java 1.8.0_112&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Type &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;expressions to have them evaluated.
Type :help &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;more information.

scala&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;注意一下啟動時的資訊:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Spark context Web UI available at http://10.1.1.123:4040
Spark context available as &lt;span class=&quot;s1&quot;&gt;'sc'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;master &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, app id &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; local-1513839499523&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
Spark session available as &lt;span class=&quot;s1&quot;&gt;'spark'&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;表示已經幫使用者啟動一個 local 的 Spark Web UI，也初始化了Spark context，表示隨時都可以寫一段程式讓 Spark 在 local 進行運作。接著讓我們來寫一段簡單的word count程式碼吧！&lt;/p&gt;

&lt;h2 id=&quot;基礎用法&quot;&gt;基礎用法&lt;/h2&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;讀取&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;$SPARK_HOME&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;根目錄下的&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;README&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;md&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;檔案&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;。&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;README.md&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;org.apache.spark.rdd.RDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;README&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;md&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MapPartitionsRDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;計算有多少文字&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;res0&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Long&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;104&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Spark Application 的運作過程可以在Spark context Web UI可以看到剛剛wordcount運作的資訊。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/mathsigit/blog_page/gh-pages/img/30_days/spark_shell_web_ui.png&quot; alt=&quot;spark_shell_web_ui.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;進階使用&quot;&gt;進階使用&lt;/h2&gt;

&lt;p&gt;也可以在 Spark-Shell 內 import 某些 Scala 或 Java 的 Library。&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.lang.Math&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.lang.Math&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;接著來計算README.md內以行(row)為比較單位，每行最多有幾個字：&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maptextFileRDD&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;maptextFileRDD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;org.apache.spark.rdd.RDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MapPartitionsRDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reduceMaptextFileRDD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maptextFileRDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;reduceMaptextFileRDD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;由此可了解單行最多的字有22個。&lt;/p&gt;

&lt;p&gt;如果要列印出RDD內容，可以使用下列語法：&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maptextFileRDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;實作hadoop-mapreduce&quot;&gt;實作Hadoop MapReduce&lt;/h2&gt;

&lt;p&gt;Big Data 的運算框架 MapReduce 一樣可以使用Spark來實作：&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;testFlatmap&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;testFlatmap&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;org.apache.spark.rdd.RDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MapPartitionsRDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reduceByKeyFlatmap&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;testFlatmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduceByKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;reduceByKeyFlatmap&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;org.apache.spark.rdd.RDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShuffledRDD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reduceByKey&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//查看結果
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reduceByKeyFlatmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;res5&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;](http://spark.apache.org/docs/latest/building-spark.html#specifying-the-hadoop-version),1), (Because,1), (Python,2), (page](http://spark.apache.org/documentation.html).,1), (cluster.,1), (its,1), ([run,1), (general,3), (have,1), (pre-built,1), (YARN,,1), ([http://spark.apache.org/developer-tools.html](the,1), (changed,1), (locally,2), (sc.parallelize(1,1), (only,1), (locally.,1), (several,1), (This,2), (basic,1), (Configuration,1), (learning,,1), (documentation,3), (first,1), (graph,1), (Hive,2), (info,1), ([&quot;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Specifying&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;yarn&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]`.,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;project&lt;/span&gt;,&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;SparkPi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;://&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&amp;gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;documentation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MASTER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Parallel&lt;/span&gt;,&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;are&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;離開spark-shell&quot;&gt;離開Spark Shell&lt;/h2&gt;

&lt;p&gt;使用下面指令就可以離開Spark Shell的介面：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;scala&amp;gt; :q
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;Spark Shell 可以讓使用者快速了解如何撰寫RDD並得到結果，不適用於大量運算。如果需要計算大量資料，建議撰寫 Scala 或是 Java 程式，編譯後打包並使用spark-submit 指令送至資源管理系統進行分散式計算，效能會比較好。&lt;/p&gt;

&lt;p&gt;簡單介紹完Spark Shell後，接下來要來介紹如何使用Spark api撰寫第一個Hello World application。&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 16-Apache Spark RDD 簡介</title>
   <link href="s/bigdata/2017/12/19/30days-series-16-introduction-of-spark-rdd"/>
   <updated>2017-12-19T16:00:00+00:00</updated>
   <id>s/bigdata/2017/12/19/30days-series-16-introduction-of-spark-rdd</id>
   <content type="html">&lt;h1 id=&quot;spark-rdd-簡介&quot;&gt;Spark RDD 簡介&lt;/h1&gt;

&lt;p&gt;Spark的核心是 RDD，Resilient Distributed DataSet的縮寫，是一種具有容錯(tolerant)與高效能(efficient)的抽象資料結構。RDD 由一到數個的 partition組成，Spark程式進行運算時，partition會分散在各個節點進行運算，預設會被存放在記憶體內，所以可以快速享各個partition的運算結果，但若記憶體不足會出現&lt;code class=&quot;highlighter-rouge&quot;&gt;OOM Exception&lt;/code&gt;錯誤訊息，可透過參數設定存放在硬碟避免發生該錯誤。&lt;/p&gt;

&lt;p&gt;RDD支援下列語言撰寫而成的object：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Scala&lt;/li&gt;
  &lt;li&gt;Java&lt;/li&gt;
  &lt;li&gt;Python&lt;/li&gt;
  &lt;li&gt;R&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spark是由Scala撰寫而成，嚴格遵守Functional Program的概念，所以RDD只能讀取無法寫入。  &lt;br /&gt;
Spark 支援讀取 HDFS 等分散式儲存裝置的檔案，故可以使用HDFS的特性便於進行分散式的運算。&lt;/p&gt;

&lt;p&gt;綜合以上可歸納出RDD具有幾個特性：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Immutable&lt;/li&gt;
  &lt;li&gt;Distributed&lt;/li&gt;
  &lt;li&gt;Parallelizing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;每個RDD會紀錄五件事情，分成兩種類別：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;i) Lineage
    &lt;ul&gt;
      &lt;li&gt;1.Set of partitions(“splits” in Hadoop).&lt;/li&gt;
      &lt;li&gt;2.List of dependencies on parent RDDs.&lt;/li&gt;
      &lt;li&gt;3.Function to compute a partition(as an Iterator) given its parent(s).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;ii) Optimized Execution
    &lt;ul&gt;
      &lt;li&gt;4.(Optional) partitioner (hash, range).&lt;/li&gt;
      &lt;li&gt;5.(Optional) preferred location(s) for each partition.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lineage為RDD的血統關係，主要用來作為容錯處理，先來看一段程式碼：&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//RDD Transformations
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;textFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hdfs://large/file&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[a-z]+&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[0-9]+&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//RDD Action
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;程式碼內容是讀取HDFS檔案後，轉將內容轉成小寫並且以空白為分割符號將每個字切開，並且以對文字與數字分別進行計算，就是一個wordcount的範例程式。  &lt;br /&gt;
一個完整的Spark Application一定會有兩大類型的操作：&lt;code class=&quot;highlighter-rouge&quot;&gt;Transformations&lt;/code&gt;與&lt;code class=&quot;highlighter-rouge&quot;&gt;Action&lt;/code&gt;。  &lt;br /&gt;
由範例來看&lt;code class=&quot;highlighter-rouge&quot;&gt;words&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;alpha&lt;/code&gt;與&lt;code class=&quot;highlighter-rouge&quot;&gt;nums&lt;/code&gt;的操作都屬於Transformations，&lt;code class=&quot;highlighter-rouge&quot;&gt;alpha.count()&lt;/code&gt;與&lt;code class=&quot;highlighter-rouge&quot;&gt;nums.count()&lt;/code&gt;屬於Action。在RDD中 Transformations 的操作是Lazy運作，亦即不會馬上進行計算，只會紀錄使用到哪些資料集(例如讀取HDFS上某個路徑)，當執行Action時才會開始進行運算。當Spark Application的Transformations 數量很多卻又需要重複運作時，可以使用&lt;code class=&quot;highlighter-rouge&quot;&gt;persist&lt;/code&gt;(或&lt;code class=&quot;highlighter-rouge&quot;&gt;cache&lt;/code&gt;)的method對某個RDD用持久化，這樣該RDD就不會因為Lazy需要重新運算，可以加快運算速度。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://spark.apache.org/docs/2.2.0/rdd-programming-guide.html#transformations&quot;&gt;查看更多的 transformations  API&lt;/a&gt;  &lt;br /&gt;
&lt;a href=&quot;https://spark.apache.org/docs/2.2.0/rdd-programming-guide.html#actions&quot;&gt;查看更多的 actions  API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;由下圖可以看出Wordcount的程式碼轉換成RDD對照與Lineage：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/mathsigit/blog_page/gh-pages/img/30_days/rdd_lineage.png&quot; alt=&quot;rdd_lineage.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From: https://www.slideshare.net/frodriguezolivera/apache-spark-41601032#44&lt;/p&gt;

&lt;p&gt;當某個RDD運作失敗時，Spark會根據Lineage找到parent RDD是誰，並且從parent RDD 繼續計算，以完成整個Spark的運算，由此可以理解Spark的容錯機制。&lt;/p&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;對Spark RDD有初步的了解後，接下來要來介紹Spark Shell，互動式的操作介面。&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Service列表與使用說明</title>
   <link href="s/document/2017/12/19/service-list-and-document"/>
   <updated>2017-12-19T00:00:00+00:00</updated>
   <id>s/document/2017/12/19/service-list-and-document</id>
   <content type="html">&lt;p&gt;根據&lt;a href=&quot;https://is-land.atlassian.net/browse/INFRA-15&quot;&gt;INFRA-15&lt;/a&gt;的需求，此篇主要用來說明現有的程式、服務…等入口點與使用說明文件的連結。&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 15-Apache Spark 簡介</title>
   <link href="s/bigdata/2017/12/19/30days-series-15-introduction-of-spark"/>
   <updated>2017-12-19T00:00:00+00:00</updated>
   <id>s/bigdata/2017/12/19/30days-series-15-introduction-of-spark</id>
   <content type="html">&lt;h1 id=&quot;apache-spark-簡介&quot;&gt;Apache Spark 簡介&lt;/h1&gt;

&lt;p&gt;目前Big data最熱門的open source專案莫過於&lt;code class=&quot;highlighter-rouge&quot;&gt;Apache Spark&lt;/code&gt;。為什麼Spark會這麼受歡迎？原因有三個：&lt;code class=&quot;highlighter-rouge&quot;&gt;速度&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;速度&lt;/code&gt;與&lt;code class=&quot;highlighter-rouge&quot;&gt;速度&lt;/code&gt;，是的！沒看錯就是速度。當初Hadoop正式釋出後造成轟動，一個跨世紀的儲存、運算、資源管理的平台誕生了，但由於MapReduce運算花費太多的磁碟IO，造成運算效能與使用者的期待落差甚遠，所以Spark推出後就因為他的運算速度而快速吸引眾多的使用者！&lt;/p&gt;

&lt;p&gt;根據&lt;a href=&quot;https://spark.apache.org/&quot;&gt;Apache Spark官方網站&lt;/a&gt;的說明，Spark在記憶體內執行運算時，最快可以比Hadoop MapReduce快100倍。即使與MapReduceㄧ樣將運算結果儲存在硬碟上，運算速度也可以快上10倍。&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Run programs up to 100x faster than Hadoop MapReduce in memory, or 10x faster on disk.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/mathsigit/blog_page/gh-pages/img/30_days/spark_logistic_regression.png&quot; alt=&quot;spark_logistic_regression.png&quot; /&gt;  &lt;br /&gt;
From: https://spark.apache.org/&lt;/p&gt;

&lt;p&gt;由於Apache spark主打的是&lt;code class=&quot;highlighter-rouge&quot;&gt;Lightning-fast cluster computing&lt;/code&gt;，輕量又快速的叢集運算，小至個人PC大到企業級伺服器，只要透過設定皆可以在這些機器上使用Spark來進行運算。&lt;/p&gt;

&lt;h2 id=&quot;運算方式&quot;&gt;運算方式&lt;/h2&gt;

&lt;p&gt;Apache Spark是一個分散式的運算框架(Framework)，可分為以下幾種執行運算的方法，後面的文章會介紹這幾種執行方式的方法與差別。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;local mode&lt;/li&gt;
  &lt;li&gt;Standalone&lt;/li&gt;
  &lt;li&gt;On Hadoop Yarn&lt;/li&gt;
  &lt;li&gt;On Apache Mesos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;spark-api&quot;&gt;Spark Api&lt;/h2&gt;

&lt;p&gt;目前Spark Api所支援的語言有：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Scala&lt;/li&gt;
  &lt;li&gt;Java&lt;/li&gt;
  &lt;li&gt;Python&lt;/li&gt;
  &lt;li&gt;R&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;由於Spark原始碼是以&lt;code class=&quot;highlighter-rouge&quot;&gt;Scala&lt;/code&gt;撰寫，所以在Scala Api的支援相較於其他語言比較完整，其次為Java、Python、R。建議使用Scala撰寫Spark Application 可以使用完整的Spark Api，未來若有機會trace source code也比較看得懂。&lt;/p&gt;

&lt;h2 id=&quot;components&quot;&gt;Components&lt;/h2&gt;

&lt;p&gt;Spaek主要包含四個函式庫的功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Spark SQL&lt;/li&gt;
  &lt;li&gt;Spark Streaming&lt;/li&gt;
  &lt;li&gt;MLlib(machine learning)&lt;/li&gt;
  &lt;li&gt;GraphX(graph)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/mathsigit/blog_page/gh-pages/img/30_days/spark_components.png&quot; alt=&quot;spark_logistic_regression.png&quot; /&gt;  &lt;br /&gt;
From: https://spark.apache.org/&lt;/p&gt;

&lt;p&gt;在Spark的篇章會介紹Spark SQL與Spark Streaming。&lt;/p&gt;

&lt;h2 id=&quot;最後&quot;&gt;最後&lt;/h2&gt;

&lt;p&gt;簡單介紹完Apache Spark，接下來會針對下面的內容做更詳細的介紹：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Spark的核心 - RDD (Resilient Distributed Dataset)&lt;/li&gt;
  &lt;li&gt;Spark Shell&lt;/li&gt;
  &lt;li&gt;使用Spark api撰寫第一個Hello World application&lt;/li&gt;
  &lt;li&gt;執行Spark Application - Spark Submit&lt;/li&gt;
  &lt;li&gt;Spark SQL&lt;/li&gt;
  &lt;li&gt;Spark Streaming&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 14-HBase SQL工具介紹</title>
   <link href="s/bigdata/2017/12/18/30days-series-14-hbase-sql-tool"/>
   <updated>2017-12-18T00:00:00+00:00</updated>
   <id>s/bigdata/2017/12/18/30days-series-14-hbase-sql-tool</id>
   <content type="html">&lt;p&gt;在前面的介紹篇章有提到，HBase本身並沒有內建SQL查詢的介面讓使用者查詢。
但並不因為這樣就無法使用SQL語法對HBase進行查詢。這篇要來介紹幾個基於HBase可使用SQL查詢的工具。&lt;/p&gt;

&lt;h2 id=&quot;apache-phoenix&quot;&gt;Apache Phoenix&lt;/h2&gt;

&lt;p&gt;Phoenix是基於HBase所開發出來的數據查詢層，使用者可以透過JDBC向Query execution engine使用ANSI SQL語法進行查詢，Phoenix會將SQL語法轉換成各種Scan與Filter的HBase Client API後，並使用預先在HBase內註冊的&lt;code class=&quot;highlighter-rouge&quot;&gt;Coprocessor&lt;/code&gt;對HBase進行分散式查詢。&lt;/p&gt;

&lt;p&gt;由於是透過HBase Coprocessor的方法進行查詢，反應時間最快可以在毫秒等級，是目前HBase SQL查詢的推薦工具之一。使用者只要透過撰寫JDBC的程式即可使用符合ANSI SQL的語法對HBase進行資料的操作！除此之外還具有ACID功能讓使用者可以更近一步的使用SQL對HBase進行更近一步的操作。&lt;/p&gt;

&lt;p&gt;不過使用Phoenix後HBase的 raw data有可能會被修改成Phoenix制訂的格式，而原先使用HBase scan可認得的資料可能就無法辨識！&lt;/p&gt;

&lt;p&gt;Phoenix原先由Saleforce所開發，爾後捐獻給Apache基金會，後來變成Apache Top project。&lt;/p&gt;

&lt;p&gt;相關安裝教學請看&lt;a href=&quot;http://phoenix.apache.org/&quot;&gt;官方網站&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../img/30_days/phoenix.png&quot; alt=&quot;phoenix.png&quot; /&gt;  &lt;br /&gt;
From:https://phoenix.apache.org/presentations/OC-HUG-2014-10-4x3.pdf&lt;/p&gt;

&lt;h2 id=&quot;haredb-hbase-client&quot;&gt;HareDB HBase Client&lt;/h2&gt;

&lt;p&gt;由台灣的軟體公司&lt;a href=&quot;https://www.is-land.com.tw&quot;&gt;亦思科技&lt;/a&gt;所研發，結合Apache Hive與HBase Coprocessor的特點，除了擁有媲美Apache Phoenix的查詢效能外，一鍵即可使用、免安裝，讓使用者可以透過內建的Web介面來對HBase進行資料的操作。內建支援HBase Bulkload功能，可讓使用者在Web介面設定資訊後，一鍵送出即可，並可透過監控畫面進行Job的觀察。&lt;/p&gt;

&lt;p&gt;其最新版本1.120.04s支援HBase 1.12版本，並內建Hive on Spark功能，可對儲存於HDFS上的格式化的資料，使用Hive SQL透過Spark的分散式運算進行查詢，效能比MapReduce快上許多！&lt;/p&gt;

&lt;p&gt;免費版本可至&lt;a href=&quot;http://www.haredb.com/HareDB/src_ap/Download_HBaseClient.aspx?l=4&quot;&gt;haredbhbaseclient_sourceforge&lt;/a&gt;，或者到&lt;a href=&quot;http://www.haredb.com/HareDB/src_ap/Download_HBaseClient.aspx?l=4&quot;&gt;HareDB官方網站&lt;/a&gt;下載。  &lt;br /&gt;
60天完整試用版經過Cloudera官方認證，具有Security功能。&lt;/p&gt;

&lt;p&gt;簡單介紹完了HBase 的SQL查詢工具後，HBase的介紹也告一段落，接下來的篇章要來介紹Apache Spark。&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 13-HBase Bulkload 簡介</title>
   <link href="s/bigdata/2017/12/17/30days-series-13-hbase-bulkload"/>
   <updated>2017-12-17T00:00:00+00:00</updated>
   <id>s/bigdata/2017/12/17/30days-series-13-hbase-bulkload</id>
   <content type="html">&lt;p&gt;前面介紹了使用&lt;code class=&quot;highlighter-rouge&quot;&gt;hbase shell&lt;/code&gt;與HBase client APIs新增資料，但這兩種方法只能一次新增一組key-value的資料，假如有一批檔案數十GB甚至上百GB，一筆一筆慢慢put所需要花費的時間就無法想像了，更不用說觸發split或是compact的情況下，效能可能會更加低落。&lt;/p&gt;

&lt;p&gt;無論是&lt;code class=&quot;highlighter-rouge&quot;&gt;hbase shell&lt;/code&gt;或是API，使用put新增資料時，會被放入被稱為&lt;code class=&quot;highlighter-rouge&quot;&gt;MemStore&lt;/code&gt;的記憶體內，同時寫入WAL[1]。在頻繁地寫入的使用情境，為了保護資料的完整，卻會讓寫入的效能低落。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[1] Write-Ahead-Log，用來記錄對HBase表格所有操作的日誌，用來確保table資料不遺漏，一個RegionServer只會有一個。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;為了提升輸入資料的效能，HBase提供bulkload的功能，讓使用者可以一次將大批資料透過MapReduce的方式將資料存入。&lt;/p&gt;

&lt;p&gt;先來看一下HBase Bulkload的Usage：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hbase org.apache.hadoop.hbase.mapreduce.ImportTsv
&lt;span class=&quot;nt&quot;&gt;-Dimporttsv&lt;/span&gt;.columns&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;a,b,c
&lt;span class=&quot;nt&quot;&gt;-Dimporttsv&lt;/span&gt;.skip.bad.lines&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;'-Dimporttsv.separator=|'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-Dimporttsv&lt;/span&gt;.timestamp&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;currentTimeAsLong
&amp;lt;tablename&amp;gt; &amp;lt;hdfs-inputdir&amp;gt;

&lt;span class=&quot;c&quot;&gt;#說明：&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#必填：&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-Dimporttsv&lt;/span&gt;.bulk.output:  使用importtsv第一階段所產生的HFile存放路徑。
tablename:                欲進行匯入資料的HBase table name。
hdfs-inputdir:            欲匯入的資料檔案路徑，必須存放在HDFS。
&lt;span class=&quot;c&quot;&gt;#選用，不一定要使用：&lt;/span&gt;
importtsv.columns:        HBase table 欄位名稱。如果是Rowkey則使用HBASE_ROW_KEY，需使用cf:qualifier的格式
importtsv.skip.bad.lines: 如果該行資料不符格式，跳過此行繼續讀取其他的資料，如果沒有設定為true，遇到badline整個bolkload作業會因錯誤而停止。
importtsv.separator:      檔案內每個欄位的分隔符號，預設為&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;,&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;。
importtsv.timestamp:      時間註記。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;hbase-bulkload-步驟&quot;&gt;HBase Bulkload 步驟&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Step 1: 上傳資料到HDFS。
假設有個檔案&lt;code class=&quot;highlighter-rouge&quot;&gt;test.txt&lt;/code&gt;，內容如下：
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;row1|c1|c2
row2|c1|c2
row3|c1|c2
row4|c1|c2
row5|c1|c2
row6|c1|c2
row7|c1|c2
row8|c1|c2
row9|c1|c2
row10|c1|c2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;上傳至HDFS路徑&lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp/bkloadInputData/test.txt&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Step 2: 建立HBase table:
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;create &lt;span class=&quot;s1&quot;&gt;'bkloadTable'&lt;/span&gt;, &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;NAME &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'cf'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Step 3: 使用ImportTsv進行Bolkload:  &lt;br /&gt;
假設已經安裝了Hadoop，並已經設定好環境變數，延續HBase安裝所使用的版本:2.0.0-alpha4。
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hadoop jar &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HBASE_HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/lib/hbase-mapreduce-2.0.0-alpha4.jar importtsv &lt;span class=&quot;nt&quot;&gt;-Dimporttsv&lt;/span&gt;.columns&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;HBASE_ROW_KEY,cf:column1,cf:column2
&lt;span class=&quot;nt&quot;&gt;-Dimporttsv&lt;/span&gt;.skip.bad.lines&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;'-Dimporttsv.separator=,'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-Dimporttsv&lt;/span&gt;.bulk.output&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;hdfs://&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;hostname&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;:9000/tmp/testoutput
bkloadTable
hdfs://&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;hostname&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;:9000/tmp/bkloadInputData
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;成功執行後，可在&lt;code class=&quot;highlighter-rouge&quot;&gt;http://{hadoop-master}:8088&lt;/code&gt;的頁面看到有個importtsv的JOB正在執行，成功執行完成後bolkload第一階段也就完成了。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Step 4: Complete BulkLoad
執行指令：
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hadoop jar &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HBASE_HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/lib/hbase-mapreduce-2.0.0-alpha4.jar
completebulkload
hdfs://&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;hostname&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;:9000/tmp/testoutput
bkloadTable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;這個步驟所需要花費的時間相當短，數秒鐘就可完成。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;經過Step 4 與Step 5後，test.txt的檔案內容就已經被匯入bkloadTable資料表內。匯入資料時可以搭配前面所介紹的Rowkey設計，這樣會讓HBase發揮更好的效果。接下來的篇章要來介紹HBase相關的SQL工具。&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 12-HBase Hello World API 教學</title>
   <link href="s/bigdata/2017/12/16/30days-series-12-hbase-helloworld-api"/>
   <updated>2017-12-16T00:00:00+00:00</updated>
   <id>s/bigdata/2017/12/16/30days-series-12-hbase-helloworld-api</id>
   <content type="html">&lt;p&gt;在這篇文章內容，將會學到如何使用HBase Client API對HBase的CRUD操作。本篇的範例程式碼所使用的HBase版本是 &lt;em&gt;HBase 0.98.x&lt;/em&gt; ，相容於 &lt;em&gt;HBase 1.x.x&lt;/em&gt; 。&lt;/p&gt;

&lt;p&gt;首先先來看一下SQL、API與HBase Shell的CRUD對照：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;SQL&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;HBase Client API&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;HBase Shell&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;select&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Get/Scan&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;get/scan&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;insert&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Put&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;put&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;delete&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Delete&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;delete&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;update&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Put&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;get/scan&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;hbase-connection&quot;&gt;HBase Connection&lt;/h2&gt;

&lt;p&gt;與所有RDB相同，連線到HBase也需要設定connection：&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.hadoop.conf.Configuration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.hadoop.hbase.HBaseConfiguration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.hadoop.hbase.client.HBaseAdmin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.hadoop.hbase.client.HTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HBaseConfiguration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hbase.zookeeper.quorum&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hbase.zookeeper.property.clientPort&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;“&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2181&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;);  
HBaseAdmin admin = new HBaseAdmin(conf);
String tableName = &quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;employees&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;使用put新增一筆row資料&quot;&gt;使用&lt;code class=&quot;highlighter-rouge&quot;&gt;Put&lt;/code&gt;新增一筆(row)資料&lt;/h2&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;employees&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Put&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;put&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Development_999999&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cf1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p-birth_date&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p-first_name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;s&quot;&gt;&quot;p-last_name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;p-gender&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p-hire_date&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;d-from_date&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;d-to_date&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1970-03-10&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Li&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;M&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1988-05-08&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1988-05-08&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;9999-01-01&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toDateValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toDateValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toDateValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;familyName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toDateValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;使用get查詢一筆row資料&quot;&gt;使用&lt;code class=&quot;highlighter-rouge&quot;&gt;Get&lt;/code&gt;查詢一筆(row)資料&lt;/h2&gt;

&lt;p&gt;現在我們來查剛剛Put進去的資料。&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;employees&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Get&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Development_999999&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
&lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;result size: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;result string: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result[%d]: %s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()));&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;使用scan來查詢table所有資料&quot;&gt;使用&lt;code class=&quot;highlighter-rouge&quot;&gt;Scan&lt;/code&gt;來查詢table所有資料&lt;/h2&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;employees&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Scan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scan&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scan&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ResultScanner&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getScanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;使用delete刪除一筆資料&quot;&gt;使用&lt;code class=&quot;highlighter-rouge&quot;&gt;Delete&lt;/code&gt;刪除一筆資料&lt;/h2&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;employees&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Delete&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Development_999999&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
&lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;htable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;最後&quot;&gt;最後&lt;/h1&gt;

&lt;p&gt;看完了Hello World版本的API後，接下來要介紹如何使用HBase Bolk-Load。&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>30天系列 Day 11-HBase RowKey Desing</title>
   <link href="s/bigdata/2017/12/15/30days-series-11-hbase-rowkey-design"/>
   <updated>2017-12-15T00:00:00+00:00</updated>
   <id>s/bigdata/2017/12/15/30days-series-11-hbase-rowkey-design</id>
   <content type="html">&lt;p&gt;如果想要享受HBase飛快的查詢速度，與避免read/write的hotspot，好的RowKey Design是很重要的。&lt;/p&gt;

&lt;p&gt;HBase的資料是儲存於Region Server並且以RowKey當作各Region分區的界線。由於RowKey是使用字典排序，當RowKey為連續字串時會導致資料傾斜，資料過度集中於某個region server。當這狀況發生時，如果有多個使用者同時對這個table發出請求(讀/寫)，這個region server會無法接受過多的請求數量而過於忙碌，這時候(讀/寫)的效能就會下降，嚴重的會導致該region server被認定已經crash，觸發HBase容錯機制而讓整個HBase叢集更為忙碌…&lt;/p&gt;

&lt;h2 id=&quot;rowkey-scan&quot;&gt;RowKey Scan&lt;/h2&gt;

&lt;p&gt;假設有個RowKey的結構長成這樣：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;userId&amp;gt;-&amp;lt;date&amp;gt;-&amp;lt;messageId&amp;gt;-&amp;lt;attachementId&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;前面有介紹過HBase在使用RoeKey當作filter時，使用Scan查詢速度最快可以到毫秒等級。一般使用者會搭配已模糊查詢的方式來查資料，而HBase的RowKey在模糊查詢上就會有個限制，就是&lt;strong&gt;只支援後面字串的模糊查詢&lt;/strong&gt;。以上面的RowKey結構為例，在查詢時就只能使用這四種方式：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. &amp;lt;userId&amp;gt;
2. &amp;lt;userId&amp;gt;-&amp;lt;date&amp;gt;
3. &amp;lt;userId&amp;gt;-&amp;lt;date&amp;gt;-&amp;lt;messageId&amp;gt;
4. &amp;lt;userId&amp;gt;-&amp;lt;date&amp;gt;-&amp;lt;messageId&amp;gt;-&amp;lt;attachementId&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;key-design-type&quot;&gt;Key Design Type&lt;/h2&gt;

&lt;p&gt;接下來會介紹下列四種RowKey設計方法：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sequential/Time-serial key&lt;/li&gt;
  &lt;li&gt;Salted key&lt;/li&gt;
  &lt;li&gt;Field swap/promotion&lt;/li&gt;
  &lt;li&gt;Random key&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;sequentialtime-serial-key&quot;&gt;Sequential/Time-serial key&lt;/h3&gt;

&lt;p&gt;如果使用Sequential/Time-serial key當作RowKey，資料會被寫入同一個region，此設計不適用於頻繁寫入的使用情境。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sequential key : 假設使用員工編號當作RowKey&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;員工編號&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0001&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0002&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0003&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0004&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;Time-serial key : 假設以訂單紀錄當作RowKey，格式為：&lt;code class=&quot;highlighter-rouge&quot;&gt;yyyy-mmdd-hhmmssss-productionId&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;訂單記錄&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2010-0101-11562366-prdId1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2010-0101-23332187-prdId2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2010-0103-14224378-prdId1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;···&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2010-0301-08262299-prdId5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2010-0302-17260101-prdId7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;···&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2010-0801-11562377-prdId5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;···&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;salted-key&quot;&gt;Salted key&lt;/h3&gt;

&lt;p&gt;俗稱的&lt;code class=&quot;highlighter-rouge&quot;&gt;灑鹽巴&lt;/code&gt;。&lt;strong&gt;使用演算法對RowKey加工&lt;/strong&gt;，讓資料平均散佈到各個Region Server。&lt;/p&gt;

&lt;p&gt;以員工編號為例&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;員工編號&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0001&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0002&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0003&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;A0004&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;使用&lt;code class=&quot;highlighter-rouge&quot;&gt;String rowkey = id.reverse()&lt;/code&gt;方法灑完鹽巴後就會成這樣：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;員工編號&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1000A&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2000A&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3000A&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;4000A&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;field-swappromotion-key&quot;&gt;Field swap/promotion key&lt;/h3&gt;

&lt;p&gt;假設RowKey的格式是這樣&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;date&amp;gt;-&amp;lt;userId&amp;gt;&lt;/code&gt;，Swap方式就是把這兩個欄位位置交換：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;date&amp;gt;-&amp;lt;userId&amp;gt; -&amp;gt; &amp;lt;userId&amp;gt;-&amp;lt;date&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;而Promotion意指將某個&lt;code class=&quot;highlighter-rouge&quot;&gt;cf:qualifier&lt;/code&gt;的值提升至RowKey的位置，與原來的RowKey形成一個新的複合RowKey：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../img/30_days/Field_promotion_key_before.png&quot; alt=&quot;Field_promotion_key_before.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../img/30_days/Field_promotion_key_after.png&quot; alt=&quot;Field_promotion_key_after.png&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;random-key&quot;&gt;Random key&lt;/h3&gt;

&lt;p&gt;Random Key，顧名思義就是隨機分布的RowKey，這種設計可以降低在&lt;strong&gt;寫入&lt;/strong&gt;的情境發生hotspot的狀況。  &lt;br /&gt;
例如可以使用MD5對timestamp加密後產生一組隨機的RowKey:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;byte[] rowkey &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; MD5&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;timestamp&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;效能&quot;&gt;效能&lt;/h2&gt;

&lt;p&gt;由下面的圖可以了解這幾種RowKey適用的情境與效能：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../img/30_days/Rowkey_performance.png&quot; alt=&quot;Rowkey_performance.png&quot; /&gt;  &lt;br /&gt;
From HBase: The Definitive Guide&lt;/p&gt;

&lt;h2 id=&quot;最後&quot;&gt;最後&lt;/h2&gt;

&lt;p&gt;任何一種的RowKey設計沒有絕對好或是不好的分別，要看使用情境再決定要挑選哪種設定方式。  &lt;br /&gt;
介紹完了RowKey設計後，接下來要來介紹HBase hello world api。&lt;/p&gt;
</content>
 </entry>
 

</feed>
