PipelineDBでCV定義をする時に気をつけること(時間関数編)とContinuous Transform

CV(Continuous View)を定義する時に、その瞬間の時間を表すものは、arrival_timestampclock_timestamp()が使えます。
now()等も時間を返しますが、この関数はCV定義に使う事はできません。

現在の日付と時刻(現在のトランザクションの開始時)

https://www.postgresql.jp/document/9.5/html/functions-datetime.html

とあります。通常のSQLではこれでも問題ないのですが、CVはStreamに対してずっとTransactionをかけている事になっているので、実質的にPipelineDBの起動時間やCVを定義した時間が返ってくる事になります。
なのでCVでは使う事ができません。

また、click_timestamp()は1つしか定義できません。複数定義すると以下のエラーが発生します。

CREATE CONTINUOUS VIEW test2 AS
SELECT
to_char(to_timestamp((item->>'eventTimestamp')::bigint + 3600*9), 'YYYY-MM-DD HH24:MI:00') as jst,
(item->>'platform')::text as platform,
(item->>'action')::text as action,
count(*) as cnt
FROM sn_action_stream
WHERE
minute(arrival_timestamp) > clock_timestamp() - interval '3 days'
AND to_timestamp((item->>'t')::bigint) > clock_timestamp() - interval '3 days'
GROUP BY
jst, platform, action;
ERROR: clock_timestamp() may only appear once in a WHERE clause

そもそも、なぜこのようにしているかと言うと、直近3日間に到着したログだけを対象にしたいが、ログは遅延して送られてくる事が多く(数日遅れて来る場合もある..)レコードの日付も3日以内である事をチェックしたい場合などです。
その場合、レコードの時間だけを対象にすれば良いのですが、それだとPipelineDBのレコードとしてのLifetimeを設定できないのです。
WITH (max_age)使えば良いのですが。

どうしても複数使いたい場合は、サブクエリで回避できます。

CREATE CONTINUOUS VIEW test2 AS
SELECT
to_char(to_timestamp((item->>'eventTimestamp')::bigint + 3600*9), 'YYYY-MM-DD HH24:MI:00') as jst,
(item->>'platform')::text as platform,
(item->>'action')::text as action,
count(*) as cnt
FROM (SELECT arrival_timestamp, item FROM sn_action_stream WHERE to_timestamp((item->>'eventTimestamp')::bigint) > clock_timestamp() - interval '3 days') _
WHERE
minute(arrival_timestamp) > clock_timestamp() - interval '3 days'
GROUP BY
jst, platform, action;

ただし、こんな事をしなくても Continuous Transform を使うともっと良い感じにできます。
Continuous Transformとは、StreamからCVを定義し、その結果を別のStreamへ流す事ができます。つまりフィルタとしての振る舞いをします。

CREATE STREAM strm_test1 (item JSONB);
CREATE STREAM strm_test2 (item JSONB);

CREATE CONTINUOUS TRANSFORM test_etl AS
SELECT item::jsonb
FROM strm_test1
WHERE
to_timestamp((item->>'eventTimestamp')::bigint) > clock_timestamp() - interval '3 days'
THEN EXECUTE PROCEDURE pipeline_stream_insert('strm_test2')
;

このように定義して、綺麗になったtest2を参照するCVを定義します。

CREATE CONTINUOUS VIEW test2 AS
SELECT
to_char(to_timestamp((item->>'eventTimestamp')::bigint + 3600*9), 'YYYY-MM-DD HH24:MI:00') as jst,
(item->>'platform')::text as platform,
(item->>'action')::text as action,
count(*) as cnt
FROM strm_test2
WHERE
minute(arrival_timestamp) > clock_timestamp() - interval '3 days'
GROUP BY
jst, platform, action;

pipeline_stream_insertはv0.9.3で用意された関数ですが、これを使わなくても独自で定義する事ができます。
話がだんだん逸れていきますが、Continuous Transformを使えばStreamのコピーをする事もできます。
それはまた別の記事で。

PipelineDBのDisk使用率とデータの有効期限に関するメモ

バージョン毎に事情が変わっているのでメモ。

  • 0.8.0
    • Minute(arrival_timestamp) がサポートされる
    • これのおかげでmrelテーブルに細かく保存されていたものの粒度が大きくなる。
  • 0.8.1
    • WITH構文がサポートされ、max_age指定が出来るようになった。
      • arrival_timestamp > clock_timestamp() - interval '3 day'といった構文と等価
    • stream_commit_interval という設定が追加される。
      • DiskにFlushするタイミングを大きくする事でDisk肥大化を防ぐ事ができる。
  • 0.8.3
    • WITH構文にstep_factorが追加される。
    • step_factorはmax_ageの期間をどれくらいのBucketに分割するかで、minute(arrival_timestamp)の変わりに使う。
  • 0.9.2
    • minute(arrival_timestamp)構文が使えなくなった。
  • 0.9.3
    • step_factorは今まで1〜50の間で設定する必要があったが、小数点を指定できるようになった。
      • 中の人が言うには、Bucketが細かくなりすぎてSELECTが遅くなるのでオススメしないとのこと。

hexo customize その1

テンプレート

https://github.com/kwhrtsk/hexo-theme-ingenuous

こちらのテンプレートをベースに、カスタムしています。

Archiveの日付部分

