大數(shù)據(jù)工程師面試題-這一篇就夠用了

Hadoop 常見面試題

  1. mr 工作原理 ☆☆☆☆
    mr 將得到的split 分配對應(yīng)的 task元镀,每個(gè)任務(wù)處理相對應(yīng)的 split爬骤,將 split 以 line 方式讀取每一行數(shù)據(jù),將數(shù)據(jù)依次讀取到100M(maprdeuce.task.io.sort.mb)的環(huán)形緩沖區(qū)讀取過程中一旦到達(dá)閾值(mapreduce.map.sort.spill.percent)80M進(jìn)行溢寫操作息尺,spiller線程溢寫到磁盤(mapreduce.cluster.local.dir)目錄中拢肆,期間會進(jìn)行kv分區(qū)(分區(qū)數(shù)由reduce數(shù)來決定)默認(rèn)使用hashpartition,再將分區(qū)中數(shù)據(jù)進(jìn)行key的排序(默認(rèn)排序規(guī)則是字典和升序)脚囊,如果設(shè)置了setCombinerClass 則會對每個(gè)分區(qū)中的數(shù)據(jù)進(jìn)行 combiner 操作,如果設(shè)置了output.compress壓縮格式會對溢寫的數(shù)據(jù)進(jìn)行壓縮桐磁,最后merge根據(jù)分區(qū)規(guī)則將數(shù)據(jù)歸并到同一個(gè)文件中等待reduce的拉取悔耘,nodemanger將啟動一個(gè)mapreduce_shuffle服務(wù)將數(shù)據(jù)以http方式拉取到reduce端,reduce處理階段當(dāng)達(dá)到閾值(默認(rèn)0.66)或map輸出數(shù)的閾值(默認(rèn)100)會進(jìn)行merge(同一分區(qū)的一組數(shù)據(jù)會先進(jìn)行歸并)|sort(將歸并好的數(shù)據(jù)進(jìn)行排序)|group(判斷迭代器中的元素是否可以迭代),處理完成mr將同一個(gè)分區(qū)內(nèi)的數(shù)據(jù)所意,在hdfs中以文件形式體現(xiàn)出來淮逊,幾個(gè)分區(qū)就會創(chuàng)建幾個(gè)文件。

其中reduce端的merge達(dá)到閾值會觸發(fā)扶踊,sort則是維持其map階段順序泄鹏,而group是設(shè)置( setGroupingComparatorClass)后才會觸發(fā)。

有效的理解mr工作流程可大大提升程序運(yùn)行效率秧耗,其中 mr 的 shuffle 也被稱為奇跡開始的地方

  1. split 機(jī)制 ☆☆☆☆☆
    spilit 是在mr 處理的map端之前產(chǎn)生的概念备籽,split切片大小,默認(rèn)等于block*1.1分井,在FileInputFormat中計(jì)算切片大小的邏輯:

blocksize:默認(rèn)是 128M车猬,可通過 dfs.blocksize 修改

minSize:默認(rèn)是 1,可通過 mapreduce.input.fileinputformat.split.minsize 修改

maxsize:默認(rèn)是 Long.MaxValue尺锚,可通過 mapreduce.input.fileinputformat.split.maxsize 修改

Hadoop FileInputFormat 源碼:

public static final String SPLIT_MAXSIZE = "mapreduce.input.fileinputformat.split.maxsize";
public static final String SPLIT_MINSIZE = "mapreduce.input.fileinputformat.split.minsize";

protected long computeSplitSize(long blockSize, long minSize, long maxSize) {
return Math.max(minSize, Math.min(maxSize, blockSize));
}
1
2
3
4
5
6
為什么split不是與block 一一對應(yīng)的珠闰?

大量小文件場景,map進(jìn)程造成資源嚴(yán)重浪費(fèi)瘫辩。

針對大小文件場景可以手動配置伏嗜。

  1. namenode,datanode,secondaryNameNode分別是干什么的?☆☆☆☆☆
    namenode伐厌,在基于主從架構(gòu)的hdfs文件系統(tǒng)中是主節(jié)點(diǎn)承绸,其主要職責(zé)就是對hdfs中的文件的元信息,副本數(shù)挣轨,文件目錄樹军熏,block 數(shù)據(jù)節(jié)點(diǎn)信息;

datanode卷扮,它是從節(jié)點(diǎn)也是數(shù)據(jù)節(jié)點(diǎn)荡澎,基于本地磁盤存儲 block(文件的形式),有相關(guān)數(shù)據(jù)塊的長度画饥、效驗(yàn)和衔瓮、時(shí)間戳,與namnode保持心跳抖甘,匯報(bào) block 狀態(tài)热鞍。

secondaryNameNode,檢查點(diǎn)節(jié)點(diǎn)衔彻,namenode 日志高可用的關(guān)鍵薇宠,其主要作用就是將namenode的元數(shù)據(jù)日志信息合并后備份,防止元數(shù)據(jù)丟失艰额。

元信息:是數(shù)據(jù)文件的block大小澄港,文件副本存儲位置,副本數(shù)量柄沮,block 數(shù)量回梧,主要體現(xiàn)在edits文件和fsimage文件废岂。

副本數(shù):hdfs 中同一個(gè)文件在多個(gè)節(jié)點(diǎn)中所存儲的總數(shù)量,也是實(shí)現(xiàn)持久化和保證安全性的關(guān)鍵狱意。

文件目錄樹:hdfs提供了一個(gè)可以維護(hù)的文件目錄湖苞,該文件目錄下存儲著有關(guān)所有hdfs的文件。

block 數(shù)據(jù)節(jié)點(diǎn)信息:如a文件在01和02節(jié)點(diǎn)中存儲详囤,該信息稱為數(shù)據(jù)節(jié)點(diǎn)信息财骨。

edits:記錄 client 執(zhí)行創(chuàng)建,移動,修改文件的信息,同時(shí)體現(xiàn)了 HDFS 的最新的狀態(tài)(二進(jìn)制文件)藏姐。

它分布在磁盤上的多個(gè)文件隆箩,名稱由前綴 edits 及后綴組成.后綴值是該文件包含的事務(wù) ID,同一時(shí)刻只有一個(gè)文件處于可讀寫狀態(tài).為避免數(shù)據(jù)丟失,事務(wù)完成后 client 端在執(zhí)行成功前,文件會進(jìn)行更新和同步,當(dāng) NN 向多個(gè)目錄寫數(shù)據(jù)時(shí),只有在所有操作更新并同步到每個(gè)副本之后執(zhí)行才成功。

fsimage:記錄的是數(shù)據(jù)塊的位置信息羔杨、數(shù)據(jù)塊的冗余信息(二進(jìn)制文件)

由于 edits 文件記錄了最新狀態(tài)信息捌臊,并且隨著操作越多,edits 文件就會越大兜材,把 edits 文件中最新的信息寫到 fsimage 文件中就解決了 edits 文件數(shù)量多不方便管理的情況娃属。

沒有體現(xiàn) HDFS 的最新狀態(tài)。

每個(gè) fsimage 文件都是文件系統(tǒng)元數(shù)據(jù)的一個(gè)完整的永久性的檢查點(diǎn)护姆。

為什么引入 secondaryNameNode矾端?

由于只有在重啟時(shí) fsimage 和 edits 才會進(jìn)行合并,得到一個(gè)新的 fsimage 文件卵皂,但是在實(shí)際生產(chǎn)環(huán)境中很少會重啟集群秩铆,NN 的重啟需要花費(fèi)很長時(shí)間,因?yàn)闀泻芏喔膭有枰喜⒌?fsimage 文件上,如果 NN 掛掉灯变,fsimage 文件沒有更新內(nèi)容殴玛,從而丟失很多改動。

但 editlog 日志大小會隨著時(shí)間變的越來越大添祸,導(dǎo)致系統(tǒng)重啟滚粟,根據(jù)日志恢復(fù)元數(shù)據(jù)的時(shí)間會越來越長;

為了避免這種情況刃泌,引入檢查點(diǎn)機(jī)制checkpoint凡壤,命名空間鏡像 fsimage 就是 HDFS 元數(shù)據(jù)的持久性檢查點(diǎn),即將內(nèi)存中的元數(shù)據(jù)落磁盤生成的文件耙替;

了解詳細(xì)可以訪問我另一個(gè)博客:hdfs詳細(xì)

https://blog.csdn.net/qq_43259670/article/details/105882983

  1. mr on yarn 工作原理 ☆☆☆☆☆
    1亚侠、向client端提交MapReduce job.

2、隨后yarn的ResourceManager進(jìn)行資源的分配.

3俗扇、由NodeManager進(jìn)行加載與監(jiān)控containers.

4硝烂、通過applicationMaster與ResourceManager進(jìn)行資源的申請及狀態(tài)的交互,由NodeManagers進(jìn)行MapReduce運(yùn)行時(shí)job的管理.

5铜幽、通過hdfs進(jìn)行job配置文件滞谢、jar包的各節(jié)點(diǎn)分發(fā)串稀。

  1. fsimage 和 edits 是干什么的?為什么要使用狮杨?☆☆☆☆
    edits:記錄 client 執(zhí)行創(chuàng)建,移動,修改文件的信息厨诸,同時(shí)體現(xiàn)了 HDFS 的最新的狀態(tài)(二進(jìn)制文件)。

它分布在磁盤上的多個(gè)文件禾酱,名稱由前綴 edits 及后綴組成.后綴值是該文件包含的事務(wù) ID,同一時(shí)刻只有一個(gè)文件處于可讀寫狀態(tài).為避免數(shù)據(jù)丟失,事務(wù)完成后 client 端在執(zhí)行成功前,文件會進(jìn)行更新和同步,當(dāng) NN 向多個(gè)目錄寫數(shù)據(jù)時(shí),只有在所有操作更新并同步到每個(gè)副本之后執(zhí)行才成功。

fsimage:記錄的是數(shù)據(jù)塊的位置信息绘趋、數(shù)據(jù)塊的冗余信息(二進(jìn)制文件)

由于 edits 文件記錄了最新狀態(tài)信息颤陶,并且隨著操作越多,edits 文件就會越大陷遮,把 edits 文件中最新的信息寫到 fsimage 文件中就解決了 edits 文件數(shù)量多不方便管理的情況滓走。

沒有體現(xiàn) HDFS 的最新狀態(tài)。

每個(gè) fsimage 文件都是文件系統(tǒng)元數(shù)據(jù)的一個(gè)完整的永久性的檢查點(diǎn)帽馋。

為什么使用搅方?

NN 使用了 FsImage+EditLog 整合的方案;

滾動將增量的 EditLog 更新到 FsImage绽族,以保證更近時(shí)點(diǎn)的 FsImage 和更小的 EditLog 體積

  1. hdfs 工作原理 ☆☆☆☆
    一般就是讀寫的工作流程姨涡,因?yàn)閔dfs 主要還是對文件存儲與讀寫。

讀流程:

client端創(chuàng)建一個(gè)代理對象與namenode進(jìn)行rpc通信吧慢,拿到namenode對象后請求獲取文件的元信息涛漂,namenode效驗(yàn)無誤后將元信息返回,client獲取到元信息之后根據(jù)元信息讀取相應(yīng)datanode的block塊检诗,將block合并成一個(gè)文件進(jìn)行返回匈仗。

寫流程:

client端創(chuàng)建一個(gè)代理對象與namenode進(jìn)行rpc通信,拿到namenode對象后請求創(chuàng)建文件的元信息逢慌,namenode觸發(fā)副本放置策略悠轩,返回元數(shù)據(jù)信息,client和datanode建立piepline連接攻泼,client將packet放入一個(gè)隊(duì)列中火架,并向第一個(gè)datanode發(fā)送packet這一過程中上游節(jié)點(diǎn)同時(shí)發(fā)送下一個(gè)packet,當(dāng) block 傳輸完成忙菠,DN 們各自向 NN 匯報(bào)距潘,同時(shí) Client 繼續(xù)傳輸下一個(gè) block所以,Client 的傳輸和 block 的匯報(bào)也是并行的

  1. block 副本放置策略 ☆☆☆
    1.x

第一個(gè)副本:放置在上傳文件的 DataNode只搁;如果時(shí)集群外提交音比,則隨機(jī)挑選一臺磁盤不太滿,CPU 不太忙的節(jié)點(diǎn)氢惋。
第二個(gè)副本:放置在于第一個(gè)副本不同的機(jī)架的節(jié)點(diǎn)上洞翩。
第三個(gè)副本:與第一個(gè)副本相同機(jī)架的節(jié)點(diǎn)稽犁。
更多副本:隨機(jī)節(jié)點(diǎn)
可能產(chǎn)生的問題是前兩個(gè)副本在同一機(jī)架當(dāng)機(jī)架出現(xiàn)問題時(shí)會丟失兩個(gè)副本

2.x

第一個(gè)副本:放置在上傳文件的 DataNode;如果時(shí)集群外提交骚亿,則隨機(jī)挑選一臺磁盤不太滿已亥,CPU 不太忙的節(jié)點(diǎn)。
第二個(gè)副本:放置在于第一個(gè)副本不同的機(jī)架的節(jié)點(diǎn)上来屠。
第三個(gè)副本:與第二個(gè)副本相同機(jī)架的節(jié)點(diǎn)虑椎。
更多副本:隨機(jī)節(jié)點(diǎn)
了解詳細(xì)可以訪問我另一個(gè)博客:hdfs詳細(xì)

https://blog.csdn.net/qq_43259670/article/details/105882983

Hive 常見面試題

  1. 簡述Hive工作原理 ☆☆☆☆☆
    1、執(zhí)行查詢:Hive接口俱笛,命令行或 web UI發(fā)送查詢驅(qū)動程序

2捆姜、get Plan:驅(qū)動程序查詢編譯器

3、詞法分析/語法分析

4迎膜、語義分析

5泥技、邏輯計(jì)劃產(chǎn)生

6、邏輯計(jì)劃優(yōu)化

7磕仅、物理計(jì)劃生成

8珊豹、物理計(jì)劃優(yōu)化

9、物理計(jì)劃執(zhí)行

10榕订、查詢結(jié)果返回

提示:以上是hive的大致工作原理流程店茶,一般面試問到這里就算比較深入了

  1. hive 內(nèi)部表和外部表區(qū)別 ☆☆☆☆☆
    創(chuàng)建表時(shí):創(chuàng)建內(nèi)部表時(shí),會將數(shù)據(jù)移動到數(shù)據(jù)倉庫指向的路徑劫恒;若創(chuàng)建外部表忽妒,僅記錄數(shù)據(jù)所在的路徑, 不對數(shù)據(jù)的位置做任何改變兼贸。

刪除表時(shí):在刪除表的時(shí)候段直,內(nèi)部表的元數(shù)據(jù)和數(shù)據(jù)會被一起刪除, 而外部表只刪除元數(shù)據(jù)溶诞,不刪除數(shù)據(jù)鸯檬。這樣外部表相對來說更加安全些,數(shù)據(jù)組織也更加靈活螺垢,方便共享源數(shù)據(jù)喧务。

提示:內(nèi)部表與外部表的區(qū)別一定要掌握,通常情況下我們都會使用外部表保證數(shù)據(jù)安全性枉圃,但是像中間表功茴,結(jié)果表這種我們就會考慮使用內(nèi)部表(管理表)

  1. 分區(qū)和分桶的區(qū)別 ☆☆☆☆
    3.1 分區(qū)
    是指按照數(shù)據(jù)表的某列或某些列分為多個(gè)區(qū),區(qū)從形式上可以理解為文件夾孽亲,比如我們要收集某個(gè)大型網(wǎng)站的日志數(shù)據(jù)坎穿,一個(gè)網(wǎng)站每天的日志數(shù)據(jù)存在同一張表上,由于每天會生成大量的日志,導(dǎo)致數(shù)據(jù)表的內(nèi)容巨大玲昧,在查詢時(shí)進(jìn)行全表掃描耗費(fèi)的資源非常多栖茉。

那其實(shí)這個(gè)情況下,我們可以按照日期對數(shù)據(jù)表進(jìn)行分區(qū)孵延,不同日期的數(shù)據(jù)存放在不同的分區(qū)吕漂,在查詢時(shí)只要指定分區(qū)字段的值就可以直接從該分區(qū)查找

