hiveでローカルホストからの接続が拒否される現象とその対処法。 | ガラス越しの世界

ガラス越しの世界

とまぁ色々あるよなないよなでぼちぼち更新。
たまには技術情報もあるよw

はい、こんばんは。

今日は技術情報としてよさ気なネタを仕入れたのでそれについて書きます。
hiveというやつで、MySQLを使用している場合に、あるホストからの接続が拒否されて、それが定数で指定された回数に達するとそれ以降そのホストからの接続が拒否されるという現象。
ちなみにLinuxの話ね。
/tmp/[ユーザ名]/hive.log(だったかな)にエラーの対処法が出ます。
曰く、mysqladmin flush-hostsを実行しろ、と。
このコマンドを実行すると接続拒否されたホストの情報がクリアされてまた接続できるようになります。
放っておくと、接続が拒否された場合にまた同じことになるので、何らかの対応が必要です。
定数というのは環境変数設定みたいなので設定できるのですが、パラメータ名は忘れましたw

んで、今回の現象。
hiveを繰り返し実行していると途中から前述のエラーで接続が拒否されてしまいます。
今回のケースではローカルホストからしか接続していません。
処理はすべてちゃんと動いています。
ではどこで接続拒否されているのか?
なんでも、hiveは0.7から統計情報を取得しているらしく。
そのための処理のところで拒否されていました。
今回使っているのは0.10.0です。
んで、ログを見てみると、こんなログが出ていました。(うろ覚えなので雰囲気で解釈してください)
「Access denied [ユーザ名];password=[パスワード]@[ホスト名]」。
これは、ユーザ名にパスワードまで含まれていますねぇ。

ということで、設定ファイルを確認しました。
今回は、/usr/hive-0.10.0(?)/conf/site_なんちゃら.xml
とりあえず/usrの下にhiveのインストールディレクトリがあり、そのconfディレクトリ内に設定のxmlファイルが有りました。
設定は複数箇所でできるようで、ファイル名とかhiveを実行する際の引数とかでも指定できるようなのでそこら辺は各環境に従ってください。
んで、問題になる設定が、dbconnectなんちゃらっていう設定。
JDBCでstatsっていうところにアクセスしていて、そこに対するパラメータで以下の様なのがありました。

&user=[ユーザ名];password=[パスワード]
&user=[ユーザ名];password=[パスワード]

パラメータを&で区切っています。
こな場合、ユーザ名とパスワードの間が;だけなので、パラメータの区切りとして認識されなかったようです。
よって、以下のように変更したら拒否されなくなりました。

&user=[ユーザ名]&password=[パスワード]
&user=[ユーザ名]&password=[パスワード]

一件落着。
たぶん。
明日ちゃんと検証しようそうしよう。
あ、ちなみに。
hiveの統計情報取得は、INSERTするときに自動で実行されるらしいです。
INSERTコマンドが動いた時点でJDBCなんちゃらPublisherっていうプロセスが自動で起動して採取してくれるようです。
LOADでは統計情報は作られません。
0.7.0の頃のHOWTOでは統計情報は取得するけど保存されないって書いてあったので、0.10.0で統計情報取得を動かす意味があるかどうかは謎ですが。。。
ちなみに、統計情報の取得は、なんちゃらgatherっていう設定をfalseに設定すると動かないらしいです。
今回は、役に立つかもしれないからとりあえず採取してみてから考えよう、とのことなので取得する設定にしてありますが。
この統計情報取得の設定はデフォルトでtrueになっているので、いらない人は手作業でfalseにしなければいけません。

ついでにこの設定。
私が設定したものではありません。
社内のインフラチームが設定したもので、設定値に&が抜けていたのがミスなのかどうかは謎です。
でも、ぐぐってみると、&無しでANALYZEコマンドがエラーになった、とかあるので、デフォルトの設定が間違っているのでしょうか。。。
わざわざ消すとも思えませんし、既存の環境で動いているhiveが0.6.0なのでそもそもその設定自体ないんですよねぇ。。。

ちなみに今回の現象に対する対応は以下の方法で検証しました。
tail -f hive.log | grep denied
で、INSERTコマンドが動いた時点でAccess deniedが出現することを確認。
テスト用テーブル(カラムはstring型のものを一つ)を作成。
テスト用テーブルに対してINSERT INTO [テーブル名] select '[適当な文字列]' from [データの入っているテーブル名] limit 1;
このINSERT文が動いた時点でAccess deniedが出現することを確認。
xmlを変更し、hiveを再起動。
同様のINSERT文を実行し、Access deniedが出ないことを確認。

以上です。

ちなみに。
この接続拒否の設定。
初期値では10回接続エラーになったらそのホストからの接続を拒否するようになっています。
今回私がハマったのと同じ状況の場合、上限に達するのはあっという間なのでご注意を。

などと。
にゃー。

2014/01/31追記
。。。すみませぬ。
パラメータの区切りの&:amp;が&に変換されていましたわ。
本文を訂正しました。