日付のFormatはmoment.jsを使っているみたいだけど、FormatにMMM DoDoを指定してもが表示されない。
どうやらmoment.jsのソースコードを見る限り、対応していないっぽい。

LL だと年月日が表示される。けど、年は要らないので、 M月D日と指定する事にしました。

画像の指定方法

{% asset_img cap1.png 画像のタイトル %}

RSSフィード生成

(node) v8::ObjectTemplate::Set() with non-primitive values is deprecated
(node) and will stop working in the next major release.

https://github.com/hexojs/hexo/issues/1924
https://github.com/hexojs/hexo/issues/1939#issuecomment-226368455

MacでNode6系だと発生するのかしら。
ひとまず、書いてある通りに実行したら発生しなくなりました。

直したいところ

  • タグの場所
  • 一覧画面(_partial/article.ejs)の先頭に、タグやカテゴリの内容を表示したい
  • Pocket対応
  • GA対応
  • 広告配置
  • 独自タグの追加(画像の配置とサイズ)

BLOGを引越してみました

Blogを引越してみました。
前のBlogは タムタムの日記 なのですが、MovableTypeのバージョンアップがかなりキツい。
MT4からMT6は骨が折れたので、諦めました。

あと、BlogをMarkdown/Githubで管理したいなーと思い、Hexoというソフトを使ってます。

design-test

本文。

HelloWorld
#include <iostream>
int main() {
std::cout << "Hello, World!\n";
}
fn main() {
println!("hello, world");
}
{
"hello": "world"
}

画像はセンタリングされる

Table

NORMAL LEFT CENTER RIGHT
1 2 3 4

GIST

.gist .blob-codeのbackgroundがtransparentになっているせいかしら。
ちょっとGistを貼り付けるのは諦めよう..

2016-04-23 14:58:48 +0000 [warn]: emit transaction failed: error_class=IOError error="closed stream" tag="fluent.info"
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/plugin/buf_file.rb:39:in `write'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/plugin/buf_file.rb:39:in `<<'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/buffer.rb:200:in `block in emit'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/buffer.rb:193:in `emit'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/output.rb:582:in `block in emit'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/output.rb:581:in `each'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/output.rb:581:in `emit'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/event_router.rb:90:in `emit_stream'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/event_router.rb:81:in `emit'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/engine.rb:177:in `block in log_event_loop'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/engine.rb:175:in `each'
2016-04-23 14:58:48 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/engine.rb:175:in `log_event_loop'
2016-04-23 14:58:48 +0000 [error]: failed to emit fluentd's log event tag="fluent.info" event={"type"=>"file", "plugin_id"=>"object:3fb5f4133eb0", "message"=>"shutting down output type=\"file\" plugin_id=\"
object:3fb5f4133eb0\""} error_class=IOError error=#<IOError: closed stream>
2016-04-23 14:58:48 +0000 [warn]: emit transaction failed: error_class=IOError error="closed stream" tag="fluent.info"
2016-04-23 14:58:48 +0000 [warn]: suppressed same stacktrace
2016-04-23 14:58:48 +0000 [error]: failed to emit fluentd's log event tag="fluent.info" event={"type"=>"copy", "plugin_id"=>"object:3fb5f144e440", "message"=>"shutting down output type=\"copy\" plugin_id=\"
object:3fb5f144e440\""} error_class=IOError error=#<IOError: closed stream>
view raw shutdown時.txt hosted with ❤ by GitHub
<source>
type monitor_agent
port 24220
</source>
<source>
type tail
format json
read_from_head true
path /data/logs/ads-summary.log
pos_file /var/log/td-agent/ads-summary_log.pos
tag smart-ad.beacon.ads-summary
#time_key timestamp
</source>
<match smart-ad.beacon.ads-summary>
type copy
deep_copy true
<store>
type s3
s3_bucket tamtam-dev
s3_region ap-northeast-1
<instance_profile_credentials>
retries 5
</instance_profile_credentials>
s3_object_key_format %{path}/ts=%{time_slice}/action=ads-summary/%{index}_%{hostname}.json.%{file_extension}
path tamtam-test/beacon
buffer_type file
buffer_path /data/td-agent/s3/ads-summary/
time_slice_format %Y-%m-%d-%H
time_slice_wait 10m
time_key timestamp
include_time_key
time_as_epoch
buffer_chunk_limit 256m
format json
utc
</store>
<store>
type flowcounter
count_keys *
unit minute
aggregate all
tag fluentd.traffic.ads-summary
</store>
</match>
view raw td-agent.conf hosted with ❤ by GitHub
2016-04-23 14:50:41 +0000 [warn]: temporarily failed to flush the buffer. next_retry=2016-04-23 14:50:42 +0000 error_class="NoMethodError" error="undefined method `object' for nil:NilClass" plugin_id="objec
t:3fb5f7cc9628"
2016-04-23 14:50:41 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-s3-0.6.6/lib/fluent/plugin/out_s3.rb:210:in `write'
2016-04-23 14:50:41 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/buffer.rb:351:in `write_chunk'
2016-04-23 14:50:41 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/buffer.rb:330:in `pop'
2016-04-23 14:50:41 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/output.rb:338:in `try_flush'
2016-04-23 14:50:41 +0000 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.12.22/lib/fluent/output.rb:149:in `run'
view raw 起動時.txt hosted with ❤ by GitHub