3.2 分桶
分桶是相對分區(qū)進(jìn)行更細(xì)粒度的劃分。

分桶將整個(gè)數(shù)據(jù)內(nèi)容安裝某列屬性值得hash值進(jìn)行區(qū)分尘应,如要按照name屬性分為3個(gè)桶惶凝,就是對name屬性值的hash值對3取摸,按照取模結(jié)果對數(shù)據(jù)分桶犬钢。

如取模結(jié)果為0的數(shù)據(jù)記錄存放到一個(gè)文件苍鲜,取模為1的數(shù)據(jù)存放到一個(gè)文件,取模為2的數(shù)據(jù)存放到一個(gè)文件

總結(jié):分區(qū)就是在hdfs上分目錄(文件夾)娜饵,分桶就是分文件。

  1. 將數(shù)據(jù)直接上傳到分區(qū)目錄(hdfs)上官辈,讓分區(qū)表和數(shù)據(jù)產(chǎn)生關(guān)聯(lián)有哪些方式箱舞?☆☆
    方案一:上傳數(shù)據(jù)后修復(fù)表
    dfs -mkdir -p 分區(qū)目錄
    dfs -put 分區(qū)目錄
    msck repair table 表名
    方案二:上傳數(shù)據(jù)后添加分區(qū)
    dfs -mkdir -p 分區(qū)目錄
    dfs -put 分區(qū)目錄
    alter table 表名 add partition();

提示:這里我們?nèi)绻苯訉⑿碌姆謪^(qū)文件上傳到hdfs上,因?yàn)閔ive沒有對應(yīng)的元數(shù)據(jù)所以是無法查詢到數(shù)據(jù)的拳亿,所以我們要進(jìn)行表修復(fù)或者添加分區(qū)晴股。

  1. 桶表是否可以通過直接load將數(shù)據(jù)導(dǎo)入?☆☆
    不可以肺魁,因?yàn)閘oad數(shù)據(jù)的話hdfs下只會有一個(gè)文件無法完成分桶的效果电湘,分桶和mapredue中的分區(qū)是一樣的道理,所以我們要借助中間表導(dǎo)入數(shù)據(jù)鹅经。

  2. order by,sort by,distribute by,cluster by的區(qū)別寂呛?☆☆☆☆
    order by會對所給的全部數(shù)據(jù)進(jìn)行全局排序 ,不管來多少數(shù)據(jù)瘾晃,都只啟動一個(gè)reducer來處理 贷痪。

sort by是局部排序 ,sort by會根據(jù)數(shù)據(jù)量的大小啟動一到多個(gè)reducer來干活蹦误,并且劫拢,它會在進(jìn)入reduce之前為每個(gè)reducer都產(chǎn)生一個(gè)排序文件 。

distribute by 控制map結(jié)果的分發(fā)强胰,它會將具有相同字段的map輸出分發(fā)到一個(gè)reduce節(jié)點(diǎn)上做處理 舱沧。

cluster by 可以理解為一個(gè)特殊的distribute by和sort by的結(jié)合,當(dāng)distribute by和sort by后面所跟的列名相同時(shí)偶洋,就等同于直接使用cluster by 跟上該列名熟吏。但是被cluster by指定的列最終的排序結(jié)果只能是降序,而且無法指定asc和desc玄窝。

提示:這個(gè)問題面試問的頻率很高分俯,大家一定要注意區(qū)分以下肾筐。

  1. 聚合函數(shù)是否可以寫在order by后面,為什么缸剪?☆☆☆☆
    不可以吗铐。

原因:執(zhí)行順序!P咏凇唬渗!order by的執(zhí)行順序在select之后,所以需使用重新定義的列名進(jìn)行排序奋渔。

提示:理解sql的執(zhí)行順序更加有利于大家寫sql

(1)from

(2)join

(3)on

(4)where

(5)select

(6)group by

(7)having

(8)order by

(9)limit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

  1. 導(dǎo)致數(shù)據(jù)傾斜的原因有哪些镊逝,有什么解決的方案?☆☆☆☆☆
    什么是數(shù)據(jù)傾斜嫉鲸?
    數(shù)據(jù)傾斜就是數(shù)據(jù)的分布不平衡撑蒜,某些地方特別多,某些地方又特別少玄渗,導(dǎo)致的在處理數(shù)據(jù)的時(shí)候座菠,有些很快就處理完了,而有些又遲遲未能處理完藤树,導(dǎo)致整體任務(wù)最終遲遲無法完成浴滴,這種現(xiàn)象就是數(shù)據(jù)傾斜。

針對mapreduce的過程來說就是岁钓,有多個(gè)reduce升略,其中有一個(gè)或者若干個(gè)reduce要處理的數(shù)據(jù)量特別大,而其他的reduce處理的數(shù)據(jù)量則比較小屡限,那么這些數(shù)據(jù)量小的reduce很快就可以完成品嚣,而數(shù)據(jù)量大的則需要很多時(shí)間雌隅,導(dǎo)致整個(gè)任務(wù)一直在等它而遲遲無法完成是晨。
跑mr任務(wù)時(shí)常見的reduce的進(jìn)度總是卡在99%,這種現(xiàn)象很大可能就是數(shù)據(jù)傾斜造成的遵倦。

造成數(shù)據(jù)傾斜的原因
比如某些業(yè)務(wù)數(shù)據(jù)作為key的字段本就很集中拓型,那么結(jié)果肯定會導(dǎo)致數(shù)據(jù)傾斜啊额嘿。
還有其他的一些原因,但是劣挫,根本原因還是key的分布不均勻册养,而其他的原因就是會造成key不均勻,進(jìn)而導(dǎo)致數(shù)據(jù)傾斜的后果压固,所以說根本原因是key的分布不均勻球拦。

既然有數(shù)據(jù)傾斜這種現(xiàn)象,就必須要有數(shù)據(jù)傾斜對應(yīng)的處理方案啊。
簡單地說數(shù)據(jù)傾斜這種現(xiàn)象導(dǎo)致的任務(wù)遲遲不能完成坎炼,耗費(fèi)了太多時(shí)間愧膀,極大地影響了性能,所以我們數(shù)據(jù)傾斜的解決方案設(shè)計(jì)思路就是往如何提高性能谣光,即如何縮短任務(wù)的處理時(shí)間這方面考慮的檩淋,而要提高性能,就要讓key分布相對均衡萄金,所以我們的終極目標(biāo)就是考慮如何預(yù)處理數(shù)據(jù)才能夠使得它的key分布均勻蟀悦。

你是如何發(fā)現(xiàn)Hive數(shù)據(jù)傾斜?
通過 yarn 監(jiān)控平臺的 task 信息查看到有個(gè)別的 task 執(zhí)行時(shí)間過于緩慢氧敢,甚至還會掛掉日戈。

解決辦法
1 合理設(shè)置Map數(shù)
1) 通常情況下,作業(yè)會通過input的目錄產(chǎn)生一個(gè)或者多個(gè)map任務(wù)孙乖。

主要的決定因素有:input的文件總個(gè)數(shù)浙炼,input的文件大小,集群設(shè)置的文件塊大小唯袄。

舉例:
a) 假設(shè)input目錄下有1個(gè)文件a弯屈,大小為780M,那么hadoop會將該文件a分隔成7個(gè)塊(6個(gè)128m的塊和1個(gè)12m的塊)越妈,從而產(chǎn)生7個(gè)map數(shù)季俩。
b) 假設(shè)input目錄下有3個(gè)文件a钮糖,b梅掠,c大小分別為10m,20m店归,150m阎抒,那么hadoop會分隔成4個(gè)塊(10m,20m消痛,128m且叁,22m),從而產(chǎn)生4個(gè)map數(shù)秩伞。即逞带,如果文件大于塊大小(128m),那么會拆分纱新,如果小于塊大小展氓,則把該文件當(dāng)成一個(gè)塊。

1
2
3
4
5
6
2) 是不是map數(shù)越多越好脸爱?

答案是否定的遇汞。如果一個(gè)任務(wù)有很多小文件(遠(yuǎn)遠(yuǎn)小于塊大小128m),則每個(gè)小文件也會被當(dāng)做一個(gè)塊,用一個(gè)map任務(wù)來完成空入,而一個(gè)map任務(wù)啟動和初始化的時(shí)間遠(yuǎn)遠(yuǎn)大于邏輯處理的時(shí)間络它,就會造成很大的資源浪費(fèi)。而且歪赢,同時(shí)可執(zhí)行的map數(shù)是受限的化戳。
1
3) 是不是保證每個(gè)map處理接近128m的文件塊,就高枕無憂了轨淌?

答案也是不一定迂烁。比如有一個(gè)127m的文件,正常會用一個(gè)map去完成递鹉,但這個(gè)文件只有一個(gè)或者兩個(gè)小字段盟步,卻有幾千萬的記錄,如果map處理的邏輯比較復(fù)雜躏结,用一個(gè)map任務(wù)去做却盘,肯定也比較耗時(shí)。

針對上面的問題2和3媳拴,我們需要采取兩種方式來解決:即減少map數(shù)和增加map數(shù)黄橘;

1
2
3
4
2 小文件合并
在map執(zhí)行前合并小文件,減少map數(shù):

CombineHiveInputFormat 具有對小文件進(jìn)行合并的功能(系統(tǒng)默認(rèn)的格式)

set mapred.max.split.size=112345600;
set mapred.min.split.size.per.node=112345600;
set mapred.min.split.size.per.rack=112345600;
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
1
2
3
4
這個(gè)參數(shù)表示執(zhí)行前進(jìn)行小文件合并屈溉,前面三個(gè)參數(shù)確定合并文件塊的大小塞关,大于文件塊大小128m的,按照128m來分隔子巾,小于128m帆赢,大于100m的,按照100m來分隔线梗,把那些小于100m的(包括小文件和分隔大文件剩下的)椰于,進(jìn)行合并。

3 復(fù)雜文件增加Map數(shù)
當(dāng)input的文件都很大仪搔,任務(wù)邏輯復(fù)雜瘾婿,map執(zhí)行非常慢的時(shí)候,可以考慮增加Map數(shù)烤咧,來使得每個(gè)map處理的數(shù)據(jù)量減少偏陪,從而提高任務(wù)的執(zhí)行效率。

增加map的方法為

根據(jù) computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))公式
調(diào)整maxSize最大值煮嫌。讓maxSize最大值低于blocksize就可以增加map的個(gè)數(shù)笛谦。
mapreduce.input.fileinputformat.split.minsize=1 默認(rèn)值為1

mapreduce.input.fileinputformat.split.maxsize=Long.MAXValue 默認(rèn)值Long.MAXValue因此,默認(rèn)情況下立膛,切片大小=blocksize

maxsize(切片最大值): 參數(shù)如果調(diào)到比blocksize小揪罕,則會讓切片變小梯码,而且就等于配置的這個(gè)參數(shù)的值。

minsize(切片最小值): 參數(shù)調(diào)的比blockSize大好啰,則可以讓切片變得比blocksize還大轩娶。

1
2
3
4
5
6
7
8
例如
--設(shè)置maxsize大小為10M,也就是說一個(gè)fileSplit的大小為10M
set mapreduce.input.fileinputformat.split.maxsize=10485760;
1
2
4 合理設(shè)置Reduce數(shù)
1框往、調(diào)整reduce個(gè)數(shù)方法一

1)每個(gè)Reduce處理的數(shù)據(jù)量默認(rèn)是256MB

set hive.exec.reducers.bytes.per.reducer=256000000;
1
2)每個(gè)任務(wù)最大的reduce數(shù)鳄抒,默認(rèn)為1009

set hive.exec.reducers.max=1009;
1
3)計(jì)算reducer數(shù)的公式

N=min(參數(shù)2,總輸入數(shù)據(jù)量/參數(shù)1)
1
2椰弊、調(diào)整reduce個(gè)數(shù)方法二

--設(shè)置每一個(gè)job中reduce個(gè)數(shù)
set mapreduce.job.reduces=3;
1
2
3许溅、reduce個(gè)數(shù)并不是越多越好

過多的啟動和初始化reduce也會消耗時(shí)間和資源;

同時(shí)過多的reduce會生成很多個(gè)文件秉版,也有可能出現(xiàn)小文件問題

總的來說就是贤重,數(shù)據(jù)傾斜的根源是key分布不均勻,所以應(yīng)對方案要么是從源頭解決(不讓數(shù)據(jù)分區(qū)清焕,直接在map端搞定)并蝗,要么就是在分區(qū)時(shí)將這些集中卻無效的key過濾(清洗)掉,或者是想辦法將這些key打亂(給key加上標(biāo)簽)秸妥,讓它們進(jìn)入到不同的reduce中滚停。

  1. Hive的四種排序 ☆☆☆
    order by
    order by 會對輸入做全局排序,因此只有一個(gè)reducer(多個(gè)reducer無法保證全局有序)
    只有一個(gè)reducer粥惧,會導(dǎo)致當(dāng)輸入規(guī)模比較大時(shí)键畴,需要較長的時(shí)間。
    set hive.mapred.mode=nonstrict; (default value / 默認(rèn)值)
    set hive.mapred.mode=strict;
    order by 和數(shù)據(jù)庫中的order by功能一致按照某一項(xiàng)&幾項(xiàng)排序輸出突雪。
    與數(shù)據(jù)庫中order by的區(qū)別在于hive.mapred.mode = strict模式下 必須指定limit否則執(zhí)行會報(bào)錯(cuò)
    原因:在order by狀態(tài)下所有的數(shù)據(jù)都會到一臺服務(wù)器進(jìn)行reduce操作也就是只有一個(gè)reduce起惕, 如果在數(shù)據(jù)量大的情況下會出現(xiàn)無果的情況,如果進(jìn)行l(wèi)imit n挂签,那只有n * map
    number 條記錄而已疤祭。只有一個(gè)reduce也可以出來里過來

sort by
sort by不是全局排序盼产,其在數(shù)據(jù)進(jìn)入reducer前完成排序
因此饵婆,如果用sort by進(jìn)行排序,并且設(shè)置mapred.reduce.tasks>1戏售,則sort by只保證每個(gè)reducer 的輸出有序侨核,不保證全局有序。
sort by 不受hive.mapred.mode是否為strict灌灾,nostrict的影響搓译。
sort by的數(shù)據(jù)只能保證在同一個(gè)reduce中的數(shù)據(jù)可以按指定字段排序。
使用sort by你可以指定執(zhí)行的reduce個(gè)數(shù)(set mapred.reduce.tasks=)锋喜,對輸出的 數(shù)據(jù)在執(zhí)行歸并排序些己,即可以得到全部結(jié)果豌鸡。
注意:可以用limit子句大大減少數(shù)據(jù)量。使用limit n后段标,傳輸?shù)絩educe端(單機(jī))的數(shù)據(jù)記錄就 減少到n*(map個(gè)數(shù))涯冠。否則由于數(shù)據(jù)過大可能出不了結(jié)果。

distribute by
按照指定的字段對數(shù)據(jù)進(jìn)行劃分到不同的輸出reduce / 文件中逼庞。
insert overwrite local directory ‘/home/hadoop/out’ select * from test order by name

distribute by length(name);
此方法會根據(jù)name的長度劃分到不同的reduce中蛇更,最終輸出到不同的文件中。
length 是內(nèi)建函數(shù)赛糟,也可以指定其他的函數(shù)或這使用自定義函數(shù)派任。

Cluster By
cluster by 除了具有 distribute by 的功能外還兼具 sort by 的功能。
但是排序只能是倒序排序璧南,不能指定排序規(guī)則為asc 或者desc掌逛。

  1. Hive的分區(qū)分桶 ☆☆☆☆☆
    我們發(fā)現(xiàn)其實(shí)桶的概念就是MapReduce的分區(qū)的概念,兩者完全相同司倚。物理上每個(gè)桶就是目錄里的一個(gè)文件颤诀,一個(gè)作業(yè)產(chǎn)生的桶(輸出文件)數(shù)量和reduce任務(wù)個(gè)數(shù)相同。

