《Greenplum5.0 最佳實踐》 訪問HDFS存儲 (七)
訪問Hadoop集群中數據用到的工具有 外部表 external tables 和 gphdfs 協議, Greenplum 可以從 HDFS 上讀取文件也可以向 HDFS 寫文件。為了達到更快的性能,所有的段數據庫是並行地讀取 HDFS 中的數據。
當Hadoop集群采用的是 Kerbes 實現集群中各個節點的認證的,以確保集群數據不被惡意攻擊。那麼 Greenplum 必須使用的用戶為 gpadmin, 該用戶擁有對外部表的讀寫權限在HDFS中,需要通過 Kerbes 的授權。為了實現對 gpadmin 的授權,需要驗證和故障排除配置。(關於kerbes的信息參看參考文獻)
前期準備工作
確保功能正常和網絡正常
1. Greenplum 數據庫集群
2. 有 Kerberos-Hadoop 集群 (具體配置參考 Greenplum Database Release Notes for supported Hadoop version 都支持那些版本的HDFS )
3. Kerberos 秘鑰服務
配置 Greenplum集群
Greenplum 必須安裝 JRE, Hadoop 客戶端文件, Kerberos 客戶端文件。
按照下麵的順序準備安裝
- 在GPDB的所有節點上都安裝相同版本的 JAVA 1.6 或者之後的版本。最好和 Hadoop 集群中配置的 JAVA環境一致。 使用命令為 java --version
- (可選項) 確認存在 Java 加密擴展 (Java Cryptography Extension JCE). 默認情況下該擴展包在 JAVA_HOME/lib/security 下。 如果安裝的是 JDK, 那麼其所在的文件路徑為 JAVA_HOME/jre/lib/security, 這個文件有 local_policy.jar 和 US_eport_policy.jar 。需要注意的是 Greenplum 和 Kerberos 都應該使用的相同的 JCE 版本。
- 在 .bashrc 或者 .bash_profile 中配置 JAVA_HOME 環境變量。
export JAVA_HOME=/usr/java/jd../
- 執行如下代碼使得環境變量生效
source .bashrc
source .bash_profile- 安裝 Kerberos 客戶端, 在所有的Greenplum節點上。確保這個安裝文件要和已有的 KDC 版本匹配 在centos 上執行如下命令:
$ sudo yum -y install krb5-libs krb5-workstation $ kinit ## 用來確定是否安裝成功
- 對Greenplum中的全部節點都安裝 Hadoop 客戶端, 參考 Hadoop 發行版相關的文件。
- 針對 Hadoop 設置Greenplum集群的參數配置。 版本為 gp_hadoop_target_version 參數用來確定 Hadoop 的版本。 gp_hadoop_home 確定Hadoop的安裝路徑 具體參考文章 《 Greenplum Database Release Notes 》 《Greenplum Database Reference Guide》
$ gpconfig -c gp_hadoop_target_version -v "hdp2" $ gpconfig -c gp_hadoop_home -v "/usr/lib/hadoop"
- 重新加載 Greenplum 的配置問價 postgresql.conf
$ gpstop -u --- 使用如下命令確認參數的修改 $ gpconfig -s gp_hadoop_version $ gpconfig -s gp_hadoop_home
- 授權 Greenplum的角色可以在HDFS中擁有自己的可讀寫外部表, 包括的用戶有 gpadmin 和 其他超級用戶。 授權 SELECT 權限能夠在 HDFS 上創建愛你可讀外部表, 授權 INSERT 權限可以去寫外部表在 HDFS 上
#= GRANT SELECT ON PROTOCOL gphdfs TO gpadmin; #= GRANT INSERT ON PROTOCOL gphdfs TO gpamdin;
- 將 Greenplum 數據庫外部表權限授予外部表所有者角色。
#= ALTER ROLE HDFS_USER CREATEEXTTABLE (type='readable'); #= ALTER ROLE HDFS_USER CREATEEXTTABLE (type='writable');
創建和安裝秘鑰文件
按照如下順序執行
- 使用 root 用戶登錄到 KDC 服務器上
- 使用 kadmin.local 命令為 gpadmin 創建新的代理
# kadmin.local -q "addprinc -randkey gpadmin@LOCAL.DOMAIN"
- 使用 kadmin.local 創建為Greenplum集群的每一個節點創建一個 Kerberos 服務代理, 這個代理的名字應該是 name|role@REALM 格式,解釋如下 name 是 gphdfs 服務的名稱,默認情況下使用 gphdfs role 是 Greenplum 集群主機的 DNS 可解析的主機名稱( hostname -f 命令) REALM 是 Kerberos 的realm, 例如 LOCAL.DOMAIN 例子如下,下麵這些明亮用來向Greenplum數據庫集群中的四個節點 (mdw.exam[ple.com smdw.example.com sdw1.example.com sdw2.example.com)
創建代理為每一個主機,使用相同的代理和realm,用每個主機的完整名稱限定替換# kadmin.local -q "addprinc -randkey6 gphdfs/mdw.example.com@LOCAL.DOMAIN" # kadmin.local -q "addprinc -randkey6 gphdfs/smdw.example.com@LOCAL.DOMAIN" # kadmin.local -q "addprinc -randkey6 gphdfs/smdw1.example.com@LOCAL.DOMAIN" # kadmin.local -q "addprinc -randkey6 gphdfs/smdw2.example.com@LOCAL.DOMAIN"
- 位每個節點創建代理(gpadmin 和 gphdfs 服務代理)。 存儲秘鑰在一個方便的文件位置(例如:/etc/security/keytabs)。也可以將秘鑰在稍後的時間內部署到各自的主機上。
# kadmin.local -q "xst -k /etc/security/keytabs/gphdfs.service.keytab gpadmin@LOCAL.DOMAIN" # kadmin.local -q "xst -k /etc/security/keytabs/mdw.service.keytrab gpadmin/mdw gphdfs/mdw.example.com@LOCAL.DOMAIN" # kadmin.local -q "xst -k /etc/security/keytabs//smdw.service.keytrab gpadmin/smdw gphdfs/smdw.example.com@LOCAL.DOMAIN" # kadmin.local -q "xst -k /etc/security/keytabs//smdw1.service.keytrab gpadmin/smdw1 gphdfs/smdw1.example.com@LOCAL.DOMAIN" # kadmin.local -q "xst -k /etc/security/keytabs//smdw1.service.keytrab gpadmin/smdw1 gphdfs/smdw2.example.com@LOCAL.DOMAIN"
- 修改 gphdfs.service.keytab 的訪問者權限
# chown gpadmin:gpadmin /etc/security/keytabs/gphdfs.service.keytab # chmod 440 /etc/security/keytabs/gphdfs.service.keytab
- 複製秘鑰文件到 gpadmin@LOCAL.DOMAIN 到GPDB的master節點上
# scp /etc/security/keytabs/gphdfs.service.keytab mdw_fqdn:/home/gpadmin/gphdfs.service.keytab
- 將對應的秘鑰文件發送到對應的GPDB節點上
# scp /etc/security/keytabs/mdw.service.keytab mdw_fqdn:/home/gpadmin/mdw.service.keytab # scp /etc/security/keytabs/smdw.service.keytab smdw_fqdn:/home/gpadmin/smdw.service.keytab # scp /etc/security/keytabs/smdw1.service.keytab smdw1_fqdn:/home/gpadmin/smdw1.service.keytab # scp /etc/security/keytabs/smdw2.service.keytab smdw2_fqdn:/home/gpadmin/smdw2.service.keytab
為 Kerberos 配置 gphdfs
- 編輯Hadoop 的 core-site.xml 客戶端配置文件在Greenplum中的所有的節點上。設置服務層的授權,使用的是 hadoop.security.authorization 參數為 true
hadoop.serurity.authorizationtrue
- 編輯集群的所有節點的 yarn-site.xml 客戶端配置文件。設置資源管理器地址和yarn的kerberos 服務代理
yarn.resourcemanger.addresshostname:8032yarn.resourcemanger.principalyarn/hostname@DOMAIN- 編輯文件 hdfs-site.xml 客戶端配置文件在全部的集群節點上。設置 NameNode 的代理, Kerberos 的秘鑰文件 dfs.namenode.kerberos.principal gphdfs 的協議代理,將會被 NameNode 使用。 dfs.namenode.https.principal 將會被 NameNode 的 安全 HTTP 協議使用 com.emc.greenplum.gpdb.hdfsconnector.serurity.user.keytab.file 對於 Kerberos HDFS 服務的秘鑰文件路徑, 例如路徑是 /home/gpamdin/mdw.service.keytab ... com.emc.greenplum.gpdb.hdfsconnector.security.user.name gphdfs 代理的節點。
dfs.namenode.kerberos.principalgphdfs/gpadmin@LOCAL.DOMAINdfs.namenode.https.principalgphdfs/gpadmin@LOCAL.DOMAINcom.emc.greenplum.gpdb.hdfsconnector.security.user.keytab.file/home/gpadmin/gpadmin.hdfs.keytabcom.emc.greenplum.gpdb.hdfsconnector.security.user.namegpadmin/@LOCAL.DOMAIN
使用Greenplum去訪問HDFS
確保 Greenplum 的所有節點可以通過 Kerberos 訪問HDFS。
在HDFS文件路徑下,執行如下的命令
hdfs dfs -ls hdfs://namenode:8020### 在HDFS上創建可讀的外部表 按照如下步驟在Hadoop上創建可讀外部表 >> 1. 創建一個逗號分隔符的文件, test1.txt 包含如下內容
25, Bill
19,Anne
32,Greg
27,Gloria
- 將這個實例文件保存到HDFS中
hdfs dfs -put test1.txt hdfs://namenode:8020/tmp
- 登錄到Greenplum數據庫集群中,創建一個可以讀的外部表,並將該外部表指向Hadoop路徑
CREATE EXTERNAL TABLE test_hdfs (age int, name text) LOCATION ('gphdfs://namenode:8020/tmp/test1.txt') FORMAT 'text' (delimiter ',');
- 讀取外部表的數據
SELECT * FROM test_hdfs;
在HDFS上創建可以寫的外部表
創建可以寫的外部表同樣按照下麵的步驟執行。
- 登錄Greenplum數據庫集群,創建一個指向HDFS上文件的外部表 test_hdfs2
CREATE WRITABLE EXTERNAL TABLE test_hdfs2 (like test_hdfs) LOCATION ('gphdfs://namenode:8020/tmp/test2.txt' ) FORMAT 'text' (DELIMITER ',');
- 向外部表中寫入數據
INSERT INTO test_hdfs2 SELECT * FROM test_hdfs;
- 檢查新創建的外部表的文件是否在HDFS中
hdfs dfs -ls hdfs://namenode:8020/tmp/test2.txt
- 確認外部表文件中的內容
hdfs dfs -cat hdfs://namenode:8020/tmp/test2.txt
異常處理部分
強製環境變量 (Forcing Classpath)
當執行 SELECT 語句查詢外部表數據的時候,如果遇到 "class not found" 錯誤。需要去編輯 $GPHOME/lib/hadoop-env.sh 文件。同時在文件的後麵追加如下信息,且在 JAVA_LIBRARY_PATH設置之前。更新該文件
if [-d "/usr/hdp/current"]; then
for f in /usr/hdp/current/*/.jar; do
CLASSPATH=${CLASSPATH}:$f;
done
fi
允許 Kerberos 客戶端可以Debug Messages
從Kerberos看到debug信息, 編輯 $GPHOME/lib/hadoop-env.sh 客戶端腳本在集群的所有節點,設置 HADOOP_OPTS 環境變量
export HADOOP_OPTS="-Djava.net.prefIPv4Stack=true -Dsun.security.krb5.debug=true ${HADOOP_OPTS}"
調整段節點上 JVM 程序的內存
每一個段數據庫都會加載一個JVM進程去讀寫HDFS上的外部文件,為了修改這個JVM進程內存的申請,需要修改環境變量 GP_JAVA_OPT
在 $GPHOME/lib/hadoop-env.sh 客戶端腳本編輯如下
export GP_JAVA_OPT=-Xmx1000m
確保 Kerberos 的安全設置
重新檢查 /etc/krb5.conf 文件
如果 AES256 加密文件不能使用,確保所有的節點都安裝了 JCE 模塊
確保全波的加密文件中的所有加密類型與 krb5.conf 定義文件匹配
cat /etc/krb5.conf | egrep supported_enctypes
測試單個段數據的聯通性
按照如下的步驟去測試 Greenplum 數據庫節點去讀取 HDFS 上的文件。這個測試方法執行的是 Greenplum 中的 HDFSReader JAVA類。可以用來幫助我們派出故障
- 將文件保存在HDFS中
hdfs dfs -put test1.txt hdfs://namenode:8020/tmp
- 在一個段數據庫上測試, 創建環境腳本文件 env.sh,
$ vi env.sh export JAVA_HOME=/usr/java/default export HADOOP_HOME=/usr/lib/hadoop export GP_HADOOP_CON_VERSIONM=hdp2 export GP_HADOOP_CON_JARDIR=/usr/lib/hadoop
- 刷新環境變量文件
source /usr/local/greenplum-db/greenplum_path.sh source env.sh source $GPHOME/lib/hadoop-env.sh
- 測試 Greenplum 的 HDFS 的讀能力
java com.emc.greenplum.gpdb.hdfsconnector.HDFSReader 0 32 TEXT hdp2 gphdfs://namenode:8020/tmp/test1.txt
參考文獻
<!https://gpdb.docs.pivotal.io/500/best_practices/kerberos-hdfs.html>
最後更新:2017-11-27 10:04:59