使用Python連接Hive
http://ilanever.com/article/detail.do;jsessionid=7559A4B25D2C5D3B40506F0811C92946?a=using_hive_in_python
客戶端連接Hive需要使用HiveServer2。HiveServer2是HiveServer的重寫版本,HiveServer不支持多個客戶端的並發請求。當前HiveServer2是基於Thrift RPC實現的。它被設計用於為像JDBC、ODBC這樣的開發API客戶端提供更好的支持。Hive 0.11版本引入的HiveServer2。
HiveServer2的啟動
啟動HiveServer2
HiveServer2的啟動十分簡便:
$ $HIVE_HOME/bin/hiveserver2
或者
$ $HIVE_HOME/bin/hive --service hiveserver2
默認情況下,HiverServer2的Thrift監聽端口是10000,其WEB UI端口是10002。可通過http://localhost:10002來查看HiveServer2的Web UI界面,這里顯示了Hive的一些基本信息。如果Web界面不能查看,則說明HiveServer2沒有成功運行。
使用beeline測試客戶端連接
HiveServer2成功運行后,我們可以使用Hive提供的客戶端工具beeline連接HiveServer2。
$ $HIVE_HOME/bin/beeline
beeline > !connect jdbc:hive2://localhost:10000
如果成功登錄將出現如下的命令提示符,此時可以編寫HQL語句。
0: jdbc:hive2://localhost:10000>
報錯:User: xxx is not allowed to impersonate anonymous
在beeline使用!connect連接HiveServer2時可能會出現如下錯誤信息:
Caused by: org.apache.hadoop.ipc.RemoteException: User: xxx is not allowed to impersonate anonymous
這里的xxx是我的操作系統用戶名稱。這個問題的解決方法是在hadoop的core-size.xml文件中添加xxx用戶代理配置:
<property> <name>hadoop.proxyuser.xxx.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.xxx.hosts</name> <value>*</value> </property>
重啟HDFS后,再用beeline連接HiveServer2即可成功連接。
常用配置
HiveServer2的配置可以參考官方文檔《Setting Up HiveServer2》
這里列舉一些hive-site.xml的常用配置:
hive.server2.thrift.port:監聽的TCP端口號。默認為10000。
hive.server2.thrift.bind.host:TCP接口的綁定主機。
hive.server2.authentication:身份驗證方式。默認為NONE(使用 plain SASL),即不進行驗證檢查。可選項還有NOSASL, KERBEROS, LDAP, PAM and CUSTOM.
hive.server2.enable.doAs:是否以模擬身份執行查詢處理。默認為true。
Python客戶端連接HiveServer2
python中用於連接HiveServer2的客戶端有3個:pyhs2,pyhive,impyla。官網的示例采用的是pyhs2,但pyhs2的官網已聲明不再提供支持,建議使用impyla和pyhive。我們這里使用的是impyla。
impyla的安裝
impyla必須的依賴包括:
- six
- bit_array
- thriftpy(python2.x則是thrift)
為了支持Hive還需要以下兩個包:
- sasl
- thrift_sasl
可在Python PI中下載impyla及其依賴包的源碼。
impyla示例
以下是使用impyla連接HiveServer2的示例:
from impala.dbapi import connect
conn = connect(host='127.0.0.1', port=10000, database='default', auth_mechanism='PLAIN') cur = conn.cursor() cur.execute('SHOW DATABASES') print(cur.fetchall()) cur.execute('SHOW Tables') print(cur.fetchall())