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枚は葉桜とさくらんぼです。一面が青々として綺麗でした。閑散としているなか葉桜を眺めるのも良いですねぇ。










Apr 30, 2019

Machine Learning Connector in Presto

This is quick tutorial for presto-ml connector. The connector isn't maintenanced actively and the supported model is only SVM.

You can see below sample query in the test directory. As the same as Teradata Aster and BigQuery ML, there're two kinds of functions.

  • learn_classifier: receives training data and generates the model
  • classify: receives the model & test data and returns the prediction


SELECT classify(features(1, 2), model)
FROM (
 SELECT learn_classifier(labels, features) AS model
 FROM (
  VALUES (1, features(1, 2))) t(labels, features)
) t2
→ 1

SELECT classify(features(1, 2), model)
FROM (
 SELECT learn_classifier(labels, features) AS model
 FROM (
  VALUES ('cat', features(1, 2))) t(labels, features)
) t2
→ 'cat'

Let's try using Iris data sets.
CREATE TABLE iris (
  id int
, sepal_length double
, sepal_width double
, petal_length double
, petal_width double
, species varchar
)

INSERT INTO iris VALUES 
(1, 5.1, 3.5, 1.4, 0.2, 'Iris-setosa'),
(2, 4.9, 3, 1.4, 0.2, 'Iris-setosa'),
(3, 4.7, 3.2, 1.3, 0.2, 'Iris-setosa'),
(4, 4.6, 3.1, 1.5, 0.2, 'Iris-setosa'),
(5, 5, 3.6, 1.4, 0.2, 'Iris-setosa'),
(6, 5.4, 3.9, 1.7, 0.4, 'Iris-setosa'),
(7, 4.6, 3.4, 1.4, 0.3, 'Iris-setosa'),
(8, 5, 3.4, 1.5, 0.2, 'Iris-setosa'),
(9, 4.4, 2.9, 1.4, 0.2, 'Iris-setosa'),
(10, 4.9, 3.1, 1.5, 0.1, 'Iris-setosa'),
(11, 5.4, 3.7, 1.5, 0.2, 'Iris-setosa'),
(12, 4.8, 3.4, 1.6, 0.2, 'Iris-setosa'),
(13, 4.8, 3, 1.4, 0.1, 'Iris-setosa'),
(14, 4.3, 3, 1.1, 0.1, 'Iris-setosa'),
(15, 5.8, 4, 1.2, 0.2, 'Iris-setosa'),
(16, 5.7, 4.4, 1.5, 0.4, 'Iris-setosa'),
(17, 5.4, 3.9, 1.3, 0.4, 'Iris-setosa'),
(18, 5.1, 3.5, 1.4, 0.3, 'Iris-setosa'),
(19, 5.7, 3.8, 1.7, 0.3, 'Iris-setosa'),
(20, 5.1, 3.8, 1.5, 0.3, 'Iris-setosa'),
(21, 5.4, 3.4, 1.7, 0.2, 'Iris-setosa'),
(22, 5.1, 3.7, 1.5, 0.4, 'Iris-setosa'),
(23, 4.6, 3.6, 1, 0.2, 'Iris-setosa'),
(24, 5.1, 3.3, 1.7, 0.5, 'Iris-setosa'),
(25, 4.8, 3.4, 1.9, 0.2, 'Iris-setosa'),
(26, 5, 3, 1.6, 0.2, 'Iris-setosa'),
(27, 5, 3.4, 1.6, 0.4, 'Iris-setosa'),
(28, 5.2, 3.5, 1.5, 0.2, 'Iris-setosa'),
(29, 5.2, 3.4, 1.4, 0.2, 'Iris-setosa'),
(30, 4.7, 3.2, 1.6, 0.2, 'Iris-setosa'),
(31, 4.8, 3.1, 1.6, 0.2, 'Iris-setosa'),
(32, 5.4, 3.4, 1.5, 0.4, 'Iris-setosa'),
(33, 5.2, 4.1, 1.5, 0.1, 'Iris-setosa'),
(34, 5.5, 4.2, 1.4, 0.2, 'Iris-setosa'),
(35, 4.9, 3.1, 1.5, 0.1, 'Iris-setosa'),
(36, 5, 3.2, 1.2, 0.2, 'Iris-setosa'),
(37, 5.5, 3.5, 1.3, 0.2, 'Iris-setosa'),
(38, 4.9, 3.1, 1.5, 0.1, 'Iris-setosa'),
(39, 4.4, 3, 1.3, 0.2, 'Iris-setosa'),
(40, 5.1, 3.4, 1.5, 0.2, 'Iris-setosa'),
(41, 5, 3.5, 1.3, 0.3, 'Iris-setosa'),
(42, 4.5, 2.3, 1.3, 0.3, 'Iris-setosa'),
(43, 4.4, 3.2, 1.3, 0.2, 'Iris-setosa'),
(44, 5, 3.5, 1.6, 0.6, 'Iris-setosa'),
(45, 5.1, 3.8, 1.9, 0.4, 'Iris-setosa'),
(46, 4.8, 3, 1.4, 0.3, 'Iris-setosa'),
(47, 5.1, 3.8, 1.6, 0.2, 'Iris-setosa'),
(48, 4.6, 3.2, 1.4, 0.2, 'Iris-setosa'),
(49, 5.3, 3.7, 1.5, 0.2, 'Iris-setosa'),
(50, 5, 3.3, 1.4, 0.2, 'Iris-setosa'),
(51, 7, 3.2, 4.7, 1.4, 'Iris-versicolor'),
(52, 6.4, 3.2, 4.5, 1.5, 'Iris-versicolor'),
(53, 6.9, 3.1, 4.9, 1.5, 'Iris-versicolor'),
(54, 5.5, 2.3, 4, 1.3, 'Iris-versicolor'),
(55, 6.5, 2.8, 4.6, 1.5, 'Iris-versicolor'),
(56, 5.7, 2.8, 4.5, 1.3, 'Iris-versicolor'),
(57, 6.3, 3.3, 4.7, 1.6, 'Iris-versicolor'),
(58, 4.9, 2.4, 3.3, 1, 'Iris-versicolor'),
(59, 6.6, 2.9, 4.6, 1.3, 'Iris-versicolor'),
(60, 5.2, 2.7, 3.9, 1.4, 'Iris-versicolor'),
(61, 5, 2, 3.5, 1, 'Iris-versicolor'),
(62, 5.9, 3, 4.2, 1.5, 'Iris-versicolor'),
(63, 6, 2.2, 4, 1, 'Iris-versicolor'),
(64, 6.1, 2.9, 4.7, 1.4, 'Iris-versicolor'),
(65, 5.6, 2.9, 3.6, 1.3, 'Iris-versicolor'),
(66, 6.7, 3.1, 4.4, 1.4, 'Iris-versicolor'),
(67, 5.6, 3, 4.5, 1.5, 'Iris-versicolor'),
(68, 5.8, 2.7, 4.1, 1, 'Iris-versicolor'),
(69, 6.2, 2.2, 4.5, 1.5, 'Iris-versicolor'),
(70, 5.6, 2.5, 3.9, 1.1, 'Iris-versicolor'),
(71, 5.9, 3.2, 4.8, 1.8, 'Iris-versicolor'),
(72, 6.1, 2.8, 4, 1.3, 'Iris-versicolor'),
(73, 6.3, 2.5, 4.9, 1.5, 'Iris-versicolor'),
(74, 6.1, 2.8, 4.7, 1.2, 'Iris-versicolor'),
(75, 6.4, 2.9, 4.3, 1.3, 'Iris-versicolor'),
(76, 6.6, 3, 4.4, 1.4, 'Iris-versicolor'),
(77, 6.8, 2.8, 4.8, 1.4, 'Iris-versicolor'),
(78, 6.7, 3, 5, 1.7, 'Iris-versicolor'),
(79, 6, 2.9, 4.5, 1.5, 'Iris-versicolor'),
(80, 5.7, 2.6, 3.5, 1, 'Iris-versicolor'),
(81, 5.5, 2.4, 3.8, 1.1, 'Iris-versicolor'),
(82, 5.5, 2.4, 3.7, 1, 'Iris-versicolor'),
(83, 5.8, 2.7, 3.9, 1.2, 'Iris-versicolor'),
(84, 6, 2.7, 5.1, 1.6, 'Iris-versicolor'),
(85, 5.4, 3, 4.5, 1.5, 'Iris-versicolor'),
(86, 6, 3.4, 4.5, 1.6, 'Iris-versicolor'),
(87, 6.7, 3.1, 4.7, 1.5, 'Iris-versicolor'),
(88, 6.3, 2.3, 4.4, 1.3, 'Iris-versicolor'),
(89, 5.6, 3, 4.1, 1.3, 'Iris-versicolor'),
(90, 5.5, 2.5, 4, 1.3, 'Iris-versicolor'),
(91, 5.5, 2.6, 4.4, 1.2, 'Iris-versicolor'),
(92, 6.1, 3, 4.6, 1.4, 'Iris-versicolor'),
(93, 5.8, 2.6, 4, 1.2, 'Iris-versicolor'),
(94, 5, 2.3, 3.3, 1, 'Iris-versicolor'),
(95, 5.6, 2.7, 4.2, 1.3, 'Iris-versicolor'),
(96, 5.7, 3, 4.2, 1.2, 'Iris-versicolor'),
(97, 5.7, 2.9, 4.2, 1.3, 'Iris-versicolor'),
(98, 6.2, 2.9, 4.3, 1.3, 'Iris-versicolor'),
(99, 5.1, 2.5, 3, 1.1, 'Iris-versicolor'),
(100, 5.7, 2.8, 4.1, 1.3, 'Iris-versicolor'),
(101, 6.3, 3.3, 6, 2.5, 'Iris-virginica'),
(102, 5.8, 2.7, 5.1, 1.9, 'Iris-virginica'),
(103, 7.1, 3, 5.9, 2.1, 'Iris-virginica'),
(104, 6.3, 2.9, 5.6, 1.8, 'Iris-virginica'),
(105, 6.5, 3, 5.8, 2.2, 'Iris-virginica'),
(106, 7.6, 3, 6.6, 2.1, 'Iris-virginica'),
(107, 4.9, 2.5, 4.5, 1.7, 'Iris-virginica'),
(108, 7.3, 2.9, 6.3, 1.8, 'Iris-virginica'),
(109, 6.7, 2.5, 5.8, 1.8, 'Iris-virginica'),
(110, 7.2, 3.6, 6.1, 2.5, 'Iris-virginica'),
(111, 6.5, 3.2, 5.1, 2, 'Iris-virginica'),
(112, 6.4, 2.7, 5.3, 1.9, 'Iris-virginica'),
(113, 6.8, 3, 5.5, 2.1, 'Iris-virginica'),
(114, 5.7, 2.5, 5, 2, 'Iris-virginica'),
(115, 5.8, 2.8, 5.1, 2.4, 'Iris-virginica'),
(116, 6.4, 3.2, 5.3, 2.3, 'Iris-virginica'),
(117, 6.5, 3, 5.5, 1.8, 'Iris-virginica'),
(118, 7.7, 3.8, 6.7, 2.2, 'Iris-virginica'),
(119, 7.7, 2.6, 6.9, 2.3, 'Iris-virginica'),
(120, 6, 2.2, 5, 1.5, 'Iris-virginica'),
(121, 6.9, 3.2, 5.7, 2.3, 'Iris-virginica'),
(122, 5.6, 2.8, 4.9, 2, 'Iris-virginica'),
(123, 7.7, 2.8, 6.7, 2, 'Iris-virginica'),
(124, 6.3, 2.7, 4.9, 1.8, 'Iris-virginica'),
(125, 6.7, 3.3, 5.7, 2.1, 'Iris-virginica'),
(126, 7.2, 3.2, 6, 1.8, 'Iris-virginica'),
(127, 6.2, 2.8, 4.8, 1.8, 'Iris-virginica'),
(128, 6.1, 3, 4.9, 1.8, 'Iris-virginica'),
(129, 6.4, 2.8, 5.6, 2.1, 'Iris-virginica'),
(130, 7.2, 3, 5.8, 1.6, 'Iris-virginica'),
(131, 7.4, 2.8, 6.1, 1.9, 'Iris-virginica'),
(132, 7.9, 3.8, 6.4, 2, 'Iris-virginica'),
(133, 6.4, 2.8, 5.6, 2.2, 'Iris-virginica'),
(134, 6.3, 2.8, 5.1, 1.5, 'Iris-virginica'),
(135, 6.1, 2.6, 5.6, 1.4, 'Iris-virginica'),
(136, 7.7, 3, 6.1, 2.3, 'Iris-virginica'),
(137, 6.3, 3.4, 5.6, 2.4, 'Iris-virginica'),
(138, 6.4, 3.1, 5.5, 1.8, 'Iris-virginica'),
(139, 6, 3, 4.8, 1.8, 'Iris-virginica'),
(140, 6.9, 3.1, 5.4, 2.1, 'Iris-virginica'),
(141, 6.7, 3.1, 5.6, 2.4, 'Iris-virginica'),
(142, 6.9, 3.1, 5.1, 2.3, 'Iris-virginica'),
(143, 5.8, 2.7, 5.1, 1.9, 'Iris-virginica'),
(144, 6.8, 3.2, 5.9, 2.3, 'Iris-virginica'),
(145, 6.7, 3.3, 5.7, 2.5, 'Iris-virginica'),
(146, 6.7, 3, 5.2, 2.3, 'Iris-virginica'),
(147, 6.3, 2.5, 5, 1.9, 'Iris-virginica'),
(148, 6.5, 3, 5.2, 2, 'Iris-virginica'),
(149, 6.2, 3.4, 5.4, 2.3, 'Iris-virginica'),
(150, 5.9, 3, 5.1, 1.8, 'Iris-virginica');

