LoginSignup
2
1

More than 5 years have passed since last update.

EMR 4->5 バージョン間で Hue データを移行する

Last updated at Posted at 2017-02-03

やりたいこと

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 エラーが表示される)

[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以降であれば履歴も表示される)

移行完了です! 

参考資料

おわりに

以上、同じ問題に直面した方向けの共有でした

問題解消の助けとなればさいわいです、不明瞭な点あればコメント等いただければ対応しますmm

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1