而分區(qū)表的概念对湃,則是新的概念崖叫。分區(qū)代表了數(shù)據(jù)的倉庫,也就是文件夾目錄拍柒。每個(gè)文件夾下面可以放不同的數(shù)據(jù)文件心傀。通過文件夾可以查詢里面存放的文件。但文件夾本身和數(shù)據(jù)的內(nèi)容毫無關(guān)系拆讯。

桶則是按照數(shù)據(jù)內(nèi)容的某個(gè)值進(jìn)行分桶脂男,把一個(gè)大文件散列稱為一個(gè)個(gè)小文件。 這些小文件可以單獨(dú)排序种呐。如果另外一個(gè)表也按照同樣的規(guī)則分成了一個(gè)個(gè)小文件宰翅。兩個(gè)表join的時(shí)候,就不必要掃描整個(gè)表爽室,只需要匹配相同分桶的數(shù)據(jù)即可汁讼。效率當(dāng)然大大提升。

同樣阔墩,對數(shù)據(jù)抽樣的時(shí)候嘿架,也不需要掃描整個(gè)文件。只需要對每個(gè)分區(qū)按照相同規(guī)則抽取一部分?jǐn)?shù) 據(jù)即可啸箫。

? 分區(qū)表
如果在建表時(shí)使用了 PARTITIONED BY耸彪,表即為分區(qū)表。分區(qū)表下的數(shù)據(jù)按分區(qū)鍵的值(或值的范圍)放在HDFS下的不同目錄中忘苛,可以有效減少查詢時(shí)掃描的數(shù)據(jù)量蝉娜,提升查詢效率唱较。
? 非分區(qū)表
非分區(qū)表即除分區(qū)表之外的表。
按表是否分桶分類
按表是否分桶可以將表分為兩類:分桶表和非分桶表召川。
? 分桶表
如果在建表時(shí)使用了 CLUSTERED BY … INTO … BUCKETS绊汹,表即為分桶表。分桶表下的數(shù)據(jù)按
分桶鍵的哈希值放在HDFS下的不同目錄中扮宠,可以有效減少查詢時(shí)掃描的數(shù)據(jù)量西乖,提升查詢效率。
? 非分桶表
非分桶表即除分桶表之外的表

  1. hive中分區(qū)可以提高查詢效率坛增,分區(qū)是否越多越好获雕,為什么?☆☆☆
    1.hive如果有過多的分區(qū)收捣,由于底層是存儲在HDFS上届案,HDFS上只用于存儲大文件 而非小文件,因?yàn)檫^多的分區(qū)會增加namenode的負(fù)擔(dān)罢艾。

2.hive會轉(zhuǎn)化為mapreduce楣颠,mapreduce會轉(zhuǎn)化為多個(gè)task。過多小文件的話咐蚯,每個(gè)文件一個(gè)task童漩,每個(gè)task一個(gè)JVM實(shí)例,JVM的開啟與銷毀會降低系統(tǒng)效率春锋。

注意:合理的分區(qū)不應(yīng)該有過多的分區(qū)和文件目錄矫膨,并且每個(gè)目錄下的文件應(yīng)該足夠大

  1. hive 調(diào)優(yōu) ☆☆☆☆☆
    12.1 hive-site.xml 與 hive cli 調(diào)參 ☆☆☆☆☆
    <configuration>
    <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://bd01:3306/hive?createDatabaseIfNotExist=true</value>
    <description>JDBC connect string for a JDBC metastore</description>
    </property>

    <property>
    <name>hive.execution.engine</name>
    <value>spark</value>
    </property>

    <property>
    <name>ngmr.partition.automerge</name>
    <value>true</value>
    </property>

    <property>
    <name>ngmr.partition.mergesize.mb</name>
    <value>3</value>
    </property>

    <property>
    <name>hive.merge.sparkfiles</name>
    <value>true</value>
    </property>

    <property>
    <name>hive.map.agg</name>
    <value>true</value>
    </property>

    <property>
    <name>hive.vectorized.execution.enabled</name>
    <value>true</value>
    </property>
<!--    cbo可以優(yōu)化hive的每次查詢-->
<property>
    <name>hive.cbo.enable</name>
    <value>true</value>
</property>
<property>
    <name>hive.stats.fetch.column.stats</name>
    <value>true</value>
</property>
<property>
    <name>hive.stats.fetch.partition.stats</name>
    <value>true</value>
</property>
<property>
    <name>hive.compute.query.using.stats</name>
    <value>true</value>
</property>

<!--    開啟數(shù)據(jù)壓縮-->
<property>
    <name>hive.exec.compress.intermediate</name>
    <value>true</value>
</property>
<property>
    <name>hive.exec.compress.output</name>
    <value>true</value>
</property>
<!--    使簡單的sql語句不執(zhí)行spark引擎-->
<property>
    <name>hive.fetch.task.conversion</name>
    <value>more</value>
</property>
<!--    有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡
group by操作是否允許數(shù)據(jù)傾斜,默認(rèn)是false期奔,當(dāng)設(shè)置為true時(shí)侧馅,執(zhí)行計(jì)劃會生成兩個(gè)map/reduce作業(yè),第一個(gè)MR中會將map的結(jié)果隨機(jī)分布到reduce中呐萌,達(dá)到負(fù)載均衡的目的來解決數(shù)據(jù)傾斜馁痴,
-->
<property>
    <name>hive.groupby.skewindata</name>
    <value>true</value>
</property>
<!--    列裁剪,默認(rèn)開啟true肺孤,在做查詢時(shí)只讀取用到的列罗晕,這個(gè)是個(gè)有用的優(yōu)化;-->
<property>
    <name>hive.optimize.cp</name>
    <value>true</value>
</property>
<!--jvm重用-->
<property>
    <name>mapreduce.job.jvm.numtasks</name>
    <value>10</value>
    <description>How many tasks to run per jvm. If set to -1, there is no limit.</description>
</property>
<property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    <description>Driver class name for a JDBC metastore</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
    <description>username to use against metastore database</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>root</value>
    <description>password to use against metastore database</description>
</property>

</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
hive cli 中設(shè)置調(diào)優(yōu)參數(shù)

// 合并 block 減少 task 數(shù)量
set ngmr.partition.automerge = true;
// jvm 重用
set mapreduce.job.jvm.numtasks=10;
// 表示將 n 個(gè) block 安排給單個(gè)線程處理渠旁。
set ngmr.partition.mergesize.mb =3;
// 開啟小文件合并
set hive.merge.sparkfiles = true;
// 開啟小文件合并
set hive.map.agg = true;
// 使用向量化查詢
set hive.vectorized.execution.enabled = true;
// cbo可以優(yōu)化hive的每次查詢
set hive.cbo.enable = true;
set hive.stats.fetch.column.stats = true;
set hive.stats.fetch.partition.stats = true;
set hive.compute.query.using.stats = true;

// 開啟數(shù)據(jù)壓縮
set hive.exec.compress.intermediate = true;
set hive.exec.compress.output = true;
// 有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡group by操作是否允許數(shù)據(jù)傾斜攀例,默認(rèn)是false船逮,當(dāng)設(shè)置為true時(shí)顾腊,執(zhí)行計(jì)劃會生成兩個(gè)map/reduce作業(yè),第一個(gè)MR中會將map的結(jié)果隨機(jī)分布到reduce中挖胃,達(dá)到負(fù)載均衡的目的來解決數(shù)據(jù)傾斜杂靶,
set hive.groupby.skewindata = true;
// 列裁剪梆惯,默認(rèn)開啟true,在做查詢時(shí)只讀取用到的列吗垮,這個(gè)是個(gè)有用的優(yōu)化垛吗;
set hive.optimize.cp = true;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
12.2 數(shù)據(jù)壓縮 ☆☆☆☆☆
12.2.1 數(shù)據(jù)的壓縮說明
壓縮模式評價(jià)

可使用以下三種標(biāo)準(zhǔn)對壓縮方式進(jìn)行評價(jià)
1、壓縮比:壓縮比越高烁登,壓縮后文件越小怯屉,所以壓縮比越高越好
2、壓縮時(shí)間:越快越好
3饵沧、已經(jīng)壓縮的格式文件是否可以再分割:可以分割的格式允許單一文件由多個(gè)Mapper程序處理锨络,可以更好的并行化
常見壓縮格式

壓縮方式 壓縮比 壓縮速度 解壓縮速度 是否可分割
gzip 13.4% 21 MB/s 118 MB/s 否
bzip2 13.2% 2.4MB/s 9.5MB/s 是
lzo 20.5% 135 MB/s 410 MB/s 是
snappy 22.2% 172 MB/s 409 MB/s 否
Hadoop編碼/解碼器方式
壓縮格式 對應(yīng)的編碼/解碼器
DEFLATE org.apache.hadoop.io.compress.DefaultCodec
Gzip org.apache.hadoop.io.compress.GzipCodec
BZip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compress.lzo.LzopCodec
Snappy org.apache.hadoop.io.compress.SnappyCodec
壓縮性能的比較
1
壓縮算法 原始文件大小 壓縮文件大小 壓縮速度 解壓速度
gzip 8.3GB 1.8GB 17.5MB/s 58MB/s
bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s
LZO 8.3GB 2.9GB 49.3MB/s 74.6MB/s
http://google.github.io/snappy/

On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.

12.2.2 壓縮配置參數(shù)
要在Hadoop中啟用壓縮,可以配置如下參數(shù)(mapred-site.xml文件中):

參數(shù) 默認(rèn)值 階段 建議
io.compression.codecs (在core-site.xml中配置) org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.BZip2Codec, org.apache.hadoop.io.compress.Lz4Codec 輸入壓縮 Hadoop使用文件擴(kuò)展名判斷是否支持某種編解碼器
mapreduce.map.output.compress false mapper輸出 這個(gè)參數(shù)設(shè)為true啟用壓縮
mapreduce.map.output.compress.codec org.apache.hadoop.io.compress.DefaultCodec mapper輸出 使用LZO狼牺、LZ4或snappy編解碼器在此階段壓縮數(shù)據(jù)
mapreduce.output.fileoutputformat.compress false reducer輸出 這個(gè)參數(shù)設(shè)為true啟用壓縮
mapreduce.output.fileoutputformat.compress.codec org.apache.hadoop.io.compress. DefaultCodec reducer輸出 使用標(biāo)準(zhǔn)工具或者編解碼器羡儿,如gzip和bzip2
mapreduce.output.fileoutputformat.compress.type RECORD
12.3 文件壓縮 ☆☆☆☆☆
Hive支持的存儲數(shù)的格式主要有:TEXTFILE(行式存儲) 、SEQUENCEFILE(行式存儲)是钥、ORC(列式存儲)掠归、PARQUET(列式存儲)。

12.3.1 列式存儲和行式存儲

上圖左邊為邏輯表悄泥,右邊第一個(gè)為行式存儲虏冻,第二個(gè)為列式存儲。

行存儲的特點(diǎn): 查詢滿足條件的一整行數(shù)據(jù)的時(shí)候弹囚,列存儲則需要去每個(gè)聚集的字段找到對應(yīng)的每個(gè)列的值兄旬,行存儲只需要找到其中一個(gè)值,其余的值都在相鄰地方余寥,所以此時(shí)行存儲查詢的速度更快领铐。select *

列存儲的特點(diǎn): 因?yàn)槊總€(gè)字段的數(shù)據(jù)聚集存儲,在查詢只需要少數(shù)幾個(gè)字段的時(shí)候宋舷,能大大減少讀取的數(shù)據(jù)量绪撵;每個(gè)字段的數(shù)據(jù)類型一定是相同的,列式存儲可以針對性的設(shè)計(jì)更好的設(shè)計(jì)壓縮算法祝蝠。 select 某些字段效率更高

TEXTFILE和SEQUENCEFILE的存儲格式都是基于行存儲的音诈;

ORC和PARQUET是基于列式存儲的。

12.3.2 TEXTFILE格式
默認(rèn)格式绎狭,數(shù)據(jù)不做壓縮细溅,磁盤開銷大,數(shù)據(jù)解析開銷大儡嘶±模可結(jié)合Gzip、Bzip2使用(系統(tǒng)自動檢查蹦狂,執(zhí)行查詢時(shí)自動解壓)誓篱,但使用這種方式朋贬,hive不會對數(shù)據(jù)進(jìn)行切分,從而無法對數(shù)據(jù)進(jìn)行并行操作窜骄。

12.3.3 ORC格式
Orc (Optimized Row Columnar)是hive 0.11版里引入的新的存儲格式锦募。

可以看到每個(gè)Orc文件由1個(gè)或多個(gè)stripe組成,每個(gè)stripe250MB大小邻遏,這個(gè)Stripe實(shí)際相當(dāng)于RowGroup概念糠亩,不過大小由4MB->250MB,這樣能提升順序讀的吞吐率准验。每個(gè)Stripe里有三部分組成削解,分別是Index Data,Row Data,Stripe Footer:

一個(gè)orc文件可以分為若干個(gè)Stripe

一個(gè)stripe可以分為三個(gè)部分

indexData:某些列的索引數(shù)據(jù)

rowData :真正的數(shù)據(jù)存儲

StripFooter:stripe的元數(shù)據(jù)信息

1)Index Data:一個(gè)輕量級的index,默認(rèn)是每隔1W行做一個(gè)索引沟娱。這里做的索引只是記錄某行的各字段在Row Data中的offset氛驮。

2)Row Data:存的是具體的數(shù)據(jù),先取部分行济似,然后對這些行按列進(jìn)行存儲矫废。對每個(gè)列進(jìn)行了編碼,分成多個(gè)Stream來存儲砰蠢。

3)Stripe Footer:存的是各個(gè)stripe的元數(shù)據(jù)信息

每個(gè)文件有一個(gè)File Footer复隆,這里面存的是每個(gè)Stripe的行數(shù)默责,每個(gè)Column的數(shù)據(jù)類型信息等;每個(gè)文件的尾部是一個(gè)PostScript,這里面記錄了整個(gè)文件的壓縮類型以及FileFooter的長度信息等榜聂。在讀取文件時(shí)荤懂,會seek到文件尾部讀PostScript燎潮,從里面解析到File Footer長度蔑滓,再讀FileFooter,從里面解析到各個(gè)Stripe信息拆宛,再讀各個(gè)Stripe嗓奢,即從后往前讀。

12.3.4 PARQUET格式
Parquet是面向分析型業(yè)務(wù)的列式存儲格式浑厚,由Twitter和Cloudera合作開發(fā)股耽,2015年5月從Apache的孵化器里畢業(yè)成為Apache頂級項(xiàng)目。

Parquet文件是以二進(jìn)制方式存儲的钳幅,所以是不可以直接讀取的物蝙,文件中包括該文件的數(shù)據(jù)和元數(shù)據(jù),因此Parquet格式文件是自解析的敢艰。

通常情況下诬乞,在存儲Parquet數(shù)據(jù)的時(shí)候會按照Block大小設(shè)置行組的大小,由于一般情況下每一個(gè)Mapper任務(wù)處理數(shù)據(jù)的最小單位是一個(gè)Block,這樣可以把每一個(gè)行組由一個(gè)Mapper任務(wù)處理丽惭,增大任務(wù)執(zhí)行并行度击奶。Parquet文件的格式如下圖所示辈双。

上圖展示了一個(gè)Parquet文件的內(nèi)容责掏,一個(gè)文件中可以存儲多個(gè)行組,文件的首位都是該文件的Magic Code湃望,用于校驗(yàn)它是否是一個(gè)Parquet文件换衬,F(xiàn)ooter length記錄了文件元數(shù)據(jù)的大小,通過該值和文件長度可以計(jì)算出元數(shù)據(jù)的偏移量证芭,文件的元數(shù)據(jù)中包括每一個(gè)行組的元數(shù)據(jù)信息和該文件存儲數(shù)據(jù)的Schema信息瞳浦。除了文件中每一個(gè)行組的元數(shù)據(jù),每一頁的開始都會存儲該頁的元數(shù)據(jù)废士,在Parquet中叫潦,有三種類型的頁:數(shù)據(jù)頁、字典頁和索引頁官硝。數(shù)據(jù)頁用于存儲當(dāng)前行組中該列的值矗蕊,字典頁存儲該列值的編碼字典,每一個(gè)列塊中最多包含一個(gè)字典頁氢架,索引頁用來存儲當(dāng)前行組下該列的索引傻咖,目前Parquet中還不支持索引頁。

