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を余儀なくされるのでご注意くださいませ〜。

Oct 13, 2019

After Presto Conference Tokyo

7/11に開催されたPresto Conference Tokyo 2019について書こう書こうと思いつつ放置していたところ、ちょうど3ヶ月後の10/11にコミッターになったので、ご報告もかねて下書きを開きました。この記事では当日話そうと思ってスライドから削った部分や最近のコミュニティについて書きたいと思います。

現在Presto Software Foundation (PSF)とPresto Foundationという2つの組織があり、前者はPrestoを最初に作り始めたクリエイター達およびStarburstのメンバーを中心に、Arm Treasure DataVaradaQuboleなどその他にも多くの企業・開発者から支持されながら運営されています。後者はFacebookを中心にTwitter, Uber, Alibabaが支持していて、Linux Foundationにホストされることが先日発表されました。こう書くとどららを選ぶべきか悩むかもしれませんが、前者の方が開発の速度は早くコミュニティが非常に活発に動いてるので、特別な理由がなければPSF側のPrestoを使用することやコミュニティへの参加をお勧めします。Facebook側のリポジトリやSlackも見るようにしているのですが、対応が遅く残念な気持ちになります。メーリングリストは両者で同じアドレスが使用されているのですが、回答者の多くはPSFのコミュニティメンバーなのでSlackで直接質問するとすぐ回答を得られます。

PSFのSlackにはこちらのページにあるリンクから参加できます。
https://prestosql.io/slack.html

チャンネルは結構多くて戸惑いそうですが、個人的にお勧めするチャンネルは以下の通りです。

  • #troubleshooting #generalで質問しても問題ないのですがトラブル等はこちらで質問すると素早く回答を得ることができます
  • #community-announcement ミートアップなどの情報がポストされます
  • #dev 開発に興味がある方はぜひ!
  • #general-jp 日本語で気軽に話せるチャンネルです

実際に開発に参加しなくても、もっと日本からコミュニティに参加してくれる方が増えてくれるととても嬉しいです。コードは書かずにSlackで議論に参加しているだけのメンバーもいますが、多数のコネクタを1リポジトリで管理していることもあり、そういったフィードバックはとても貴重に扱われます。

その他のリンクとしては以下のようなものがあります。

今更になりますがPresto Conference Tokyo 2019を企画してくださったArm Treasure Dataの方々、参加者のみなさん、HadoopのIssueを進めてくださったお二方、どうも有り難うございました。また来年も開催できると良いですね。

Aug 30, 2019

Everything becomes F

すべてがFになる」の後半を読んでいたら、平日にも関わらず朝の4時半頃まで起きてしまいました...。今まで読んだ森博嗣さんの作品の中で最も面白かったです。これがデビュー作というのが凄い。次は百年シリーズを読もうと思っていたのですが、S&Mシリーズを順に読んでみることにします。最近話題になっている「三体」も買ってあるので楽しみです。



作中のプログラミングのシーンを読んでいて、数年前に電車に乗っていた時、隣にいた女性が子どもに「片手でいくつまで数をかぞえられる?お母さんは31まで数えられるよ」と言って、二進数を教えていたのをふと思い出しました。あの人はプログラマーだったかが気になります。
右手を例にあげると、手前に向けたグーの状態が00000で0、親指を立てると00001で1、次に親指を戻して人差し指を立てると00010で2という具合で2^5 - 1である31まで数えることができます。

00000→0
00001→1
00010→2
00011→3
00100→4
...
11110→30
11111→31

この方法を使うと両手で1023(2^10 - 1)まで数えることができます。数学としては当たり前であっても両手で自分の手に約1000個の数字が収まるというのはなんだか不思議な感じがします。

Jul 28, 2019

After the Matinee

7月に休みをとって宮城の松島海岸に1泊2日で旅行してきました。いつも一人で旅行に行くときは本を持っていくのですが、今回は本屋で目にとまった「マチネの終わりに」と共に。恋愛小説を読むのは初めてでしたが、いわゆるドロドロとした内容で読んでいて辛い部分もありつつも先が気になる展開が続き、結局初日の夕ご飯前には読み切ってしまいました。作中で何度か出てくる「未来は常に過去を変えている」という文章がとても心に残っています。良かった思い出がふとしたきっかけで悲しい思い出になったり、その逆もあったりしますもんね。ギタリストと国際ジャーナリストの恋愛ということもあり、芸術、イラク情勢、原爆やサブプライムローンなど様々な話題が散りばめられていて、読んだあとに自分でもう一度学びたいと感じる本でした。11月1日には映画が公開される予定とのことで、できれば初日に観に行きたいなぁと思っています。


松島湾

福浦橋

福浦島

遊覧船からの眺め
松島自体は初日は小雨が降っていて少し残念でしたが綺麗なアジサイの写真が撮れて満足です。行きの新幹線と仙台駅でご飯を食べ過ぎたこともあり早めにホテルへチェックインしてのんびりしてました。2日目は朝露天風呂に入っていたら松島湾が眩し過ぎて目がちゃんと開かないぐらいには天気が良かったです。チェックアウトしてからは海岸通りをぶらぶらして福浦島に向かいました。木が生い茂っていてちょっとしたジャングルみたいで散策を楽しめました。松島湾を1周する遊覧船に乗ろうと思ってたのですが、受付の方に仙台方面に戻るのであれば電車が少ないので塩川港まで行くルートがお勧めですよと教えていただき、そっちに乗ってみました。最後に仙台駅でお寿司を食べて新幹線で帰宅です。お寿司以外にもたくさん美味しいもの、牛タン、穴子、牡蠣、笹かまぼこ、ずんだジェラート、ずんだシェイクなどなどを食べて終始満腹でした。

May 17, 2019

The Garden of words

お花見シーズンぶりに、またもやお昼にオフィスを抜け出して新宿御苑に行ってきました。たまたま「森のおもちゃ美術館」というイベントがやっていて、幼稚園児ぐらいの子達が無邪気にはしゃいでる姿になんだか癒されました。いつも新宿門から入って奥側のバラ花壇までは行かないんですが、そのイベントに釣られて行ってみたところ綺麗な花がたくさん咲いてました。1番上の白いふわふわしたやつが綺麗だったので名札(?)も撮って帰って家で調べたところ、これは作者がつけたあだ名みたいなやつだったらしく、正式な名前が分からず...。

帰りは新宿門まで日本庭園側を歩いていたら、老夫婦が結構な量の葉っぱをむしってカバンに入れていて、なんだろうと思ってよく見てみたら茶葉でした。あれだけ持って帰るってことはきっと飲むんだろうなぁ。新宿御苑の茶葉ってどんな味するんだろう。

最後の2枚は葉桜とさくらんぼです。一面が青々として綺麗でした。閑散としているなか葉桜を眺めるのも良いですねぇ。