hive 鎖定(翻譯自Hive wiki)


Hive 並發模型

使用案例

並發支持 (http://issues.apache.org/jira/browse/HIVE-1293) 是數據庫的必須,而且他們的使用案例很好懂。至少,我們要盡可能支持並發讀和寫。添加幾個發現當前已經鎖定的鎖,是有用的。這里沒有一個直接的需求添加一個API顯式獲取鎖,所以,所有鎖都是隱式獲取的。

hive定義一下模式的鎖(注意不需要意向鎖)

  • 共享 (S)
  • 排他 (X)

見名知意,多個共享鎖可以同時獲取,而排他鎖會阻塞其他鎖。

兼容性列表如下:

  • *
Existing Lock S X
Requested Lock
  • *
  • *
  • *
S
  • *
True False
X
  • *
False False

對於一些操作,鎖的性質是有層次的。例如,一些分區操作,表也是被鎖定(例如,保證表的分區正在創建時,表不能被刪除)

鎖模式獲取背后的原理如下:

對於非分區表,鎖定模式相當直觀。當表正在讀取時,一個S鎖被獲取。而對其他操作(插入數據到表,修改表的任何屬性)就要獲取X鎖。

對於分區表,原理如下:

當讀取表分區時,會獲取表的S鎖。對於其他操作,會獲取分區的X鎖。但是,如果修改僅僅是針對新分區,就會獲取表的S鎖,而修改是針對所有分區,會獲取表的X鎖。

所以,當舊分區讀寫時,新分區也可以被轉換為RCFile。

無論何時,分區被鎖定時,會獲取所有的它的父節點的S鎖。

基於這,操作的鎖獲取如下:

Hive Command Locks Acquired
select .. T1 partition P1 S on T1, T1.P1
insert into T2(partition P2) select .. T1 partition P1 S on T2, T1, T1.P1 and X on T2.P2
insert into T2(partition P.Q) select .. T1 partition P1 S on T2, T2.P, T1, T1.P1 and X on T2.P.Q
alter table T1 rename T2 X on T1
alter table T1 add cols X on T1
alter table T1 replace cols X on T1
alter table T1 change cols X on T1
alter table T1 add partition P1 S on T1, X on T1.P1
alter table T1 drop partition P1 S on T1, X on T1.P1
alter table T1 touch partition P1 S on T1, X on T1.P1
*alter table T1 set serdeproperties * S on T1
*alter table T1 set serializer * S on T1
*alter table T1 set file format * S on T1
*alter table T1 set tblproperties * X on T1
drop table T1 X on T1

為了避免死鎖,這里提出一個非常簡單的計划.所有鎖定的對象按照字典排序,然后在按照鎖定模式獲取。注意一些場景,對象列表可能不知道——例如,動態分區,編譯時不知道正在修改的分區列表。所以,列表會保守生成,由於分區的數量可能不知道,所以會在表或所知的前綴上獲取排他鎖。

添加兩個可配置的參數,決定鎖嘗試時,鎖嘗試次數和等待時間。如果重試的次數是非常高的,它可以導致一個活鎖。參考zookeeper recipes(http://hadoop.apache.org/zookeeper/docs/r3.1.2/recipes.html#sc_recipes_Locks),理解如何使用zookeeper apis實現read/write鎖。需要注意的是,不是等待的鎖請求將被拒絕。存在的鎖將會釋放,然后等待的鎖會在嘗試周期后繼續嘗試。

因為鎖的分層特性,上面列出的規定recipe將無法正常工作:

 

表T的S鎖規定如下:

調用create( ),創建一個路徑名為"/warehouse/T/read-"的節點。協議中,這個鎖定的節點會在后面使用。保證設置序列和臨時標志。

在鎖定的節點調用getChildren( ),不設置watch的標記

如果已經有一個子節點,路徑名以"write-"和一個更小的序列號數字開頭,已經被獲取了,那么這個鎖不能被獲取。刪除第一步驟創建的節點,返回。

否則授權鎖。

 

表T的X鎖規定如下:

調用create( ),創建一個路徑名為"/warehouse/T/write-"的節點。協議中,這個鎖定的節點會在后面使用。保證設置序列和臨時標志。

在鎖定的節點調用getChildren( ),不設置watch的標記

如果已經有一個子節點,路徑名以"read-"或者"write-"和一個更小的序列號數字開頭,已經被獲取了,那么這個鎖不能被獲取。刪除第一步驟創建的節點,返回。

否則授權鎖。

擬定的計算,為了讀飢餓了寫,如果遇到長時間的讀,會導致寫的飢餓。

這個默認hive行為不會改變,並發不會支持。

 

關閉並發

關閉並發,可以修改下面的變量為false: hive.support.concurrency

調試

查看表的鎖,可以執行下面的命令:

SHOW LOCKS <TABLE_NAME>;
SHOW LOCKS <TABLE_NAME> extended;
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>);
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>) extended;

 

翻譯自 https://cwiki.apache.org/confluence/display/Hive/Locking


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM