1. 程式人生 > >spaark面試題(變態版)

spaark面試題(變態版)

1、Operation category READ is not supported in state standby是什麼原因導致的

org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.ipc.StandbyException): Operation category READ is not supported in state standby 答:此時請登入Hadoop的管理介面檢視執行節點是否處於standby
如登入地址是:http://xx.xx.xx.xx:50070/dfshealth.html#tab-overview
如果是,則不可在處於StandBy機器執行spark計算,因為該臺機器為備分機器

2、不配置spark.deploy.recoveryMode選項為ZOOKEEPER,會有什麼不好的地方

如果不設定spark.deploy.recoveryMode的話,那麼叢集的所有執行資料在Master重啟是都會丟失,可參考BlackHolePersistenceEngine的實現。

3、多Master如何配置

因為涉及到多個Master,所以對於應用程式的提交就有了一點變化,因為應用程式需要知道當前的Master的IP地址和埠。這種HA方案處理這種情況很簡單,只需要在SparkContext指向一個Master列表就可以了,如spark://host1:port1,host2:port2,host3:port3,應用程式會輪詢列表。

4、No Space Left on the device(Shuffle臨時檔案過多)

由於Spark在計算的時候會將中間結果儲存到/tmp目錄,而目前linux又都支援tmpfs,其實就是將/tmp目錄掛載到記憶體當中。
那麼這裡就存在一個問題,中間結果過多導致/tmp目錄寫滿而出現如下錯誤
No Space Left on the device
解決辦法
第一種:修改配置檔案spark-env.sh,把臨時檔案引入到一個自定義的目錄中去即可
export SPARK_LOCAL_DIRS=/home/utoken/datadir/spark/tmp
第二種:偷懶方式,針對tmp目錄不啟用tmpfs,直接修改/etc/fstab

5、java.lang.OutOfMemory, unable to create new native thread

Caused by: java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
上面這段錯誤提示的本質是Linux作業系統無法建立更多程序,導致出錯,並不是系統的記憶體不足。因此要解決這個問題需要修改Linux允許建立更多的程序,就需要修改Linux最大程序數。
[utoken@nn1 ~]$ulimit -a
臨時修改允許開啟的最大程序數
[utoken@nn1 ~]$ulimit -u 65535
臨時修改允許開啟的檔案控制代碼
[utoken@nn1 ~]$ulimit -n 65535
永久修改Linux最大程序數量
[utoken@nn1 ~]$ vim /etc/security/limits.d/90-nproc.conf
soft nproc 60000
root soft nproc unlimited
永久修改使用者開啟檔案的最大控制代碼數,該值預設1024,一般都會不夠,常見錯誤就是not open file
[utoken@nn1 ~]$ vim /etc/security/limits.conf
bdata soft nofile 65536
bdata hard nofile 65536

6、Worker節點中的work目錄佔用許多磁碟空間

目錄地址:/home/utoken/software/spark-1.3.0-bin-hadoop2.4/work
這些是Driver上傳到worker的檔案,需要定時做手工清理,否則會佔用許多磁碟空間

7、spark-shell提交Spark Application如何解決依賴庫

spark-shell的話,利用–driver-class-path選項來指定所依賴的jar檔案,注意的是–driver-class-path後如果需要跟著多個jar檔案的話,jar檔案之間使用冒號(:)來分割。

8、Spark在釋出應用的時候,出現連線不上master問題,如下

15/11/19 11:35:50 INFO AppClient$ClientEndpoint: Connecting to master spark://s1:7077…
15/11/19 11:35:50 WARN ReliableDeliverySupervisor: Association with remote system [akka.tcp://sparkMaster@s1:7077] has failed, address is now gated for [5000] ms. Reason: [Disassociated]
解決方式
檢查所有機器時間是否一致、hosts是否都配置了對映、客戶端和伺服器端的Scala版本是否一致、Scala版本是否和Spark相容
檢查是否相容問題請參考官方網站介紹:

9、開發spark應用程式(和Flume-NG結合時)釋出應用時可能出現

org.jboss.netty.channel.ChannelException: Failed to bind to: /192.168.10.156:1880015/11/27 10:33:44 ERROR ReceiverSupervisorImpl: Stopped receiver with error: org.jboss.netty.channel.ChannelException: Failed to bind to: /192.168.10.156:18800 
15/11/27 10:33:44 ERROR Executor: Exception in task 0.0 in stage 2.0 (TID 70) 
org.jboss.netty.channel.ChannelException: Failed to bind to: /192.168.10.156:18800
at org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:272)
Caused by: java.net.BindException: Cannot assign requested address
由於spark通過Master釋出的時候,會自動選取傳送到某一臺的worker節點上,所以這裡繫結埠的時候,需要選擇相應的worker伺服器,但是由於我們無法事先了解到,spark釋出到哪一臺伺服器的,所以這裡啟動報錯,是因為在 192.168.10.156:18800的機器上面沒有啟動Driver程式,而是釋出到了其他伺服器去啟動了,所以無法監聽到該機器出現問題,所以我們需要設定spark分發包時,釋出到所有worker節點機器,或者釋出後,我們去尋找釋出到了哪一臺機器,重新修改繫結IP,重新發布,有一定機率釋出成功。詳情可見《印象筆記-戰5渣系列——Spark Streaming啟動問題 - 推酷》

10、spark-shell 找不到hadoop so問題解決

[main] WARN org.apache.hadoop.util.NativeCodeLoader - Unable to load native-hadoop library for your platform… using builtin-java classes where applicable
在Spark的conf目錄下,修改spark-env.sh檔案,加入LD_LIBRARY_PATH環境變數,值為HADOOP的native庫路徑即可.

11、ERROR XSDB6: Another instance of Derby may have already booted the database /home/bdata/data/metastore_db.

在使用Hive on Spark模式操作hive裡面的資料時,報以上錯誤,原因是因為HIVE採用了derby這個內嵌資料庫作為資料庫,它不支援多使用者同時訪問,解決辦法就是把derby資料庫換成mysql資料庫即可
變更方式

12、java.lang.IllegalArgumentException: java.net.UnknownHostException: dfscluster

解決辦法:
找不到hdfs叢集名字dfscluster,這個檔案在HADOOP的etc/hadoop下面,有個檔案hdfs-site.xml,複製到Spark的conf下,重啟即可
如:執行指令碼,分發到所有的Spark叢集機器中,
[bdata@bdata4 hadoop]foriin34,35,36,37,38;doscphdfs−site.xml192.168.10.i:/u01/spark-1.5.1/conf/ ; done

13、Exception in thread “main” java.lang.Exception: When running with master ‘yarn-client’ either HADOOP_CONF_DIR or

YARN_CONF_DIR must be set in the environment.
問題:在執行yarn叢集或者客戶端時,報以上錯誤,
[bdata@bdata4 bin]$ ./spark-sql –master yarn-client
Exception in thread “main” java.lang.Exception: When running with master ‘yarn-client’ either HADOOP_CONF_DIR or YARN_CONF_DIR must be set in the environment.
解決辦法
根據提示,配置HADOOP_CONF_DIR or YARN_CONF_DIR的環境變數即可
export HADOOP_HOME=/u01/hadoop-2.6.1
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
PATH=PATH:HOME/.local/bin:HOME/bin:SQOOP_HOME/bin:HIVEHOME/bin:HADOOP_HOME/bin

14、Job aborted due to stage failure: Task 3 in stage 0.0 failed 4 times, most recent failure: Lost task 3.3 in

