Dec 25, 2019

Note for Hive DbNotificationListener

HiveにはDbNotificationListenerという、有効にするとイベントをメタストアに格納してくれる機能があるのですが、それをDockerで試す流れです。

HiveのドキュメントはReplicationのページにちょこっと載っています。
https://cwiki.apache.org/confluence/display/Hive/Replication

サンプルのリポジトリはこちらです。
https://github.com/ebyhr/hive-notification-docker

環境によってはhive-hcatalog-sever-extensions jarを追加する必要はありませんが、今回ベースにしているprestodevのHadoopイメージだと必要になるので自前で追加しています。

この機能はhive-site.xmlに以下を追加することで有効になります。
<property>
<name>hive.metastore.event.listeners</name>
<value>org.apache.hive.hcatalog.listener.DbNotificationListener</value>
</property>


INSRETなどのDMLに関するイベントも拾いたい場合は以下も追加します。
<property>
<name>hive.metastore.dml.events</name>
<value>true</value>
</property>

イベントの保存期間はデフォルトで1日(86400秒)です。変更したい場合は以下のプロパティを追記・編集する必要があります。
<property>
<name>hive.metastore.event.db.listener.timetolive</name>
<value>86400s</value>
</property>

イベントが格納されるテーブル定義は以下のようになっています。

CREATE TABLE `NOTIFICATION_LOG` (
`NL_ID` bigint(20) NOT NULL,
`EVENT_ID` bigint(20) NOT NULL,
`EVENT_TIME` int(11) NOT NULL,
`EVENT_TYPE` varchar(32) NOT NULL,
`CAT_NAME` varchar(256) DEFAULT NULL,
`DB_NAME` varchar(128) DEFAULT NULL,
`TBL_NAME` varchar(256) DEFAULT NULL,
`MESSAGE` longtext,
`MESSAGE_FORMAT` varchar(16) DEFAULT NULL,
PRIMARY KEY (`NL_ID`)
)



試しにCREATE TABLEを実行してどんな内容が書き込まれるか確認してみましょう。Hiveはパスワード不要で、メタストアには以下の情報で接続できます。

  • ユーザー名: root
  • パスワード: root
  • ポート: 13306 (コンテナ外からアクセスする場合) or 3306


Hive> CREATE TABLE test_notify (c1 INT);

MariaDB> SELECT * FROM metastore.NOTIFICATION_LOG;

|     1 |        1 | 1576740085 | CREATE_TABLE | hive     | default | test_notify |

 {"server":"","servicePrincipal":"","db":"default","table":"test_notify",
 "tableType":"MANAGED_TABLE",
 "tableObjJson":"
  {\"1\":{\"str\":\"test_notify\"},
   \"2\":{\"str\":\"default\"},
   \"3\":{\"str\":\"root\"},
   \"4\":{\"i32\":1576740084},
   \"5\":{\"i32\":0},
   \"6\":{\"i32\":0},
   \"7\":{\"rec\":
    {\"1\":{\"lst\":[\"rec\",1,{\"1\":{\"str\":\"c1\"},\"2\":{\"str\":\"int\"}}]},
     \"2\":{\"str\":\"hdfs://hadoop-master:9000/user/hive/warehouse/test_notify\"},
     \"3\":{\"str\":\"org.apache.hadoop.mapred.TextInputFormat\"},
     \"4\":{\"str\":\"org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat\"},
     \"5\":{\"tf\":0},
     \"6\":{\"i32\":-1},
     \"7\":{\"rec\":
      {\"2\":{\"str\":\"org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe\"},
       \"3\":{\"map\":[\"str\",\"str\",1,{\"serialization.format\":\"1\"}]}}},
     \"8\":{\"lst\":[\"str\",0]},
     \"9\":{\"lst\":[\"rec\",0]},
     \"10\":{\"map\":[\"str\",\"str\",0,{}]},
     \"11\":{\"rec\":
      {\"1\":{\"lst\":[\"str\",0]},
       \"2\":{\"lst\":[\"lst\",0]},
       \"3\":{\"map\":[\"lst\",\"str\",0,{}]}}},
     \"12\":{\"tf\":0}}},
       \"8\":{\"lst\":[\"rec\",0]},
       \"9\":{\"map\":[\"str\",\"str\",7,
        {\"totalSize\":\"0\",
         \"numRows\":\"0\",
         \"rawDataSize\":\"0\",
         \"COLUMN_STATS_ACCURATE\":
          \"{\\\"BASIC_STATS\\\":\\\"true\\\",
             \\\"COLUMN_STATS\\\":{\\\"c1\\\":\\\"true\\\"}}\",
         \"numFiles\":\"0\",
         \"transient_lastDdlTime\":\"1576740084\",
         \"bucketing_version\":\"2\"}]},
         \"12\":{\"str\":\"MANAGED_TABLE\"},
     \"13\":{\"rec\":{\"1\":{\"map\":[\"str\",\"lst\",1,
       {\"root\":[\"rec\",4,
        {\"1\":{\"str\":\"INSERT\"},
         \"2\":{\"i32\":-1},
         \"3\":{\"str\":\"root\"},
         \"4\":{\"i32\":1},
         \"5\":{\"tf\":1}},
       {\"1\":{\"str\":\"SELECT\"},
         \"2\":{\"i32\":-1},
         \"3\":{\"str\":\"root\"},
         \"4\":{\"i32\":1},\"5\":{\"tf\":1}},
       {\"1\":{\"str\":\"UPDATE\"},
         \"2\":{\"i32\":-1},
         \"3\":{\"str\":\"root\"},
         \"4\":{\"i32\":1},
         \"5\":{\"tf\":1}},
       {\"1\":{\"str\":\"DELETE\"},
         \"2\":{\"i32\":-1},
         \"3\":{\"str\":\"root\"},
         \"4\":{\"i32\":1},
         \"5\":{\"tf\":1}}]}]}}},
     \"14\":{\"tf\":0},\"17\":{\"str\":\"hive\"},\"18\":{\"i32\":1}}",
       "timestamp":1576740085,"files":[]}


| json-0.2       |

JSONが格納されているMessageカラムは見やすさのために改行していますが、上記のような内容がレコードとして格納されていきます。クエリによっては追加されるレコードが1行とは限らないので、そこは注意が必要です。なお、Thrift経由でアクセスしたい場合は以下のメソッドが用意されています。
  • get_next_notification
  • get_current_notificationEventId
  • get_notification_events_count

余談ですが、IntelliJ IDEAでThriftHiveMetastoreに定義ジャンプしようとすると、少なくとも僕の環境では100%ハングしてForce Killを余儀なくされるのでご注意くださいませ〜。

No comments:

Post a Comment