存儲文件的查詢速度測試:

1)TextFile
hive (default)> select count(*) from log_text;
_c0
100000
Time taken: 21.54 seconds, Fetched: 1 row(s)

2)ORC
hive (default)> select count(*) from log_orc;
_c0
100000
Time taken: 20.867 seconds, Fetched: 1 row(s)

3)Parquet
hive (default)> select count(*) from log_parquet;
_c0
100000
Time taken: 22.922 seconds, Fetched: 1 row(s)

存儲文件的查詢速度總結(jié):
ORC > TextFile > Parquet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Spark 常見面試題

  1. 說出幾個(gè)常見的rdd算子岖研? ☆☆☆☆
    1.1 transformation算子
    map,filter,flatmap,groupbykey,repartition

1.2 action 算子
reduce,collect,count,take,saveAsTextFile

  1. rdd是什么卿操?rdd的創(chuàng)建方式有幾種?分別是怎么分區(qū)的孙援?☆☆☆
    2.1 rdd是什么害淤?
    rdd即彈性分布式數(shù)據(jù)集,是spark中最基本的數(shù)據(jù)抽象拓售,它代表一個(gè)不可變的筝家、可分區(qū)的內(nèi)部元素可并行計(jì)算 的集合。

2.2 rdd的創(chuàng)建方式
使用makeRDD通過集合創(chuàng)建邻辉。由本地核數(shù)來決定分區(qū)數(shù)量

使用外部數(shù)據(jù)源創(chuàng)建如hdfs溪王。由block的數(shù)量來決定的,通常默認(rèn)為2個(gè)分區(qū)最低也是2個(gè)值骇。

由另一個(gè)rdd得出的結(jié)果創(chuàng)建莹菱,即轉(zhuǎn)換時(shí)創(chuàng)建。根據(jù)父rdd的 reduceTask數(shù)量

  1. RDD的依賴關(guān)系 ☆☆☆☆☆
    3.1 寬依賴:多個(gè)子RDD的分區(qū)依賴同一個(gè)父RDD的Partition
    3.2 窄依賴:每一個(gè)父RDD的Partition最多被子RDD的 一個(gè)Partition使用
    3.3 為什么要?jiǎng)澐忠蕾囮P(guān)系吱瘩?
    簡單的說道伟,有效分別各個(gè)算子之間的關(guān)系有利于生成dag圖形,以及程序運(yùn)行過程中產(chǎn)生的多次依賴變化的監(jiān)察,窄依賴就是將依賴較為單一依賴視為一種方式蜜徽,如果將寬窄依賴混為一談祝懂,處理、區(qū)分拘鞋、運(yùn)行都會導(dǎo)致效率的分配不均砚蓬。

  2. task,stage盆色,job分別是什么灰蛙? ☆☆☆☆☆
    4.1 task
    即 stage 下的一個(gè)任務(wù)執(zhí)行單元,一般來說隔躲,一個(gè) rdd 有多少個(gè) partition摩梧,就 會有多少個(gè) task,因?yàn)槊恳粋€(gè) task 只是處理一個(gè)partition 上的數(shù)據(jù)宣旱。

4.2 stage
一個(gè)Job會被拆分為多組Task仅父,每組任務(wù)被稱為一個(gè)stage,每一次數(shù)據(jù)的shuffle都會產(chǎn)生一個(gè)stage浑吟。

4.3 job
每觸發(fā)一次action操作就會生成一個(gè)job笙纤,

4.4 為什么要?jiǎng)澐?stage?
由于劃分完 stage 之后买置,在同一個(gè)stage中只有窄依賴粪糙,沒有寬依賴,可以實(shí)現(xiàn)流水線計(jì)算忿项,stage中的每一個(gè)分區(qū)對應(yīng)一個(gè)task蓉冈,在同一個(gè)stage中就有很多可以并行運(yùn)行的task。

  1. RDD的緩存持久化機(jī)制轩触?☆☆☆☆☆
    主要通過cache寞酿,persist,checkpoint來實(shí)現(xiàn)RDD 的緩存持久化機(jī)制

5.1 cache與persist:
cache默認(rèn)將數(shù)據(jù)存儲在內(nèi)存中脱柱,底層實(shí)現(xiàn)是persist
persist定義了相關(guān)多種的數(shù)據(jù)存儲策略伐弹,如多副本,磁盤榨为,內(nèi)存等惨好,將數(shù)據(jù)存儲在內(nèi)存中就會產(chǎn)生相應(yīng)的oom內(nèi)存溢出問題,以及內(nèi)存如果不夠數(shù)據(jù)放置随闺,并不能保證數(shù)據(jù)準(zhǔn)確日川,安全性。
它不會改變r(jià)dd的依賴關(guān)系矩乐,程序運(yùn)行完成后對應(yīng)的緩存數(shù)據(jù)就自動消失
后續(xù)要觸發(fā) cache 和 persist 持久化操作龄句,需要有一個(gè)action操作
它不會開啟其他新的任務(wù)回论,一個(gè)action操作就對應(yīng)一個(gè)job
5.2 checkpoint:
可以把數(shù)據(jù)持久化寫入到hdfs上
后續(xù)要觸發(fā)checkpoint持久化操作,需要有一個(gè)action操作分歇,后續(xù)會開啟新的job執(zhí)行checkpoint操作
它會改變r(jià)dd的依賴關(guān)系傀蓉,后續(xù)數(shù)據(jù)丟失了不能夠在通過血統(tǒng)進(jìn)行數(shù)據(jù)的恢復(fù)。程序運(yùn)行完成后對應(yīng)的checkpoint數(shù)據(jù)就不會消失

  1. spark常見調(diào)優(yōu) ☆☆☆☆☆
    6.1 修改序列化機(jī)制有效壓縮數(shù)據(jù)量职抡,通過使用Kryo優(yōu)化序列化性能 ☆☆☆☆☆
    conf.set("spark.serializer","org.apache.spark.serializer.KryoSerializer ")
    1
    6.2 在實(shí)際的生產(chǎn)環(huán)境中葬燎,提交spark任務(wù)時(shí),使用spark-submit shell腳本繁调,在里面調(diào)整對應(yīng)的參數(shù)萨蚕“胁荩☆☆☆☆
    提交任務(wù)的腳本:

spark-submit \

--master spark://node1:7077 \

--class com.kaikeba.WordCount \

--num-executors 3 \ 配置executor的數(shù)量

--driver-memory 1g \ 配置driver的內(nèi)存(影響不大)

--executor-memory 1g \ 配置每一個(gè)executor的內(nèi)存大小

--executor-cores 3 \ 配置每一個(gè)executor的cpu個(gè)數(shù)

/export/servers/wordcount.jar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
6.3 提高并行度 ☆☆☆☆
設(shè)置task的數(shù)量

spark.defalut.parallelism

默認(rèn)是沒有值的蹄胰,如果設(shè)置了值為10,它會在shuffle的過程才會起作用奕翔。

比如 val rdd2 = rdd1.reduceByKey(+)

此時(shí)rdd2的分區(qū)數(shù)就是10

可以通過在構(gòu)建SparkConf對象的時(shí)候設(shè)置裕寨,例如:

new SparkConf().set("spark.defalut.parallelism","500")
1
給RDD重新設(shè)置partition的數(shù)量

使用rdd.repartition 來重新分區(qū),該方法會生成一個(gè)新的rdd派继,使其分區(qū)數(shù) 變大宾袜。

此時(shí)由于一個(gè)partition對應(yīng)一個(gè)task,那么對應(yīng)的task個(gè)數(shù)越多驾窟,通過這 種方式也可以提高并行度庆猫。

通過設(shè)置參數(shù)sql.shuffle.partitions=500 默認(rèn)為200;

可以適當(dāng)增大绅络,來提高并行度月培。 比如設(shè)置為 spark.sql.shuffle.partitions=500

6.4 RDD 的重用和持久化 ☆☆☆☆☆
適當(dāng)?shù)闹赜煤统志没疪DD能有效減少同一段代碼重復(fù)與調(diào)用的次數(shù),從而提高 程序的運(yùn)行效率和性能恩急,通常使用persist杉畜,cache方法。
在持久化過程中適當(dāng)?shù)氖褂眯蛄谢蓽p少數(shù)據(jù)的size從而降低內(nèi)存和cpu的計(jì) 算耗時(shí)和存儲空間衷恭。
序列化的方式此叠,唯一的缺點(diǎn)就是,在獲取數(shù)據(jù)的時(shí)候随珠,需要反序列化灭袁。但是可 以減少占用的空間和便于網(wǎng)絡(luò)傳輸。
如果序列化純內(nèi)存方式窗看,還是導(dǎo)致OOM茸歧,內(nèi)存溢出;就只能考慮磁盤的方式烤芦, 內(nèi)存+磁盤的普通方式(無序列化)举娩。
為了數(shù)據(jù)的高可靠性,而且內(nèi)存充足,可以使用雙副本機(jī)制铜涉,進(jìn)行持久化
持久化的雙副本機(jī)制智玻,持久化后的一個(gè)副本,因?yàn)闄C(jī)器宕機(jī)了芙代,副本丟了吊奢,就還是得重新計(jì)算一次;

持久化的每個(gè)數(shù)據(jù)單元纹烹,存儲一份副本页滚,放在其他節(jié)點(diǎn)上面,從而進(jìn)行容錯(cuò)铺呵;一個(gè)副本丟了裹驰,不用重新計(jì)算,還可以使用另外一份副本片挂。這種方式幻林,僅僅針對你的內(nèi)存資源極度充足。

比如: StorageLevel.MEMORY_ONLY_2

6.5 適當(dāng)將那些多次使用變量廣播出去 ☆☆
比如一個(gè)任務(wù)需要50個(gè)executor音念,1000個(gè)task沪饺,共享數(shù)據(jù)為100M。

在不使用廣播變量的情況下闷愤,1000個(gè)task整葡,就需要該共享數(shù)據(jù)的1000個(gè)副本, 也就是說有1000份數(shù)需要大量的網(wǎng)絡(luò)傳輸和內(nèi)存開銷存儲讥脐。耗費(fèi)的內(nèi)存大小 1000100=100G.
使用了廣播變量后遭居,50個(gè)executor就只需要50個(gè)副本數(shù)據(jù),而且不一定都是 從Driver傳輸?shù)矫總€(gè)節(jié)點(diǎn)攘烛,還可能是就近從最近的節(jié)點(diǎn)的executor的 blockmanager上拉取廣播變量副本魏滚,網(wǎng)絡(luò)傳輸速度大大增加;內(nèi)存開銷 50
100M=5G
如何使用?
1.通過sparkContext的broadcast方法把數(shù)據(jù)轉(zhuǎn)換成廣播變量坟漱,類型為Broadcast鼠次,
val broadcastArray: Broadcast[Array[Int]] = sc.broadcast(Array(1,2,3,4,5,6))
sc.broadcast(Array(1,2,3,4,5,6))
2.然后executor上的BlockManager就可以拉取該廣播變量的副本獲取具體的數(shù)據(jù)。
獲取廣播變量中的值可以通過調(diào)用其value方法
val array: Array[Int] = broadcastArray.value
1
2
3
4
5
6
總結(jié):

不使用廣播變量的內(nèi)存開銷為100G芋齿,使用后的內(nèi)存開銷5G腥寇,這里就相差了20 倍左右的網(wǎng)絡(luò)傳輸性能損耗和內(nèi)存開銷,使用廣播變量后對于性能的提升和影響觅捆,還是很可觀的赦役。

廣播變量的使用不一定會對性能產(chǎn)生決定性的作用。比如運(yùn)行30分鐘的spark作業(yè)栅炒,可能做了廣播變量以后掂摔,速度快了2分鐘术羔,或者5分鐘。但是一點(diǎn)一滴的調(diào)優(yōu)乙漓,積少成多级历。最后還是會有效果的。

注意事項(xiàng):

能不能將一個(gè)RDD使用廣播變量廣播出去叭披?不能寥殖,因?yàn)镽DD是不存儲數(shù)據(jù)的∩可以將RDD的結(jié)果廣播出去嚼贡。
廣播變量只能在Driver端定義,不能在Executor端定義同诫。
在Driver端可以修改廣播變量的值粤策,在Executor端無法修改廣播變量的值。
如果executor端用到了Driver的變量剩辟,如果不使用廣播變量在Executor 有多少task就有多少Driver端的變量副本掐场。
如果Executor端用到了Driver的變量往扔,如果使用廣播變量在每個(gè)Executor中只有一份Driver端的變量副本贩猎。
6.6 盡量避免shuffle ☆☆☆☆☆
有效的避免shuffle可以減少網(wǎng)絡(luò)間io和各個(gè)分區(qū)之間傳輸。

如何避免?

案例:

//錯(cuò)誤的做法:
// 傳統(tǒng)的join操作會導(dǎo)致shuffle操作萍膛。
// 因?yàn)閮蓚€(gè)RDD中吭服,相同的key都需要通過網(wǎng)絡(luò)拉取到一個(gè)節(jié)點(diǎn)上,由一個(gè)task進(jìn)行join操作蝗罗。
val rdd3 = rdd1.join(rdd2)

//正確的做法:
// Broadcast+map的join操作艇棕,不會導(dǎo)致shuffle操作。
// 使用Broadcast將一個(gè)數(shù)據(jù)量較小的RDD作為廣播變量串塑。
val rdd2Data = rdd2.collect()
val rdd2DataBroadcast = sc.broadcast(rdd2Data)

// 在rdd1.map算子中沼琉,可以從rdd2DataBroadcast中,獲取rdd2的所有數(shù)據(jù)桩匪。
// 然后進(jìn)行遍歷打瘪,如果發(fā)現(xiàn)rdd2中某條數(shù)據(jù)的key與rdd1的當(dāng)前數(shù)據(jù)的key是相同的,那么就判定可以進(jìn)行join傻昙。
// 此時(shí)就可以根據(jù)自己需要的方式闺骚,將rdd1當(dāng)前數(shù)據(jù)與rdd2中可以連接的數(shù)據(jù),拼接在一起(String或Tuple)妆档。
val rdd3 = rdd1.map(rdd2DataBroadcast...)

// 注意僻爽,以上操作,建議僅僅在rdd2的數(shù)據(jù)量比較少(比如幾百M(fèi)贾惦,或者一兩G)的情況下使用胸梆。
// 因?yàn)槊總€(gè)Executor的內(nèi)存中敦捧,都會駐留一份rdd2的全量數(shù)據(jù)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
6.7 使用map-side預(yù)聚合的shuffle操作 ☆☆☆
如果因?yàn)闃I(yè)務(wù)需要碰镜,一定要使用shuffle操作绞惦,無法用map類的算子來替代,那么盡量使用可以map-side預(yù)聚合的算子洋措。

所謂的map-side預(yù)聚合济蝉,說的是在每個(gè)節(jié)點(diǎn)本地對相同的key進(jìn)行一次聚合操作,類似于MapReduce中的本地combiner菠发。

map-side預(yù)聚合之后王滤,每個(gè)節(jié)點(diǎn)本地就只會有一條相同的key,因?yàn)槎鄺l相同的key都被聚合起來了滓鸠。其他節(jié)點(diǎn)在拉取所有節(jié)點(diǎn)上的相同key時(shí)雁乡,就會大大減少需 要拉取的數(shù)據(jù)數(shù)量,從而也就減少了磁盤IO以及網(wǎng)絡(luò)傳輸開銷糜俗。

通常來說踱稍,在可能的情況下,建議使用reduceByKey或者aggregateByKey算子來 替代掉groupByKey算子悠抹。因?yàn)閞educeByKey和aggregateByKey算子都會使用用戶 自定義的函數(shù)對每個(gè)節(jié)點(diǎn)本地的相同key進(jìn)行預(yù)聚合珠月。

而groupByKey算子是不會進(jìn)行預(yù)聚合的,全量的數(shù)據(jù)會在集群的各個(gè)節(jié)點(diǎn)之間分 發(fā)和傳輸楔敌,性能相對來說比較差啤挎。