[Stage 0:> (0 + 4) / 42]2016-01-15 11:28:16,512 [org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 0 on 192.168.10.38: remote Rpc client disassociated
[Stage 0:> (0 + 4) / 42]2016-01-15 11:28:23,188 [org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 1 on 192.168.10.38: remote Rpc client disassociated
[Stage 0:> (0 + 4) / 42]2016-01-15 11:28:29,203 [org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 2 on 192.168.10.38: remote Rpc client disassociated
[Stage 0:> (0 + 4) / 42]2016-01-15 11:28:36,319 [org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 3 on 192.168.10.38: remote Rpc client disassociated
2016-01-15 11:28:36,321 [org.apache.spark.scheduler.TaskSetManager]-[ERROR] Task 3 in stage 0.0 failed 4 times; aborting job
Exception in thread “main” org.apache.spark.SparkException : Job aborted due to stage failure: Task 3 in stage 0.0 failed 4 times, most recent failure: Lost task 3.3 in stage 0.0 (TID 14, 192.168.10.38): ExecutorLostFailure (executor 3 lost)
Driver stacktrace:
at org.apache.spark.scheduler.DAGScheduler.org$apache$spark$scheduler$DAGScheduler$$failJobAndIndependentStages(DAGScheduler.scala:1283)
解決方案
這裡遇到的問題主要是因為資料來源資料量過大,而機器的記憶體無法滿足需求,導致長時間執行超時斷開的情況,資料無法有效進行互動計算,因此有必要增加記憶體

15、長時間等待無反應,並且看到伺服器上面的web介面有記憶體和核心數,但是沒有分配,如下圖

[Stage 0:> (0 + 0) / 42]
或者日誌資訊顯示:
16/01/15 14:18:56 WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient resources
解決方案
出現上面的問題主要原因是因為我們通過引數spark.executor.memory設定的記憶體過大,已經超過了實際機器擁有的記憶體,故無法執行,需要等待機器擁有足夠的記憶體後,才能執行任務,可以減少任務執行記憶體,設定小一些即可

16、記憶體不足或資料傾斜導致Executor Lost(spark-submit提交)

TaskSetManager: Lost task 1.0 in stage 6.0 (TID 100, 192.168.10.37): java.lang.OutOfMemoryError: Java heap space
16/01/15 14:29:51 INFO BlockManagerInfo: Added broadcast_8_piece0 in memory on 192.168.10.37:57139 (size: 42.0 KB, free: 24.2 MB)
16/01/15 14:29:53 INFO BlockManagerInfo: Added broadcast_8_piece0 in memory on 192.168.10.38:53816 (size: 42.0 KB, free: 24.2 MB) 
16/01/15 14:29:55 INFO TaskSetManager: Starting task 3.0 in stage 6.0 (TID 102, 192.168.10.37, ANY, 2152 bytes) 
16/01/15 14:29:55 WARN TaskSetManager: Lost task 1.0 in stage 6.0 (TID 100, 192.168.10.37): java.lang.OutOfMemoryError: Java heap space 
at java.io.BufferedOutputStream.(BufferedOutputStream.java:76) 
at java.io.BufferedOutputStream.(BufferedOutputStream.java:59)
…….
org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 6.0 failed 4 times, most recent failure: Lost task 0.3 in stage 6.0 (TID 142, 192.168.10.36): ExecutorLostFailure (executor 4 lost)
……
WARN TaskSetManager: Lost task 4.1 in stage 6.0 (TID 137, 192.168.10.38): java.lang.OutOfMemoryError: GC overhead limit exceeded
解決辦法:
由於我們在執行Spark任務是,讀取所需要的原資料,資料量太大,導致在Worker上面分配的任務執行資料時所需要的記憶體不夠,直接導致記憶體溢位了,所以我們有必要增加Worker上面的記憶體來滿足程式執行需要。
在Spark Streaming或者其他spark任務中,會遇到在Spark中常見的問題,典型如Executor Lost 相關的問題(shuffle fetch 失敗,Task失敗重試等)。這就意味著發生了記憶體不足或者資料傾斜的問題。這個目前需要考慮如下幾個點以獲得解決方案:
A、相同資源下,增加partition數可以減少記憶體問題。 原因如下:通過增加partition數,每個task要處理的資料少了,同一時間內,所有正在執行的task要處理的數量少了很多,所有Executor佔用的記憶體也變小了。這可以緩解資料傾斜以及記憶體不足的壓力。
B、關注shuffle read 階段的並行數。例如reduce,group 之類的函式,其實他們都有第二個引數,並行度(partition數),只是大家一般都不設定。不過出了問題再設定一下,也不錯。
C、給一個Executor 核數設定的太多,也就意味著同一時刻,在該Executor 的記憶體壓力會更大,GC也會更頻繁。我一般會控制在3個左右。然後通過提高Executor數量來保持資源的總量不變。

17、 Spark Streaming 和kafka整合後讀取訊息報錯:OffsetOutOfRangeException

解決方案:如果和kafka訊息中介軟體結合使用,請檢查訊息體是否大於預設設定1m,如果大於,則需要設定fetch.message.max.bytes=1m,這裡需要把值設定大些

18、java.io.IOException : Could not locate executable null\bin\winutils.exe in the Hadoop binaries.(spark sql on hive 任務引發HiveContext NullPointerException)

解決辦法
在開發hive和Spark整合的時候,如果是Windows系統,並且沒有配置HADOOP_HOME的環境變數,那麼可能找不到winutils.exe這個工具,由於使用hive時,對該命令有依賴,所以不要忽視該錯誤,否則將無法建立HiveContext,一直報Exception in thread “main” java.lang.RuntimeException: java.lang.NullPointerException
因此,解決該辦法有兩個方式
A、把任務打包成jar,上傳到伺服器上面,伺服器是配置過HADOOP_HOME環境變數的,並且不需要依賴winutils,所以只需要通過spark-submit方式提交即可,如:
[bdata@bdata4 app]$ spark-submit –class com.pride.hive.HiveOnSparkTest –master spark://bdata4:7077 spark-simple-1.0.jar
B、解決winutils.exe命令不可用問題,配置Windows上面HADOOP_HOME的環境變數,或者在程式最開始的地方設定HADOOP_HOME的屬性配置,這裡需要注意,由於最新版本已經沒有winutils這些exe命令了,我們需要在其他地方下載該命令放入HADOOP的bin目錄下,當然也可以直接配置下載專案的環境變數,變數名一定要是HADOOP_HOME才行
下載地址:https://github.com/srccodes/hadoop-common-2.2.0-bin/archive/master.zip (記得翻牆哦)
任何專案都生效,需要配置Windows的環境變數,如果只在程式中生效可在程式中配置即可,如
//用於解決Windows下找不到winutils.exe命令
System. setProperty(“hadoop.home.dir”, “E:\Software\hadoop-common-2.2.0-bin” );

19、The root scratch dir: /tmp/hive on HDFS should be writable. Current permissions are: rwx

解決辦法
1、程式中設定環境變數:System.setProperty(“HADOOP_USER_NAME”, “bdata”)
2、修改HDFS的目錄許可權
Update the permission of your /tmp/hive HDFS directory using the following command
hadoop dfs -chmod 777 /tmp/hive
此問題暫未解決,估計是17點解決winutils有問題,建議最好把任務程式釋出到伺服器上面解決

20、Exception in thread “main” org.apache.hadoop.security.AccessControlException : Permission denied: user=Administrator,access=WRITE, inode=”/data”:bdata:supergroup:drwxr-xr-x

解決辦法
1、在系統的環境變數或java JVM變數裡面新增HADOOP_USER_NAME,如程式中新增System.setProperty(“HADOOP_USER_NAME”, “bdata”);,這裡的值就是以後會執行HADOOP上的Linux的使用者名稱,如果是eclipse,則修改完重啟eclipse,不然可能不生效
2、hdfs dfs -chmod 777 修改相應許可權地址

21、執行Spark-SQL報錯:org.apache.spark.sql.AnalysisException: unresolved operator ‘Project

解決辦法:
在Spark-sql和hive結合時或者單獨Spark-sql,執行某些sql語句時,偶爾出現上面錯誤,那麼我們可以檢查一下sql的問題,這裡遇到的問題是巢狀語句太多,導致spark無法解析,所以需要修改sql或者改用其他方式處理;特別注意該語句可能在hive裡面沒有錯誤,spark才會出現的一種錯誤。

22、在$SPARK_HOME/conf/spark-env.sh中設定這些變數好像也只是在terminal中的shell環境中才有效JAVA_HOME is not set Exception: Java gateway process exited before sending the driver its port number

但是在命令列中是有的
pipi@pipicmp:~$ echo $JAVA_HOME
/home/pipi/ENV/jdk
解決方法1:在py程式碼中加入JAVA_HOME到os中
JAVA_HOME = /home/pipi/ENV/jdk
os.environ['JAVA_HOME'] = conf.get(SECTION, 'JAVA_HOME')
解決方法2:或者在hadoop中配置好JAVA_HOME
hadoop中配置JAVA_HOME

23、ValueError: Cannot run multiple SparkContexts at once

Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /__ / .__/\_,_/_/ /_/\_\   version 2.0.1
      /_/

Using Python version 3.5.2 (default, Sep 10 2016 08:21:44)
SparkSession available as 'spark'.
ValueError: Cannot run multiple SparkContexts at once; existing SparkContext(app=pyspark-shell, master=local) created by <module> at <frozen importlib._bootstrap>:222 
原因是:from pyspark.shell import sqlContext
引入的包中也定義了一個sc = spark.sparkContext導致和本程式碼中定義重複了。

24、spark輸出太多warning messages

除錯log時候發現問題解決了
在簡略Spark輸出設定時[Spark安裝和配置 ]修改過$SPARK_HOME/conf/log4j.properties.template檔案只輸出WARN資訊,就算改成了ERROR,資訊也還是會自動修改成WARN輸出出來,不過多了一條提示:
Setting default log level to "WARN". To adjust logging level use sc.setLogLevel(newLevel).
就在這時發現了一個解決方案:
根據提示在程式碼中加入sc.setLogLevel('ERROR')就可以解決了!

25、org.apache.spark.shuffle.FetchFailedException

一般發生在有大量shuffle操作的時候,task不斷的failed,然後又重執行,一直迴圈下去,非常的耗時一般遇到這種問題提高executor記憶體即可,同時增加每個executor的cpu,這樣不會減少task並行度。

26、Executor&Task Lost因為網路或者gc的原因,worker或executor沒有接收到executor或task的心跳反饋WARN

TaskSetManager:

Lost task 1.0 in stage 0.0 (TID 1, aa.local): ExecutorLostFailure (executor lost) 
提高 spark.network.timeout 的值,根據情況改成300(5min)或更高。
預設為 120(120s),配置所有網路傳輸的延時,如果沒有主動設定以下引數,預設覆蓋其屬性
spark.core.connection.ack.wait.timeout
spark.akka.timeout
spark.storage.blockManagerSlaveTimeoutMs
spark.shuffle.io.connectionTimeout
spark.rpc.askTimeout or spark.rpc.lookupTimeout

27、Master掛掉,standby重啟也失效

如Master預設使用512M記憶體,當叢集中執行的任務特別多時,就會掛掉,原因是master會讀取每個task的event log日誌去生成spark ui,記憶體不足自然會OOM,可以在master的執行日誌中看到,通過HA啟動的master自然也會因為這個原因失敗。
1).增加Master的記憶體佔用,在Master節點spark-env.sh 中設定:
export SPARK_DAEMON_MEMORY 10g # 根據你的實際情況
2).減少儲存在Master記憶體中的作業資訊
spark.ui.retainedJobs 500   # 預設都是1000 spark.ui.retainedStages 500

28、worker掛掉或假死有時候我們還會在web ui中看到worker節點消失或處於dead狀態

在該節點執行的任務則會報各種 lost worker 的錯誤,引發原因和上述大體相同,worker記憶體中儲存了大量的ui資訊導致gc時失去和master之間的心跳。

解決
1)增加Master的記憶體佔用,在Worker節點spark-env.sh 中設定:
export SPARK_DAEMON_MEMORY 2g # 根據你的實際情況
2)減少儲存在Worker記憶體中的Driver,Executor資訊
spark.worker.ui.retainedExecutors 200   # 預設都是1000 spark.worker.ui.retainedDrivers 200

