Apache Kudu的基本思想、架構和與Impala實踐
Apache Kudu是一個為了Hadoop系統環境而打造的列存儲管理器,與一般的Hadoop生態環境中的其他應用一樣,具有能在通用硬件上運行、水平擴展性佳和支持高可用性操作等功能。
在Kudu出現之前,Hadoop生態環境中的儲存主要依賴HDFS和HBase,追求高吞吐批處理的用例中使用HDFS,追求低延時隨機讀取用例下用HBase,而Kudu正好能兼顧這兩者。
Kudu的主要優點:
- 快速處理OLAP(Online Analytical Processing)任務
- 集成MapReduce、Spark和其他Hadoop環境組件
- 與Impala高度集成,使得這成為一種高效訪問交互HDFS的方法
- 強大而靈活的統一性模型
- 在執行同時連續隨機訪問時表現優異
- 通過Cloudera Manager可以輕松管理控制
- 高可用性,tablet server和master利用Raft Consensus算法保證節點的可用
- 結構數據模型
常見的應用場景:
- 剛剛到達的數據就馬上要被終端用戶使用訪問到
- 同時支持在大量歷史數據中做訪問查詢和某些特定實體中需要非常快響應的顆粒查詢
- 基於歷史數據使用預測模型來做實時的決定和刷新
- 要求幾乎實時的流輸入處理
基本概念
列數據存儲 Columnar Data Store
Kudu是一種列數據儲存結構,以強類型的列(strong-type column)儲存數據。
高效讀取
可選擇單個列或者某個列的一部分來訪問,可以在滿足本身查詢需要的狀態下,選擇最少的磁盤或者存儲塊來訪問,相對於基於行的存儲,更節省訪問資源,更高效。
數據比較
由於給定的某一個列當中都是同樣類型的數據,所以對於同一個量級的數據比較時,這種存儲方式比混合類型存儲的更具優勢。
表Table
同理,一種數據設計模式schema,根據primary key來排序組織。一個表可以被分到若干個分片中,稱為tablet。
分片Tablet
一個tablet是指表上一段連續的segment。一個特定的tablet會被復制到多個tablet服務器上,其中一個會被認為是leader tablet。每一個備份tablet都可以支持讀取、寫入請求。
分片服務器 Tablet Server
負責為客戶端儲存和提供tablets。只有Leader Tablet可以寫入請求,其他的tablets只能執行請求。
Master
Master負責追蹤tablets、tablet severs、catalog table和其他與集群相關的metadata。另外也為客戶端協調metadata的操作。
Raft Consensus算法
前文介紹過了
Catalog Table
Kudu的metadata的中心位置,存儲表和tablet的信息,客戶端可以通過master用客戶端api來訪問。
邏輯復制 Logical Replication
Kudu並是不是在硬盤數據上做復制的,而是采取了邏輯復制的辦法,這有以下一些好處:
- 盡管insert和update需要通過網絡對數據做transmit,但是delete操作不需要移動任何數據。Delete操作的請求會發送到每一個tablet server上,在本地做刪除操作。
- 普通的物理操作,比如數據壓縮,並不需要通過網絡做數據transmit,但不同於HDFS,每個請求都需要通過網絡把請求傳送到各個備份節點上來滿足操作需要。
- 每個備份不需要同時進行操作,降低寫入壓力,避免高延時。
隨機寫入效率
在內存中每個tablet分區維護一個MemRowSet來管理最新更新的數據,當尺寸大於一定大小之后會flush到磁盤上行成DiskRowSet,多個DiskRowSet會在適當的時候做歸並操作。 這些被flush到磁盤的DiskRowSet數據分為兩種,一種是Base數據,按列式存儲格式存在,一旦生成不再修改,另一種是Delta文件,儲存Base中有更新的數據,一個Base文件可以對應多個Delta文件。
Delta文件的存在使得檢索過程需要額外的開銷,這些Delta文件是根據被更新的行在Base文件中的位移來檢索的,而且做合並時也是有選擇的進行。
此外DRS(Distributed Resource Scheduler)自身也會合並,為了保障檢索延遲的可預測性。Kudu的DRS默認以32MB為單位進行拆分,Compaction過程是為了對內容進行排序重組,減少不同DRS之間key的overlap,進而在檢索的時候減少需要參與檢索的DRS的數量。
Kudu整體框架
與Impala的簡單實踐
安裝部分不寫了,自己都裝出屎了。
通過Impala使用Kudu可以新建內部表和外部表兩種。
- 內部表(Internal Table):事實上是屬於Impala管理的表,當刪除時會確確實實地刪除表結構和數據。在Impala中建表時,默認建的是內部表。
- 外部表(External Table):不由Impala管理,當刪除這個表時,並不能從源位置將其刪除,只是接觸了Kudu到Impala之間對於這個表的關聯關系
創建一個簡單的Kudu表:
CREATE TABLE kaka_first
(
id BIGINT,
name STRING
)
DISTRIBUTE BY HASH INTO 16 BUCKETS
TBLPROPERTIES(
'storage_handler' = 'com.cloudera.kudu.hive.KuduStorageHandler',
'kudu.table_name' = 'kaka_first',
'kudu.master_addresses' = '10.10.245.129:7051',
'kudu.key_columns' = 'id'
);
建表語句中,默認第一個就是Primary Key,是個not null列,在后面的kudu.key_columns
中列出,這邊至少寫一個。
- storage_handler:選擇通過Impala訪問kudu的機制,必須填成
com.cloudera.kudu.hive.KuduStorageHandler
- kudu.table_name:Impala為Kudu建(或者關聯的)的表名
- kudu.master_addresses:Impala需要訪問的Kudu master列表
- kudu.key_columns:Primary key列表
插入數據
INSERT INTO kaka_first VALUES (1, "john"), (2, "jane"), (3, "jim");
Impala默認一次同時最多插入1024條記錄,作為一個batch
更新數據
UPDATE kaka_first SET name="bob" where id = 3;
刪除數據
DELETE FROM kaka_first WHERE id < 3;
修改表屬性
ALTER TABLE kaka_first RENAME TO employee;
//重命名
ALTER TABLE employee
SET TBLPROPERTIES('kudu.master_addresses' = '10.10.245.135:7051');
//更改kudu master address
ALTER TABLE employee SET TBLPROPERTIES('EXTERNAL' = 'TRUE');
//將內部表變為外部表
一個應用
從MySql導出數據到本地txt
select * from DAYCACHETBL into outfile '/tmp/DAYCACHETBL.txt'
fields terminated by '\t'
lines terminated by '\n';
保存到hdfs中/data
目錄下
hdfs dfs -mkdir /data
hdfs dfs -put /tmp/DAYCACHETBL.txt /data
在hive shell中創建hive表
create table DAYCACHETBL (
METERID string,
SOURCEID int,
VB double,
DELTA double,
DTIME string,
UPGUID string,
UPBATCH string,
level string,
YEAR string,
MONTH string,
QUARTER string,
WEEK string,
D_DELTA double
)
ROW FORMAT DELIMITED
fields terminated by '\t'
lines terminated by '\n'
stored as textfile
location '/data';
在impala-shell下創建kudu表
create table DAYCACHETBL2 (
METERID string,
SOURCEID int,
VB double,
DELTA double,
DTIME string,
UPGUID string,
UPBATCH string,
level string,
YEAR string,
MONTH string,
QUARTER string,
WEEK string,
D_DELTA double
)
DISTRIBUTE BY HASH INTO 16 BUCKETS
TBLPROPERTIES(
'storage_handler' = 'com.cloudera.kudu.hive.KuduStorageHandler',
'kudu.table_name' = 'DAYCACHETBL2',
'kudu.master_addresses' = 'kudu1:7051,kudu2:7051,kudu3:7051',
'kudu.key_columns' = 'METERID'
);
將hive表中的內容插入kudu表
insert into DAYCACHETBL2 select * from DAYCACHETBL;