比如如下兩幅圖,就是典型的例子卵凑,分別基于reduceByKey和groupByKey進(jìn)行單 詞計(jì)數(shù)庆聘。其中第一張圖是groupByKey的原理圖,可以看到勺卢,沒有進(jìn)行任何本地聚 合時(shí)伙判,所有數(shù)據(jù)都會在集群節(jié)點(diǎn)之間傳輸;第二張圖是reduceByKey的原理圖黑忱,可以看到宴抚,每個(gè)節(jié)點(diǎn)本地的相同key數(shù)據(jù),都進(jìn)行了預(yù)聚合杨何,然后才傳輸?shù)狡渌?jié)點(diǎn)上進(jìn)行全局聚合酱塔。

groupByKey進(jìn)行單詞計(jì)數(shù)原理:

reduceByKey單詞計(jì)數(shù)原理:

6.8 使用高性能的算子 ☆☆☆☆
6.8.1 使用reduceByKey/aggregateByKey替代groupByKey
reduceByKey/aggregateByKey 可以進(jìn)行預(yù)聚合操作,減少數(shù)據(jù)的傳輸量危虱,提升性能

groupByKey 不會進(jìn)行預(yù)聚合操作羊娃,進(jìn)行數(shù)據(jù)的全量拉取,性能比較低

6.8.2 使用mapPartitions替代普通map ☆☆☆☆
mapPartitions類的算子埃跷,一次函數(shù)調(diào)用會處理一個(gè)partition所有的數(shù)據(jù)蕊玷,而不 是一次函數(shù)調(diào)用處理一條邮利,性能相對來說會高一些。

但是有的時(shí)候垃帅,使用mapPartitions會出現(xiàn)OOM(內(nèi)存溢出)的問題延届。因?yàn)閱未魏?數(shù)調(diào)用就要處理掉一個(gè)partition所有的數(shù)據(jù),如果內(nèi)存不夠贸诚,垃圾回收時(shí)是無法 回收掉太多對象的方庭,很可能出現(xiàn)OOM異常。所以使用這類操作時(shí)要慎重酱固!

6.8.3 使用foreachPartitions替代foreach ☆☆☆☆
原理類似于“使用mapPartitions替代map”械念,也是一次函數(shù)調(diào)用處理一個(gè)partition的所有數(shù)據(jù),而不是一次函數(shù)調(diào)用處理一條數(shù)據(jù)运悲。在實(shí)踐中發(fā)現(xiàn)龄减,foreachPartitions類的算子,對性能的提升還是很有幫助的班眯。比 如在foreach函數(shù)中希停,將RDD中所有數(shù)據(jù)寫MySQL,那么如果是普通的foreach算子署隘,就會一條數(shù)據(jù)一條數(shù)據(jù)地寫宠能,每次函數(shù)調(diào)用可能就會創(chuàng)建一個(gè)數(shù)據(jù)庫連接,此時(shí)就勢必會頻繁地創(chuàng)建和銷毀數(shù)據(jù)庫連接定踱,性能是非常低下棍潘;但是如果用foreachPartitions算子一次性處理一個(gè)partition的數(shù)據(jù),那么對于每個(gè)partition崖媚,只要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)庫連接即可,然后執(zhí)行批量插入操作恤浪,此時(shí)性能是比較高的畅哑。實(shí)踐中發(fā)現(xiàn),對于1萬條左右的數(shù)據(jù)量寫MySQL水由,性能可以提升30%以上荠呐。

6.8.4 使用filter之后進(jìn)行coalesce操作 ☆☆☆☆
通常對一個(gè)RDD執(zhí)行filter算子過濾掉RDD中較多數(shù)據(jù)后(比如30%以上的數(shù)據(jù)),建議使用coalesce算子砂客,手動減少RDD的partition數(shù)量泥张,將RDD中的數(shù)據(jù)壓縮到更少的partition中去。

因?yàn)閒ilter之后鞠值,RDD的每個(gè)partition中都會有很多數(shù)據(jù)被過濾掉媚创,此時(shí)如果照常進(jìn)行后續(xù)的計(jì)算,其實(shí)每個(gè)task處理的partition中的數(shù)據(jù)量并不是很多彤恶,有一點(diǎn)資源浪費(fèi)呛占,而且此時(shí)處理的task越多伍俘,可能速度反而越慢讳苦。

因此用coalesce減少partition數(shù)量,將RDD中的數(shù)據(jù)壓縮到更少的partition 之后瘫怜,只要使用更少的task即可處理完所有的partition。在某些場景下本刽,對于 性能的提升會有一定的幫助鲸湃。

6.8.5 使用repartitionAndSortWithinPartitions替代repartition與sort類操作 ☆☆☆
repartitionAndSortWithinPartitions是Spark官網(wǎng)推薦的一個(gè)算子,官方建議子寓,如果需

要在repartition重分區(qū)之后唤锉,還要進(jìn)行排序,建議直接使用repartitionAndSortWithinPartitions算子别瞭。

因?yàn)樵撍阕涌梢砸贿呥M(jìn)行重分區(qū)的shuffle操作窿祥,一邊進(jìn)行排序。shuffle與sort兩個(gè)操作同時(shí)進(jìn)行蝙寨,比先shuffle再sort來說晒衩,性能可能是要高的。

6.8.6 使用fastutil優(yōu)化數(shù)據(jù)格式 ☆☆☆☆☆
fastutil是擴(kuò)展了Java標(biāo)準(zhǔn)集合框架(Map墙歪、List听系、Set;HashMap虹菲、ArrayList靠胜、 HashSet)的類庫,提供了特殊類型的map毕源、set浪漠、list和queue;

fastutil能夠提供更小的內(nèi)存占用霎褐,更快的存取速度址愿;我們使用fastutil提供的集合類,來替代自己平時(shí)使用的JDK的原生的Map冻璃、List响谓、Set.

Spark中應(yīng)用fastutil的場景和使用

算子函數(shù)使用了外部變量

1.你可以使用Broadcast廣播變量優(yōu)化;

2.可以使用Kryo序列化類庫省艳,提升序列化性能和效率娘纷;

3.如果外部變量是某種比較大的集合,那么可以考慮使用fastutil改寫外部 變量跋炕;

首先從源頭上就減少內(nèi)存的占用(fastutil)赖晶,通過廣播變量進(jìn)一步減少內(nèi)存占用,再通過Kryo序列化類庫進(jìn)一步減少內(nèi)存占用枣购。

算子函數(shù)里使用了比較大的集合Map/List

在你的算子函數(shù)里嬉探,也就是task要執(zhí)行的計(jì)算邏輯里面擦耀,如果有邏輯中,出現(xiàn)涩堤,要?jiǎng)?chuàng)建比較大的Map眷蜓、List等集合,

可能會占用較大的內(nèi)存空間胎围,而且可能涉及到消耗性能的遍歷吁系、存取等集合操作;那么此時(shí)白魂,可以考慮將這些集合類型使用fastutil類庫重寫汽纤,使用了fastutil集合類以后,就可以在一定程度上福荸,減少task創(chuàng)建出來的集合類型的內(nèi)存占用蕴坪。

避免executor內(nèi)存頻繁占滿,頻繁喚起GC敬锐,導(dǎo)致性能下降背传。

fastutil的使用

第一步:在pom.xml中引用fastutil的包

<dependency>
<groupId>fastutil</groupId>
<artifactId>fastutil</artifactId>
<version>5.0.9</version>
</dependency>
1
2
3
4
5
第二步:平時(shí)使用List (Integer)的替換成IntList即可。

List的list對應(yīng)的到fastutil就是IntList類型

使用說明:

基本都是類似于IntList的格式台夺,前綴就是集合的元素類型径玖;

特殊的就是Map,Int2IntMap颤介,代表了key-value映射的元素類型梳星。
reduce,collect,count,take,saveAsTextFile

Flume 常見面試題

  1. Flume 工作機(jī)制 ☆☆☆☆
    核心概念是agent,里面包括source滚朵、chanel和sink三個(gè)組件冤灾。
    source運(yùn)行在日志收集節(jié)點(diǎn)進(jìn)行日志采集,之后臨時(shí)存儲在chanel中始绍,sink負(fù)責(zé)將chanel中的數(shù)據(jù)發(fā)送到目的地瞳购。
    只有成功發(fā)送之后chanel中的數(shù)據(jù)才會被刪除。
    首先書寫flume配置文件亏推,定義agent、source年堆、chanel和sink然后將其組裝吞杭,執(zhí)行flume-ng命令。

  2. Flume 采集數(shù)據(jù)出現(xiàn)丟失怎么辦变丧? ☆☆☆☆☆
    不會芽狗,Channel存儲可以存儲在File中,數(shù)據(jù)傳輸自身有事務(wù)痒蓬。

也可以使用斷點(diǎn)續(xù)傳TailDir Source童擎,防止傳輸時(shí)出現(xiàn)網(wǎng)絡(luò)問題導(dǎo)致數(shù)據(jù)丟失滴劲。

FileChannel優(yōu)化

通過配置dataDirs指向多個(gè)路徑,每個(gè)路徑對應(yīng)不同的硬盤顾复,增大Flume吞吐量班挖。

checkpointDir 和 backupCheckpointDir 也盡量配置在不同硬盤對應(yīng)的目錄中,保證 checkpoint 壞掉后芯砸,可以快速使用 backupCheckpointDir 恢復(fù)數(shù)據(jù)

  1. Flume 高可用 ☆☆☆☆
    3.1 failover 故障轉(zhuǎn)移
    核心配置

當(dāng)采集數(shù)據(jù)的節(jié)點(diǎn)發(fā)生故障將流入到另一個(gè)節(jié)點(diǎn)上保證數(shù)據(jù)不出現(xiàn)斷傳現(xiàn)象

定義了2個(gè)sink

a1.sinks = k1 k2

set gruop

設(shè)置一個(gè)sink組萧芙,一個(gè)sink組下可以包含很多個(gè)sink

a1.sinkgroups = g1

set sink group

指定g1這個(gè)sink組下有k1 k2 這2個(gè)sink

a1.sinkgroups.g1.sinks = k1 k2
1
2
3
4
5
6
7
8
9
配置多個(gè) sinks讓數(shù)據(jù)流入一個(gè) sinkgroups中

核心配置

set failover

指定sink組高可用的策略---failover故障轉(zhuǎn)移

a1.sinkgroups.g1.processor.type = failover

指定k1這個(gè)sink的優(yōu)先級 優(yōu)先向k1傳輸數(shù)據(jù)優(yōu)先級為10

a1.sinkgroups.g1.processor.priority.k1 = 10

指定k2這個(gè)sink的優(yōu)先級

a1.sinkgroups.g1.processor.priority.k2 = 5

指定故障轉(zhuǎn)移的最大時(shí)間,如果超時(shí)會出現(xiàn)異常 10000毫秒后沒有響應(yīng)就向k2傳輸數(shù)據(jù)

a1.sinkgroups.g1.processor.maxpenalty = 10000
1
2
3
4
5
6
7
8
9
說明:
這里首先要申明一個(gè)sinkgroups,然后再設(shè)置2個(gè)sink ,k1與k2,其中2個(gè)優(yōu)先級是10和5假丧。
而processor的maxpenalty被設(shè)置為10秒双揪,默認(rèn)是30秒.表示故障轉(zhuǎn)移的最大時(shí)間

3.2 load balance 負(fù)載均衡
實(shí)現(xiàn)多個(gè)flume采集數(shù)據(jù)的時(shí)候避免單個(gè)flume的負(fù)載比較高,實(shí)現(xiàn)多個(gè)flume采集器負(fù)載均衡包帚。

核心配置

set load-balance

指定sink組高可用的策略---load_balance負(fù)載均衡

a1.sinkgroups.g1.processor.type =load_balance

默認(rèn)是 round_robin輪詢渔期,還可以選擇 random

a1.sinkgroups.g1.processor.selector = round_robin

如果backoff被開啟,則sink processor會屏蔽故障的sink

a1.sinkgroups.g1.processor.backoff = true
1
2
3
4
5
6
7

  1. Flume上傳文件到HDFS時(shí)參數(shù)大量小文件? ☆☆☆
    調(diào)整hdfs.rollInterval(間隔)渴邦、hdfs.rollSize(大蟹杼恕)、hdfs.rollCount(數(shù)量)這三個(gè)參數(shù)的值几莽。

  2. Flume內(nèi)存 ☆☆☆
    開發(fā)中在flume-env.sh中設(shè)置JVM heap為4G或更高迅办,部署在單獨(dú)的服務(wù)器上(4核8線程16G內(nèi)存)

-Xmx與-Xms最好設(shè)置一致,減少內(nèi)存抖動帶來的性能影響章蚣,如果設(shè)置不一致容易導(dǎo)致頻繁fullgc站欺。

  1. Flume 事務(wù) ☆☆☆☆
    Flume 的事務(wù)機(jī)制(類似數(shù)據(jù)庫的事務(wù)機(jī)制):Flume 使用兩個(gè)獨(dú)立的事務(wù)分別負(fù)責(zé)從

Soucrce 到 Channel,以及從 Channel 到 Sink 的事件傳遞纤垂。

比如 spooling directory source 為 文件的每一行創(chuàng)建一個(gè)事件矾策,一旦事務(wù)中所有的事件全部傳遞到 Channel 且提交成功,那么 Soucrce 就將該文件標(biāo)記為完成峭沦。

同理贾虽,事務(wù)以類似的方式處理從 Channel 到 Sink 的傳遞過程,如果因?yàn)槟撤N原因使得事件無法記錄吼鱼,那么事務(wù)將會回滾蓬豁。且所有的事件都會保持到

Channel 中,等待重新傳遞菇肃。

1)Flume事務(wù)組成地粪,Put事務(wù),Take事務(wù)

Taildir Source:斷點(diǎn)續(xù)傳琐谤、多目錄蟆技。Flume1.6以前需要自己自定義Source記錄每次讀取文件位置,實(shí)現(xiàn)斷點(diǎn)續(xù)傳。

File Channel:數(shù)據(jù)存儲在磁盤质礼,宕機(jī)數(shù)據(jù)可以保存旺聚。但是傳輸速率慢。適合對數(shù)據(jù)傳輸可靠性要 求高的場景眶蕉,比如砰粹,金融數(shù)據(jù)。

Memory Channel:數(shù)據(jù)存儲在內(nèi)存中妻坝,宕機(jī)數(shù)據(jù)丟失伸眶。傳輸速率快。適合對數(shù)據(jù)傳輸可靠性要求 不高的場景刽宪,比如厘贼,普通的日志數(shù)據(jù)。

Kafka Channel:減少了Flume的Sink階段圣拄,提高了傳輸效率嘴秸。

Source到Channel是Put事務(wù)

Channel到Sink是Take事務(wù)

  1. 你是如何實(shí)現(xiàn)Flume數(shù)據(jù)傳輸?shù)谋O(jiān)控的 ☆☆☆
    使用第三方框架 Ganglia 實(shí)時(shí)監(jiān)控 Flume

  2. Flume 的 Source,Sink庇谆,Channel 的作用岳掐?你們公司Source 是什么類型? ☆☆☆☆☆
    1饭耳、作用

(1)Source 組件是專門用來收集數(shù)據(jù)的串述,可以處理各種類型、各種格式的日志數(shù)據(jù)寞肖,

包括 avro纲酗、thrift、exec新蟆、jms觅赊、spooling directory、netcat琼稻、sequence generator吮螺、syslog、http帕翻、

legacy

(2)Channel 采集的數(shù)據(jù)進(jìn)行緩存鸠补,存入Memory 或 File 。

(3)Sink 組件是用于把數(shù)據(jù)發(fā)送到目的地的組件嘀掸,包括 Hdfs莫鸭、Logger、avro横殴、

thrift、ipc、file衫仑、Hbase梨与、solr、自定義文狱。

2粥鞋、我公司采用的 Source 類型為:

(1)監(jiān)控后臺日志:exec

(2)監(jiān)控后臺產(chǎn)生日志的端口:netcat

  1. Flume 參數(shù)調(diào)優(yōu) ☆☆☆☆
    Source