29、報錯:

ERROR storage.DiskBlockObjectWriter: Uncaught exception while reverting partial writes to file /hadoop/application_1415632483774_448143/spark-local-20141127115224-9ca8/04/shuffle_1_1562_27
java.io.FileNotFoundException: /hadoop/application_1415632483774_448143/spark-local-20141127115224-9ca8/04/shuffle_1_1562_27 (No such file or directory)

表面上看是因為shuffle沒有地方寫了,如果後面的stack是local space 的問題,那麼清一下磁碟就好了。上面這種問題,是因為一個excutor給分配的記憶體不夠,此時,減少excutor-core的數量,加大excutor-memory的值應該就沒有問題。

30、報錯:

ERROR executor.CoarseGrainedExecutorBackend: Driver Disassociated [akka.tcp://sparkExecutor@pc-jfqdfx31:48586] -> [akka.tcp://sparkDriver@pc-jfqdfx30:41656] disassociated! Shutting down.
15/07/23 10:50:56 ERROR executor.CoarseGrainedExecutorBackend: RECEIVED SIGNAL 15: SIGTERM
這個錯誤比較隱晦,從資訊上看來不知道是什麼問題,但是歸根結底還是記憶體的問題,有兩個方法可以解決這個錯誤,一是,如上面所說,加大excutor-memory的值,減少executor-cores的數量,問題可以解決。二是,加大executor.overhead的值,但是這樣其實並沒有解決掉根本的問題。所以如果叢集的資源是支援的話,就用1的辦法吧。
另外,這個錯誤也出現在partitionBy(new HashPartition(partiton-num))時,如果partiton-num太大或者太小的時候會報這種錯誤,說白了也是記憶體的原因,不過這個時候增加記憶體和overhead沒有什麼用,得去調整這個partiton-num的值。

31、給定a、b兩個檔案,各存放50億個url,每個url各佔64位元組,記憶體限制是4G,讓你找出a、b檔案共同的url?

方案1:可以估計每個檔案安的大小為5G×64=320G,遠遠大於記憶體限制的4G。所以不可能將其完全載入到記憶體中處理。考慮採取分而治之的方法。
遍歷檔案a,對每個url求取hash(url)%1000,然後根據所取得的值將url分別儲存到1000個小檔案(記為a0,a1,…,a999)中。這樣每個小檔案的大約為300M。
遍歷檔案b,採取和a相同的方式將url分別儲存到1000小檔案(記為b0,b1,…,b999)。這樣處理後,所有可能相同的url都在對應的小檔案(a0vsb0,a1vsb1,…,a999vsb999)中,不對應的小檔案不可能有相同的url。然後我們只要求出1000對小檔案中相同的url即可。
求每對小檔案中相同的url時,可以把其中一個小檔案的url儲存到hash_set中。然後遍歷另一個小檔案的每個url,看其是否在剛才構建的hash_set中,如果是,那麼就是共同的url,存到檔案裡面就可以了。

方案2:如果允許有一定的錯誤率,可以使用Bloomfilter,4G記憶體大概可以表示340億bit。將其中一個檔案中的url使用Bloomfilter對映為這340億bit,然後挨個讀取另外一個檔案的url,檢查是否與Bloomfilter,如果是,那麼該url應該是共同的url(注意會有一定的錯誤率)。
Bloomfilter日後會在本BLOG內詳細闡述。補充:另外一種思路,是將url通過演算法轉為數字型別,轉換後的連線就是比較數值是否相等了。

32、有一個1G大小的一個檔案,裡面每一行是一個詞,詞的大小不超過16位元組,記憶體限制大小是1M,要求返回頻數最高的100個詞。

Step1:順序讀檔案中,對於每個詞x,取hash(x)%5000,然後按照該值存到5000個小檔案(記為f0,f1,...,f4999)中,這樣每個檔案大概是200k左右,如果其中的有的檔案超過了1M大小,還可以按照類似的方法繼續往下分,直到分解得到的小檔案的大小都不超過1M;
Step2:對每個小檔案,統計每個檔案中出現的詞以及相應的頻率(可以採用trie樹/hash_map等),並取出出現頻率最大的100個詞(可以用含100個結點的最小堆),並把100詞及相應的頻率存入檔案,這樣又得到了5000個檔案;
Step3:把這5000個檔案進行歸併(類似與歸併排序);
草圖如下(分割大問題,求解小問題,歸併):

33、現有海量日誌資料儲存在一個超級大的檔案中,該檔案無法直接讀入記憶體,要求從中提取某天出訪問百度次數最多的那個IP。

Step1:從這一天的日誌資料中把訪問百度的IP取出來,逐個寫入到一個大檔案中;
Step2:注意到IP是32位的,最多有2^32個IP。同樣可以採用對映的方法,比如模1000,把整個大檔案對映為1000個小檔案;
Step3:找出每個小文中出現頻率最大的IP(可以採用hash_map進行頻率統計,然後再找出頻率最大的幾個)及相應的頻率;
Step4:在這1000個最大的IP中,找出那個頻率最大的IP,即為所求。

34、LVS和HAProxy相比,它的缺點是什麼?

之前,的確是用LVS進行過MySQL叢集的負載均衡,對HAProxy也有過了解,但是將這兩者放在眼前進行比較,還真沒試著瞭解過。面試中出現了這麼一題,面試官給予的答案是LVS的配置相當繁瑣,後來查找了相關資料,對這兩種負載均衡方案有了更進一步的瞭解。LVS的負載均衡效能之強悍已經達到硬體負載均衡的F5的百分之60了,而HAproxy的負載均衡和Nginx負載均衡,均為硬體負載均衡的百分之十左右。由此可見,配置複雜,相應的效果也是顯而易見的。在查詢資料的過程中,試著將LVS的10種排程演算法瞭解了一下,看似數量挺多的10種演算法其實在不同的演算法之間,有些只是有著一些細微的差別。在這10種排程演算法中,靜態排程演算法有四種,動態排程演算法有6種。
靜態排程演算法:
①RR輪詢排程演算法
這種排程演算法不考慮伺服器的狀態,所以是無狀態的,同時也不考慮每個伺服器的效能,比如我有1-N臺伺服器,來N個請求了,第一個請求給第一臺,第二個請求給第二臺,,,第N個請求給第N臺伺服器,就醬紫。
②加權輪詢
這種排程演算法是考慮到伺服器的效能的,你可以根據不同伺服器的效能,加上權重進行分配相應的請求。
③基於目的地址的hash雜湊
這種排程演算法和基於源地址的hash雜湊異曲同工,都是為了維持一個session,基於目的地址的hash雜湊,將記住同一請求的目的地址,將這類請求發往同一臺目的伺服器。簡而言之,就是發往這個目的地址的請求都發往同一臺伺服器。而基於源地址的hash雜湊,就是來自同一源地址的請求都發往同一臺伺服器。
④基於源地址的hash雜湊
上述已講,不再贅述。
動態排程
①最少連線排程演算法
這種排程演算法會記錄響應請求的伺服器上所建立的連線數,每接收到一個請求會相應的將該伺服器的所建立連線數加1,同時將新來的請求分配到當前連線數最少的那臺機器上。
②加權最少連線排程演算法
這種排程演算法在最少連線排程演算法的基礎上考慮到伺服器的效能。當然,做這樣子的考慮是有其合理性存在的,如果是同一規格的伺服器,那麼建立的連線數越多,必然越增加其負載,那麼僅僅根據最少連線數的排程演算法,必然可以實現合理的負載均衡。但如果,伺服器的效能不一樣呢?比如我有一臺伺服器,最多隻能處理10個連線,現在建立了3個,還有一臺伺服器最多能處理1000條連線,現在建立了5個,如果單純地按照上述的最少連線排程演算法,妥妥的前者嘛,但前者已經建立了百分之三十的連線了,而後者連百分之一的連線還沒有建立,試問,這合理嗎?顯然不合理。所以加上權重,才算合理。相應的公式也相當簡單:active*256/weight。
③最短期望排程演算法
這種演算法,是避免出現上述加權最少連線排程演算法中的一種特殊情況,導致即使加上權重,排程器也無差別對待了,舉個栗子:
假設有三臺伺服器ABC,其當前所建立的連線數相應地為1,2,3,而權重也是1,2,3。那麼如果按照加權最少連線排程演算法的話,算出來是這樣子的:
  A:1256/1=256
  B:2256/2=256
  C:3256/3=256
我們會發現,即便加上權重,A、B、C,經過計算還是一樣的,這樣子排程器會無差別的在A、B、C中任選一臺,將請求發過去。
而最短期望將active256/weight的演算法改進為(active+1)256/weight
那麼還是之前的例子:
  A:(1+1)256/1=2/1256=2256
  B:(2+1)256/2=3/2256=1.5256
  C:(3+1)256、3=4/3256≈1.3256
  顯然C
④永不排隊演算法
  將請求發給當前連線數為0的伺服器上。
⑤基於區域性的最少連線排程演算法
這種排程演算法應用於Cache系統,維持一個請求到一臺伺服器的對映,其實我們仔細想想哈,之前做的一系列最少連線相關的排程演算法。考慮到的是伺服器的狀態與效能,但是一次請求並不是單向的,就像有一個從未合作過的大牛,他很閒,你讓他去解決一個之前碰到過的一個問題,未必有找一個之前已經跟你合作過哪怕現在不怎麼閒的臭皮匠效果好哦~,所以基於區域性的最少連線排程演算法,維持的這種對映的作用是,如果來了一個請求,相對應的對映的那臺伺服器,沒有超載,ok交給老夥伴完事吧,俺放心,如果那臺伺服器不存在,或者是超載的狀態且有其他伺服器工作在一半的負載狀態,則按最少連線排程演算法在叢集其餘的伺服器中找一臺將請求分配給它。
⑥基於複製的區域性最少連線排程演算法
這種排程演算法同樣應用於cache系統,但它維持的不是到一臺伺服器的對映而是到一組伺服器的對映,當有新的請求到來,根據最小連線原則,從該對映的伺服器組中選擇一臺伺服器,如果它沒有超載則交給它去處理這個請求,如果發現它超載,則從伺服器組外的叢集中,按最少連線原則拉一臺機器加入伺服器組,並且在伺服器組有一段時間未修改後,將最忙的那臺伺服器從伺服器組中剔除。

35、Sqoop用起來感覺怎樣?

說實話,Sqoop在匯入資料的速度上確實十分感人,通過進一步瞭解,發現Sqoop1和Sqoop2在架構上還是有明顯不同的,無論是從資料型別上還是從安全許可權,密碼暴露方面,Sqoop2都有了明顯的改進,同時同一些其他的異構資料同步工具比較,如淘寶的DataX或者Kettle相比,Sqoop無論是從匯入資料的效率上還是從支援外掛的豐富程度上,Sqoop還是相當不錯滴!!

36、ZooKeeper的角色以及相應的Zookepper工作原理?

果然,人的記憶力是有衰減曲線的,當面試官丟擲這個問題後,前者角色,我只答出了兩種(leader和follower),後者原理壓根就模糊至忘記了。所以惡補了一下,涉及到Zookeeper的角色大概有如下四種:leader、learner(follower)、observer、client。其中leader主要用來決策和排程,follower和observer的區別僅僅在於後者沒有寫的職能,但都有將client請求提交給leader的職能,而observer的出現是為了應對當投票壓力過大這種情形的,client就是用來發起請求的。而Zookeeper所用的分散式一致性演算法包括leader的選舉其實和-原始部落的獲得神器為酋長,或者得玉璽者為皇帝類似,誰id最小,誰為leader,會根據你所配置的相應的檔案在相應的節點機下生成id,然後相應的節點會通過getchildren()這個函式獲取之前設定的節點下生成的id,誰最小,誰是leader。並且如果萬一這個leader掛掉了或者墮落了,則由次小的頂上。而且在配置相應的zookeeper檔案的時候回有類似於如下字樣的資訊:Server.x=AAAA:BBBB:CCCC。其中的x即為你的節點號哈,AAAA對應你所部屬zookeeper所在的ip地址,BBBB為接收client請求的埠,CCCC為重新選舉leader埠。

37、HBase的Insert與Update的區別?

這個題目是就著最近的一次專案問的,當時實現的與hbase互動的三個方法分別為insert、delete、update。由於那個專案是對接的一個專案,對接的小夥伴和我協商了下,不將update合併為insert,如果合併的話,按那個專案本身,其實通過insert執行overwrite相當於間接地Update,本質上,或者說在展現上是沒什麼區別的包括所呼叫的put。但那僅僅是就著那個專案的程式而言,如果基於HBase shell層面。將同一rowkey的資料插入HBase,其實雖然展現一條,但是相應的timestamp是不一樣的,而且最大的版本數可以通過配置檔案進行相應地設定。

38、請簡述大資料的結果展現方式。

1)報表形式
基於資料探勘得出的資料報表,包括資料表格、矩陣、圖形和自定義格式的報表等,使用方便、設計靈活。
2)圖形化展現
提供曲線、餅圖、堆積圖、儀表盤、魚骨分析圖等圖形形式巨集觀展現模型資料的分佈情況,從而便於進行決策。
3)KPI展現
提供表格式績效一覽表並可自定義績效檢視方式,如資料表格或走勢圖,企業管理者可根據可度量的目標快速評估進度。
4)查詢展現
按資料查詢條件和查詢內容,以資料表格來彙總查詢結果,提供明細查詢功能,並可在查詢的資料表格基礎上進行上鑽、下鑽、旋轉等操作。

