30.ISR、OSR、AR 是什么?
ISR:In-Sync Replicas 副本同步隊列
OSR:Out-of-Sync Replicas
AR:Assigned Replicas 所有副本
ISR是由leader維護,follower從leader同步數(shù)據(jù)有一些延遲(具體可以參見 圖文了解 Kafka 的副本復(fù)制機制),超過相應(yīng)的閾值會把 follower 剔除出 ISR, 存入OSR(Out-of-Sync Replicas )列表,新加入的follower也會先存放在OSR中。AR=ISR+OSR。
31.LEO、HW、LSO、LW等分別代表什么
LEO:是 LogEndOffset 的簡稱,代表當前日志文件中下一條
HW:水位或水印(watermark)一詞,也可稱為高水位(high watermark),通常被用在流式處理領(lǐng)域(比如Apache Flink、Apache Spark等),以表征元素或事件在基于時間層面上的進度。在Kafka中,水位的概念反而與時間無關(guān),而是與位置信息相關(guān)。嚴格來說,它表示的就是位置信息,即位移(offset)。取 partition 對應(yīng)的 ISR中 最小的 LEO 作為 HW,consumer 最多只能消費到 HW 所在的位置上一條信息。
LSO:是 LastStableOffset 的簡稱,對未完成的事務(wù)而言,LSO 的值等于事務(wù)中第一條消息的位置(firstUnstableOffset),對已完成的事務(wù)而言,它的值同 HW 相同
LW:Low Watermark 低水位, 代表 AR 集合中最小的 logStartOffset 值。
32.Kafka 在什么情況下會出現(xiàn)消息丟失?
參考數(shù)據(jù)可靠性和數(shù)據(jù)一致性
33.怎么盡可能保證 Kafka 的可靠性
參考數(shù)據(jù)可靠性和數(shù)據(jù)一致性
34.消費者和消費者組有什么關(guān)系?
每個消費者從屬于消費組。具體關(guān)系如下:
35.Kafka 的每個分區(qū)只能被一個消費者線程,如何做到多個線程同時消費一個分區(qū)?
36.數(shù)據(jù)傳輸?shù)氖聞?wù)有幾種?
數(shù)據(jù)傳輸?shù)氖聞?wù)定義通常有以下三種級別:
最多一次: 消息不會被重復(fù)發(fā)送,最多被傳輸一次,但也有可能一次不傳輸
最少一次: 消息不會被漏發(fā)送,最少被傳輸一次,但也有可能被重復(fù)傳輸.
精確的一次(Exactly once): 不會漏傳輸也不會重復(fù)傳輸,每個消息都傳輸被
37.Kafka 消費者是否可以消費指定分區(qū)消息?
Kafa consumer消費消息時,向broker發(fā)出fetch請求去消費特定分區(qū)的消息,consumer指定消息在日志中的偏移量(offset),就可以消費從這個位置開始的消息,customer擁有了offset的控制權(quán),可以向后回滾去重新消費之前的消息,這是很有意義的
38.Kafka消息是采用Pull模式,還是Push模式?
Kafka最初考慮的問題是,customer應(yīng)該從brokes拉取消息還是brokers將消息推送到consumer,也就是pull還push。在這方面,Kafka遵循了一種大部分消息系統(tǒng)共同的傳統(tǒng)的設(shè)計:producer將消息推送到broker,consumer從broker拉取消息。
一些消息系統(tǒng)比如Scribe和Apache Flume采用了push模式,將消息推送到下游的consumer。這樣做有好處也有壞處:由broker決定消息推送的速率,對于不同消費速率的consumer就不太好處理了。消息系統(tǒng)都致力于讓consumer以最大的速率最快速的消費消息,但不幸的是,push模式下,當broker推送的速率遠大于consumer消費的速率時,consumer恐怕就要崩潰了。最終Kafka還是選取了傳統(tǒng)的pull模式。Pull模式的另外一個好處是consumer可以自主決定是否批量的從broker拉取數(shù)據(jù)。Push模式必須在不知道下游consumer消費能力和消費策略的情況下決定是立即推送每條消息還是緩存之后批量推送。如果為了避免consumer崩潰而采用較低的推送速率,將可能導致一次只推送較少的消息而造成浪費。Pull模式下,consumer就可以根據(jù)自己的消費能力去決定這些策略。Pull有個缺點是,如果broker沒有可供消費的消息,將導致consumer不斷在循環(huán)中輪詢,直到新消息到t達。為了避免這點,Kafka有個參數(shù)可以讓consumer阻塞知道新消息到達(當然也可以阻塞知道消息的數(shù)量達到某個特定的量這樣就可以批量發(fā)
39.Kafka 消息格式的演變清楚嗎?
Kafka 的消息格式經(jīng)過了四次大變化,
0.8.x版本的消息格式如下:
這個版本的 Message 格式加入了 Key 相關(guān)的信息,以及 內(nèi)容的長度等,各個字段的含義介紹如下:
crc:占用4個字節(jié),主要用于校驗消息的內(nèi)容;
magic:這個占用1個字節(jié),主要用于標識 Kafka 版本。
attributes:占用1個字節(jié),這里面存儲了消息壓縮使用的編碼。這個版本的 Kafka 僅支持 gzip、snappy 以及 lz4(0.8.2引入) 三種壓縮格式;后四位如果是0001則標識gzip壓縮,如果是0010則是snappy壓縮,如果是0011則是snappy壓縮,如果是0000則表示沒有使用壓縮。
key length:占用4個字節(jié)。主要標識 Key 的內(nèi)容的長度 K;
key:占用 K 個字節(jié)。存儲的是 key 的具體內(nèi)容
value length:占用4個字節(jié)。主要標識 value 的內(nèi)容的長度 V;
value:這個占用的字節(jié)為 V。value即是消息的真實內(nèi)容,在 Kafka 中這個也叫做payload。
這個版本的MessageSet 格式和之前一樣,就不介紹了。但是需要注意的是,這個版本 MessageSet 中的 offset 字段存儲的已經(jīng)不是消息物理偏移量了,而是邏輯地址,比如0,、1、2....。有了邏輯地址,我們就可以解決之前Kafka 0.7.0遇到的一些問題,比如可以在壓縮消息內(nèi)通過偏移量進行尋址,壓縮消息可以checkpoint內(nèi)部的消息等。
0.10.x版本的消息格式如下:
可以看出,這個版本相對于 Kafka 0.8.x版本的消息格式變化不大,各個字段的含義:這個版本的 Message 格式加入了 Key 相關(guān)的信息,以及 內(nèi)容的長度等,各個字段的含義介紹如下:
crc:占用4個字節(jié),主要用于校驗消息的內(nèi)容;
magic:這個占用1個字節(jié),主要用于標識 Kafka 版本。Kafka 0.10.x magic默認值為1
attributes:占用1個字節(jié),這里面存儲了消息壓縮使用的編碼以及Timestamp類型。這個版本的 Kafka 僅支持 gzip、snappy 以及 lz4(0.8.2引入) 三種壓縮格式;后四位如果是?0001 則表示 gzip 壓縮,如果是?0010?則是 snappy 壓縮,如果是?0011 則是 lz4 壓縮,如果是0000則表示沒有使用壓縮。第4個bit位如果為0,代表使用create time;如果為1代表append time;其余位(第5~8位)保留;
key length:占用4個字節(jié)。主要標識 Key 的內(nèi)容的長度 K;
key:占用 K 個字節(jié)。存儲的是 key 的具體內(nèi)容
value length:占用4個字節(jié)。主要標識 value 的內(nèi)容的長度 V;
value:這個占用的字節(jié)為 V。value即是消息的真實內(nèi)容,在 Kafka 中這個也叫做payload。
40.Kafka 偏移量的演變清楚嗎?
參見官方文檔,此問題很少問
41.Kafka 高效文件存儲設(shè)計特點
Kafka把topic中一個parition大文件分成多個小文件段,通過多個小文件段,就容易定期清除或刪除已經(jīng)消費完文件,減少磁盤占用。
通過索引信息可以快速定位message和確定response的最大大小。
通過index元數(shù)據(jù)全部映射到memory,可以避免segment file的IO磁盤操作。
通過索引文件稀疏存儲,可以大幅降低index文件元數(shù)據(jù)占用空間大小
42.Kafka創(chuàng)建Topic時如何將分區(qū)放置到不同的Broker中
副本因子不能大于 Broker 的個數(shù);
第一個分區(qū)(編號為0)的第一個副本放置位置是隨機從 brokerList 選擇的;
其他分區(qū)的第一個副本放置位置相對于第0個分區(qū)依次往后移。也就是如果我們有5個 Broker,5個分區(qū),假設(shè)第一個分區(qū)放在第四個 Broker 上,那么第二個分區(qū)將會放在第五個 Broker 上;第三個分區(qū)將會放在第一個 Broker 上;第四個分區(qū)將會放在第二個 Broker 上,依次類推;
剩余的副本相對于第一個副本放置位置其實是由 nextReplicaShift 決定的,而這個數(shù)也是隨機產(chǎn)生的;
具體可以參見Kafka創(chuàng)建Topic時如何將分區(qū)放置到不同的Broker中。
43.Kafka新建的分區(qū)會在哪個目錄下創(chuàng)建
我們知道,在啟動 Kafka 集群之前,我們需要配置好 log.dirs 參數(shù),其值是 Kafka 數(shù)據(jù)的存放目錄,這個參數(shù)可以配置多個目錄,目錄之間使用逗號分隔,通常這些目錄是分布在不同的磁盤上用于提高讀寫性能。當然我們也可以配置 log.dir 參數(shù),含義一樣。只需要設(shè)置其中一個即可。
如果 log.dirs 參數(shù)只配置了一個目錄,那么分配到各個 Broker 上的分區(qū)肯定只能在這個目錄下創(chuàng)建文件夾用于存放數(shù)據(jù)。
但是如果 log.dirs 參數(shù)配置了多個目錄,那么 Kafka 會在哪個文件夾中創(chuàng)建分區(qū)目錄呢?答案是:Kafka 會在含有分區(qū)目錄最少的文件夾中創(chuàng)建新的分區(qū)目錄,分區(qū)目錄名為 Topic名+分區(qū)ID。注意,是分區(qū)文件夾總數(shù)最少的目錄,而不是磁盤使用量最少的目錄!也就是說,如果你給 log.dirs 參數(shù)新增了一個新的磁盤,新的分區(qū)目錄肯定是先在這個新的磁盤上創(chuàng)建直到這個新的磁盤目錄擁有的分區(qū)目錄不是最少為止。
44.談一談 Kafka 的再均衡
在Kafka中,當有新消費者加入或者訂閱的topic數(shù)發(fā)生變化時,會觸發(fā)Rebalance(再均衡:在同一個消費者組當中,分區(qū)的所有權(quán)從一個消費者轉(zhuǎn)移到另外一個消費者)機制,Rebalance顧名思義就是重新均衡消費者消費。Rebalance的過程如下:
第一步:所有成員都向coordinator發(fā)送請求,請求入組。一旦所有成員都發(fā)送了請求,coordinator會從中選擇一個consumer擔任leader的角色,并把組成員信息以及訂閱信息發(fā)給leader。第二步:leader開始分配消費方案,指明具體哪個consumer負責消費哪些topic的哪些partition。一旦完成分配,leader會將這個方案發(fā)給coordinator。coordinator接收到分配方案之后會把方案發(fā)給各個consumer,這樣組內(nèi)的所有成員就都知道自己應(yīng)該消費哪些分區(qū)了。所以對于Rebalance來說,Coordinator起著至關(guān)重要的作用
45.談?wù)?Kafka 分區(qū)分配策略
每個 Topic 一般會有很多個 partitions。為了使得我們能夠及時消費消息,我們也可能會啟動多個 Consumer 去消費,而每個 Consumer 又會啟動一個或多個streams去分別消費 Topic 對應(yīng)分區(qū)中的數(shù)據(jù)。我們又知道,Kafka 存在 Consumer Group 的概念,也就是group.id
一樣的 Consumer,這些 Consumer 屬于同一個Consumer Group,組內(nèi)的所有消費者協(xié)調(diào)在一起來消費訂閱主題(subscribed topics)的所有分區(qū)(partition)。當然,每個分區(qū)只能由同一個消費組內(nèi)的一個consumer來消費。那么問題來了,同一個 Consumer Group 里面的 Consumer 是如何知道該消費哪些分區(qū)里面的數(shù)據(jù)呢?
如上圖,Consumer1 為啥消費的是 Partition0 和 Partition2,而不是 Partition0 和 Partition3?這就涉及到 Kafka內(nèi)部分區(qū)分配策略(Partition Assignment Strategy)了。
在 Kafka 內(nèi)部存在兩種默認的分區(qū)分配策略:Range 和 RoundRobin。當以下事件發(fā)生時,Kafka 將會進行一次分區(qū)分配:
同一個 Consumer Group 內(nèi)新增消費者
消費者離開當前所屬的Consumer Group,包括shuts down 或 crashes
訂閱的主題新增分區(qū)
將分區(qū)的所有權(quán)從一個消費者移到另一個消費者稱為重新平衡(rebalance),如何rebalance就涉及到本文提到的分區(qū)分配策略。下面我們將詳細介紹 Kafka 內(nèi)置的兩種分區(qū)分配策略。本文假設(shè)我們有個名為 T1 的主題,其包含了10個分區(qū),然后我們有兩個消費者(C1,C2)來消費這10個分區(qū)里面的數(shù)據(jù),而且 C1 的 num.streams = 1,C2 的 num.streams = 2。
Range strategy
Range策略是對每個主題而言的,首先對同一個主題里面的分區(qū)按照序號進行排序,并對消費者按照字母順序進行排序。在我們的例子里面,排完序的分區(qū)將會是0, 1, 2, 3, 4, 5, 6, 7, 8, 9;消費者線程排完序?qū)荂1-0, C2-0, C2-1。然后將partitions的個數(shù)除于消費者線程的總數(shù)來決定每個消費者線程消費幾個分區(qū)。如果除不盡,那么前面幾個消費者線程將會多消費一個分區(qū)。在我們的例子里面,我們有10個分區(qū),3個消費者線程, 10 3 = 3,而且除不盡,那么消費者線程 C1-0 將會多消費一個分區(qū),所以最后分區(qū)分配的結(jié)果看起來是這樣的:
C1-0 將消費 0, 1, 2, 3 分區(qū)C2-0 將消費 4, 5, 6 分區(qū)C2-1 將消費 7, 8, 9 分區(qū)
假如我們有11個分區(qū),那么最后分區(qū)分配的結(jié)果看起來是這樣的:
C1-0 將消費 0, 1, 2, 3 分區(qū)C2-0 將消費 4, 5, 6, 7 分區(qū)C2-1 將消費 8, 9, 10 分區(qū)
假如我們有2個主題(T1和T2),分別有10個分區(qū),那么最后分區(qū)分配的結(jié)果看起來是這樣的:
C1-0 將消費 T1主題的 0, 1, 2, 3 分區(qū)以及 T2主題的 0, 1, 2, 3分區(qū)C2-0 將消費 T1主題的 4, 5, 6 分區(qū)以及 T2主題的 4, 5, 6分區(qū)C2-1 將消費 T1主題的 7, 8, 9 分區(qū)以及 T2主題的 7, 8, 9分區(qū)
可以看出,C1-0 消費者線程比其他消費者線程多消費了2個分區(qū),這就是Range strategy的一個很明顯的弊端。
RoundRobin strategy
使用RoundRobin策略有兩個前提條件必須滿足:
同一個Consumer Group里面的所有消費者的num.streams必須相等;
每個消費者訂閱的主題必須相同。
所以這里假設(shè)前面提到的2個消費者的num.streams = 2。RoundRobin策略的工作原理:將所有主題的分區(qū)組成 TopicAndPartition 列表,然后對 TopicAndPartition 列表按照 hashCode 進行排序,這里文字可能說不清,看下面的代碼應(yīng)該會明白:
val allTopicPartitions = ctx.partitionsForTopic.flatMap {case(topic, partitions) =>
info("Consumer %s rebalancing the following partitions for topic %s: %s"
.format(ctx.consumerId, topic, partitions))
partitions.map(partition => {
TopicAndPartition(topic, partition)
})
}.toSeq.sortWith((topicPartition1, topicPartition2) => {
/*
* Randomize the order by taking the hashcode to reduce the likelihood of all partitions of a given topic ending
* up on one consumer (if it has a high enough stream count).
*/
topicPartition1.toString.hashCode < topicPartition2.toString.hashCode
})
最后按照round-robin風格將分區(qū)分別分配給不同的消費者線程。
在我們的例子里面,假如按照 hashCode 排序完的topic-partitions組依次為T1-5, T1-3, T1-0, T1-8, T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我們的消費者線程排序為C1-0, C1-1, C2-0, C2-1,最后分區(qū)分配的結(jié)果為:
C1-0 將消費 T1-5, T1-2, T1-6 分區(qū);C1-1 將消費 T1-3, T1-1, T1-9 分區(qū);C2-0 將消費 T1-0, T1-4 分區(qū);C2-1 將消費 T1-8, T1-7 分區(qū);
多個主題的分區(qū)分配和單個主題類似,這里就不在介紹了。
根據(jù)上面的詳細介紹相信大家已經(jīng)對Kafka的分區(qū)分配策略原理很清楚了。不過遺憾的是,目前我們還不能自定義分區(qū)分配策略,只能通過partition.assignment.strategy參數(shù)選擇 range 或 roundrobin。partition.assignment.strategy參數(shù)默認的值是range。
46.Kafka Producer 是如何動態(tài)感知主題分區(qū)數(shù)變化的?
47.Kafka 是如何實現(xiàn)高吞吐率的?
Kafka是分布式消息系統(tǒng),需要處理海量的消息,Kafka的設(shè)計是把所有的消息都寫入速度低容量大的硬盤,以此來換取更強的存儲能力,但實際上,使用硬盤并沒有帶來過多的性能損失。kafka主要使用了以下幾個方式實現(xiàn)了超高的吞吐率:
順序讀寫;
零拷貝
文件分段
批量發(fā)送
數(shù)據(jù)壓縮。
48.Kafka 監(jiān)控都有哪些?
比較流行的監(jiān)控工具有:
KafkaOffsetMonitor
KafkaManager
Kafka Web Console
Kafka Eagle
JMX協(xié)議(可以用諸如jdk自帶的jconsole來進行連接獲取狀態(tài)信息)
49.如何為Kafka集群選擇合適的Topics/Partitions數(shù)量
參見《如何為Kafka集群選擇合適的Topics/Partitions數(shù)量》
50.談?wù)勀銓?Kafka 事務(wù)的了解?
參見這篇文章:http://www.jasongj.com/kafka/transaction/
51.談?wù)勀銓?Kafka 冪等的了解?
參見這篇文章:http://www.lxweimin.com/p/b1599f46229b
52.Kafka 缺點?
由于是批量發(fā)送,數(shù)據(jù)并非真正的實時;
對于mqtt協(xié)議不支持;
不支持物聯(lián)網(wǎng)傳感數(shù)據(jù)直接接入;
僅支持統(tǒng)一分區(qū)內(nèi)消息有序,無法實現(xiàn)全局消息有序;
監(jiān)控不完善,需要安裝插件;
依賴zookeeper進行元數(shù)據(jù)管理;
53.Kafka 新舊消費者的區(qū)別
舊的 Kafka 消費者 API 主要包括:SimpleConsumer(簡單消費者) 和 ZookeeperConsumerConnectir(高級消費者)。SimpleConsumer 名字看起來是簡單消費者,但是其實用起來很不簡單,可以使用它從特定的分區(qū)和偏移量開始讀取消息。高級消費者和現(xiàn)在新的消費者有點像,有消費者群組,有分區(qū)再均衡,不過它使用 ZK 來管理消費者群組,并不具備偏移量和再均衡的可操控性。
現(xiàn)在的消費者同時支持以上兩種行為,所以為啥還用舊消費者 API 呢?
54.Kafka 分區(qū)數(shù)可以增加或減少嗎?為什么?
我們可以使用 bin/kafka-topics.sh 命令對 Kafka 增加 Kafka 的分區(qū)數(shù)據(jù),但是 Kafka 不支持減少分區(qū)數(shù)。Kafka 分區(qū)數(shù)據(jù)不支持減少是由很多原因的,比如減少的分區(qū)其數(shù)據(jù)放到哪里去?是刪除,還是保留?刪除的話,那么這些沒消費的消息不就丟了。如果保留這些消息如何放到其他分區(qū)里面?追加到其他分區(qū)后面的話那么就破壞了 Kafka 單個分區(qū)的有序性。如果要保證刪除分區(qū)數(shù)據(jù)插入到其他分區(qū)保證有序性,那么實現(xiàn)起來邏輯就會非常復(fù)雜。
?55.kafka消息的存儲機制
?kafka通過 topic來分主題存放數(shù)據(jù),主題內(nèi)有分區(qū),分區(qū)可以有多個副本,分區(qū)的內(nèi)部還細分為若干個 segment。都是持久化到磁盤,采用零拷貝技術(shù)。
1、高效檢索
分區(qū)下面,會進行分段操作,每個分段都會有對應(yīng)的素引,這樣就可以根據(jù) offset二分查找定位到消息在哪一段,根據(jù)段的索引文件,定位具體的 mle ssage
2、分區(qū)副本可用性(1 eader選舉,zk來協(xié)調(diào)
如果1eader宕機,選出了新的1eader,而新的 leader并不能保證已經(jīng)完全同步了之前1eader的所有數(shù)據(jù),只能保證HW(高水位設(shè)置)之前的數(shù)據(jù)是同步過的,此時所有的 follower都要將數(shù)據(jù)截斷到W的位置,再和新的 leader同步數(shù)據(jù),來保證數(shù)據(jù)一致。
當宕機的 leader恢復(fù),發(fā)現(xiàn)新的1eader中的數(shù)據(jù)和自己持有的數(shù)據(jù)不一致,此時宕機的1 eader會將自己的數(shù)據(jù)截斷到宕機之前的hw位置,然后同步新1 eader的數(shù)據(jù)。宕機的1eader活過來也像 follower一樣同步數(shù)據(jù),來保證數(shù)據(jù)的一致性。
56.相比較于傳統(tǒng)消息隊列,kafka的區(qū)別
1、分區(qū)性:存儲不會受單一服務(wù)器存儲空間的限制
2、高可用性:副本1 eader選舉
3、消息有序性:一個分區(qū)內(nèi)是有序的。
4、負載均衡性:分區(qū)內(nèi)的一條消息,只會被消費組中的一個消費者消費,主題中的消息,會均衡的發(fā)送給消費者組中的所有消費者進行消費。
57.消息丟失和消息重復(fù)
同步:這個生產(chǎn)者寫一條消息的時候,它就立馬發(fā)送到某個分區(qū)去。
異步:這個生產(chǎn)者寫一條消息的時候,先是寫到某個緩沖區(qū),這個緩沖區(qū)里的數(shù)據(jù)還沒寫到 broker集群里的某個分區(qū)的時候,它就返回到 client去了
針對消息丟失:同步模式下,確認機制設(shè)置為-1,即讓消息寫入 Leader和 Fol lower之后再確認消息發(fā)送成功:
異步模式下,為防止緩沖區(qū)滿,可以在配置文件設(shè)置不限制阻塞超時時間,當緩沖區(qū)滿時讓生產(chǎn)者一直處于阻塞狀態(tài)
針對消息重復(fù),將消息的唯一標識保存到外部介質(zhì)中,每次消費時判斷是否處理過即可
五.Hbase
1.Hbase調(diào)優(yōu)
高可用
在HBase中Hmaster負責監(jiān)控RegionServer的生命周期,均衡RegionServer的負載,如果Hmaster掛掉了,那么整個HBase集群將陷入不健康的狀態(tài),并且此時的工作狀態(tài)并不會維持太久。所以HBase支持對Hmaster的高可用配置。
預(yù)分區(qū)
? ? ? ?每一個region維護著startRow與endRowKey,如果加入的數(shù)據(jù)符合某個region維護的rowKey范圍,則該數(shù)據(jù)交給這個region ?? ? ? ?維護。那么依照這個原則,我們可以將數(shù)據(jù)所要投放的分區(qū)提前大致的規(guī)劃好,以提高HBase性能。
優(yōu)化RowKey設(shè)計
? ? ? ?一條數(shù)據(jù)的唯一標識就是rowkey,那么這條數(shù)據(jù)存儲于哪個分區(qū),取決于rowkey處于哪個一個預(yù)分區(qū)的區(qū)間內(nèi),設(shè)計rowkey? ? ? ? ? 的主要目的 ,就是讓數(shù)據(jù)均勻的分布于所有的region中,在一定程度上防止數(shù)據(jù)傾斜
內(nèi)存優(yōu)化
HBase操作過程中需要大量的內(nèi)存開銷,畢竟Table是可以緩存在內(nèi)存中的,一般會分配整個可用內(nèi)存的70%給HBase的Java堆。但是不建議分配非常大的堆內(nèi)存,因為GC過程持續(xù)太久會導致RegionServer處于長期不可用狀態(tài),一般16~48G內(nèi)存就可以了,如果因為框架占用內(nèi)存過高導致系統(tǒng)內(nèi)存不足,框架一樣會被系統(tǒng)服務(wù)拖死。
2.hbase的rowkey怎么創(chuàng)建好?列族怎么創(chuàng)建比較好?
hbase存儲時,數(shù)據(jù)按照Row key的字典序(byte order)排序存儲。設(shè)計key時,要充分排序存儲這個特性,將經(jīng)常一起讀取的行存儲放到一起。(位置相關(guān)性)
一個列族在數(shù)據(jù)底層是一個文件,所以將經(jīng)常一起查詢的列放到一個列族中,列族盡量少,減少文件的尋址時間。
設(shè)計原則
1)rowkey 長度原則
2)rowkey 散列原則
3)rowkey 唯一原則
如何設(shè)計
1)生成隨機數(shù)、hash、散列值
2)字符串反轉(zhuǎn)
3) 字符串拼接
3.hbase過濾器實現(xiàn)用途
增強hbase查詢數(shù)據(jù)的功能
減少服務(wù)端返回給客戶端的數(shù)據(jù)量
4.HBase宕機如何處理
答:宕機分為HMaster宕機和HRegisoner宕機,如果是HRegisoner宕機,HMaster會將其所管理的region重新分布到其他活動的RegionServer上,由于數(shù)據(jù)和日志都持久在HDFS中,該操作不會導致數(shù)據(jù)丟失。所以數(shù)據(jù)的一致性和安全性是有保障的。
如果是HMaster宕機,HMaster沒有單點問題,HBase中可以啟動多個HMaster,通過Zookeeper的Master Election機制保證總有一個Master運行。即ZooKeeper會保證總會有一個HMaster在對外提供服務(wù)。
5.hive跟hbase的區(qū)別是?
共同點:
1.hbase與hive都是架構(gòu)在hadoop之上的。都是用hadoop作為底層存儲
區(qū)別:
2.Hive是建立在Hadoop之上為了減少MapReduce jobs編寫工作的批處理系統(tǒng),HBase是為了支持彌補Hadoop對實時操作的缺陷的項目 。
3.想象你在操作RMDB數(shù)據(jù)庫,如果是全表掃描,就用Hive+Hadoop,如果是索引訪問,就用HBase+Hadoop 。
4.Hive query就是MapReduce jobs可以從5分鐘到數(shù)小時不止,HBase是非常高效的,肯定比Hive高效的多。
5.Hive本身不存儲和計算數(shù)據(jù),它完全依賴于HDFS和MapReduce,Hive中的表純邏輯。
6.hive借用hadoop的MapReduce來完成一些hive中的命令的執(zhí)行
7.hbase是物理表,不是邏輯表,提供一個超大的內(nèi)存hash表,搜索引擎通過它來存儲索引,方便查詢操作。
8.hbase是列存儲。
9.hdfs作為底層存儲,hdfs是存放文件的系統(tǒng),而Hbase負責組織文件。
10.hive需要用到hdfs存儲文件,需要用到MapReduce計算框架。
6.hbase寫流程
1/ 客戶端要連接zookeeper, 從zk的/hbase節(jié)點找到hbase:meta表所在的regionserver(host:port);
2/ regionserver掃描hbase:meta中的每個region的起始行健,對比r000001這條數(shù)據(jù)在那個region的范圍內(nèi);
3/ 從對應(yīng)的 info:server key中存儲了region是有哪個regionserver(host:port)在負責的;
4/ 客戶端直接請求對應(yīng)的regionserver;
5/ regionserver接收到客戶端發(fā)來的請求之后,就會將數(shù)據(jù)寫入到region中
7.hbase讀流程
1/ 首先Client連接zookeeper, 找到hbase:meta表所在的regionserver;
2/ 請求對應(yīng)的regionserver,掃描hbase:meta表,根據(jù)namespace、表名和rowkey在meta表中找到r00001所在的region是由那個regionserver負責的;
3/找到這個region對應(yīng)的regionserver
4/ regionserver收到了請求之后,掃描對應(yīng)的region返回數(shù)據(jù)到Client
(先從MemStore找數(shù)據(jù),如果沒有,再到BlockCache里面讀;BlockCache還沒有,再到StoreFile上讀(為了讀取的效率);
如果是從StoreFile里面讀取的數(shù)據(jù),不是直接返回給客戶端,而是先寫入BlockCache,再返回給客戶端。)
8.hbase數(shù)據(jù)flush過程
1)當MemStore數(shù)據(jù)達到閾值(默認是128M,老版本是64M),將數(shù)據(jù)刷到硬盤,將內(nèi)存中的數(shù)據(jù)刪除,同時刪除HLog中的歷史數(shù)據(jù);
2)并將數(shù)據(jù)存儲到HDFS中;
3)在HLog中做標記點。
9.數(shù)據(jù)合并過程
當數(shù)據(jù)塊達到4塊,hmaster將數(shù)據(jù)塊加載到本地,進行合并
當合并的數(shù)據(jù)超過256M,進行拆分,將拆分后的region分配給不同的hregionserver管理
當hregionser宕機后,將hregionserver上的hlog拆分,然后分配給不同的hregionserver加載,修改.META.
注意:hlog會同步到hdfs
10.Hmaster和Hgionserver職責
Hmaster
1、管理用戶對Table的增、刪、改、查操作;
2、記錄region在哪臺Hregion server上
3、在Region Split后,負責新Region的分配;
4、新機器加入時,管理HRegion Server的負載均衡,調(diào)整Region分布
5、在HRegion Server宕機后,負責失效HRegion Server 上的Regions遷移。
Hgionserver
HRegion Server主要負責響應(yīng)用戶I/O請求,向HDFS文件系統(tǒng)中讀寫數(shù)據(jù),是HBASE中最核心的模塊。
HRegion Server管理了很多table的分區(qū),也就是region。
11.HBase列族和region的關(guān)系?
HBase有多個RegionServer,每個RegionServer里有多個Region,一個Region中存放著若干行的行鍵以及所對應(yīng)的數(shù)據(jù),一個列族是一個文件夾,如果經(jīng)常要搜索整個一條數(shù)據(jù),列族越少越好,如果只有一部分的數(shù)據(jù)需要經(jīng)常被搜索,那么將經(jīng)常搜索的建立一個列族,其他不常搜索的建立列族檢索較快。
12.請簡述Hbase的物理模型是什么
13.請問如果使用Hbase做即席查詢,如何設(shè)計二級索引
14.如何避免讀、寫HBaes時訪問熱點問題?
(1)加鹽
這里所說的加鹽不是密碼學中的加鹽,而是在rowkey的前面增加隨機數(shù),具體就是給rowkey分配一個隨機前綴以使得它和之前的rowkey的開頭不同。給多少個前綴?這個數(shù)量應(yīng)該和我們想要分散數(shù)據(jù)到不同的region的數(shù)量一致(類似hive里面的分桶)。
( 自己理解:即region數(shù)量是一個范圍,我們給rowkey分配一個隨機數(shù),前綴(隨機數(shù))的范圍是region的數(shù)量)
加鹽之后的rowkey就會根據(jù)隨機生成的前綴分散到各個region上,以避免熱點。
(2)哈希
哈希會使同一行永遠用一個前綴加鹽。哈希也可以使負載分散到整個集群,但是讀卻是可以預(yù)測的。使用確定的哈希可以讓客戶端重構(gòu)完整的rowkey,可以使用get操作準確獲取某一個行數(shù)據(jù)。
(3)反轉(zhuǎn)
第三種防止熱點的方法是反轉(zhuǎn)固定長度或者數(shù)字格式的rowkey。這樣可以使得rowkey中經(jīng)常改變的部分(最沒有意義的部分)放在前面。這樣可以有效的隨機rowkey,但是犧牲了rowkey的有序性。反轉(zhuǎn)rowkey的例子:以手機號為rowkey,可以將手機號反轉(zhuǎn)后的字符串作為rowkey,從而避免諸如139、158之類的固定號碼開頭導 致的熱點問題。
(4)時間戳反轉(zhuǎn)
一個常見的數(shù)據(jù)處理問題是快速獲取數(shù)據(jù)的最近版本,使用反轉(zhuǎn)的時間戳作為rowkey的一部分對這個問題十分有用,可以用Long.Max_Value – timestamp追加到key的末尾,例如[key][reverse_timestamp] ,[key] 的最新值可以通過scan [key]獲得[key]的第一條記錄,因為HBase中rowkey是有序的,第一條記錄是最后錄入的數(shù)據(jù)。
(5)盡量減少行和列的大小
在HBase中,value永遠和它的key一起傳輸?shù)摹.斁唧w的值在系統(tǒng)間傳輸時,它的rowkey,列名,時間戳也會一起傳輸。如果你的rowkey和列名很大,HBase storefiles中的索引(有助于隨機訪問)會占據(jù)HBase分配的大量內(nèi)存,因為具體的值和它的key很大。可以增加block大小使得storefiles索引再更大的時間間隔增加,或者修改表的模式以減小rowkey和列名的大小。壓縮也有助于更大的索引。
(6)其他辦法
列族名的長度盡可能小,最好是只有一個字符。冗長的屬性名雖然可讀性好,但是更短的屬性名存儲在HBase中會更好。也可以在建表時預(yù)估數(shù)據(jù)規(guī)模,預(yù)留region數(shù)量,例如create ‘myspace:mytable’, SPLITS => [01,02,03,,…99]
15.布隆過濾器在HBASE中的應(yīng)用
主要提高隨機讀的性能
16.Hbase是用來干嘛的?什么樣的數(shù)據(jù)會放到hbase
17.Hbase和Hive的區(qū)別與適用場景
18.Hbase在建表時的設(shè)計原則(注意事項)
1、預(yù)分區(qū)
?Hbase默認建表時有一個 region,這個 region的 rowkey是沒有邊界的,即沒有 startkey和 endkey在數(shù)據(jù)寫入時,所有數(shù)據(jù)都會寫入這個默認的 region,隨著數(shù)據(jù)量的不斷增加,會進行 split,分成2個 region在此過程中,會產(chǎn)生兩個問題:
1.數(shù)據(jù)往一個 region寫,會有寫熱點問題。2. region split會消耗寶貴的集群I/0資源。我們可以控制在建表的時候,創(chuàng)建多個空 region,并確定每個 region的 startkey和 endkey,這樣只要我們的 rowkey設(shè)計能均勻的命中各個 region,就不會存在寫熱點問題。自然 split的幾率也會大大降低。
2、 rowkey設(shè)計原則
(1) rowkey長度越短越好。數(shù)據(jù)的持久化文件 Hfile中是按照 Keyvalue存儲的,如果 rowkey過長會極大影響File的存儲效率; Memstore將緩存部分數(shù)據(jù)到內(nèi)存,如果 rowk-ey字段過長,內(nèi)存的有效利用率就會降低,系統(tǒng)不能緩存更多的數(shù)據(jù),這樣會降低檢索效率。
2) rowkey盡量散列。建議將 rowkey的高位作為散列字段,將提高數(shù)據(jù)均衡分布在每個 Regionserver以實現(xiàn)負載均衡的幾率。(哈希、反轉(zhuǎn)等也可以避免熱點問題
(3) rowkey保證唯一性。
3、列族設(shè)計原則
(1)建表至少指定一個列族,但一般不超過三個,一般一個,因為 flush和 compact是以 region為單位,所以,某個 column family在 flush的時候,它鄰近的 column family也會因關(guān)聯(lián)效應(yīng)被觸發(fā)f1ush,最終導致系統(tǒng)產(chǎn)生更多的1/0
2)列族名字不宜過長,會冗余存儲。
3)不同列族的記錄的數(shù)量級不易相差太大,比如A,B兩個列族,A為100萬條,B為100億條,則A會被分散到多個 region(可能會跨 reglon server),導致對A的掃描效率低下
19.hbase優(yōu)化方法
1、減少調(diào)整
(1)減少 region分裂
根據(jù)你的 Rowkey設(shè)計來進行預(yù)建分區(qū),減少 region的動態(tài)分裂。
2)給HFi1設(shè)定合適大小
?Hfile是數(shù)據(jù)底層存儲文件,在每個 memstore進行刷新時會生成一 Hfile,當 Hfile增加到一定程度時,會將屬于一個 region的HFi1e進行合并,這個步驟會帶來開銷但不可避免,但是合并后 reglon大小如果大于設(shè)定的值,那么 region會進行分裂。為了減少這樣的無謂的1/0開銷,建議估計項目數(shù)據(jù)量大小,給 Hfile設(shè)定一個合適的值
2、減少啟停
?Hbase中也存在頻繁開啟關(guān)閉帯來的問題。
(1)關(guān)閉 Compaction,在閑時進行手動 Compact ion0因為 Hbase中存在 Minor Compaction和
?Ma jor Compaction,合并就是1/0讀寫,大量的 Hfile進行肯定會帶來I/0開銷,甚至是1/0風暴所以為了避免這種不受控制的意外發(fā)生,建議關(guān)閉自動 Compact ion,在閑時進行 compaction o2)當需要寫入大量離線數(shù)據(jù)時建議使用 Bul kloado
3、減少數(shù)據(jù)量
(1)開啟過濾,提高查詢速度,可以減少網(wǎng)絡(luò)102)使用壓縮:一般推薦使用 Snappy和LZ0壓縮。
4、合理設(shè)計(建表注意事項)
分區(qū)、 Rowkey設(shè)計、列族的設(shè)計
20.Hbase中的region server發(fā)生故障后的處理方法(zk-->WAL)
Hbase檢測宕機是通過 Zookeeper實現(xiàn)的,正常情況下 Regionserver會周期性向 Zookeeper發(fā)送心跳,一旦發(fā)生宕機,心跳就會停止,超過一定時間( Sessi ontimeout) Zookeeper就會認為 Regionserver宕機離線,并將該消息通知給 Master0一臺 Regionserver只有一個Hog文件,然后,將og按照
Region進行分組,切分到每個 regionserver中,因此在回放之前首先需要將og按照 Region進行分組,每個 Region的日志數(shù)據(jù)放在一起,方便后面按照 Region進行回放。這個分組的過程就稱為HLog切分。然后再對 region重新分配,并對其中的Hog進行回放將數(shù)據(jù)寫入 memstore刷寫到磁盤,完成最終數(shù)據(jù)恢復(fù)。
六.數(shù)倉
1.維表和寬表的考查(主要考察維表的使用及維度退化手法)
維表數(shù)據(jù)一般根據(jù)ods層數(shù)據(jù)加工生成,在設(shè)計寬表的時候,可以適當?shù)挠靡恍┚S度退化手法,將維度退化到事實表中,減少事實表和維表的關(guān)聯(lián)
2.數(shù)倉表命名規(guī)范
3.拉鏈表的使用場景
4.一億條數(shù)據(jù)查的很慢,怎么查快一點
5.有什么維表
時間維表,用戶維表,醫(yī)院維表等
6.數(shù)據(jù)源都有哪些
業(yè)務(wù)庫數(shù)據(jù)源:mysql,oracle,mongo
日志數(shù)據(jù):ng日志,埋點日志
爬蟲數(shù)據(jù)
7.你們最大的表是什么表,數(shù)據(jù)量多少
ng日志表,三端(app,web,h5)中app端日志量最大,清洗入庫后的數(shù)據(jù)一天大概xxxxW
8.數(shù)倉架構(gòu)體系
9.數(shù)據(jù)平臺是怎樣的,用到了阿里的那一套嗎?
沒用到阿里那一套,數(shù)據(jù)平臺為自研產(chǎn)品
10.你了解的調(diào)度系統(tǒng)有那些?,你們公司用的是哪種調(diào)度系統(tǒng)
airflow,azkaban,ooize,我們公司使用的是airflow
11.你們公司數(shù)倉底層是怎么抽數(shù)據(jù)的?
業(yè)務(wù)數(shù)據(jù)用的是datax
日志數(shù)據(jù)用的是logstash
12.為什么datax抽數(shù)據(jù)要比sqoop 快?
13.埋點數(shù)據(jù)你們是怎樣接入的
logstash-->kafka-->logstash-->hdfs
14.如果你們業(yè)務(wù)庫的表有更新,你們數(shù)倉怎么處理的?
15.能獨立搭建數(shù)倉嗎
可以
16.搭建過CDH 集群嗎
17.說一下你們公司的大數(shù)據(jù)平臺架構(gòu)?你有參與嗎?
18.介紹一下你自己的項目和所用的技術(shù)
19.對目前的流和批處理的認識?就是談?wù)勛约旱母惺?/p>
20.你了解那些OLAP 引擎,MPP 知道一些嗎?clickHouse 了解一些嗎?你自己做過測試性能嗎?
21.Kylin 有了解嗎?介紹一下原理
22.datax 源碼有改造過嗎
23.你們數(shù)倉的APP 層是怎么對外提供服務(wù)的?
1.直接存入mysql業(yè)務(wù)庫,業(yè)務(wù)方直接讀取
2.數(shù)據(jù)存入mysql,以接口的形式提供數(shù)據(jù)
3.數(shù)據(jù)存入kylin,需求方通過jdbc讀取數(shù)據(jù)
24.數(shù)據(jù)接入進來,你們是怎樣規(guī)劃的,有考慮數(shù)據(jù)的膨脹問題嗎
25.簡述拉鏈表,流水表以及快照表的含義和特點
26.全量表(df),增量表(di),追加表(da),拉鏈表(dz)的區(qū)別及使用場景
27.你們公司的數(shù)倉分層,每一層是怎么處理數(shù)據(jù)的
28.什么是事實表,什么是維表
29.星型模型和雪花模型
30.緩慢變化維如何處理,幾種方式
31.datax與sqoop的優(yōu)缺點
32.datax抽數(shù)碰到emoji表情怎么解決
33.工作中碰到什么困難,怎么解決的
34.如何用數(shù)據(jù)給公司帶來收益
35.需求驅(qū)動和業(yè)務(wù)驅(qū)動,數(shù)據(jù)開發(fā)和ETL開發(fā),實戰(zhàn)型和博客型
36.如何用數(shù)據(jù)實現(xiàn)業(yè)務(wù)增長,黑客增長?
37.什么是大數(shù)據(jù)?千萬級別的數(shù)據(jù)完全可以用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫集群解決,為什么要用到大數(shù)據(jù)平臺。
38.數(shù)據(jù)質(zhì)量,元數(shù)據(jù)管理,指標體系建設(shè),數(shù)據(jù)驅(qū)動
39.什么是數(shù)倉,建設(shè)數(shù)倉時碰到過什么問題
40.實時數(shù)倉技術(shù)選型及保證exactly-once
41.維度建模和范式建模的區(qū)別;
42.埋點的碼表如何設(shè)計;
43.集市層和公共層的區(qū)別;
44.緩慢變化維的處理方式
45.聊聊數(shù)據(jù)質(zhì)量
46.說說你從0-1搭建數(shù)倉都做了什么?你覺得最有挑戰(zhàn)的是什么?
47.數(shù)據(jù)模型如何構(gòu)建,星型、雪花、星座的區(qū)別和工作中如何使用;
48.如何優(yōu)化整個數(shù)倉的執(zhí)行時長,比如7點所有任務(wù)跑完,如何優(yōu)化到5點;
49.數(shù)據(jù)傾斜,遇到哪些傾斜,怎么發(fā)現(xiàn)的?怎么處理的?;
Hive調(diào)優(yōu),數(shù)據(jù)工程師成神之路
50.如何保證數(shù)據(jù)質(zhì)量;
51.如何保證指標一致性;
52.了解onedata嗎,說說你的理解;
53.數(shù)據(jù)漂移如何解決;
54.實時場景如何解決的;
55.拉鏈表如何設(shè)計,拉鏈表出現(xiàn)數(shù)據(jù)回滾的需求怎么解決。
56.平臺選型依據(jù);
57.數(shù)倉分層、模型、每層都是做什么的?為什么這么做?
58.交叉維度的解決方案?
59.數(shù)據(jù)質(zhì)量如何保證(DQC)?
60.任務(wù)延遲如何優(yōu)化(SLA)?
61.聊一下數(shù)據(jù)資產(chǎn)。
62.如果讓你設(shè)計實時數(shù)倉你會如何設(shè)計,為什么?
63.指標如何定義?
64.sql問題:連續(xù)活躍n天用戶的獲取;
65.數(shù)據(jù)傾斜的sql如何優(yōu)化;數(shù)據(jù)量大的sql如何優(yōu)化?
Hive調(diào)優(yōu),數(shù)據(jù)工程師成神之路
66.數(shù)據(jù)倉庫主題的劃分,參考Teradata的LDM模型;
67.Kimball和Inmon的相同和不同;
68.數(shù)據(jù)質(zhì)量管理、數(shù)據(jù)治理有什么好的方案?知識庫管理有什么好的思路?血緣關(guān)系圖。
69.元數(shù)據(jù)管理相關(guān)問題,集群存儲不夠了,需要清理不需要的任務(wù)和數(shù)據(jù)該怎么做?
70.業(yè)務(wù)庫2億數(shù)據(jù)入倉的策略,一次全量,之后每次增量;
71.什么場景會出現(xiàn)數(shù)據(jù)傾斜,怎么解決?比如select user_id,count(1) from table group by user_id,其中某些user_id的訪問量很大,查詢不出結(jié)果該怎么辦?
Hive調(diào)優(yōu),數(shù)據(jù)工程師成神之路
72.sql里面on和where有區(qū)別嗎??
73.聊一下技術(shù)架構(gòu),整個項目每個環(huán)節(jié)用的什么技術(shù)這個樣子;
74.hive、hbase、spark。。。。這些大數(shù)據(jù)組件,熟悉哪個或者哪些?我說hive和hbase,對方就問hive和hbase的原理,差異等問題;
75.有沒有實時數(shù)倉的經(jīng)驗,數(shù)據(jù)實時入倉思路,canal;
76.你對當前的項目組有沒有什么自己的看法、意見或者需要改進的地方,這個改進對你有沒有什么影響
77.ods的增量能否做成通用的?
78.公共層和數(shù)據(jù)集市層的區(qū)別和特點?
79.從原理上說一下mpp和mr的區(qū)別
80.對了中間還有問數(shù)倉數(shù)據(jù)的輸出主要是哪些還有數(shù)倉的分層;
81.報表如何展示
82.數(shù)據(jù)庫和數(shù)據(jù)倉庫有什么區(qū)別
1、數(shù)據(jù)庫是面向事務(wù)的,數(shù)據(jù)是由日常的業(yè)務(wù)產(chǎn)生的,常更新:
? ? ?數(shù)據(jù)倉庫是面向主題的,數(shù)據(jù)來源于數(shù)據(jù)庫或文件,經(jīng)過一定的規(guī)則轉(zhuǎn)換得到,用來分析的。
2、數(shù)據(jù)庫一般是用來存儲當前交易數(shù)據(jù),
? ? ?數(shù)據(jù)倉庫存儲一般存儲的是歷史數(shù)據(jù)
3、數(shù)據(jù)庫的設(shè)計一般是符合三范式的,有最大的精確度和最小的冗余度,有利于數(shù)據(jù)的插入;
? ? ? 數(shù)據(jù)倉庫的設(shè)計一般是星型的,有利于査詢。
七.Flink
1.Flink實時計算時落磁盤嗎
不落,是內(nèi)存計算
2.日活DAU的統(tǒng)計需要注意什么
3.Flink調(diào)優(yōu)
4.Flink的容錯是怎么做的
定期checkpoint存儲oprator state及keyedstate到stateBackend
5.Parquet格式的好處?什么時候讀的快什么時候讀的慢
6.flink中checkPoint為什么狀態(tài)有保存在內(nèi)存中這樣的機制?為什么要開啟checkPoint?
開啟checkpoint可以容錯,程序自動重啟的時候可以從checkpoint中恢復(fù)數(shù)據(jù)
7.flink保證Exactly_Once的原理?
1.開啟checkpoint
2.source支持數(shù)據(jù)重發(fā)
3.sink支持事務(wù),可以分2次提交,如kafka;或者sink支持冪等,可以覆蓋之前寫入的數(shù)據(jù),如redis
滿足以上三點,可以保證Exactly_Once
8.flink的時間形式和窗口形式有幾種?有什么區(qū)別,你們用在什么場景下的?
9.flink的背壓說下?
10.flink的watermark機制說下,以及怎么解決數(shù)據(jù)亂序的問題?
11.flink on yarn執(zhí)行流程
? ? ? ?Flink任務(wù)提交后,Client向HDFS上傳Flink的Jar包和配置,之后向Yarn ResourceManager提交任務(wù),ResourceManager分配Container資源并通知對應(yīng)的NodeManager啟動ApplicationMaster,ApplicationMaster啟動后加載Flink的Jar包和配置構(gòu)建環(huán)境,然后啟動JobManager,之后ApplicationMaster向ResourceManager申請資源啟動TaskManager,ResourceManager分配Container資源后,由ApplicationMaster通知資源所在節(jié)點的NodeManager啟動TaskManager,NodeManager加載Flink的Jar包和配置構(gòu)建環(huán)境并啟動TaskManager,TaskManager啟動后向JobManager發(fā)送心跳包,并等待JobManager向其分配任務(wù)。
12.說一說spark 和flink 的區(qū)別?
八.Java
1.hashMap底層源碼,數(shù)據(jù)結(jié)構(gòu)
2.寫出你用過的設(shè)計模式,并舉例說明解決的實際問題
3.Java創(chuàng)建線程的幾種方式
繼承Thread類,重寫run方法
實現(xiàn)Runnable接口,實現(xiàn)run方法
通過線程池獲取線程
實現(xiàn)Callable接口并實現(xiàn)call方法,創(chuàng)建該類的實例,使用FutureTask類包裝Callable對象,使用FutureTask對象作為Thread對象的target創(chuàng)建并啟用新線程
4.請簡述操作系統(tǒng)的線程和進程的區(qū)別
5.Java程序出現(xiàn)OutOfMemoryError:unable to create new native thread 的原因可能有哪些?如何分析和解決?
6.采用java或自己熟悉的任何語言分別實現(xiàn)簡單版本的線性表和鏈表,只需實現(xiàn)add,remove方法即可
7.ArrayList和LinkedList的區(qū)別
8.JVM 內(nèi)存分哪幾個區(qū),每個區(qū)的作用是什么?
9.Java中迭代器和集合的區(qū)別?
集合是將所有數(shù)據(jù)加載到內(nèi)存,然后通過集合的方法去內(nèi)存中獲取,而迭代器是一個對象,實現(xiàn)了Iterator接口,實現(xiàn)了接口的hasNext和Next方法。
10.HashMap 和 HashTable 區(qū)別
1) 線程安全性不同
HashMap 是線程不安全的,HashTable 是線程安全的,其中的方法是 Synchronize 的,
在多線程并發(fā)的情況下,可以直接使用 HashTabl,但是使用 HashMap 時必須自己增加同步
處理。
2) 是否提供 contains 方法
HashMap 只有 containsValue 和 containsKey 方法;HashTable 有 contains、containsKey
和 containsValue 三個方法,其中 contains 和 containsValue 方法功能相同。
3) key 和 value 是否允許 null 值
Hashtable 中,key 和 value 都不允許出現(xiàn) null 值。HashMap 中,null 可以作為鍵,這
樣的鍵只有一個;可以有一個或多個鍵所對應(yīng)的值為 null。
4) 數(shù)組初始化和擴容機制
HashTable 在不指定容量的情況下的默認容量為 11,而 HashMap 為 16,Hashtable 不
要求底層數(shù)組的容量一定要為 2 的整數(shù)次冪,而 HashMap 則要求一定為 2 的整數(shù)次冪。
Hashtable 擴容時,將容量變?yōu)樵瓉淼?2 倍加 1,而 HashMap 擴容時,將容量變?yōu)樵?/p>
來的 2 倍。
11.線程池使用注意哪些方面?
線程池分為單線程線程池,固定大小線程池,可緩沖的線程池
12.HashMap和TreeMap的區(qū)別?TreeMap排序規(guī)則?
TreeMap會自動進行排序,根據(jù)key的Compare方法進行排序
13.用java實現(xiàn)單例模式
14.使用遞歸算法求n的階乘:n! ,語言不限
15.HashMap和Hashtable的區(qū)別是什么
16.TreeSet 和 HashSet 區(qū)別
HashSet 是采用 hash 表來實現(xiàn)的。其中的元素沒有按順序排列,add()、remove()以及
contains()等方法都是復(fù)雜度為 O(1)的方法。
TreeSet 是采用樹結(jié)構(gòu)實現(xiàn)(紅黑樹算法)。元素是按順序進行排列,但是 add()、
remove()以及 contains()等方法都是復(fù)雜度為 O(log (n))的方法。它還提供了一些方法來處理
排序的 set,如 first(),last(),headSet(),tailSet()等等。
17.Stringbuffer 和 Stringbuild 區(qū)別
1、StringBuffer 與 StringBuilder 中的方法和功能完全是等價的。
2、只是 StringBuffer 中的方法大都采用了 synchronized 關(guān)鍵字進行修飾,因此是線程
安全的,而 StringBuilder 沒有這個修飾,可以被認為是線程不安全的。
3、在單線程程序下,StringBuilder 效率更快,因為它不需要加鎖,不具備多線程安全
而 StringBuffer 則每次都需要判斷鎖,效率相對更低
18.Final、Finally、Finalize
final:修飾符(關(guān)鍵字)有三種用法:修飾類、變量和方法。修飾類時,意味著它不
能再派生出新的子類,即不能被繼承,因此它和 abstract 是反義詞。修飾變量時,該變量
使用中不被改變,必須在聲明時給定初值,在引用中只能讀取不可修改,即為常量。修飾
方法時,也同樣只能使用,不能在子類中被重寫。
finally:通常放在 try…catch 的后面構(gòu)造最終執(zhí)行代碼塊,這就意味著程序無論正常執(zhí)
行還是發(fā)生異常,這里的代碼只要 JVM 不關(guān)閉都能執(zhí)行,可以將釋放外部資源的代碼寫在
finally 塊中。
finalize:Object 類中定義的方法,Java 中允許使用 finalize() 方法在垃圾收集器將對象
從內(nèi)存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在銷毀對象時調(diào)用
的,通過重寫 finalize() 方法可以整理系統(tǒng)資源或者執(zhí)行其他清理工作。
19..==和 Equals 區(qū)別
== : 如果比較的是基本數(shù)據(jù)類型,那么比較的是變量的值
如果比較的是引用數(shù)據(jù)類型,那么比較的是地址值(兩個對象是否指向同一塊內(nèi)
存)
equals:如果沒重寫 equals 方法比較的是兩個對象的地址值。
如果重寫了 equals 方法后我們往往比較的是對象中的屬性的內(nèi)容
equals 方法是從 Object 類中繼承的,默認的實現(xiàn)就是使用==
20.比較ArrayList,LinkedList的存儲特性和讀寫性能
21.Java 類加載過程
Java類加載需要經(jīng)歷一下幾個過程:
加載
加載時類加載的第一個過程,在這個階段,將完成一下三件事情:
通過一個類的全限定名獲取該類的二進制流。
將該二進制流中的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法去運行時數(shù)據(jù)結(jié)構(gòu)。?
在內(nèi)存中生成該類的Class對象,作為該類的數(shù)據(jù)訪問入口。
?驗證
驗證的目的是為了確保Class文件的字節(jié)流中的信息不回危害到虛擬機.在該階段主要完成以下四鐘驗證:?
文件格式驗證:驗證字節(jié)流是否符合Class文件的規(guī)范,如主次版本號是否在當前虛擬機范圍內(nèi),常量池中的常量是否有不被支持的類型.
元數(shù)據(jù)驗證:對字節(jié)碼描述的信息進行語義分析,如這個類是否有父類,是否集成了不被繼承的類等。
字節(jié)碼驗證:是整個驗證過程中最復(fù)雜的一個階段,通過驗證數(shù)據(jù)流和控制流的分析,確定程序語義是否正確,主要針對方法體的驗證。如:方法中的類型轉(zhuǎn)換是否正確,跳轉(zhuǎn)指令是否正確等。
符號引用驗證:這個動作在后面的解析過程中發(fā)生,主要是為了確保解析動作能正確執(zhí)行。
準備
準備階段是為類的靜態(tài)變量分配內(nèi)存并將其初始化為默認值,這些內(nèi)存都將在方法區(qū)中進行分配。準備階段不分配類中的實例變量的內(nèi)存,實例變量將會在對象實例化時隨著對象一起分配在Java堆中。
解析
該階段主要完成符號引用到直接引用的轉(zhuǎn)換動作。解析動作并不一定在初始化動作完成之前,也有可能在初始化之后。
初始化
初始化時類加載的最后一步,前面的類加載過程,除了在加載階段用戶應(yīng)用程序可以通過自定義類加載器參與之外,其余動作完全由虛擬機主導和控制。到了初始化階段,才真正開始執(zhí)行類中定義的Java程序代碼。
22.java中垃圾收集的方法有哪些?
23.如何判斷一個對象是否存活?(或者GC對象的判定方法)
判斷一個對象是否存活有兩種方法:?
引用計數(shù)法
可達性算法(引用鏈法)
24.jvm、堆棧
25.java基本數(shù)據(jù)類型
九.Elasticsearch
1.為什么要用es?存進es的數(shù)據(jù)是什么格式的,怎么查詢
十.Flume
1.什么是flume
a.Flume是一個分布式、可靠、和高可用的海量日志采集、聚合和傳輸?shù)南到y(tǒng)。
b.Flume可以采集文件,socket數(shù)據(jù)包等各種形式源數(shù)據(jù),又可以將采集到的數(shù)據(jù)輸出到HDFS、hbase、hive、kafka等眾多外部存儲系統(tǒng)中
c.一般的采集需求,通過對flume的簡單配置即可實現(xiàn)
d.ume針對特殊場景也具備良好的自定義擴展能力,因此,flume可以適用于大部分的日常數(shù)據(jù)采集場景
2.flume運行機制
Flume分布式系統(tǒng)中最核心的角色是agent,flume采集系統(tǒng)就是由一個個agent所連接起來形成
每一個agent相當于一個數(shù)據(jù)傳遞員,內(nèi)部有三個組件:
Source:采集源,用于跟數(shù)據(jù)源對接,以獲取數(shù)據(jù)
Sink:下沉地,采集數(shù)據(jù)的傳送目的,用于往下一級agent傳遞數(shù)據(jù)或者往最終存儲系統(tǒng)傳遞數(shù)據(jù)
Channel:angent內(nèi)部的數(shù)據(jù)傳輸通道,用于從source將數(shù)據(jù)傳遞到sink
3.Flume采集數(shù)據(jù)到Kafka中丟數(shù)據(jù)怎么辦
4.Flume怎么進行監(jiān)控?
5.Flume的三層架構(gòu),collector、agent、storage
十一.Sqoop
1.Sqoop底層運行的任務(wù)是什么
只有Map階段,沒有Reduce階段的任務(wù)。
2.sqoop的遷移數(shù)據(jù)的原理
3.Sqoop參數(shù)
/opt/module/sqoop/bin/sqoop import \
--connect \
--username \
--password \
--target-dir \
--delete-target-dir \
--num-mappers \
--fields-terminated-by ? \
--query ? "$2" ' and $CONDITIONS;'
4.Sqoop導入導出Null存儲一致性問題
Hive中的Null在底層是以“\N”來存儲,而MySQL中的Null在底層就是Null,為了保證數(shù)據(jù)兩端的一致性。在導出數(shù)據(jù)時采用--input-null-string和--input-null-non-string兩個參數(shù)。導入數(shù)據(jù)時采用--null-string和--null-non-string。
5.Sqoop數(shù)據(jù)導出一致性問題
1)場景1:如Sqoop在導出到Mysql時,使用4個Map任務(wù),過程中有2個任務(wù)失敗,那此時MySQL中存儲了另外兩個Map任務(wù)導入的數(shù)據(jù),此時老板正好看到了這個報表數(shù)據(jù)。而開發(fā)工程師發(fā)現(xiàn)任務(wù)失敗后,會調(diào)試問題并最終將全部數(shù)據(jù)正確的導入MySQL,那后面老板再次看報表數(shù)據(jù),發(fā)現(xiàn)本次看到的數(shù)據(jù)與之前的不一致,這在生產(chǎn)環(huán)境是不允許的。
2)場景2:設(shè)置map數(shù)量為1個(不推薦,面試官想要的答案不只這個)
多個Map任務(wù)時,采用–staging-table方式,仍然可以解決數(shù)據(jù)一致性問題。
6.通過sqoop把數(shù)據(jù)加載到mysql中,如何設(shè)置主鍵?
十二.Redis
1.緩存穿透、緩存雪崩、緩存擊穿
1)緩存穿透是指查詢一個一定不存在的數(shù)據(jù)。由于緩存命不中時會去查詢數(shù)據(jù)庫,查不到
數(shù)據(jù)則不寫入緩存,這將導致這個不存在的數(shù)據(jù)每次請求都要到數(shù)據(jù)庫去查詢,造成緩存穿
透。
解決方案:
① 是將空對象也緩存起來,并給它設(shè)置一個很短的過期時間,最長不超過 5 分鐘
② 采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的 bitmap 中,一個一定
不存在的數(shù)據(jù)會被這個 bitmap 攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力
2)如果緩存集中在一段時間內(nèi)失效,發(fā)生大量的緩存穿透,所有的查詢都落在數(shù)據(jù)庫上,
就會造成緩存雪崩。
解決方案:
盡量讓失效的時間點不分布在同一個時間點
3)緩存擊穿,是指一個 key 非常熱點,在不停的扛著大并發(fā),當這個 key 在失效的瞬間,
持續(xù)的大并發(fā)就穿破緩存,直接請求數(shù)據(jù)庫,就像在一個屏障上鑿開了一個洞。
可以設(shè)置 key 永不過期
2.數(shù)據(jù)類型
3.持久化
1)RDB 持久化:
① 在指定的時間間隔內(nèi)持久化
② 服務(wù) shutdown 會自動持久化
③ 輸入 bgsave 也會持久化
2)AOF : 以日志形式記錄每個更新操作
Redis 重新啟動時讀取這個文件,重新執(zhí)行新建、修改數(shù)據(jù)的命令恢復(fù)數(shù)據(jù)。
保存策略:
推薦(并且也是默認)的措施為每秒持久化一次,這種策略可以兼顧速度和安全性。
缺點:
1 比起 RDB 占用更多的磁盤空間
2 恢復(fù)備份速度要慢
3 每次讀寫都同步的話,有一定的性能壓力
4 存在個別 Bug,造成恢復(fù)不能
選擇策略:
官方推薦:
string
字符串
list
可以重復(fù)的集合
set
不可以重復(fù)的集合
hash
類似于 Map<String,String>
zset(sorted set)
帶分數(shù)的 set?
如果對數(shù)據(jù)不敏感,可以選單獨用 RDB;不建議單獨用 AOF,因為可能出現(xiàn) Bug;如果只是做純內(nèi)存緩存,可以都不用
4.悲觀鎖和樂觀鎖
悲觀鎖:執(zhí)行操作前假設(shè)當前的操作肯定(或有很大幾率)會被打斷(悲觀)。基于這個假設(shè),我們在做操作前就會把相關(guān)資源鎖定,不允許自己執(zhí)行期間有其他操作干擾。
樂觀鎖:執(zhí)行操作前假設(shè)當前操作不會被打斷(樂觀)。基于這個假設(shè),我們在做操作前不會鎖定資源,萬一發(fā)生了其他操作的干擾,那么本次操作將被放棄。Redis 使用的就是樂觀鎖。
5.redis 是單線程的,為什么那么快
1)完全基于內(nèi)存,絕大部分請求是純粹的內(nèi)存操作,非常快速。
2)數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作也簡單,Redis 中的數(shù)據(jù)結(jié)構(gòu)是專門進行設(shè)計的
3)采用單線程,避免了不必要的上下文切換和競爭條件,也不存在多進程或者多線程導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現(xiàn)死鎖而導致的性能消耗
4)使用多路 I/O 復(fù)用模型,非阻塞 IO
5)使用底層模型不同,它們之間底層實現(xiàn)方式以及與客戶端之間通信的應(yīng)用協(xié)議不一樣,
Redis 直接自己構(gòu)建了 VM 機制 ,因為一般的系統(tǒng)調(diào)用系統(tǒng)函數(shù)的話,會浪費一定的時間去移動和請求
6.redis的熱鍵問題?怎么解決?
十三.Mysql
1.請寫出mysql登錄命令,用戶名user,密碼123456,地址192.168.1.130
mysql?-h192.168.1.130-uuser?-p123456?-P3306?-Dwemeta_test
2.為什么MySQL的索引要使用B+樹而不是其它樹形結(jié)構(gòu)?比如B樹?
B樹
? ? ? ?B樹不管葉子節(jié)點還是非葉子節(jié)點,都會保存數(shù)據(jù),這樣導致在非葉子節(jié)點中能保存的指針數(shù)量變少(有些資料也稱為扇出)
指針少的情況下要保存大量數(shù)據(jù),只能增加樹的高度,導致IO操作變多,查詢性能變低;
B+樹
1.單一節(jié)點存儲更多的元素,使得查詢的IO次數(shù)更少。
2.所有查詢都要查找到葉子節(jié)點,查詢性能穩(wěn)定。
3.所有葉子節(jié)點形成有序鏈表,便于范圍查詢,遠遠高于B-樹
十四.數(shù)據(jù)結(jié)構(gòu)與算法
1.二分查找
package com.wedoctor.search;
public class Binarysearch {
? public static int bsearchWithoutRecursion(int arr[], int key) {
? ? ? ? int low = 0;
? ? ? ? int high = arr.length - 1;
? ? ? ? while (low <= high) {
? ? ? ? ? ? int mid = low + (high - low)? 2;
? ? ? ? ? ? if (arr[mid] > key)
? ? ? ? ? ? ? ? high = mid - 1;
? ? ? ? ? ? else if (arr[mid] < key)
? ? ? ? ? ? ? ? low = mid + 1;
? ? ? ? ? ? else
? ? ? ? ? ? ? ? return mid;
? ? ? ? }
? ? ? ? return -1;
? ? }
? ? public static void main(String[] args) {
? ? ? ? int arr[] = {1,3,5,6,8,9,11,14,23};
? ? ? ? int num = bsearchWithoutRecursion(arr, 9);
? ? ? ? System.out.println(num);
? ? }
}
2.快排
3.歸并排序
4.冒泡排序
package com.wedoctor.sort;
import java.util.Arrays;
public class BubbleSort {
? ? public static void main(String[] args) {
? ? ? ? int[] arr = new int[] { 2, 8, 7, 9, 4, 1, 5, 0 };
? ? ? ? bubbleSort(arr);
? ? }
? ? public static void bubbleSort(int[] arr) {
? ? ? ? //控制多少輪
? ? ? ? for (int i = 1; i < arr.length; i++) {
? ? ? ? ? ? //控制每一輪的次數(shù)
? ? ? ? ? ? for (int j = 0; j <= arr.length -1 - i; j++) {
? ? ? ? ? ? ? ? if (arr[j] > arr[j + 1]) {
? ? ? ? ? ? ? ? ? ? int temp;
? ? ? ? ? ? ? ? ? ? temp = arr[j];
? ? ? ? ? ? ? ? ? ? arr[j] = arr[j + 1];
? ? ? ? ? ? ? ? ? ? arr[j + 1] = temp;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? System.out.println(Arrays.toString(arr));
? ? }
}
5.字符串反轉(zhuǎn)
package com.wedoctor.str;
public class StrReverse {
? ? public? static? String getNewStr(String str){
? ? ? ? StringBuffer sb = new StringBuffer(str);
? ? ? ? String newStr = sb.reverse().toString();
? ? ? ? return newStr;
? ? }
? ? public static void main(String[] args) {
? ? ? ? System.out.println(getNewStr("thjymhr"));
? ? }
}
6.Btree簡單講一下
B樹(B-樹)是一種適合外查找的搜索樹,是一種平衡的多叉樹?
B樹的每個結(jié)點包含著結(jié)點的值和結(jié)點所處的位置
7.動態(tài)規(guī)劃 最大連續(xù)子序列和
package com.wedoctor;
import java.util.Arrays;
public class MaxSum {
? ? public static int findMax(int arr[]){
? ? ? ? if (arr.length == 1){
? ? ? ? ? ? return arr[0];
? ? ? ? }
? ? ? ? int mid = (arr.length) / 2;
? ? ? ? int[] leftArr = Arrays.copyOfRange(arr, 0, mid);
? ? ? ? int[] rightArr = Arrays.copyOfRange(arr, mid, arr.length);
? ? ? ? int lenLeft = findMax(leftArr);
? ? ? ? int lenRight = findMax(rightArr);
? ? ? ? int lenMid = maxInMid(leftArr, rightArr);
? ? ? ? int max = Math.max(Math.max(lenLeft,lenRight),lenMid);
? ? ? ? return max;
? ? }
? ? public static int maxInMid(int left[],int right[]){
? ? ? ? int maxLeft = 0;
? ? ? ? int maxRight = 0;
? ? ? ? int tmpLeft = 0;
? ? ? ? int tmpRight = 0;
? ? ? ? for (int i = 0;i< left.length;i++){
? ? ? ? ? ? tmpLeft = tmpLeft + left[left.length - 1 - i];
? ? ? ? ? ? maxLeft = Math.max(tmpLeft,maxLeft);
? ? ? ? }
? ? ? ? for (int i = 0;i< right.length;i++){
? ? ? ? ? ? tmpRight = tmpRight + right[i];
? ? ? ? ? ? maxRight = Math.max(tmpRight,maxRight);
? ? ? ? }
? ? ? ? return? maxRight + maxLeft;
? ? }
? ? public static void main(String[] args) {
? ? ? ? int arr[] = {3,-1,10};
? ? ? ? System.out.println(findMax(arr));
? ? }
}
8.二叉樹概念,特點及代碼實現(xiàn)
二叉樹是n(n>=0)個結(jié)點的有限集合,該集合或者為空集(稱為空二叉樹),或者由一個根結(jié)點和兩棵互不相交的、分別稱為根結(jié)點的左子樹和右子樹組成。
特點:
每個結(jié)點最多有兩顆子樹,所以二叉樹中不存在度大于2的結(jié)點。
左子樹和右子樹是有順序的,次序不能任意顛倒。
即使樹中某結(jié)點只有一棵子樹,也要區(qū)分它是左子樹還是右子樹。
實現(xiàn):
package com.wedoctor;
public class BinaryTreeNode {
? ? int data;
? ? BinaryTreeNode left;
? ? BinaryTreeNode right;
? ? BinaryTreeNode (int x) {
? ? ? ? data= x;
? ? }
? ? public BinaryTreeNode(int data, BinaryTreeNode left, BinaryTreeNode right) {
? ? ? ? this.data = data;
? ? ? ? this.left = left;
? ? ? ? this.right = right;
? ? }
? ? public int getData() {
? ? ? ? return data;
? ? }
? ? public void setData(int data) {
? ? ? ? this.data = data;
? ? }
? ? public BinaryTreeNode getLeft() {
? ? ? ? return left;
? ? }
? ? public void setLeft(BinaryTreeNode left) {
? ? ? ? this.left = left;
? ? }
? ? public BinaryTreeNode getRight() {
? ? ? ? return right;
? ? }
? ? public void setRight(BinaryTreeNode right) {
? ? ? ? this.right = right;
? ? }
}
9.鏈表
十五.Linux
1.怎么查看用戶組
2.怎么修改文件權(quán)限
3.常用的命令有哪些
4.怎么修改文本文件第一行字符
5.查看內(nèi)存
top
6.查看磁盤存儲情況
df -h
7.查看磁盤IO讀寫(yum install iotop安裝)
iotop
8.直接查看比較高的磁盤讀寫程序
iotop?-o
9.查看端口占用情況
netstat -tunlp | grep 端口號
10.查看報告系統(tǒng)運行時長及平均負載
uptime
11.查看進程
ps ?aux