1. 四種數據庫的比較
數據庫 | 描述 |
---|---|
Greenplum | 開源大規模並行數據分析引擎。借助MPP架構,在大型數據集上執行復雜SQL分析的速度比很多解決方案都要快。應用廣泛。 |
Teradata | 大型數據倉庫系統,產品成熟,價格昂貴。用於證券系統。 |
Presto | 分布式SQL查詢引擎, 專門進行高速、實時的數據分析。本身不存儲數據,但是可以接入多種數據源。擅長對海量數據進行復雜的分析。用於大數據量分析。 |
Clickhouse | 用於在線數據分析。支持功能簡單。CPU 利用率高,速度極快。用於行為統計分析。 |
2. Greenplum數據庫
2.1 Greenplum架構
2.1.1 采用MMP架構
-
master host:負責與客戶端對接, 不包含任何用戶數據,使用postgres數據庫內核,保存有元數據,與segment 由局域網通訊。
-
segment:存放數據,監聽master的連接,用戶只能通過master訪問,是獨立的PostgreSQL數據庫。一個節點可運行多個segment實例
-
Interconnect:協調進程,由局域網互連,支持TCP or UDP
2.2.2 Hadoop與MPP的應用區別
Hadoop | MPP |
---|---|
非結構化數據,半結構化數據 | 關系數據 |
海量數據存儲查詢、批量數據ETL、日志分析、文本分析 | 多維度數據自助分析、數據集市 |
- 可將兩種架構混合使用(MPPDB+Hadoop):用MPP處理PB級別的、高質量的結構化數據,同時為應用提供豐富的SQL和事物支持能力;用Hadoop實現半結構化、非結構化數據處理。這樣可以同時滿足結構化、半結構化和非結構化數據的高效處理需求。
2.2 greenplum 的高可用性
2.2.1 master冗余
-
設立Standby 節點復制master的系統目錄表日志( catalog tables )
-
master壞掉時需由管理員觸發**standby成為新master。
-
使用基於預讀日志(WAL)的流復制來保持primary master和standby master服務器同步。
2.2.2 segment冗余
- 主segment接收來自master的請求以更改主segment的數據庫,然后將這些更改復制到相應的mirror segment上。
- 可選擇對主機mirror(group mirroring)或對segment分散mirror(spread mirroring)。
- group mirroring:一台機器出現問題時,另一台機器將有兩倍負荷
- spread mirroring:可負載均衡
- 當segment實例或主機發生故障,master將記錄實例的down狀態,並**與其對應的segment實例。
- Mirror segment采用物理文件復制的方案,而對於堆表,會先同步日志,當主segment的塊需要寫回磁盤時再同步mirror的文件,primary segment失敗時,mirror自動成為primary,且狀態為 Change Tracking。mirror失敗時,primary會將狀態改為 Change Tracking
- AO表(Append-optimized)不使用內存緩存機制。對AO表的塊所做的更改會立即復制到mirror segment上。
2.3 greenplum的並行查詢
- 一個表的數據按hash映射分布在不同segment節點上,每次操作產生一個slice,slice之間通過 gather、broadcast、redistribution 方式傳播
gather | broadcast | redistribution |
---|---|---|
每個節點數據發至master節點 | 表數據分布在各節點上,需每個節點發數據至每個節點,使每個節點都擁有表的完整數據,適用於小表 | join與group by時,廣播代價大時可按鍵重新將各節點數據打散至各節點再對每個節點操作,適用於大表 |
- greenplum支持有三種存儲方式: 行存儲、列存儲、外部表
行存儲 | 列存儲 | 外部表 |
---|---|---|
多列更新快 | 一次只訪問幾個字段,壓縮比高 | 數據庫只保留元數據信息 |
- 可以對數據進行hash分區或范圍分區
2.4 greenplum的多版本控制(MVCC)
事務型數據庫用鎖機制控制並發訪問,greenplum用多版本控制保證數據一致性。最大的好處是讀寫不沖突,讀的是snapshot。
3 Teradata數據庫
3.1 Teradata 數據庫架構
每個節點物理上是一個SMP處理單元(多CPU計算機),節點硬件包括CPU、內存、磁盤、網卡、BYNET端口
網卡:與IBM MainFrame連接的Channel Adapter;局域網網卡。 一個節點上只會使用一種網卡,但會有多塊網卡,分別用於不同的連接和冗余。
3.1.1 連接層
CLI( call level interface ):請求響應、創建session、緩沖區分配、信息打包
TDP( teradata director program ): 運行在客戶端系統:session初始化終止、登陸、驗證、恢復重起、現有人員傳遞至PE的 session 隊列
MTDP( micro TDP ):與TDP的區別是不負責session在PE間分配。
MOSI( micro operating system interface ):實現不同數據庫平台上運行的隔離層
3.1.2 PE層(parsing engine)
-
session control:主控logon、logoff
-
**parser:**解析sql,判斷語法語義正確性,查詢字典確認請求對象是否存在,用戶是否有權限
-
**optimizer:**評估執行計划,轉為AMP可執行步驟
-
**dispatcher:**分配AMP 所選任務,返回用戶結果
3.1.3 MPL層(message passing layer)
MPL 層負責 PE 與 AMP之間傳送信息、合成的返回結果集傳 PE,由 PDE 與 Bynet 軟硬件組成
PDE (parallel database extension):
- 直接架構在操作系統之上的一個接口層 , 提供並行環境, 執行虛擬處理器、進行Teradata並行任務調度、進行操作系統內核和Teradata數據庫的運行時故障處理。
bynet軟件、硬件:
- 用於節點之間的雙向廣播(bidirectional broadcast)、多路傳遞(multicast)和點對點通信(point-to-point communication),
- BYNET還實現SQL查詢過程中的合並功能(每個節點或AMP,均勻分布表中一部分數據,當查詢的時候每個節點並行查詢,結果匯總到某個節點反饋給查詢者,提高查詢速度。
- 一般典型的teradata有兩個BYNET同時工作 , BYNET自動均衡,避免某一個負載太多
- PE能支持120個session處理,每個session可管理16個請求與相關結果,但每個時間點只有一個請求活動
3.1.4 AMP層
AMP(access module process)
-
ShareNothing架構的核心。
-
一個AMP最多控制 64個物理磁盤 (對商用OLTP來說,主要由DBA控制記錄在磁盤的分布)
-
hash算法類似矩陣映射,修改AMP數時只需變動hashmap,速度非常快。
-
每個AMP可並行處理80個任務
AMP功能:
- 排序、聚合、格式化、轉換操作
- 可能將數據傳給其它 AMP
- Lock 數據庫或表
- 返回結果給dispatcher
- 空間使用控制和空間分配
- 輸出數據的編碼轉換,與PE相反的工作
3.1.5 VDisk層
存儲數據根據哈希算法被均勻分散存儲到磁盤陣列中的不同的磁盤上。RAID0 與 RAID5 為主。因采用混合均勻存儲而不存在數據庫重組問題。
3.2 Teradata的並行處理能力
查詢並行:每個AMP作為一個虛擬進程,獨立處理一部分數據(如查詢一個表)
步內並行:每個運算步驟都由多個進程並行處理(如借助於pipline的 join操作)
多步並行:優化器分解sql請求原則是盡可能使各步獨立(如兩個表的查詢同時進行)
傳統 OLTP 對於提出的新的問題,DBA 會建立一條新的索引,可能使數據庫占用磁盤空間過大。而 teradata 采用將相同執行步驟的執行結果暫存於系統緩沖區的方法, 減少數據庫本身的大小。
teradata 提供的並行 OLAP 操作有:排序、累計、移動平均、移動和、移動養分、采樣、分位、限定
3.3 Teradata做的優化
3.3.1 大數據量與小數據量訪問矛盾
teradata 在解決 hash 函數范圍查詢需要訪問所有數據的問題時引入用戶索引(分區主索引PPI),將數據按索引進行分區
3.3.2用戶管理
引入角色來分配權限
引入用戶參數為用戶配置持久空間(分配的最大存儲容量)、spool空間(存放中間過程與最后結果 )、臨時空間(存放global temporary table被實例化的數據)限制、缺省數據庫設定、用戶密碼設定
3.3.3 索引
AMP分組:對一個操作只使用部分amp單元進行處理,提高數據吞吐量
利用稀疏索引來去除大量空值索引
3.3.4 加速處理
-
解析器與分派器合為一
-
增強插入更新能力
-
引入合並更新
3.3.5 索引
-
對於unique key 元組在各磁盤分布
-
對於none-unique key 元組按key分布
-
次索引一般沒有必要,taradata本身性能很高
3.3.6 鎖機制
-
排它鎖(create table):拒絕任意鎖
-
寫鎖(update):拒絕read、write、exclusive
-
讀鎖(select):拒絕write、exclusive
-
訪問鎖:只拒絕排它鎖(用於積累大量行數據,但結果可能不是最新結果)
4 Presto數據庫
presto是facebook為了改進之前基於map-reduce的hive框架查詢數據倉庫時間過長而開發的數據分析工具。Presto本身不是數據庫,而是分布式查詢引擎。Presto可以訪問HDFS,及其他數據源,數據庫。但不能處理在線事務。
Presto被設計為數據倉庫和數據分析產品:數據分析、大規模數據聚集和生成報表。這些工作經常通常被認為是線上分析處理操作 。
4.1 Presto架構:
采用 master - slave 模型:
-
**coordinator:**master,負責meta管理,worker管理,query解析與調度
-
worker: 計算與讀寫
-
discovery server: 通常內嵌於coordinator節點中,也可以單獨部署,用於節點心跳。
4.2 Presto數據模式
-
catalog:一類數據源,如mysql,hive
-
schema:數據庫
-
table:表
存儲單元包括 page,block:
page:多行數據集合,包含多列,但只提供邏輯行,實際以列存儲
block:一列數據
-
array類型 int 、long、double
- valueisnull[] 一行是否有值
- value[] 一行具體值
-
可變寬 string
- slice 所有行拼接的字符串
- offset 每一行的偏移位置
- valueisnull[] 某行是否有值
-
固定寬string
-
字典(distinct值較少)
- 任意類型
- ids[] 每一行數據對應字典中編號
4.3 Presto查詢
**sql 查詢:**http POST 請求
**抽象語法樹:**以 query 為單位,分層表示子查詢
**邏輯計划:**將抽象語法樹轉為最簡單操作
優化器:
- 把聚合節點寫成map-reduce形式(partial node 和 final node)
- 在map-reduce節點插入exchange節點
- 將提前加速節點下扒
- 能合並的合並
**調度器:**以exchange節點划分的段為單位進行調度
- 每類fragment 由哪些機器執行
- source類型任務:根據meta決定讀取多少split,分配一個split到一台機器, 在配置中指定了network-topology=flat,則盡量選擇split所在的機器。 每個結果會向每個上層fragment的機器發送
- fixed類型與single類型(由 query.initial-hash-partitions參數配置,默認是8 ):為某個fragment分配幾台機器,中間結果分配多台機器,只最后結果分配一台機器
- 下游機器多台的(group by)按 groupby計算hash,按hash選擇一個下游機器輸出, 對於非group by的計算,會隨機選擇或者round robin。
物理執行計划:
- fragment發送到機器上后,由結點樹形式轉寫成operator list,根據邏輯代碼動態編譯生成字節碼。動態生成字節碼,主要是利用編譯原理:
- 展開循環
- 根據數據列的類型,直接調用對用的函數,以減少分支跳轉語句。
-
source類型的operator ,每一次調用都會獲取一份新的數據;對於Aggregate的operator,只有之前所有的operator都finish之后,才能獲取輸出結果。
-
聚合計算有兩類
- AggregationOperator:對每行操作,每次輸出一個結果
- HashAggregationOperator:對列用hash計算key,key相同才把結果存在一起,用於group by類計算
-
聚合計算均提供四個接口用於在map-reduce之間加一層計算,接受中間結果輸入輸出。
-
接受原始數據的輸入
-
接受中間結果的輸入
-
輸出中間結果
-
輸出最終結果。
-
-
函數分兩類:
-
Scaler函數:數據的轉換處理,不保存狀態,一個輸入產生一個輸出。
-
Aggregate函數:數據的聚合處理,利用已有狀態+輸入,產生新的狀態。
-
4.4 Presto內存管理
內存池:
- system pool:40% 留給系統
- reserve pool:10% 留給最大query
- general pool:用於一般查詢
為了防止大任務分配到每台機器后一部分(在該機器是最大內存的任務)在reserve pool執行完成,另一部分(在該機器不是最大內存任務)在general pool等待執行,造成死鎖,presto將最大query分配給reserve pool的任務交給coordinator去做(雖然這會造成一部分不執行這個query的機器reserve pool 浪費),而不是讓每台機器把最大query任務在reserve pool執行。
cordinator計算query的每個task的內存大小,同時有一個線程定期輪訓每台機器內存狀態,匯總query內存與機器內存后, coordinator會挑選出一個內存使用最大的query,分配給Reserved Pool。
4.5 Presto實現低延時查詢的原理
-
傳統 sql 優化
-
完全基於內存的並行計算
- 源數據的並行讀取:每個 Source節點 調用 HDFS InputSplit API , 然后每個InputSplit分配一個Worker節點去執行
- 分布式hash聚合:partial任務的結果按group by的hash值分配不同計算節點
-
流水線
- 每個worker從優先級隊列中取 PrioritizedSplitRunner 對象,周期檢查完成情況並刪除完成的任務,未完成的放回隊列
- 每個節點的exchange操作為每個向上一個Stage的Worker節點拉數據,數據的最小單位是一個Page對象,取到數據后放入Pages隊列中
- 任務執行時每個operator從上一個operator取page,數據存在則執行(page是由列存儲的block組成的幾行數據)
-
本地化計算
- 優先選擇數據在的位置節點作為worker
-
動態編譯執行計划(如循環展開優化): 使用Google Guava提供的LoadingCache緩存生成的Byte Code。
-
小心使用內存和數據結構
使用Slice進行內存操作,Slice使用Unsafe#copyMemory實現了高效的內存拷貝,
-
類BlinkDB的近似查詢
為了加快avg、count distinct、percentile等聚合函數的查詢速度, 引入了一些近似查詢函數approx_avg、approx_distinct、approx_percentile。approx_distinct使用HyperLogLog Counting算法實現。
- HyperLogLog 算法:key值hash轉為64位bit,取低6位作為實驗輪數(桶號),取60位中第一個出現1的位置的序號,轉為2進制bit,存入桶中。統計每個桶中最大的序號,由下公式得到元素的部數量
- HyperLogLog 算法:key值hash轉為64位bit,取低6位作為實驗輪數(桶號),取60位中第一個出現1的位置的序號,轉為2進制bit,存入桶中。統計每個桶中最大的序號,由下公式得到元素的部數量
-
GC控制
Presto團隊在使用hotspot java7時發現了一個JIT的BUG,當代碼緩存快要達到上限時,JIT可能會停止工作,從而無法將使用頻率高的代碼動態編譯為native代碼。
Presto團隊使用了一個比較Hack的方法去解決這個問題,增加一個線程在代碼緩存達到70%以上時進行顯式GC,使得已經加載的Class從perm中移除,避免JIT無法正常工作的BUG。
Presto TPCH benchmark測試
5 ClickHouse數據庫
5.1 ClickHouse 架構
5.1.1 clickHouse 存儲架構
5.1.2 ClickHouse部署
-
擴展性
clickhouse本身不擴展,可借助Distributed引擎(本身不存儲數據)
寫:
-
指定哪些數據寫入到哪些節點里
-
通過一個節點寫,數據分到不同的節點里,通過指定分片的key來分發數據。
-
數據寫入是異步的,對於插入數據到集群的其他節點,數據先是寫入到本地磁盤,然后在后台發送到其他分片服務器,如果想查看數據有沒有同步完,可以檢查下面的目錄:/var/lib/clickhouse/data/database/table
讀:
- 由一個節點收集所有節點數據返回客戶端
-
-
可靠性
依賴於zookeeper,使用物理復制
5.2 ClickHouse數據庫系統特點
- 在內存數據庫領域號稱是最快的。
-
數據始終以列存儲,包括矢量執行過程。
-
有兩種不同的加速查詢處理的方法: 矢量化查詢執行和運行時代碼生成
-
clickhouse是列存儲數據庫,使用向量查詢技術,select,orderby,limit操作都不改原列向量,而是新建。適合少修改的數據。
-
clickhouse使用抽象滲漏提高速度,使列的數據與數據類型、數據塊處理分離。
-
查詢流水線每一步中間數據都保存,臨時數據要適合CPU緩存。
-
對於分布式數據不完全支持join這樣的復雜查詢。
-
ClickHouse 使用稀疏索引,不適合高負載的點狀查詢。
-
ClickHouse 不依賴Hadoop 生態
-
不支持事物,不支持Update/Delete操作
-
向量化引擎:數據不僅按列存儲,而且由矢量 - 列的部分進行處理。這使我們能夠實現高CPU性能。
-
允許在運行時創建表和數據庫,加載數據和運行查詢,而無需重新配置和重新啟動服務器。
5.3 ClickHouse運行快的原因
-
它的數據剪枝能力比較強,分區剪枝在執行層,而存儲格式用局部數據表示,就可以更細粒度地做一些數據的剪枝。它的引擎在實際使用中應用了一種現在比較流行的 LSM 方式。
-
它對整個資源的垂直整合能力做得比較好,並發 MPP+ SMP 這種執行方式可以很充分地利用機器的集成資源。它的實現又做了很多性能相關的優化,它的一個簡單的匯聚操作有很多不同的版本,會根據不同 Key 的組合方式有不同的實現。對於高級的計算指令,數據解壓時,它也有少量使用。
-
ClickHouse 是一套完全由 C++ 模板 Code 寫出來的實現
-
不支持Transaction
-
使用了矢量化查詢執行
- 當進行查詢時,操作被轉發到數組上,而不是在特定的值上
- 向量化查詢執行實用性並不那么高,如果臨時數據並不適合L2緩存,讀緩存將有問題。但是向量化查詢執行更容易利用CPU的SIMD能力。
-
提供了有限的運行時動態代碼生成(group by的內部循環第一階段)。
- 運行時代碼生成可以更好地將多個操作融合在一起,從而充分利用 CPU 執行單元和流水線。矢量化查詢執行不是特別實用,因為它涉及必須寫到緩存並讀回的臨時向量。如果 L2 緩存容納不下臨時數據,那么這將成為一個問題。但矢量化查詢執行更容易利用 CPU 的 SIMD 功能。
6 OLAP相關知識
6.1 OLTP與OLAP
**聯機事務處理( OLTP)**由業務數據庫所支持,數據固定,操作負載少,強調數據庫一致性與可恢復性。
**在線分析處理(OLAP )**由數據倉庫支持,反應歷史數據、多來源數據,通常多維建模,典型的OLAP操作有:上鑽(聚合)、下鑽(展開)、切割(選擇和投影)、軸轉(多維視圖)。
OLAP的查詢問題有不確定性。
OLAP數據庫最關鍵的兩個因素是:並行處理與可擴展性
ROLAP(關系型OLAP):在標准的或擴展的關系DBMS 上,支持擴展SQL和特殊訪問
MOLAP(多維OLAP ):直接把多維數據存儲在特定的數據結構
6.2 OLAP場景的關鍵特征
- 大多數是讀請求
- 數據總是以相當大的批(> 1000 rows)進行寫入
- 不修改已添加的數據
- 每次查詢都從數據庫中讀取大量的行,但是同時又僅需要少量的列
- 寬表,即每個表包含着大量的列
- 較少的查詢(通常每台服務器每秒數百個查詢或更少)
- 對於簡單查詢,允許延遲大約50毫秒
- 列中的數據相對較小: 數字和短字符串(例如,每個URL 60個字節)
- 處理單個查詢時需要高吞吐量(每個服務器每秒高達數十億行)
- 事務不是必須的
- 對數據一致性要求低
- 每一個查詢除了一個大表外都很小
- 查詢結果明顯小於源數據,換句話說,數據被過濾或聚合后能夠被盛放在單台服務器的內存中
7 數據庫技術中常見名詞與技術
7.1 數據共享的方式
shared everything(SMP):網絡與磁盤是瓶頸(SQLServer)
shared disk(NUMA): 存儲器接口達到飽和的時候,增加節點並不能獲得更高的性能 (Oracle Rac)
shared nothing(MPP): 各自處理自己的數據,可擴展,成本低
7.2 MPP大規模並行處理架構
● 任務並行執行;
● 數據分布式存儲(本地化);
● 分布式計算;
● 私有資源;
● 橫向擴展;
● Shared Nothing架構。
7.2 MPPDB特征
(1)無master 高平結構
(2)可處理 PB 級數據,采用 hash 分布、random 策略存儲,采用先進壓縮算法
(3)高擴展,支持集群擴容縮容
(4)高並發:讀寫不互斥,可邊加載邊查詢
(5)行列混合存儲
7.3 列存儲技術(達夢商用數據庫為例)
數據組織實現:
不同於普通段、簇、頁管理,采用HTS(huge tablespace)相當於文件系統。
HTS -> SCH模式目錄 -> TAB表目錄 -> COL列(.dta文件,默認64M)-> 區(存儲行數在一開始就指定,開始位置4k對齊)
輔助表:管理HTS中數據,每條記錄對應一個區,查詢在輔助表進行
智能索引:
一定程度上可以替代BTree索引,最大最小值可起到過濾作用
自適應壓縮:
-
字典編碼
-
異常值( 少數不同時, 異常值使用<行號+值>的方式存儲 )
-
RLE編碼(數據大量相同,每個值個數較均勻)
-
序列編碼(存在代數關系時,可只存與共用基礎數值的差值,)
自適應的步驟:
- 如果該列為自增列或序列,則直接使用序列編碼;
- 獲得區數據統計信息:不同值個數n_dist、每個不同值個數、不同值數據指針、每個值連續出現的次數、整型數的最大值;
- 根據獲得的區統計信息,確定使用常量編碼、RLE編碼還是字典編碼;這三種編碼的使用順序為:優先使用常量編碼,其次使用RLE編碼,最后才使用字典編碼。
- 如果編碼后的總長度超過了原始長度,則不編碼,直接返回;
- 注:解壓引起的性能損失遠遠小於磁盤IO等待的開銷。
7.4 RAID方案
以 RAID1 與 RAID5 最常見
JBOD | 磁盤直接串連 |
---|---|
JBOD | 磁盤直接串連而成的磁盤櫃 |
RAID0 | 無冗余分布存儲 |
RAID1 | 鏡像冗余 |
RAID2 | 海明碼校驗,4個磁盤存數據分布存儲,3個磁盤校驗,實際很少用 |
RAID3 | 至少三數據盤分布存儲(按位分布或按字節分布),一磁盤校驗,適用於大容量分散順序訪問。RAID3在有壞盤時性能下降,常由RAID5代替 |
RAID4 | 同RAID3,但按塊分布,讀性能好,寫性能差,實際少見 |
RAID5 | 同RAID4,校驗數據分布在各磁盤,不存在RAID4的寫瓶頸,目前最佳方案 |
RAID6 | 上面只保護單個磁盤失效,RAID6為雙重校驗(可在兩個磁盤用兩種算法存不同的校驗數據),寫性能差 |
RAID00 | 雙重RAID0 |
RAID01 | 先鏡像1再條帶化0,保證數據安全性的同時又提高了性能 |
RAID10 | 先條帶化0再鏡像1,保證數據安全性的同時又提高了性能 |
RAID30/50/60 | 提高性能 |
RAID7 | 一套事件驅動的操作系統,采用非同步訪問減輕寫瓶頸提高IO,自動讀寫優化 |
RAID-DP | 采用NVRAM存儲寫數據,掉電也不丟失,集中寫,采用RAID6,性能比RAID4下降小於2%,固件實時更新時也不中斷 |
RAID5E | 提供冗余盤,在一塊磁盤損壞時自動降級至RAID5,時間較長 |
7.5 LSM-Tree (long structured merge tree)
-
最大的特點就是寫入速度快,主要利用了磁盤的順序寫
-
LSM-tree 主要針對的場景是寫密集、少量查詢的場景。 被用於各種鍵值數據庫
- 寫:一次寫操作會先寫入內存(f0層), 數據達到一定大小,就使用歸並排序來合並,並寫入磁盤(f1層),當磁盤f1層達到一定大小會繼續合並為c2層。
- 讀:查詢時是一層一層向下查
-
lsm-tree 的一種實現 LevelDB:文件分三種,內存中有memtable,immutable,磁盤中有SStable(sorted string table)寫會寫入memtable,當達到閾值,就把immutable合並入磁盤並把memtable轉為immutable。
7.6 kafka 並行框架
7.6.1 kafka 架構
Topic 和 Partition
在 Kafka 中的每一條消息都有一個 Topic,Kafka 為每個topic維護了分布式的分區(Partition)日志文件, 發布到此 Partition 的消息都會被追加到 Log 文件的尾部,由offset數組記錄消息位置。保證partition下消息有序,但topic下消息非有序
消費模型
Kafka 采取拉取模型(Poll),由自己控制消費速度,防止基於推送(push)因消費進程掛掉或網絡不好導致的消息丟失
網絡模型
-
多線程的 Selector 模型 : Acceptor 運行在一個單獨的線程中, 讀取操作會在 Selector 注冊 Read 事件。 成功后,將請求放入 Message Queue共享隊列中。 寫線程池中,取出這個請求,對其進行邏輯處理。
-
這樣,即使某個請求線程阻塞了,還有后續的線程從消息隊列中獲取請求並進行處理。
-
在寫線程中處理完邏輯處理,由於注冊了 OP_WIRTE 事件,所以還需要對其發送響應。
7.6.2 kafka 高可靠分布式存儲模型
依靠的是副本機制,就算機器宕機也不會數據丟失。
Producer 向 Leader 發送數據時,可以通過 request.required.acks 參數來設置數據可靠性的級別:
• 1:默認選項,producer收到一次確認即完成。
• 0:無需確認
• -1:ISR 中的所有 Follower 都確認接收到數據后才算一次發送完成,可靠性最高。
(ISR = Leader + 較新副本)ISR可用於替代leader
AR(Assigned Replicas) = ISR + 老副本
確認模式 | request .required .acks | 描述 | 特點 |
---|---|---|---|
al-least-once | 1 | Producer 收到來自 Ack 的確認,則表示該消息已經寫入到 Kafka 了 | Producer 超時或收到錯誤,重試發送消息,可能導致消息寫入兩次 |
at-most-once | 0 | 發送后無需確認 | |
exactly-once | -1 | 保證消息最多一次地傳遞給 Consumer | kafka實現:每個producer向特定topic的特定partition維護一個序號,每次broker收到消息都要求producer序號比自己的大1 |
Kafka 中事務實現 exactly-once 語義。
7.5.3 高性能的日志存儲
- 一個 Topic 下面的所有消息都是以 Partition 的方式分布式的存儲在多個節點上。
-
每個 Partition 其實都會對應一個日志目錄,在目錄下面會對應多個日志分段(LogSegment)。
LogSegment 文件由兩部分組成,分別為“.index”文件和“.log”文件,分別表示為 Segment 索引文件和數據文件。
-
由於 Kafka 消息數據太大,如果全部建立索引,既占了空間又增加了耗時,所以 Kafka 選擇了稀疏索引的方式,這樣索引可以直接進入內存,加快偏查詢速度。
轉自:https://blog.csdn.net/qq_37517281/article/details/105466829