39、例舉身邊的大資料。

QQ,微博等社交軟體產生的資料
天貓,京東等電子商務產生的資料
網際網路上的各種資料

40、簡述大資料的資料管理方式。

對於影象、視訊、URL、地理位置等型別多樣的資料,難以用傳統的結構化方式描述,因此需要使用由多維表組成的面向列儲存的資料管理系統來組織和管理資料。也就是說,將資料按行排序,按列儲存,將相同欄位的資料作為一個列族來聚合儲存。不同的列族對應資料的不同屬性,這些屬性可以根據需求動態增加,通過這樣的分散式實時列式資料庫對資料統一進行結構化儲存和管理,避免了傳統資料儲存方式下的關聯查詢。

41、什麼是大資料?

大資料是指無法在容許的時間內用常規軟體工具對其內容進行抓取、管理和處理的資料。

42、海量日誌資料,提取出某日訪問百度次數最多的那個IP。

首先是這一天,並且是訪問百度的日誌中的IP取出來,逐個寫入到一個大檔案中。注意到IP是32位的,最多有個2^32個IP。同樣可以採用對映的方法,比如模1000,把整個大檔案對映為1000個小檔案,再找出每個小文中出現頻率最大的IP(可以採用hash_map進行頻率統計,然後再找出頻率最大的幾個)及相應的頻率。然後再在這1000個最大的IP中,找出那個頻率最大的IP,即為所求。
或者如下闡述(雪域之鷹):
演算法思想:分而治之+Hash
1)IP地址最多有2^32=4G種取值情況,所以不能完全載入到記憶體中處理;
2)可以考慮採用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日誌分別儲存到1024個小檔案中。這樣,每個小檔案最多包含4MB個IP地址;
3)對於每一個小檔案,可以構建一個IP為key,出現次數為value的Hashmap,同時記錄當前出現次數最多的那個IP地址;
4)可以得到1024個小檔案中的出現次數最多的IP,再依據常規的排序演算法得到總體上出現次數最多的IP;