In this data sets, species is a label and sepal_length, sepal_width and so on are features.
SELECT
 learn_classifier(species, features(sepal_length, sepal_width, petal_length, petal_width)) AS model
FROM iris
                      model                   
-------------------------------------------------
 3c 43 6c 61 73 73 69 66 69 65 72 28 76 61 72 63
 68 61 72 29 3e                               

This features function gives the number (0~9) to each arguments and returns it as map types. It returns unexpected parameters if the arguments number is over 10.
SELECT features(-100, 100);
        _col0     
---------------------
 {0=-100.0, 1=100.0}

SELECT features(1,2,3,4,5,6,7,8,9,10,11);
→Unexpected parameters

Next, let's try to get the prediction using classify function. features(5.9, 3, 5.1, 1.8) is final rows above the insert statements. I used it for clarify. We can get expected result 'Iris-virginica', the same as inserted data.
SELECT classify(features(5.9, 3, 5.1, 1.8), model)
FROM (
SELECT
 learn_classifier(species, features(sepal_length, sepal_width, petal_length, petal_width)) AS model
FROM iris
) t
     _col0   
----------------
 Iris-virginica


Though we want to store the machine learning model in a storage, current learn_classifier doesn't allow it. It uses original type in the connector.
CREATE TABLE learn_classifier_model AS
 SELECT learn_classifier(labels, features) AS model
 FROM (
  VALUES ('cat', features(1, 2))) t(labels, features)
;
→ Unsupported type: Classifier(varchar)

If you're interested in presto-ml, you can address this issue https://github.com/prestosql/presto/issues/662.

Apr 20, 2019

INSERT OVERWRITE in Presto

If you are hive user and ETL developer, you may see a lot of INSERT OVERWRITE. Though it's not yet documented, Presto also supports OVERWRITE mode for partitioned table.

Currently, there are 3 modes, OVERWRITE, APPEND and ERROR.

OVERWRITE overwrites existing partition.
APPEND appends rows in existing partition.
ERROR fails when the partition already exists.

You can change the mode by set session command.
set session hive.insert_existing_partitions_behavior = 'overwrite';
set session hive.insert_existing_partitions_behavior = 'append';
set session hive.insert_existing_partitions_behavior = 'error';

The enhanced feature for an unpartitioned table is ongoing in this PR (https://github.com/prestosql/presto/pull/648) by James Xu.

The enhancement was merged as https://github.com/prestosql/presto/pull/924

Mar 18, 2019

MSCK in Presto

Presto release 304 contains new procedure system.sync_partition_metadata() developed by @luohao.  This is similar to hive's MSCK REPAIR TABLE.

Document about Hive Connector Procedures is https://prestosql.io/docs/current/connector/hive.html#procedures

The syntax is `system.sync_partition_metadata(schema_name, table_name, mode)`. The supported mode are add, drop and full. Example query is

  • call system.sync_partition_metadata('default', 'test_partition', 'add');
  • call system.sync_partition_metadata('default', 'test_partition', 'drop');
  • call system.sync_partition_metadata('default', 'test_partition', 'full');

# Mode DROP
hive> create table default.test_partition (c1 int) partitioned by (dt string);
hive> insert overwrite table default.test_partition partition(dt = '20190101') values (1);
hive> dfs -mv hdfs://hadoop-master:9000/user/hive/warehouse/test_partition/dt=20190101 /tmp/;
hive> show partitions default.test_partition;
dt=20190101

presto> use hive.default;
presto> call system.sync_partition_metadata('default', 'test_partition', 'drop');

hive> show partitions default.test_partition;
→ Empty

# Mode ADD
hive> dfs -mv /tmp/dt=20190101 hdfs://hadoop-master:9000/user/hive/warehouse/test_partition/;

presto> call system.sync_partition_metadata('default', 'test_partition', 'add');

hive>  show partitions default.test_partition;
dt=20190101

# Mode FULL performs both DROP and ADD. 

Jan 4, 2019

Try Apache Griffin

Currently, Griffin doesn't provide the binary, therefore you need to build it yourself. It's not difficult though. I tried it on hortonworks:sandbox-hdp container. Even if you're using default environment, additional steps are just adding Spark on Ambari and installing maven.

# Add Spark
login ambari (http://localhost:8080/#/login)
Spark2 -> Service Actions -> Start

# Login to hortonworks:sandbox-hdp using bash
docker exec -it sandbox-hdp bash

# Install maven if not installed on there
wget http://ftp.riken.jp/net/apache/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz
tar -xvf apache-maven-3.6.0-bin.tar.gz
cd apache-maven-3.6.0
mv apache-maven-3.6.0 /opt/apache-maven-3.6.0
vi /etc/environment
  M2_HOME="/opt/apache-maven-3.6.0"
  export PATH=$M3:$PATH

sudo update-alternatives --install "/usr/bin/mvn" "mvn" "/opt/apache-maven-3.6.0/bin/mvn" 0
sudo update-alternatives --set mvn /opt/apache-maven-3.6.0/bin/mvn

# Install griffin (http://griffin.apache.org/docs/quickstart.html)
wget https://www.apache.org/dist/incubator/griffin/0.3.0-incubating/griffin-0.3.0-incubating-source-release.zip
unzip griffin-0.3.0-incubating-source-release.zip
cd griffin-0.3.0-incubating
mvn clean install
  It takes about few minutes (my case was 14 min) and the size will be 660MB.
mv measure/target/measure-0.3.0-incubating.jar /usr/local/griffin-measure.jar

# Prepare demo data
wget --recursive --no-parent http://griffin.apache.org/data/batch
cd griffin.apache.org/data/batch
chmod +x *.sh
./gen_demo_data.sh

hive
CREATE EXTERNAL TABLE `demo_src`(
  `id` bigint,
  `age` int,
  `desc` string)
PARTITIONED BY (
  `dt` string,
  `hour` string)
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY '|'
;

CREATE EXTERNAL TABLE `demo_tgt`(
  `id` bigint,
  `age` int,
  `desc` string)
PARTITIONED BY (
  `dt` string,
  `hour` string)
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY '|'
;


LOAD DATA LOCAL INPATH 'demo_src' INTO TABLE demo_src PARTITION (dt='20180912',hour='09');
LOAD DATA LOCAL INPATH 'demo_tgt' INTO TABLE demo_tgt PARTITION (dt='20180912',hour='09');

# Create config file
vi env.json
{
  "spark": {
    "log.level": "WARN"
  },
  "sinks": [
    {
      "type": "console"
    },
    {
      "type": "hdfs",
      "config": {
        "path": "hdfs:///griffin/persist"
      }
    },
    {
      "type": "elasticsearch",
      "config": {
        "method": "post",
        "api": "http://es:9200/griffin/accuracy"
      }
    }
  ]
}


vi dq.json
{
  "name": "batch_accu",
  "process.type": "batch",
  "data.sources": [
    {
      "name": "src",
      "baseline": true,
      "connectors": [
        {
          "type": "hive",
          "version": "1.2",
          "config": {
            "database": "default",
            "table.name": "demo_src"
          }
        }
      ]
    }, {
      "name": "tgt",
      "connectors": [
        {
          "type": "hive",
          "version": "1.2",
          "config": {
            "database": "default",
            "table.name": "demo_tgt"
          }
        }
      ]
    }
  ],
  "evaluate.rule": {
    "rules": [
      {
        "dsl.type": "griffin-dsl",
        "dq.type": "accuracy",
        "out.dataframe.name": "accu",
        "rule": "src.id = tgt.id AND src.age = tgt.age AND src.desc = tgt.desc",
        "details": {
          "source": "src",
          "target": "tgt",
          "miss": "miss_count",
          "total": "total_count",
          "matched": "matched_count"
        },
        "out": [
          {
            "type": "metric",
            "name": "accu"
          },
          {
            "type": "record",
            "name": "missRecords"
          }
        ]
      }
    ]
  },
  "sinks": ["CONSOLE", "HDFS"]
}

# Run !
spark-submit --class org.apache.griffin.measure.Application --master yarn --deploy-mode client --queue default --driver-memory 1g --executor-memory 1g --num-executors 2 /usr/local/griffin-measure.jar /env.json /dq.json

# Result
data source timeRanges: src -> (1544668358323, 1544668358323], tgt -> (1544668358323, 1544668358323]
[1544668358323] batch_accu start: application_1544490410222_0011
batch_accu [1544668358323] metrics:
{"name":"batch_accu","tmst":1544668358323,"value":{"total_count":125000,"miss_count":512,"matched_count":124488}}

# Check above miss_count manually
select
 count(src.id) as total_count
 ,sum(if(tgt.id is null, 1, 0)) as miss_count
 ,sum(if(tgt.id is not null, 1, 0)) as matched_count
from demo_src src
left outer join demo_tgt tgt
on src.id = tgt.id AND src.age = tgt.age AND src.desc = tgt.desc
;

total_count, miss_count, matched_count
125000, 512, 124488

# Generated files on HDFS
[[email protected] /]# hdfs dfs -ls /griffin/persist/batch_accu/1544668358323
Found 5 items
-rw-r--r--   1 root hdfs          0 2018-12-13 02:33 /griffin/persist/batch_accu/1544668358323/_FINISH
-rw-r--r--   1 root hdfs        137 2018-12-13 02:33 /griffin/persist/batch_accu/1544668358323/_LOG
-rw-r--r--   1 root hdfs        113 2018-12-13 02:33 /griffin/persist/batch_accu/1544668358323/_METRICS
-rw-r--r--   1 root hdfs         30 2018-12-13 02:32 /griffin/persist/batch_accu/1544668358323/_START

-rw-r--r--   1 root hdfs      44543 2018-12-13 02:33 /griffin/persist/batch_accu/1544668358323/missRecords


hdfs dfs -cat /griffin/persist/batch_accu/1544668358323/_FINISH
(empty)

hdfs dfs -cat /griffin/persist/batch_accu/1544668358323/_LOG
================ log of Thu Dec 16 02:32:38 UTC 2018 ================
--- Thu Dec 16 02:33:18 UTC 2018 ---
process using time: 40444 ms


hdfs dfs -cat /griffin/persist/batch_accu/1544668358323/_METRICS
{"name":"batch_accu","tmst":1544668358323,"value":{"total_count":125000,"miss_count":512,"matched_count":124488}}


hdfs dfs -cat /griffin/persist/batch_accu/1544668358323/_START
application_1544490410222_0011



hdfs dfs -cat /griffin/persist/batch_accu/1544668358323/missRecords
{"id":124,"age":1273,"desc":"1273","dt":"20180912","hour":"09","__tmst":1544668358323}
{"id":124,"age":1065,"desc":"1065","dt":"20180912","hour":"09","__tmst":1544668358323}
{"id":124,"age":1798,"desc":"1798","dt":"20180912","hour":"09","__tmst":1544668358323}

Jan 1, 2019

Throw Back 2018


On
夏頃から転職活動を始めたこともあって、後半は仕事に集中できていたかと言われると怪しいなぁという1年でした。2018年はSQL, Java, Python, Javascriptとまんべんなく触っていたように思います。転職先ではJava, Pythonを書く量が多そうかなという印象です。
Off
今自分1人で住んでる実家の売却が決まってバタバタした1年でした。3月末までに引っ越す予定なので、そろそろ家を探さねば...。意識的に変化を起こそうといつもとは違う選択した年でもあり、iPhoneからPixelに変えたのもそういう表れだったりします。音楽を聴く量が増え、ゲームをやる時間はだいぶ減りました。

Music
  • RETURN TO SENDER
  • CAND¥¥¥LAND feat. LIZ (Pa's Lam System Remix)
  • 衣替え feat. BONNIE PINK
  • くりかえしのMUSIC feat. 岸田繁(くるり)- tofubeats REMIX
去年はtofubeatsの曲をひたすら聴いてました。今年こそはライブに行きたい...!

Book
  • 人間のように泣いたのか?
  • NETFLIXの最強人事戦略
  • シンドローム
  • 天空の矢はどこへ?
  • 暗号解読
  • 君の名は。
  • 君の名は。 Another Side:Earthbound
  • ニューエリート グーグル流・新しい価値を生み出し世界を変える人たち
  • 世界一速く結果を出す人は、なぜ、メールを使わないのか
  • 集中力はいらない
  • 女王の百年密室―GOD SAVE THE QUEEN―
  • 血か、死か、無か?
  • サルたちの狂宴
  • Effective Java 第3版
  • Java 逆引きレシピ
  • Javaによる関数型プログラミング
  • Go言語でつくるインタプリタ
  • Hadoop徹底入門
  • C++ プログラミング入門
ついにWシリーズが終わってしまって悲しい...。でも最終巻の"人間のように泣いたのか?"の終わり方はすごく好きな感じでホッとしました。勉強関連の本はJavaを中心に、気晴らしにC++の本を買ってみました。

Comic
  • それでも町は廻っている
  • VINLAND SAGA
  • BANANA FISH
  • ベルセルク
  • Jドリーム
  • AIの遺電子 RED QUEEN
  • さよなら私のクラマー
  • さよならフットボール
  • 日常
  • アルスラーン戦記
  • ヒナまつり
  • ダンジョン飯
  • タヌキとキツネ
  • 約束のネバーランド
  • NEW GAME!
  • 進撃の巨人
  • BLUE GIANT SUPREME
  • 岡崎に捧ぐ
  • 山本さんちのねこの話
  • 無慈悲な8bit
  • 静かなるドン
  • 囚人リク
  • 鮫島、最後の十五日
  • 3月のライオン
  • うちのトイプーがアイドルすぎる
  • まどろみマーメイド
"岡崎に捧ぐ"が面白くて、山本さほさんの本をまとめ買いしました。それ町は日常系だけど、だたほのぼのしてるだけでなく途中現実的な描写もあって、よつばと!とは違う面白さがあります。

Movie
Netflixやhuluを解約したのもあってあまり映画は観なかったんですが、シュガーラッシュは前作が好きだったので、上映開始日に観に行きました。 レビューを眺めてたところ、これは"プリンセスの再定義だ"と言ってる方がいてなるほどな〜と思いました。

Game
  • Red Dead Redemption 2
  • Shadow of the Tomb Raider
  • Spider-Man
  • Fallout 76
  • The Legend of Zelda: Breath of the Wild
ゲームは重めなものを4つ買ってみたもののSpider-ManとFalloutは酔いがひどく途中で止めちゃいました。RDR2は前作やっていなかったこともあり新鮮でした。

Gadget
  • Google Pixel 3
  • iPhone XS
  • Clova Friends Mini (Brown) + Clova Friends Dock
  • デロンギ オイルヒーター
  • Beats X 
  • LG 4K ディスプレイ
  • Apple Pencil
Pixel 3を買おうとしたところ手元に届くまで1ヶ月近くかかるということでiPhone XSを買ったんですが、重くて手に馴染まないのとちょうど長めの風邪を引いてFace IDが使えない不便さもあって結局Pixel 3を買いました。カメラが綺麗で写真撮るのが楽しいです。