增加 Source 個(gè)(使用 Tair Dir Source 時(shí)可增加 FileGroups 個(gè)數(shù))可以增大 Source 的讀

取數(shù)據(jù)的能力。例如:當(dāng)某一個(gè)目錄產(chǎn)生的文件過多時(shí)需要將這個(gè)文件目錄拆分成多個(gè)文件

目錄瞄崇,同時(shí)配置好多個(gè) Source 以保證 Source 有足夠的能力獲取到新產(chǎn)生的數(shù)據(jù)呻粹。

batchSize 參數(shù)決定 Source 一次批量運(yùn)輸?shù)?Channel 的 event 條數(shù),適當(dāng)調(diào)大這個(gè)參數(shù)可

以提高 Source 搬運(yùn) Event 到 Channel 時(shí)的性能苏研。

Channel

type 選擇 memory 時(shí) Channel 的性能最好等浊,但是如果 Flume 進(jìn)程意外掛掉可能會丟失數(shù)

據(jù)。

type 選擇 file 時(shí) Channel 的容錯(cuò)性更好摹蘑,但是性能上會比 memory channel 差筹燕。

使用 file Channel 時(shí) dataDirs 配置多個(gè)不同盤下的目錄可以提高性能。

Capacity 參數(shù)決定 Channel 可容納最大的 event 條數(shù)衅鹿。

transactionCapacity 參數(shù)決定每次 Source 往 channel 里面寫的最大 event 條數(shù)和每次 Sink 從 channel 里面讀的最大 event 條數(shù)撒踪。

transactionCapacity 需要大于 Source 和 Sink 的 batchSize 參數(shù)。

Sink

增加 Sink 的個(gè)數(shù)可以增加 Sink 消費(fèi) event 的能力大渤。Sink 也不是越多越好夠用就行制妄,過

多的 Sink 會占用系統(tǒng)資源,造成系統(tǒng)資源不必要的浪費(fèi)泵三。

Kafka 常見面試題

  1. Kafka 消息數(shù)據(jù)積壓耕捞,消費(fèi)能力不足怎么處理? ☆☆☆☆☆
    1)可以考慮增加Topic的分區(qū)數(shù)切黔,并且同時(shí)提升消費(fèi)組的消費(fèi)者數(shù)量砸脊,消費(fèi)者數(shù)=分區(qū)數(shù)。(兩者缺一不可)

2)如果是下游的數(shù)據(jù)處理不及時(shí):提高每批次拉取的數(shù)量纬霞。批次拉取數(shù)據(jù)過少(拉取數(shù)據(jù)/處理時(shí)間<生產(chǎn)速度)凌埂,使處理的數(shù)據(jù)小于生產(chǎn)的數(shù)據(jù),也會造成數(shù)據(jù)積壓诗芜。

  1. Kafka 消息重復(fù)消費(fèi)和消息丟包的解決辦法 ☆☆☆☆☆
    消費(fèi)者 (offset手動提交瞳抓,業(yè)務(wù)邏輯成功處理后,提交offset)

保證不重復(fù)消費(fèi):落表(主鍵或者唯一索引的方式伏恐,避免重復(fù)數(shù)據(jù))

業(yè)務(wù)邏輯處理(選擇唯一主鍵存儲到Redis或者mongdb中孩哑,先查詢是否存在,若存在則不處理翠桦;若不存在横蜒,先插入Redis或Mongdb,再進(jìn)行業(yè)務(wù)邏輯處理)

自主維護(hù) offset 判斷不存在才插入值

  1. Kafka 有哪些情形會造成重復(fù)消費(fèi)胳蛮? ☆☆☆☆☆
    消費(fèi)者消費(fèi)后沒有commit offset(程序崩潰/強(qiáng)行kill/消費(fèi)耗時(shí)/自動提交偏移情況下unscrible)

  2. 那些情景會造成消息漏消費(fèi)? ☆☆☆☆☆
    先提交offset丛晌,后消費(fèi)仅炊,有可能造成數(shù)據(jù)的重復(fù)

  3. Kafka中的ISR、AR又代表什么澎蛛?☆☆☆☆☆
    ISR:與leader保持同步的follower集合(保持所有同步的副本包括leader)
    AR:分區(qū)的所有副本

  4. Kafka中的HW抚垄、LEO等分別代表什么? ☆☆☆☆☆
    LEO:每個(gè)副本的最后一條消息的offset
    HW:一個(gè)分區(qū)中所有副本最小的offset

  5. Kafka 如何保證數(shù)據(jù)的順序性谋逻,該如何解決呆馁?它怎么體現(xiàn)消息順序性的?☆☆☆☆☆
    7.1 解決數(shù)據(jù)順序性
    相同訂單的數(shù)據(jù)毁兆,發(fā)送同一個(gè)分區(qū)中去

采用kafka分區(qū)策略

第一種分區(qū)策略:給定了分區(qū)號浙滤,直接將數(shù)據(jù)發(fā)送到指定的分區(qū)里面去

第二種分區(qū)策略:沒有給定分區(qū)號,給定數(shù)據(jù)的key值荧恍,通過key取上hashCode進(jìn)行分區(qū)

第三種分區(qū)策略:既沒有給定分區(qū)號瓷叫,也沒有給定key值,直接輪循進(jìn)行分區(qū)

第四種分區(qū)策略:自定義分區(qū)

producer.send(new ProducerRecord<String, String>("test", Integer.toString(i), Integer.toString(i)));
//kafka的第一種分區(qū)方式送巡,如果給定了分區(qū)號摹菠,那么就直接將數(shù)據(jù)發(fā)送到指定的分區(qū)號里面去
producer.send(new ProducerRecord<String, String>("test",2,"helloworld",i+""));
//kafka的第二種分區(qū)策略,沒有給定分區(qū)號骗爆,給定了數(shù)據(jù)的key次氨,那么就通過key取hashcode,將數(shù)據(jù)均勻的發(fā)送到三臺機(jī)器里面去
//注意如果實(shí)際工作當(dāng)中摘投,要通過key取上hashcode來進(jìn)行分區(qū)煮寡,那么就一定要 保證key的變化,否則犀呼,數(shù)據(jù)就會全部去往一個(gè)分區(qū)里面
producer.send(new ProducerRecord<String, String>("test",i+"",i+""));
//kafka的第三種分區(qū)策略幸撕,既沒有給定分區(qū)號,也沒有給定數(shù)據(jù)的key值外臂,那么就會按照輪循的方式進(jìn)行數(shù)的發(fā)送
producer.send(new ProducerRecord<String, String>("test",i+""));
//kafka的第四種分區(qū)策略坐儿,自定義分區(qū)類,實(shí)現(xiàn)我們數(shù)據(jù)的分區(qū)
1
2
3
4
5
6
7
8
9
Flume 整合 Kafka 順序性

kafka sink

defalutPartitonId

將數(shù)據(jù)發(fā)送到指定的分區(qū)中去宋光,例如:將數(shù)據(jù)發(fā)送到 3 號分區(qū)貌矿,指定 3 就可以了

partitionIdHeader

自定義分區(qū)策略指定一個(gè)類繼承 kafka.partitioner.class

詳細(xì)配置:

http://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html

7.2 Kafka 如何體現(xiàn)消息有序性的
每個(gè)分區(qū)內(nèi),每條消息都有一個(gè)offset罪佳,故只能保證分區(qū)內(nèi)有序逛漫。
如果為了保證topic整個(gè)有序,那么將partition調(diào)整為1.

  1. Kafka中的分區(qū)器赘艳、序列化器酌毡、攔截器是否了解克握?它們之間的處理順序是什么?☆☆☆
    攔截器 -> 序列化器 -> 分區(qū)器

  2. 當(dāng)你使用kafka-topics.sh創(chuàng)建(刪除)了一個(gè)topic之后阔馋,Kafka背后會執(zhí)行什么邏輯玛荞? ☆☆☆
    1)會在zookeeper中的/brokers/topics節(jié)點(diǎn)下創(chuàng)建一個(gè)新的topic節(jié)點(diǎn),如:/brokers/topics/first
    2)觸發(fā)Controller的監(jiān)聽程序
    3)kafka Controller 負(fù)責(zé)topic的創(chuàng)建工作呕寝,并更新metadata cache

  3. Kafka有什么優(yōu)缺點(diǎn)?

  4. topic的分區(qū)數(shù)可不可以增加婴梧?如果可以怎么增加下梢?如果不可以,那又是為什么塞蹭?☆☆☆☆☆
    可以增加
    bin/kafka-topics.sh --zookeeper localhost:2181/kafka --alter --topic topic-config --partitions 3

  5. topic的分區(qū)數(shù)可不可以減少孽江?如果可以怎么減少?如果不可以番电,那又是為什么岗屏?☆☆☆☆☆
    不可以減少,被刪除的分區(qū)數(shù)據(jù)難以處理漱办。

  6. Kafka有內(nèi)部的topic嗎这刷?如果有是什么?有什么所用娩井? ☆☆☆☆
    __consumer_offsets,保存消費(fèi)者offset

  7. Kafka分區(qū)分配的概念暇屋? ☆☆☆☆☆
    一個(gè)topic多個(gè)分區(qū),一個(gè)消費(fèi)者組多個(gè)消費(fèi)者洞辣,故需要將分區(qū)分配個(gè)消費(fèi)者(roundrobin咐刨、range)

  8. Kafka如何保證不丟失消息?☆☆☆☆☆
    復(fù)制因子:創(chuàng)建topic的時(shí)候指定復(fù)制因子大于1時(shí)扬霜,一個(gè)分區(qū)被分配到一個(gè)broker上定鸟,同時(shí)會在其他broker上維護(hù)一個(gè)分區(qū)副本;
    isr列表:分區(qū)及其副本分別為leader和follower著瓶,leader對外提供讀寫服務(wù)联予,follower會向leader發(fā)送同步請求,拉取最新的數(shù)據(jù)蟹但,如果follower和leader的消息差距保持在一定范圍之內(nèi)躯泰,那么這個(gè)follower在isr列表內(nèi);當(dāng)分區(qū)leader所在broker宕機(jī)华糖,會從isr列表中選舉一個(gè)follower作為新的leader提供服務(wù)
    通過kafka的acks參數(shù)可以控制消息的發(fā)送行為麦向,acks可選的值有0、1客叉、all诵竭;當(dāng)設(shè)置為0時(shí)话告,生產(chǎn)者消息發(fā)送成功即為成功,不關(guān)心是否寫入到磁盤及后續(xù)操作卵慰;當(dāng)設(shè)置為1時(shí)沙郭,消息發(fā)送到分區(qū)leader后寫入磁盤即為成功;當(dāng)設(shè)置為all時(shí)裳朋,消息發(fā)送到分區(qū)leader并寫入磁盤后病线,同步給isr列表中的所有分區(qū)副本后即為成功

  9. Kafka中有那些地方需要選舉?這些地方的選舉策略又有哪些鲤嫡?☆☆☆☆☆
    partition leader(ISR)送挑,controller(先到先得)

  10. Kafka的那些設(shè)計(jì)讓它有如此高的性能?☆☆☆☆☆
    分區(qū)暖眼,順序?qū)懘疟P惕耕,0-copy 零拷貝、利用操作系統(tǒng)頁緩存诫肠、磁盤順序?qū)?/p>

kafka零拷貝原理
分區(qū)司澎、分段、建立索引
生產(chǎn)者栋豫、消費(fèi)者批處理

Hbase 常見面試題

  1. rowkey 設(shè)計(jì)規(guī)則 ☆☆☆☆☆
    1.長度限制(64k)

2.散列性(rowkey 盡量打散挤安,防止 regionserver 產(chǎn)生熱點(diǎn)問題)

3.唯一性(字段唯一)

熱點(diǎn)

熱點(diǎn)發(fā)生在大量的client直接訪問集群的一個(gè)或極少數(shù)個(gè)節(jié)點(diǎn)(訪問可能是讀,寫或者其他操作)笼才。大量訪問會使熱點(diǎn)region所在的單個(gè)機(jī)器超出自身承受能力漱受,引起性能下降甚至region不可用,這也會影響同一個(gè)RegionServer上的其他region骡送,由于主機(jī)無法服務(wù)其他region的請求昂羡。設(shè)計(jì)良好的數(shù)據(jù)訪問模式以使集群被充分,均衡的利用摔踱。

1.1 rowkey 怎么設(shè)計(jì)虐先?☆☆☆☆☆
使用數(shù)據(jù)庫中(主鍵+時(shí)間戳).md5加密

主鍵+|

而|是字典的最大值,而 Hbase rowkey是按照字典順序進(jìn)行排序

結(jié)果就是

““ 0000|

0000| 0001|

0001| 0002|

0002| 0003|

0003| 0004|

依次類推派敷,就可以實(shí)現(xiàn)預(yù)分區(qū)防止 regionserver 產(chǎn)生熱點(diǎn)問題

最后 rowkey 就為:

主鍵+|+加密后的時(shí)間戳

0001 | asdaswiwq

  1. 提高Hbase讀寫性能的通用做法? ☆☆☆
    寫方面 : 1. 批量寫 2. 多線程并發(fā)寫 3. BulkLoad 4. 預(yù)拆分Region

讀方面 : 1. 多線程并發(fā)讀 2.讀多寫少業(yè)務(wù)可以將BlockCache占比調(diào)大 3.設(shè)置Bloomfilter 4. 預(yù)拆分Region

  1. 講一下 Hbase 架構(gòu) ☆☆☆☆
    Hbase主要包含HMaster/HRegionServer/Zookeeper

HRegionServer 負(fù)責(zé)實(shí)際數(shù)據(jù)的讀寫. 當(dāng)訪問數(shù)據(jù)時(shí), 客戶端直接與RegionServer通信.

HBase的表根據(jù)Row Key的區(qū)域分成多個(gè)Region, 一個(gè)Region包含這這個(gè)區(qū)域內(nèi)所有數(shù)據(jù). 而Region server負(fù)責(zé)管理多個(gè)Region, 負(fù)責(zé)在這個(gè)Region server上的所有region的讀寫操作.

HMaster 負(fù)責(zé)管理Region的位置, DDL(新增和刪除表結(jié)構(gòu))

協(xié)調(diào)RegionServer
在集群處于數(shù)據(jù)恢復(fù)或者動態(tài)調(diào)整負(fù)載時(shí),分配Region到某一個(gè)RegionServer中
管控集群,監(jiān)控所有Region Server的狀態(tài)
提供DDL相關(guān)的API, 新建(create),刪除(delete)和更新(update)表結(jié)構(gòu).
Zookeeper 負(fù)責(zé)維護(hù)和記錄整個(gè)Hbase集群的狀態(tài)