43、搜尋引擎會通過日誌檔案把使用者每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度為1-255位元組。

假設目前有一千萬個記錄(這些查詢串的重複度比較高,雖然總數是1千萬,但如果除去重複後,不超過3百萬個。一個查詢串的重複度越高,說明查詢它的使用者越多,也就是越熱門。),請你統計最熱門的10個查詢串,要求使用的記憶體不能超過1G。
典型的TopK演算法,還是在這篇文章裡頭有所闡述,詳情請參見:十一、從頭到尾徹底解析Hash表演算法。
文中,給出的最終演算法是:
第一步、先對這批海量資料預處理,在O(N)的時間內用Hash表完成統計(之前寫成了排序,特此訂正。July、2011.04.27);
第二步、藉助堆這個資料結構,找出TopK,時間複雜度為N‘logK。
即,藉助堆結構,我們可以在log量級的時間內查詢和調整/移動。因此,維護一個K(該題目中是10)大小的小根堆,然後遍歷300萬的Query,分別和根元素進行對比所以,我們最終的時間複雜度是:O(N)+N’*O(logK),(N為1000萬,N’為300萬)。ok,更多,詳情,請參考原文。
或者:採用trie樹,關鍵字域存該查詢串出現的次數,沒有出現為0。最後用10個元素的最小推來對出現頻率進行排序。

