やりたいこと
EMR メジャーバージョン 4 から 5 へ移行する際、Hue データ(保存クエリ/履歴/共有設定など)をそのまま移動させて使いたい
課題背景
EMR のリリースバージョン emr-4 から emr-5 へアップグレードする場合、Hue はバージョン 3.7 から 3.10 へ変わります
Hue 3.10 は、ドキュメント管理方法や クエリエディタが刷新されたバージョン
Hue は Web上で Hiveクエリ等を生成/実行し、クエリや結果をチームで共有したりできるツールで、アドホック集計で便利なツールですが、Hue 3.10 はエディタが刷新されているため、デフォルト設定では 旧バージョンのエディタ(beeswaxなど)で生成したデータが参照できない 状態になります
発生する問題
1.データ移行中にエラーがでて移行完了できない
hue dumpdata/loaddata
を使ったデータ移行途中で、エラーが発生する
例1
desktop_documentpermissionテーブルのユニークキー違反
django.db.utils.IntegrityError: Problem installing fixture 'hue_data_backup-jq.json': Could not load desktop.DocumentPermission(pk=2): (1062, "Duplicate entry '1-read' for key 'desktop_documentpermission_doc_id_60b132dd84ab9469_uniq'")
mysql> show create table desktop_documentpermission;
CREATE TABLE `desktop_documentpermission` (
`perms` varchar(10) COLLATE utf8_bin NOT NULL,
`doc_id` int(11) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
↓ 新たに追加された制約
UNIQUE KEY `desktop_documentpermission_doc_id_60b132dd84ab9469_uniq` (`doc_id`,`perms`),
KEY `desktop_documentpermission_fbbb6049` (`doc_id`),
CONSTRAINT `doc_id_refs_id_6e61f686` FOREIGN KEY (`doc_id`) REFERENCES `desktop_document` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=69682 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
例2
"Duplicate entry 'oozie-bundle' for key 'app_label'"
今回は事前に除外しますが、contenttypesをダンプに含めると出ます
django.db.utils.IntegrityError: Problem installing fixture 'hue_data_backup_jq.json': Could not load contenttypes.ContentType(pk=43): (1062, "Duplicate entry 'oozie-bundle' for key 'app_label'")
例3
外部キー制約違反
今回は事前に除外しますが、auth_permission をダンプに含めると出ます
Problem installing fixtures:
The row in table 'auth_permission' with primary key '49' has an invalid foreign key:
auth_permission.content_type_id contains a value '17' that does not have a corresponding value in django_content_type.id.
などなど
2.データ移行が成功したにもかかわらず、過去データが参照できない
hue dumpdata/loaddata
を使ってデータ移行した後、Hue 画面上で 旧エディタで作成したクエリが表示できない
(500 エラーが表示される)
-
アクセス先URL(Hiveクエリエディタ)
https://hue-hostname:8888/beeswax/execute/design/{id} -
/var/log/hue/runcpserver.log
500エラー発生時、ログには Document matching query does not exist が出力される
[18/Jan/2017 15:15:33 +0900] middleware INFO Processing exception: Document matching query does not exist.: Traceback (most recent call last):
File "/usr/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/handlers/base.py", line 112, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/db/transaction.py", line 371, in inner
return func(*args, **kwargs)
File "/usr/lib/hue/apps/beeswax/src/beeswax/views.py", line 418, in execute_query
authorized_get_design(request, design_id)
File "/usr/lib/hue/apps/beeswax/src/beeswax/views.py", line 671, in authorized_get_design
design.doc.get().can_read_or_exception(request.user)
File "/usr/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/db/models/manager.py", line 151, in get
return self.get_queryset().get(*args, **kwargs)
File "/usr/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/db/models/query.py", line 310, in get
self.model._meta.object_name)
DoesNotExist: Document matching query does not exist.
[dd/mmm/yyyy hh:mm:ss +0900] access INFO xxx.xxx.xxx.xxx user - "GET /beeswax/execute/design/{id} HTTP/1.1"
解決方法
1. 前処理(データ修正)
移行先の新バージョンのMySQL制約に引っかかるデータを、旧バージョンで修正します
※本手順3.で何もエラーが発生しない状況であれば、手順1.はSKIPして構いません
※本手順3.で発生するエラーにあわせて、必要があれば何度か実施します
※データ操作するので、事前にバックアップ( hue datadump
)を取っておくと安心です
Hue database 設定を参照
旧バージョン
/etc/hue/conf/hue.ini
[[database]]
engine = mysql
name = huedb
case_insensitive_collation = utf8_unicode_ci
test_charset = utf8
test_collation = utf8_bin
host = ip-xxx.xxx.compute.internal
user = hue
test_name = test_huedb
password = xxxxxxxxxx
mysql cli で接続
ホスト名/パスワードは hue.ini にあるとおり入力します
$ mysql -u hue -h ip-xxx.xxx.compute.internal -p huedb
データ修正(例)
ここではクエリデータのパーミッション設定に重複がでるケースを想定し(筆者環境でも同エラーが出ました)
解消するクエリを書きます
※発生する問題に合わせて、解消クエリは適宜検討してください
キー重複するレコード群を取得
mysql>
select doc_id,perms,count(*) as cnt
from desktop_documentpermission
group by doc_id,perms having cnt > 1
order by cnt desc;
+--------+-------+-----+
| doc_id | perms | cnt |
+--------+-------+-----+
| 9999 | write | 2 |
| 9999 | read | 2 |
....
| 99999 | write | 2 |
| 99999 | read | 2 |
+--------+-------+-----+
対象レコードの削除
重複しているレコードのうち片方を削除することにします
(ここでは重複したもののidが小さいほうを対象に選びます)
mysql>
select a.doc_id,a.perms,min(b.id)
from (
select doc_id,perms,count(*) as cnt
from desktop_documentpermission
group by doc_id,perms having cnt > 1
order by cnt desc
) a
left outer join
desktop_documentpermission b
on a.doc_id = b.doc_id and a.perms = b.perms
group by a.doc_id,a.perms;
結果id を指定してDELETEします
mysql>
delete from desktop_documentpermission where id in (,,,);
2. Hue data dump 実行
1.できれいになった Hueデータ をダンプします
auth.permission と contenttypes は移行先DBに既に値が入っているため、ダンプ時に除外 します
旧バージョン
$ sudo /usr/lib/hue/build/env/bin/hue dumpdata \
--exclude auth.permission \
--exclude contenttypes \
> hue_data_backup.json
3. Hue data load 実行
旧バージョンで取得したダンプファイルを新バージョンのクラスタへ運び、load します
jq コマンドはお好みですが、loadエラーが発生したときに問題箇所を探しやすいのでおすすめです
新バージョン
$ cat hue_data_backup.json | jq . > hue_data_backup-jq.json
$ sudo /usr/lib/hue/build/env/bin/hue loaddata hue_data_backup-jq.json
Installed 999999999 object(s) from 999 fixture(s)
loaddata でエラー発生したときは
基本的にMySQL上の制約に引っかかるエラーが出ます
エラー内容を確認して、MySQL上のテーブル制約(UNIQUE KEY/FOREIGN KEY等)を確認し、制約に違反しないデータに修正します
※loadが成功するまで、手順1.から繰り返します
4. Hue DB レコード修正
新バージョンでは、旧エディタで作成されたデータを新エディタで開こうとしてエラー発生させるため、レコードを直接修正します
Hue database 設定を参照
手順1と同様ですが念のため
新バージョン
/etc/hue/conf/hue.ini
[[database]]
engine = mysql
name = huedb
case_insensitive_collation = utf8_unicode_ci
test_charset = utf8
test_collation = utf8_bin
host = ip-xxx.xxx.compute.internal
user = hue
test_name = test_huedb
password = xxxxxxxxxx
mysql cli で接続
ホスト名/パスワードは hue.ini にあるとおり入力します
$ mysql -u hue -h ip-xxx.xxx.compute.internal -p huedb
Update 文実行
desktop_document テーブル内に入っている旧エディタ作成のクエリは、desktopというアプリに関連付けられています
このデータは新バージョンでnotebookというエディタで開く挙動をし、問題の DoesNotExist エラーを発生させます
そこで(今回の例では、レコードはすべてbeeswaxで作成したクエリデータのため)明示的に beeswax savedquery に書き換えてしまいます
※ほかのエディタ(アプリ)で生成したデータの場合、レコードにあわせクエリ調整する必要があるかもしれません
mysql> select * from django_content_type where id in (51,58);
+----+--------------+-----------+-------------+
| id | name | app_label | model |
+----+--------------+-----------+-------------+
| 51 | document tag | desktop | documenttag |
| 58 | saved query | beeswax | savedquery |
+----+--------------+-----------+-------------+
mysql> update desktop_document set content_type_id = 58 where content_type_id = 51;
5. Hue 画面から確認
下記のようなURLにアクセスし、正常に表示されることを確認します
https://hue-hostname:8888/home2
https://hue-hostname:8888/beeswax/execute/design/{id}
beeswax クエリに関しては、この方法で問題なく表示されました
また、上記手順を行ったうえであれば、新エディタ(notebook)画面上のSavedQuery/履歴 タブ内に
beeswax で作成したクエリ群がnotebook 形式で開けるリンクが作成されました
(Hue-3.10ではSavedQueryのみ、Hue-3.11以降であれば履歴も表示される)
移行完了です!
参考資料
- https://community.cloudera.com/t5/Web-UI-Hue-Beeswax/What-is-the-easiest-way-to-back-up-Hue-s-quot-saved-queries-quot/td-p/29931
-
Configuring the Hue Server to Store Data in MySQL
CDH で Hueデータ移行を行う際の手順を参考にしました -
https://issues.cloudera.org/browse/HUE-4346
新エディタ(notebook)上で SavedQuery/履歴 を表示させる対応(emr-3.11)
おわりに
以上、同じ問題に直面した方向けの共有でした
問題解消の助けとなればさいわいです、不明瞭な点あればコメント等いただければ対応しますmm