zookeeper探測和記錄Hbase集群中服務(wù)器的狀態(tài)信息.如果zookeeper發(fā)現(xiàn)服務(wù)器宕機(jī),它會通知Hbase的master節(jié)點(diǎn).

  1. 講一下hbase讀數(shù)據(jù)的流程 ☆☆☆☆
    首先蛹批,客戶端需要獲知其想要讀取的信息的Region的位置,這個(gè)時(shí)候篮愉,Client訪問hbase上數(shù)據(jù)時(shí)并不需要Hmaster參與(HMaster僅僅維護(hù)著table和Region的元數(shù)據(jù)信息腐芍,負(fù)載很低),只需要訪問zookeeper试躏,從meta表獲取相應(yīng)region信息(地址和端口等)猪勇。【Client請求ZK獲取.META.所在的RegionServer的地址颠蕴∑玻】
    客戶端會將該保存著RegionServer的位置信息的元數(shù)據(jù)表.META.進(jìn)行緩存助析。然后在表中確定待檢索rowkey所在的RegionServer信息(得到持有對應(yīng)行鍵的.META表的服務(wù)器名)∫文【獲取訪問數(shù)據(jù)所在的RegionServer地址】
    根據(jù)數(shù)據(jù)所在RegionServer的訪問信息外冀,客戶端會向該RegionServer發(fā)送真正的數(shù)據(jù)讀取請求。服務(wù)器端接收到該請求之后需要進(jìn)行復(fù)雜的處理掀泳。
    先從MemStore找數(shù)據(jù)雪隧,如果沒有拉背,再到StoreFile上讀(為了讀取的效率)蟹腾。
  2. 講一下hbase的寫數(shù)據(jù)的流程 ☆☆☆☆
    Client先訪問zookeeper,從.META.表獲取相應(yīng)region信息屯阀,然后從meta表獲取相應(yīng)region信息
    根據(jù)namespace固灵、表名和rowkey根據(jù)meta表的數(shù)據(jù)找到寫入數(shù)據(jù)對應(yīng)的region信息
    找到對應(yīng)的regionserver 把數(shù)據(jù)先寫到WAL中,即HLog劫流,然后寫到MemStore上
    MemStore達(dá)到設(shè)置的閾值后則把數(shù)據(jù)刷成一個(gè)磁盤上的StoreFile文件巫玻。
    當(dāng)多個(gè)StoreFile文件達(dá)到一定的大小后(這個(gè)可以稱之為小合并,合并數(shù)據(jù)可以進(jìn)行設(shè)置祠汇,必須大于等于2仍秤,小于10——hbase.hstore.compaction.max和hbase.hstore.compactionThreshold,默認(rèn)為10和3)可很,會觸發(fā)Compact合并操作诗力,合并為一個(gè)StoreFile,(這里同時(shí)進(jìn)行版本的合并和數(shù)據(jù)刪除我抠。)
    當(dāng)Storefile大小超過一定閾值后苇本,會把當(dāng)前的Region分割為兩個(gè)(Split)【可稱之為大合并,該閾值通過hbase.hregion.max.filesize設(shè)置菜拓,默認(rèn)為10G】瓣窄,并由Hmaster分配到相應(yīng)的HRegionServer,實(shí)現(xiàn)負(fù)載均衡
  3. 講一下hbase的存儲結(jié)構(gòu),這樣的存儲結(jié)構(gòu)有什么優(yōu)缺點(diǎn) ☆☆☆☆
    Hbase的優(yōu)點(diǎn)及應(yīng)用場景:

半結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù): 對于數(shù)據(jù)結(jié)構(gòu)字段不夠確定或雜亂無章非常難按一個(gè)概念去進(jìn)行抽取的數(shù)據(jù)適合用HBase纳鼎,因?yàn)镠Base支持動態(tài)添加列俺夕。
記錄很稀疏: RDBMS的行有多少列是固定的。為null的列浪費(fèi)了存儲空間贱鄙。HBase為null的Column不會被存儲劝贸,這樣既節(jié)省了空間又提高了讀性能。
多版本號數(shù)據(jù): 依據(jù)Row key和Column key定位到的Value能夠有隨意數(shù)量的版本號值逗宁,因此對于須要存儲變動歷史記錄的數(shù)據(jù)映九,用HBase是很方便的。比方某個(gè)用戶的Address變更疙剑,用戶的Address變更記錄也許也是具有研究意義的氯迂。
僅要求最終一致性: 對于數(shù)據(jù)存儲事務(wù)的要求不像金融行業(yè)和財(cái)務(wù)系統(tǒng)這么高践叠,只要保證最終一致性就行。(比如HBase+elasticsearch時(shí)嚼蚀,可能出現(xiàn)數(shù)據(jù)不一致)
高可用和海量數(shù)據(jù)以及很大的瞬間寫入量: WAL解決高可用禁灼,支持PB級數(shù)據(jù),put性能高 適用于插入比查詢操作更頻繁的情況轿曙。比如弄捕,對于歷史記錄表和日志文件。(HBase的寫操作更加高效)
業(yè)務(wù)場景簡單: 不需要太多的關(guān)系型數(shù)據(jù)庫特性导帝,列入交叉列守谓,交叉表,事務(wù)您单,連接等斋荞。
Hbase的缺點(diǎn):

單一RowKey固有的局限性決定了它不可能有效地支持多條件查詢
不適合于大范圍掃描查詢
不直接支持 SQL 的語句查詢
Redis 20問

  1. 你們項(xiàng)目中有用過 Redis ? 場景在哪里? ☆☆☆☆☆
    ① Token 令牌生成虐秦,替代 Session平酿,Session只存在于當(dāng)前的 jvm 中,將 Token 存入 redis 里實(shí)現(xiàn)共享悦陋。

② 短信驗(yàn)證碼 code蜈彼。

③ 熱點(diǎn) key 預(yù)熱,數(shù)據(jù)庫第一次請求速度非常慢俺驶,熱點(diǎn)數(shù)據(jù)(經(jīng)常會被查詢幸逆,但是不經(jīng)常被修改或者刪除的數(shù)據(jù))放入redis。

④ 網(wǎng)頁 PVUV 計(jì)數(shù)暮现,由于 redis 是單線程線程安全可以保證計(jì)數(shù)的原子性还绘。

⑤ 分布式鎖 setnx、使用框架 resdison送矩。

⑥ 訂單的有效期 蚕甥、使用 redis key 的有效期,key 失效監(jiān)聽栋荸,進(jìn)行回調(diào)菇怀。

⑦ 實(shí)現(xiàn)注冊中心、分布式配置中心

  1. Redis 線程是否安全 晌块?☆☆☆☆
    安全爱沟,依靠 IO 多路復(fù)用提高處理效率

redis 官方不支持 windows 版本,windows 不支持 epoll

Redis的底層采用Nio中的多路復(fù)用的機(jī)制匆背,能夠非常好的支持這樣的并發(fā)呼伸,從而保證
線程安全問題;。

Redis單線程,也就是底層采用一個(gè)線程維護(hù)多個(gè)不同的客戶端io操作括享。.
但是 NIO 在不同的操作系統(tǒng)上實(shí)現(xiàn)的方式有所不同搂根,在我們windows操作系統(tǒng)使用select
實(shí)現(xiàn)輪訓(xùn)時(shí)間復(fù)雜度是為o(n),而且還存在空輪訓(xùn)的情況铃辖,效率非常低剩愧,其次是 默認(rèn)對我
們輪訓(xùn)的數(shù)據(jù)有一定限制,所以支持上萬的 tcp 連接是非常難娇斩。

所以在 linux 操作系統(tǒng)采用 epoll 實(shí)現(xiàn)事件驅(qū)動回調(diào)仁卷,不會存在空輪訓(xùn)的情況,只對活躍的
socket 連接實(shí)現(xiàn)主動回調(diào)這樣在性能上有大大的提升犬第,所以時(shí)間復(fù)雜度是為o(1)锦积。

所以為什么nginx redis.都能夠非常高支持高并發(fā),最終都是linux中的 IO 多路復(fù)用機(jī)制
epoll.

io 多路復(fù)用原則
服務(wù)器端只有一個(gè)線程去處理 n 多個(gè)請求歉嗓,判斷是否有數(shù)據(jù)丰介,有數(shù)據(jù)進(jìn)行流入 buffer 中寫滿后由才進(jìn)行操作。

字節(jié)傳輸與 buffer 傳輸

字節(jié)流傳輸效率比較低鉴分,傳輸字節(jié)一個(gè)一個(gè)寫入

buffer 傳輸效率比較高基矮,寫滿后以一個(gè)塊的形式把字節(jié)寫入

  1. Redis 中是否有事務(wù)機(jī)制?事務(wù)支持回滾嗎冠场?☆☆☆☆☆
    Redis 支持事務(wù),和 mysql 的事務(wù)有很大區(qū)別 本砰,Redis 一旦開啟事務(wù)其他線程也可以對這個(gè) key進(jìn)行操作很難像mysql 一樣保證數(shù)據(jù)的原子性 碴裙。
    mysql 中一旦有線程對一行數(shù)據(jù)進(jìn)行事務(wù)操作,其他線程對這一行數(shù)據(jù)是不能進(jìn)行操作的点额,redis和mysql 正好相反舔株。
    Redis 的 Watch 采用樂觀鎖機(jī)制控制,樂觀鎖主要是指當(dāng)每次拿數(shù)據(jù)的時(shí)候都認(rèn)為都別人不會更改还棱,所以不會上鎖载慈,允許多個(gè)線程進(jìn)行操作,這也是 Redis 不能保證數(shù)據(jù)原子性的原因所在珍手。
    redis 不存在事務(wù)回滾办铡。

為什么 redis 不采用事務(wù)回滾?
回滾的目的就是將mysql的行鎖進(jìn)行釋放琳要,而 redis 不存在行鎖寡具,但是 redis 有取消事務(wù),使用discard 會放棄事務(wù)塊的所有命令稚补。

  1. Redis 與 mysql 如何保持?jǐn)?shù)據(jù)一致性童叠?☆☆☆☆
    通過 redis 發(fā)布訂閱,去訂閱到數(shù)據(jù)庫的 binlog 保持和mysql數(shù)據(jù)一致性课幕。

采用增量 binlog 同步的方案

  1. Redis 宕機(jī)厦坛,數(shù)據(jù)會丟失嗎五垮? ☆☆☆☆☆
    不會,因?yàn)橛?RDB 和AOF

開啟AOF 持久化最多可能丟失 1s 數(shù)據(jù)杜秸。

  1. Redis 持久化 ☆☆☆☆☆
    6.1 RDB 和 AOF
    6.1.1 RDB
    RDB 是以二進(jìn)制文件放仗,是在某個(gè)時(shí)間 點(diǎn)將數(shù)據(jù)寫入一個(gè)臨時(shí)文件,持久化結(jié)束后亩歹,用這個(gè)臨時(shí)文件替換上次持久化的文件匙监,達(dá)到數(shù)據(jù)恢復(fù)。
    優(yōu)點(diǎn):使用單獨(dú)子進(jìn)程來進(jìn)行持久化小作,主進(jìn)程不會進(jìn)行任何 IO 操作亭姥,保證了 redis 的高性能
    缺點(diǎn):RDB 是間隔一段時(shí)間進(jìn)行持久化,如果持久化之間 redis 發(fā)生故障顾稀,會發(fā)生數(shù)據(jù)丟失达罗。所以這種方式更適合數(shù)據(jù)要求不嚴(yán)謹(jǐn)?shù)臅r(shí)候

這里說的這個(gè)執(zhí)行數(shù)據(jù)寫入到臨時(shí)文件的時(shí)間點(diǎn)是可以通過配置來自己確定的,通過配置redis 在 n 秒內(nèi)如果超過 m 個(gè) key 被修改這執(zhí)行一次 RDB 操作静秆。這個(gè)操作就類似于在這個(gè)時(shí)間點(diǎn)來保存一次 Redis 的所有數(shù)據(jù)粮揉,一次快照數(shù)據(jù)。所有這個(gè)持久化方法也通常叫做 snapshots抚笔。

開啟 RDB

dbfilename:持久化數(shù)據(jù)存儲在本地的文件

dbfilename dump.rdb

dir:持久化數(shù)據(jù)存儲在本地的路徑扶认,如果是在/redis/redis-3.0.6/src下啟動的redis-cli,則數(shù)據(jù)會存儲在當(dāng)前src目錄下

dir ./

snapshot觸發(fā)的時(shí)機(jī)殊橙,save

如下為900秒后辐宾,至少有一個(gè)變更操作,才會snapshot

對于此值的設(shè)置膨蛮,需要謹(jǐn)慎叠纹,評估系統(tǒng)的變更操作密集程度

可以通過“save “””來關(guān)閉snapshot功能

save時(shí)間,以下分別表示更改了1個(gè)key時(shí)間隔900s進(jìn)行持久化存儲敞葛;更改了10個(gè)key300s進(jìn)行存儲誉察;更改10000個(gè)key60s進(jìn)行存儲。

save 900 1
save 300 10
save 60 10000

當(dāng)snapshot時(shí)出現(xiàn)錯(cuò)誤無法繼續(xù)時(shí)惹谐,是否阻塞客戶端“變更操作”持偏,“錯(cuò)誤”可能因?yàn)榇疟P已滿/磁盤故障/OS級別異常等

stop-writes-on-bgsave-error yes

是否啟用rdb文件壓縮,默認(rèn)為“yes”豺鼻,壓縮往往意味著“額外的cpu消耗”综液,同時(shí)也意味這較小的文件尺寸以及較短的網(wǎng)絡(luò)傳輸時(shí)間

rdbcompression yes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
6.1.2 AOF
Append-only file,將“操作 + 數(shù)據(jù)”以格式化指令的方式追加到操作日志文件的尾部儒飒,在 append 操作返回后(已經(jīng)寫入到文件或者即將寫入)谬莹,才進(jìn)行實(shí)際的數(shù)據(jù)變更,“日志文件”保存了歷史所有的操作過程;當(dāng) server 需要數(shù)據(jù)恢復(fù)時(shí)附帽,可以直接 replay 此日志文件埠戳,即可還原所有的操作過程。AOF 相對可靠蕉扮,它和 mysql 中 bin.log整胃、apache.log、zookeeper 中 txn-log 簡直異曲同工喳钟。AOF 文件內(nèi)容是字符串屁使,非常容易閱讀和解析。
優(yōu)點(diǎn):可以保持更高的數(shù)據(jù)完整性奔则,如果設(shè)置追加 file 的時(shí)間是 1s蛮寂,如果 redis 發(fā)生故障,最多會丟失 1s 的數(shù)據(jù)易茬;且如果日志寫入不完整支持 redis-check-aof 來進(jìn)行日志修復(fù)酬蹋;AOF 文件沒被 rewrite 之前(文件過大時(shí)會對命令進(jìn)行合并重寫),可以刪除其中的某些命令(比如誤操作的 flushall)抽莱。
缺點(diǎn):AOF 文件比 RDB 文件大范抓,且恢復(fù)速度慢。

我們可以簡單的認(rèn)為 AOF 就是日志文件食铐,此文件只會記錄“變更操作”(例如:set/del 等)匕垫,如果 server 中持續(xù)的大量變更操作,將會導(dǎo)致 AOF 文件非常的龐大虐呻,意味著 server 失效后年缎,數(shù)據(jù)恢復(fù)的過程將會很長;事實(shí)上铃慷,一條數(shù)據(jù)經(jīng)過多次變更,將會產(chǎn)生多條 AOF 記錄蜕该,其實(shí)只要保存當(dāng)前的狀態(tài)犁柜,歷史的操作記錄是可以拋棄的;因?yàn)?AOF 持久化模式還伴生了“AOF rewrite”堂淡。
AOF 的特性決定了它相對比較安全馋缅,如果你期望數(shù)據(jù)更少的丟失,那么可以采用 AOF 模式绢淀。如果 AOF 文件正在被寫入時(shí)突然 server 失效萤悴,有可能導(dǎo)致文件的最后一次記錄是不完整,你可以通過手工或者程序的方式去檢測并修正不完整的記錄皆的,以便通過 aof 文件恢復(fù)能夠正常覆履;同時(shí)需要提醒,如果你的 redis 持久化手段中有 aof,那么在 server 故障失效后再次啟動前硝全,需要檢測 aof 文件的完整性栖雾。

AOF 默認(rèn)關(guān)閉,開啟方法伟众,修改配置文件 reds.conf:appendonly yes

開啟 AOF(Append-only file)

此選項(xiàng)為aof功能的開關(guān)析藕,默認(rèn)為“no”,可以通過“yes”來開啟aof功能

只有在“yes”下凳厢,aof重寫/文件同步等特性才會生效

appendonly yes

指定aof文件名稱

appendfilename appendonly.aof

指定aof操作中文件同步策略账胧,有三個(gè)合法值:always everysec no,默認(rèn)為everysec

appendfsync everysec

在aof-rewrite期間,appendfsync是否暫緩文件同步先紫,"no"表示“不暫緩”治泥,“yes”表示“暫緩”,默認(rèn)為“no”

no-appendfsync-on-rewrite no

aof文件rewrite觸發(fā)的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才會觸發(fā)rewrite泡孩,默認(rèn)“64mb”车摄,建議“512mb”

auto-aof-rewrite-min-size 64mb

相對于“上一次”rewrite,本次rewrite觸發(fā)時(shí)aof文件應(yīng)該增長的百分比仑鸥。

每一次rewrite之后吮播,redis都會記錄下此時(shí)“新aof”文件的大小(例如A),那么當(dāng)aof文件增長到A*(1 + p)之后

觸發(fā)下一次rewrite眼俊,每一次aof記錄的添加意狠,都會檢測當(dāng)前aof文件的尺寸。