44、有一個1G大小的一個檔案,裡面每一行是一個詞,詞的大小不超過16位元組,記憶體限制大小是1M。返回頻數最高的100個詞。

方案:順序讀檔案中,對於每個詞x,取hash(x)%5000,然後按照該值存到5000個小檔案(記為x0,x1,…x4999)中。這樣每個檔案大概是200k左右。
如果其中的有的檔案超過了1M大小,還可以按照類似的方法繼續往下分,直到分解得到的小檔案的大小都不超過1M。
對每個小檔案,統計每個檔案中出現的詞以及相應的頻率(可以採用trie樹/hash_map等),並取出出現頻率最大的100個詞(可以用含100個結點的最小堆),並把100個詞及相應的頻率存入檔案,這樣又得到了5000個檔案。下一步就是把這5000個檔案進行歸併(類似與歸併排序)的過程了。

45、有10個檔案,每個檔案1G,每個檔案的每一行存放的都是使用者的query,每個檔案的query都可能重複。要求你按照query的頻度排序。

還是典型的TOPK演算法,解決方案如下:
方案1:
順序讀取10個檔案,按照hash(query)%10的結果將query寫入到另外10個檔案(記為)中。這樣新生成的檔案每個的大小大約也1G(假設hash函式是隨機的)。
找一臺記憶體在2G左右的機器,依次對用hash_map(query,query_count)來統計每個query出現的次數。利用快速/堆/歸併排序按照出現次數進行排序。將排序好的query和對應的query_cout輸出到檔案中。這樣得到了10個排好序的檔案(記為)。
對這10個檔案進行歸併排序(內排序與外排序相結合)。
方案2:
一般query的總量是有限的,只是重複的次數比較多而已,可能對於所有的query,一次性就可以加入到記憶體了。這樣,我們就可以採用trie樹/hash_map等直接來統計每個query出現的次數,然後按出現次數做快速/堆/歸併排序就可以了。
方案3:
與方案1類似,但在做完hash,分成多個檔案後,可以交給多個檔案來處理,採用分散式的架構來處理(比如MapReduce),最後再進行合併。

46、JVM&垃圾回收機制

三個代:年輕代(Young Generation)、年老代(Old Generation)和持久代(Permanent Generation)

47、在2.5億個整數中找出不重複的整數,注,記憶體不足以容納這2.5億個整數。

