Hive リモート接続を構成して有効にする
ハイブのリモート接続
Hive リモート接続を構成するには、まず HiveServer2 が起動し、指定されたポートでリッスンしていることを確認します。
hive/bin/hiveserver2
HiveServer2 が実行されているかどうかを確認する
# lsof -i:10000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 660 root 565u IPv6 89917 0t0 TCP *:ndmp (LISTEN)
デフォルトで Hive へのリモート接続
Hive が Hadoop と統合された環境で実行されている場合、HiveServer2 は Hadoop のユーザー認証メカニズムと統合でき、認証と認可に認証された Hadoop ユーザー資格情報を使用します。
IDEA のデータベース メニュー バーで次のように操作し、Hive 接続を追加し、
Hive アドレスと Hadoop で使用するユーザー名を入力します。
注: 初めて使用する場合、構成プロセスで JDBC ドライバーが見つからないというメッセージが表示されます。プロンプトに従ってダウンロードしてください。
[テスト]をクリックするTest Connection
と、Hive への接続が失敗し、hiveserver2 のバックグラウンド ログに次のプロンプトが表示されることがわかります。
WARN [HiveServer2-Handler-Pool: Thread-47] thrift.ThriftCLIService (ThriftCLIService.java:OpenSession(340)) - Error opening session:
org.apache.hive.service.cli.HiveSQLException: Failed to open new session: java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: root is not allowed to impersonate root
at org.apache.hive.service.cli.session.SessionManager.createSession(SessionManager.java:434)
at org.apache.hive.service.cli.session.SessionManager.openSession(SessionManager.java:373)
at org.apache.hive.service.cli.CLIService.openSessionWithImpersonation(CLIService.java:195)
at org.apache.hive.service.cli.thrift.ThriftCLIService.getSessionHandle(ThriftCLIService.java:472)
at org.apache.hive.service.cli.thrift.ThriftCLIService.OpenSession(ThriftCLIService.java:322)
at org.apache.hive.service.rpc.thrift.TCLIService$Processor$OpenSession.getResult(TCLIService.java:1497)
at org.apache.hive.service.rpc.thrift.TCLIService$Processor$OpenSession.getResult(TCLIService.java:1482)
at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:39)
at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:39)
at org.apache.hive.service.auth.TSetIpAddressProcessor.process(TSetIpAddressProcessor.java:56)
at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:286)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
解決:
Hadoop/etc/hadoop/core-site.xml
以下の設定をファイルに追加し、各ノードに配布します。
注: root
: は、実行時に Hadoop コンポーネントによって使用されるユーザー名を指します。これは、独自の構成に従って変更する必要があります。
</property>
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
Hadoopとhiveserver2を再起動した後、接続テストを再開します。
カスタム認証クラスを使用して Hive にリモート接続する
Hive では、デフォルトでユーザー認証メカニズムが有効になっていません。つまり、Hive のデフォルトのユーザー名とパスワードは空です。セキュリティのために、認証クラスをカスタマイズすることで、ユーザーとパスワードで Hive にログインできるようにすることができます。
Java プロジェクトを作成し、Hive 用の JDBC ドライバーなどの必要な依存関係がプロジェクトに含まれていることを確認します。
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>3.1.3</version>
</dependency>
注: サーバーで使用される Hive JDBC バージョンと一致している必要があります。
PasswdAuthenticationProvider インターフェイスを実装するクラスを作成します。
package cn.ybzy.demo;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;
import org.slf4j.Logger;
import javax.security.sasl.AuthenticationException;
public class MyHiveCustomPasswdAuthenticator implements PasswdAuthenticationProvider {
private Logger LOG = org.slf4j.LoggerFactory.getLogger(MyHiveCustomPasswdAuthenticator.class);
private static final String HIVE_JDBC_PASSWD_AUTH_PREFIX = "hive.jdbc_passwd.auth.%s";
private Configuration conf = null;
@Override
public void Authenticate(String userName, String passwd)
throws AuthenticationException {
LOG.info("Hive 用户: " + userName + " 尝试登录");
String passwdConf = getConf().get(String.format(HIVE_JDBC_PASSWD_AUTH_PREFIX, userName));
if (passwdConf == null) {
String message = "找不到对应用户的密码配置, 用户:" + userName;
LOG.info(message);
throw new AuthenticationException(message);
}
if (!passwd.equals(passwdConf)) {
String message = "用户名和密码不匹配, 用户:" + userName;
throw new AuthenticationException(message);
}
}
public Configuration getConf() {
if (conf == null) {
this.conf = new Configuration(new HiveConf());
}
return conf;
}
public void setConf(Configuration conf) {
this.conf = conf;
}
}
Java プロジェクトをパッケージ化し、同時に Hive の lib ディレクトリにアップロードします
mv hive/MyHiveCustomPasswdAuthenticator.jar hive/lib/
構成用に hive-site.xml を変更します。
<!-- 使用自定义远程连接用户名和密码 -->
<property>
<name>hive.server2.authentication</name>
<value>CUSTOM</value><!--默认为none,修改成CUSTOM-->
</property>
<!-- 指定解析类 -->
<property>
<name>hive.server2.custom.authentication.class</name>
<value>cn.ybzy.demo.MyHiveCustomPasswdAuthenticator</value>
</property>
<!--设置用户名和密码 name属性中root是用户名 value属性中时密码-->
<property>
<name>hive.jdbc_passwd.auth.hive</name>
<value>hive123</value>
</property>
権限の問題
IDEA で Hive にリモート接続して操作する場合、次の例外が発生する場合があります。
ERROR --- [ HiveServer2-Background-Pool: Thread-440] org.apache.hadoop.hive.metastore.utils.MetaStoreUtils (line: 166) : Got exception: org.apache.hadoop.security.AccessControlException Permission denied: user=hive, access=WRITE, inode="/hive/warehouse":root:supergroup:drwxr-xr-x
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:399)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:255)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:193)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:1855)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:1839)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkAncestorAccess(FSDirectory.java:1798)
at org.apache.hadoop.hdfs.server.namenode.FSDirMkdirOp.mkdirs(FSDirMkdirOp.java:59)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirs(FSNamesystem.java:3175)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.mkdirs(NameNodeRpcServer.java:1145)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.mkdirs(ClientNamenodeProtocolServerSideTranslatorPB.java:714)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:527)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1036)
at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:1000)
at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:928)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1729)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2916)
理由:
Hive を操作する場合、HDFS を操作することになりますが、Hive にログインしているユーザーには操作権限がありません
解決:
Hive ユーザー (hive など) が HDFS を操作できることを確認してください。
たとえば、Hive はメタストア データの保存場所を構成するため、/hive/warehouse
対応するアクセス許可をディレクトリに付与する必要があります。
hadoop fs -chown hive:hive /hive/warehouse
IDEA でデータベースを作成します。
create database demo;
HDFS を表示します。
追加の指示
上記の方法に加えて、Hive は Kerberos または LDAP の高度な認証方法も提供します。これらは少し複雑なので、ここでは説明しません。
さらに、Hive の以前のバージョン (2.x 以前) では、Hive リモート接続のユーザー名とパスワードを次のように構成できます。
<property>
<name>hive.server2.authentication</name>
<value>PASSWORD</value>
</property>
<property>
<name>hive.server2.authentication.user.name</name>
<value>hive</value>
</property>
<property>
<name>hive.server2.authentication.user.password</name>
<value>hive123</value>
</property>
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>node01</value>
</property>