auto-aof-rewrite-percentage 100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
redis 提供了 3 種AOF 記錄同步選項(xiàng):

always:每次有數(shù)據(jù)修改發(fā)生時(shí)都會寫入 AOF 文件疮胖,能夠保證數(shù)據(jù)安全性 环戈,但是效率比較低
everysec:每秒同步一次,可能會丟失 1s 內(nèi)的數(shù)據(jù)澎灸,性能和安全都比較中庸的方式院塞,也是 redis 推薦的方式。
no:從不同步性昭。高效但是數(shù)據(jù)不會被持久化拦止。
直接修改 redis.conf 中 appendonly yes

建議最好還是使用 everysec 既能夠保證數(shù)據(jù)的同步、效率也還可以糜颠。

6.2 RDB 和 AOF 區(qū)別汹族?
RDB 屬于全量同步,把所有數(shù)據(jù)生成二進(jìn)制文件保存到磁盤中其兴,屬于定時(shí)性(規(guī)定時(shí)間的操作)

效率比較高 但是可能丟失數(shù)據(jù)

AOF 屬于增量同步顶瞒,把 set 操作記錄到日志文件中,效率比較低元旬,最多只會丟失 1s 數(shù)據(jù)榴徐,數(shù)據(jù)恢復(fù)較慢

  1. Redis 中如何存放對象 ☆☆☆
    存放 json 守问、存放二進(jìn)制

json 閱讀性比較強(qiáng)

二進(jìn)制 閱讀性比較差(不能跨語言)

  1. Redis 內(nèi)存滿了怎么辦?☆☆☆☆
    使用淘汰策略箕速,將一些不使用的 key 提前釋放掉

voltile-lru 從已經(jīng)設(shè)置過期時(shí)間的數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰

voltile-ttl 從已經(jīng)設(shè)置過期時(shí)間的數(shù)據(jù)庫集當(dāng)中挑選將要過期的數(shù)據(jù)

voltile-random 從已經(jīng)設(shè)置過期時(shí)間的數(shù)據(jù)集任意選擇淘汰數(shù)據(jù)

allkeys-lru 從數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰

allkeys-random 從數(shù)據(jù)集中任意選擇淘汰的數(shù)據(jù)

no-eviction 禁止驅(qū)逐數(shù)據(jù)

  1. Redis 如何實(shí)現(xiàn)高可用酪碘? 哨兵機(jī)制的作用?☆☆☆☆☆
    為什么要做高可用集群盐茎?

redis 可能出現(xiàn)單點(diǎn)故障兴垦,如果采用主從復(fù)制一旦宕機(jī),需要手動的去選擇一個(gè)主節(jié)點(diǎn)出來效率極低字柠。

因此引用哨兵機(jī)制探越,讓哨兵進(jìn)程監(jiān)控 master 狀態(tài),當(dāng)它存在宕機(jī)會自動的選出一個(gè)從節(jié)點(diǎn)作為新的主節(jié)點(diǎn)窑业。

9.2 哨兵機(jī)制的作用钦幔?
哨兵機(jī)制,比較類似ZK的設(shè)計(jì)思路常柄。

哨兵數(shù)量與Redis節(jié)點(diǎn)數(shù)量一致鲤氢,單個(gè)哨兵監(jiān)控主節(jié)點(diǎn),發(fā)現(xiàn)主節(jié)點(diǎn)出現(xiàn)故障或者宕機(jī)會讓另一個(gè)哨兵對主節(jié)點(diǎn)進(jìn)行檢查如果發(fā)現(xiàn)主節(jié)點(diǎn)失效西潘,會選擇新一個(gè)主節(jié)點(diǎn)卷玉。

9.3 哨兵機(jī)制的優(yōu)缺點(diǎn)
1、哨兵集群中只要有一臺宕了喷市,整個(gè)集群的故障轉(zhuǎn)移機(jī)制就失效了相种。

2、哨兵啟動時(shí)候redis主庫必需運(yùn)行正常品姓,否則故障轉(zhuǎn)移機(jī)制也失效寝并。

3、應(yīng)用端需要先詢問哨兵才能訪問到redis主庫腹备,是否對效率也有明顯的影響衬潦。

4、只能存在一個(gè)master節(jié)點(diǎn)不能存在多個(gè)植酥,數(shù)據(jù)可能產(chǎn)生冗余别渔,數(shù)據(jù)同步效率較低,浪費(fèi)資源惧互。

  1. Redis 緩存穿透、雪崩喇伯、擊穿如何解決喊儡?☆☆☆☆☆
    緩存穿透:指查詢一個(gè)一定不存在的數(shù)據(jù),如果從存儲層查不到數(shù)據(jù)則不寫入緩存稻据,這將

導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請求都要到 DB 去查詢艾猜,可能導(dǎo)致 DB 掛掉买喧。

解決方案:1.查詢返回的數(shù)據(jù)為空,仍把這個(gè)空結(jié)果進(jìn)行緩存匆赃,但過期時(shí)間會比較短淤毛;2.布

隆過濾器:將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的 bitmap 中,一個(gè)一定不存在的數(shù)據(jù)

會被這個(gè) bitmap 攔截掉算柳,從而避免了對 DB 的查詢低淡。

緩存擊穿:對于設(shè)置了過期時(shí)間的 key,緩存在某個(gè)時(shí)間點(diǎn)過期的時(shí)候瞬项,恰好這時(shí)間點(diǎn)對

這個(gè) Key 有大量的并發(fā)請求過來蔗蹋,這些請求發(fā)現(xiàn)緩存過期一般都會從后端 DB 加載數(shù)據(jù)并

回設(shè)到緩存,這個(gè)時(shí)候大并發(fā)的請求可能會瞬間把 DB 壓垮囱淋。解決方案:1.使用互斥鎖:當(dāng)緩存失效時(shí)猪杭,不立即去 load db,先使用如 Redis 的 setnx 去設(shè)

置一個(gè)互斥鎖妥衣,當(dāng)操作成功返回時(shí)再進(jìn)行 load db 的操作并回設(shè)緩存皂吮,否則重試 get 緩存的

方法。2.永遠(yuǎn)不過期:物理不過期税手,但邏輯過期(后臺異步線程去刷新)蜂筹。

緩存雪崩:設(shè)置緩存時(shí)采用了相同的過期時(shí)間,導(dǎo)致緩存在某一時(shí)刻同時(shí)失效冈止,請求全部

轉(zhuǎn)發(fā)到 DB狂票,DB 瞬時(shí)壓力過重雪崩。與緩存擊穿的區(qū)別:雪崩是很多 key熙暴,擊穿是某一個(gè)

key 緩存闺属。

解決方案:將緩存失效時(shí)間分散開,比如可以在原有的失效時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值周霉,

比如 1-5 分鐘隨機(jī)掂器,這樣每一個(gè)緩存的過期時(shí)間的重復(fù)率就會降低,就很難引發(fā)集體失效

的事件俱箱。

  1. Redis 如何實(shí)現(xiàn)分布式鎖国瓮? ☆☆☆☆
    先拿 setnx 來爭搶鎖,搶到之后狞谱,再用 expire 給鎖加一個(gè)過期時(shí)間防止鎖忘記了釋放乃摹。

如果在 setnx 之后執(zhí)行 expire 之前進(jìn)程意外 crash 或者要重啟維護(hù)了,那會怎么樣跟衅?

set 指令有非常復(fù)雜的參數(shù)孵睬,這個(gè)應(yīng)該是可以同時(shí)把 setnx 和 expire 合成一條指令來用的!

  1. Redis 集群有哪些方案伶跷?☆☆☆
    12.1 Twemproxy – Twitter
    優(yōu)點(diǎn):
  • 開發(fā)簡單掰读,對應(yīng)用幾乎透明
  • 歷史悠久秘狞,方案成熟

缺點(diǎn):

  • 代理影響性能
  • lvs和twemproxy會有節(jié)點(diǎn)性能瓶頸
  • redis擴(kuò)容非常麻煩
  • twitter內(nèi)部已放棄使用該方案,新使用的架構(gòu)未開源

12.2 Codis – 豌豆莢
優(yōu)點(diǎn):

  • 開發(fā)簡單蹈集,對應(yīng)用幾乎透明
  • 性能比Twemproxy好
  • 有圖形化界面烁试,擴(kuò)容容易,運(yùn)維方便

缺點(diǎn):

  • 代理依舊影響性能
  • 組件過多拢肆,需要很多機(jī)器資源
  • 修改了redis代碼减响,導(dǎo)致和官方無法同步,新特性跟進(jìn)緩慢
  • 開發(fā)團(tuán)隊(duì)準(zhǔn)備主推基于redis改造的reborndb

12.3 Redis Cluster – 官方
優(yōu)點(diǎn):

  • 組件all-in-box善榛,部署簡單辩蛋,節(jié)約機(jī)器資源
  • 性能比proxy模式好
  • 自動故障轉(zhuǎn)移、Slot遷移中數(shù)據(jù)可用
  • 官方原生集群方案移盆,更新與支持有保障

缺點(diǎn):

  • 架構(gòu)比較新悼院,最佳實(shí)踐較少
  • 多鍵操作支持有限(驅(qū)動可以曲線救國)
  • 為了性能提升,客戶端需要緩存路由表信息
  • 節(jié)點(diǎn)發(fā)現(xiàn)咒循、reshard操作不夠自動化
  1. Redis 有哪些數(shù)據(jù)結(jié)構(gòu)据途? ☆☆☆☆☆
    字符串 String、字典 Hash叙甸、列表 List颖医、集合 Set、有序集合 SortedSet裆蒸。如果是高級用戶熔萧,那

么還會有,如果你是 Redis 中高級用戶僚祷,還需要加上下面幾種數(shù)據(jù)結(jié)構(gòu) HyperLogLog佛致、

Geo、Pub/Sub辙谜。

  1. Redis 數(shù)據(jù)結(jié)構(gòu)模型(跳躍表俺榆、布隆過濾器)☆☆☆

  2. 訂單超時(shí)自動取消如何實(shí)現(xiàn)? ☆☆☆☆☆
    使用 Token 當(dāng) Token 失效時(shí)會走客戶端的回調(diào)方法装哆,檢測訂單是否支付罐脊,沒有支付直接提示訂單超時(shí)。

  3. Redis 主從復(fù)制如果網(wǎng)絡(luò)延時(shí)怎么辦蜕琴?☆☆☆☆
    不能解決屬于強(qiáng)一致性問題萍桌,只能采用最終一致性方案,人工進(jìn)行數(shù)據(jù)遷移凌简,如果做了持久化將持久化文件傳到從節(jié)點(diǎn)中上炎。

1、強(qiáng)一致性:在任何時(shí)刻所有的用戶或者進(jìn)程查詢到的都是最近一次成功更新的數(shù)據(jù)号醉。強(qiáng)一致性是程度最高一致性要求反症,也是最難實(shí)現(xiàn)的。關(guān)系型數(shù)據(jù)庫更新操作就是這個(gè)案例畔派。

2铅碍、最終一致性:和強(qiáng)一致性相對,在某一時(shí)刻用戶或者進(jìn)程查詢到的數(shù)據(jù)可能都不同线椰,但是最終成功更新的數(shù)據(jù)都會被所有用戶或者進(jìn)程查詢到胞谈。當(dāng)前主流的nosql數(shù)據(jù)庫都是采用這種一致性策略。

  1. Redis 主從同步效率非常慢怎么解決憨愉?☆☆☆☆
    采用多主多從或者是樹狀形式實(shí)現(xiàn)同步烦绳。

  2. Redis Cluster 集群 ☆☆☆☆☆
    對key進(jìn)行分片存儲在不同卡槽,分?jǐn)?key 存放

卡槽邏輯根據(jù) crc16(meite)=50018%16384=9666

快速進(jìn)行擴(kuò)容和縮容配紫,同步效率比較高

  1. 說說你對redis 哨兵機(jī)制的理解 ☆☆☆☆☆
    (1)集群監(jiān)控舰罚,負(fù)責(zé)監(jiān)控redis master 和slave進(jìn)程是否正常工作膊毁。

(2)消息通知,如果某個(gè)redis實(shí)例有故障,那么哨兵負(fù)責(zé)發(fā)送消息作為報(bào)警通知給管理員吃型。

(3)故障轉(zhuǎn)移,如果master node掛掉了拯欧,會自動轉(zhuǎn)移到slave node上打颤。

(4)配置中心,如果故障轉(zhuǎn)移發(fā)生了于个,通知client客戶端新的master地址氛魁。

(1)故障轉(zhuǎn)移時(shí),判斷一個(gè)master node宕機(jī)了厅篓,需要大部分哨兵都同意才行秀存,涉及到分布式選舉問題。
(2)即使部分哨兵節(jié)點(diǎn)掛掉了贷笛,哨兵集群還是能正常工作的应又,因?yàn)槿绻粋€(gè)作為高可用機(jī)制重要組成部分的故障轉(zhuǎn)移系統(tǒng)本身就是單點(diǎn),那么就不靠譜乏苦。

哨兵的核心知識

哨兵至少需要3個(gè)實(shí)例株扛,來保證自己的健壯性。
哨兵+redis主從的部署架構(gòu)汇荐,是不會保證數(shù)據(jù)零丟失的洞就,只能保證redis集群的高可用性
對于哨兵+redis主從這種復(fù)雜的部署架構(gòu),盡量在測試環(huán)境和生產(chǎn)環(huán)境掀淘,都進(jìn)行充分的測試和演練旬蟋。

  1. 為什么 Redis 需要把所有數(shù)據(jù)放到內(nèi)存中?☆☆☆☆☆
    Redis 為了達(dá)到最快的讀寫速度將數(shù)據(jù)都讀到內(nèi)存中革娄,并通過異步的方式將數(shù)據(jù)寫入磁盤倾贰。

所以 redis 具有快速和數(shù)據(jù)持久化的特征冕碟,如果不將數(shù)據(jù)放在內(nèi)存中,磁盤 I/O 速度為嚴(yán)重影響 redis 的性能匆浙。

在內(nèi)存越來越便宜的今天安寺,redis 將會越來越受歡迎, 如果設(shè)置了最大使用的內(nèi)存首尼,則數(shù)據(jù)已有記錄數(shù)達(dá)

到內(nèi)存限值后不能繼續(xù)插入新值挑庶。

侵權(quán)請聯(lián)系刪除~~~~~
-------------------------------------------end----------------------------------------------------
————————————————
版權(quán)聲明:本文為CSDN博主「abluer~」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議软能,轉(zhuǎn)載請附上原文出處鏈接及本聲明迎捺。
原文鏈接:https://blog.csdn.net/qq_43259670/article/details/105927827

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市查排,隨后出現(xiàn)的幾起案子凳枝,更是在濱河造成了極大的恐慌,老刑警劉巖雹嗦,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件范舀,死亡現(xiàn)場離奇詭異,居然都是意外死亡了罪,警方通過查閱死者的電腦和手機(jī)锭环,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泊藕,“玉大人辅辩,你說我怎么就攤上這事⊥拊玻” “怎么了玫锋?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長讼呢。 經(jīng)常有香客問我撩鹿,道長,這世上最難降的妖魔是什么悦屏? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任节沦,我火速辦了婚禮,結(jié)果婚禮上础爬,老公的妹妹穿的比我還像新娘甫贯。我一直安慰自己,他們只是感情好看蚜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布叫搁。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪渴逻。 梳的紋絲不亂的頭發(fā)上疾党,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音惨奕,去河邊找鬼仿贬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛墓贿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜓氨,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼聋袋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了穴吹?” 一聲冷哼從身側(cè)響起幽勒,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎港令,沒想到半個(gè)月后啥容,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顷霹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年咪惠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淋淀。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遥昧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出朵纷,到底是詐尸還是另有隱情炭臭,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布袍辞,位于F島的核電站鞋仍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏搅吁。R本人自食惡果不足惜威创,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望似芝。 院中可真熱鬧那婉,春花似錦、人聲如沸党瓮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呛谜,卻和暖如春在跳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隐岛。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工猫妙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人聚凹。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓割坠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親妒牙。 傳聞我的和親對象是個(gè)殘疾皇子彼哼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容