方案1:採用2-Bitmap(每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義)進行,共需記憶體2^32*2bit=1GB記憶體,還可以接受。然後掃描這2.5億個整數,檢視Bitmap中相對應位,如果是00變01,01變10,10保持不變。所描完事後,檢視bitmap,把對應位是01的整數輸出即可。
方案2:也可採用與第1題類似的方法,進行劃分小檔案的方法。然後在小檔案中找出不重複的整數,並排序。然後再進行歸併,注意去除重複的元素。

48、騰訊面試題:給40億個不重複的unsignedint的整數,沒排過序的,然後再給一個數,如何快速判斷這個數是否在那40億個數當中?

第一反應時快速排序+二分查詢。以下是其它更好的方法:
方案1:oo,申請512M的記憶體,一個bit位代表一個unsignedint值。讀入40億個數,設定相應的bit位,讀入要查詢的數,檢視相應bit位是否為1,為1表示存在,為0表示不存在。
方案2:這個問題在《程式設計珠璣》裡有很好的描述,大家可以參考下面的思路

49、怎麼在海量資料中找出重複次數最多的一個?

方案1:先做hash,然後求模對映為小檔案,求出每個小檔案中重複次數最多的一個,並記錄重複次數。然後找出上一步求出的資料中重複次數最多的一個就是所求(具體參考前面的題)。

50、上千萬或上億資料(有重複),統計其中出現次數最多的錢N個數據。

方案1:上千萬或上億的資料,現在的機器的記憶體應該能存下。所以考慮採用hash_map/搜尋二叉樹/紅黑樹等來進行統計次數。然後就是取出前N個出現次數最多的資料了,可以用第2題提到的堆機制完成。

51、一個文字檔案,大約有一萬行,每行一個詞,要求統計出其中最頻繁出現的前10個詞,請給出思想,給出時間複雜度分析。

方案1:這題是考慮時間效率。用trie樹統計每個詞出現的次數,時間複雜度是O(n*le)(le表示單詞的平準長度)。然後是找出出現最頻繁的前10個詞,可以用堆來實現,前面的題中已經講到了,時間複雜度是O(n*lg10)。所以總的時間複雜度,是O(n*le)與O(n*lg10)中較大的哪一個。

52、WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster uito ensure that workers are registered and have sufficient memory

當前的叢集的可用資源不能滿足應用程式所請求的資源。
資源分2類: cores 和 ram
Core代表對執行可用的executor slots
Ram代表每個Worker上被需要的空閒記憶體來執行你的Application。
解決方法:
應用不要請求多餘空閒可用資源的
關閉掉已經執行結束的Application

53、Application isn’t using all of the Cores: How to set the Cores used by a Spark App

設定每個App所能獲得的core
解決方法:
spark-env.sh裡設定spark.deploy.defaultCores 或spark.cores.max

54、Spark Executor OOM: How to set Memory Parameters on Spark

OOM是記憶體裡堆的東西太多了
1)增加job的並行度,即增加job的partition數量,把大資料集切分成更小的資料,可以減少一次性load到記憶體中的資料量。InputFomart, getSplit來確定。
2)spark.storage.memoryFraction
管理executor中RDD和執行任務時的記憶體比例,如果shuffle比較小,只需要一點點shuffle memory,那麼就調大這個比例。預設是0.6。不能比老年代還要大。大了就是浪費。
3)spark.executor.memory如果還是不行,那麼就要加Executor的記憶體了,改完executor記憶體後,這個需要重啟。

55、Shark Server/ Long Running Application Metadata Cleanup

Spark程式的元資料是會往記憶體中無限儲存的。spark.cleaner.ttl來防止OOM,主要出現在Spark Steaming和Shark Server裡。
export SPARK_JAVA_OPTS +="-Dspark.kryoserializer.buffer.mb=10 -Dspark.cleaner.ttl=43200"

56、Class Not Found: Classpath Issues

問題1、缺少jar,不在classpath裡。3
問題2、jar包衝突,同一個jar不同版本。

解決1:
將所有依賴jar都打入到一個fatJar包裡,然後手動設定依賴到指定每臺機器的DIR。
val conf = new SparkConf().setAppName(appName).setJars(Seq(System.getProperty("user.dir") + "/target/scala-2.10/sparktest.jar"))

解決2:
把所需要的依賴jar包都放到default classpath裡,分發到各個worker node上。

57、使用mr,spark,spark sql編寫wordcount程式

58、如何為一個hadoop任務設定mappers的數量

使用job.setNumMapTask(intn)手動分割,這是不靠譜的
官方文件:“Note:Thisisonlyahinttotheframework”說明這個方法只是提示作用,不起決定性作用
實際上要用公式計算:
Max(min.split,min(max.split,block))就設定分片的最大最下值computeSplitSize()設定
可以參考這篇文章:http://blog.csdn.net/strongerbit/article/details/7440111

59、有可能使hadoop任務輸出到多個目錄中麼?如果可以,怎麼做?

在1.X版本後使用MultipleOutputs.java類實現

60、如何為一個hadoop任務設定要建立的reducer的數量

配置job.setNumReduceTask(intn)
或者調整hdfs-site.xml中的mapred.tasktracker.reduce.tasks.maximum預設引數值

61、Spark Streaming和Storm有何區別? 

一個實時毫秒一個準實時亞秒,不過storm的吞吐率比較低。

62、如果公司叫你寫hadoop平臺設計方案,你會如何規劃Hadoop生產叢集?

這個題目比較考驗全域性觀,站在架構師的層面去思考

63、hadoop叢集監控,你會關注哪些監控點?

偏重叢