AWS 推出 TSDB 服務:Amazon Timestream

AWS 推出了 TSDB 服務 Amazon Timestream:「Announcing Amazon Timestream – Fast, Scalable, Fully Managed Time Series Database – Register for the Preview」。

雖然還在 preview 階段,但從 pricing 頁面可以看出目前只有 us-east-2 (也就是 US East (Ohio) 這區) 有提供服務,跟其他服務不太一樣...

費用的部份,寫入、讀取與儲存是分開收費的,比較特別的是有三種不同的媒體可以存 (不同價錢),分別是 Memory、SSD 以及 Magnetic。然後都不怎麼便宜... 如果只是想找一個 TSDB,而且已經有量的人 (目前還沒量的其實在 MySQL 內跑一跑就好了 XD),可能還是得考慮自己用 Cassandra (或是 ScyllaDB) 之類的架構?

另外一篇相關的是「Amazon Forecast – Time Series Forecasting Made Easy」,透過分析 time series data 進行預測的 Amazon Forecast,看起來也還沒跟 Amazon Timestream 整合?

AWS Lambda 可執行時間提昇

AWS Lambda 的執行時間限制從本來的 5 分鐘變成 15 分鐘了:「AWS Lambda enables functions that can run up to 15 minutes」。

You can now configure your AWS Lambda functions to run up to 15 minutes per execution. Previously, the maximum execution time (timeout) for a Lambda function was 5 minutes.

不過相較於時間拉長,我比較希望能用 Lambda 接 auto scaling,內建的條件設定還是有點陽春...

各家 Serverless 服務冷啟動 (Cold Start) 的時間

看到「Serverless: Cold Start War」這篇分析了 AWS LambdaAzure FunctionsGoogle Cloud Functions 的冷啟動特性。

裡面分析了多久沒有 request 會需要冷啟動、記憶體的大小對於冷啟動速度的影響、程式語言的影響,以及程式大小的影響。

對於量很少,但是又很在意速度的人來說也許可以研究一下。不過只要有點量 (就算一分鐘只有一次) 應該都不會遇到這塊問題...

依照交通時間,評估各種「地點」的服務...

Oalley 這個服務利用「交通時間」來評估地點,最簡單的應用像是給一個地點與時間,畫出範圍:

或是給多個點以及時間來評估地點:

不過後面是用 OpenStreetMap 的資料,我丟了幾個中文測試好像都找不到,用英文倒是可以...

Amazon Aurora for MySQL 支援 Point-in-Time Recovery 了

繼四月出 DynamoDB 推出的 PITR 後 (參考「Amazon DynamoDB 的 Point-In-Time Recovery」這篇),Amazon Aurora for MySQL 也宣佈支援 PITR 了:「Amazon Aurora Backtrack – Turn Back Time」。

從截圖可以看到支援到秒層級:

然後最多 72 小時,會有額外費用:

這樣又讓 DBA 少了一些事情 XD

Amazon DynamoDB 的 Point-In-Time Recovery

Amazon DynamoDB 在 3/26 發出來的功能,以秒為單位的備份與還原機制:「New – Amazon DynamoDB Continuous Backups and Point-In-Time Recovery (PITR)」。

先打開這個功能:

打開後就會開始記錄,最多可以還原 35 天內的任何一個時間點的資料:

DynamoDB can back up your data with per-second granularity and restore to any single second from the time PITR was enabled up to the prior 35 days.

這時候就算改變資料或是刪除資料,實際上在系統內都是 Copy-on-write 操作,所以需要另外的空間,這部份會另外計價:

Pricing for continuous backups is detailed on the DynamoDB Pricing Pages. Pricing varies by region and is based on the current size of the table and indexes. For example, in US East (N. Virginia) you pay $0.20 per GB based on the size of the data and all local secondary indexes.

有這樣的功能通常是一開始設計時就有考慮 (讓底層的資料結構可以很方便的達成這樣的效果),現在只是把功能實作出來... 像 MySQL 之類的軟體就沒辦法弄成這樣 XDDD

最後有提到支援的地區,是用條列的而不是說所有有 Amazon DynamoDB 的區域都支援:

PITR is available in the US East (N. Virginia), US East (Ohio), US West (N. California), US West (Oregon), Asia Pacific (Tokyo), Asia Pacific (Seoul), Asia Pacific (Mumbai), Asia Pacific (Singapore), Asia Pacific (Sydney), Canada (Central), EU (Frankfurt), EU (Ireland), EU (London), and South America (Sao Paulo) Regions starting today.

比對一下,應該是巴黎與美國政府用的區域沒進去... 一個是去年年底開幕的區域,另一個是本來上新功能就偏慢的區域。

DNSFilter 使用 InfluxDB 與 TimescaleDB 的過程

DNSFilter 這篇講 InfluxDBTimescaleDB 的文章頗有趣的:「Towards 3B time-series data points per day: Why DNSFilter replaced InfluxDB with TimescaleDB」。

在沒有實際用過之前,其實都只能算是一方之詞... 另外這種轉換其實也跟每個公司內的組織組成有關,像是熟悉 PostgreSQL 的單位就比較有機會用 TimescaleDB 解決 time series data 的問題。

不過有個地方倒是讓我想記錄起來:

Comparing TimescaleDB to InfluxDB at the same time — we realized we were losing data. InfluxDB relied on precisely timed execution of rollup commands to process the last X minutes of data into rollups. Combined with our series of rollups, we realized that some slow queries were causing us to lose data. The TimescaleDB data had 1–5% more entries! Also we no longer had to deal with cardinality issues, and could show our customers every last DNS request, even at a monthly rollup.

會掉資料等於是跟 InfluxDB 的使用者發出警訊,要大家確認自己手上的資料是否正確... 這對於正確性要求 100% 的應用就不是開玩笑了 @_@

Trac 1.2 的 Due Date...

在先前的文章提到了把自己在用的事件管理系統 Trac 從 1.0 升級到 1.2,然後 Due Date 的設計改變了:「Trac 1.1 增加的 time 欄位,以及 Due Date 資料的轉移」、「總算把手上的 Trac 1.0 升級到 1.2 了...」。

Trac 1.2 的資料型態是在底層存 unix timestamp 的變形 (乘以 1000000,然後前端補上 0 存成文字),這幾天用下來才發現一些以前沒遇到的問題。

一開始轉到 Trac 1.2 是設成 date,但意外的發現 (因為伺服器時間不是 UTC),不同時區的使用者在更新 ticket 時,系統會判定 Due Date 有變動而產生變更記錄,想了一下就改用 datetime 來處理這個問題。

用了 datetime 一陣子後,才發現先前的公司遇到的情境中,時區差異都很小,所以不會有 Due Date 理解上的問題 (像是從 +7 到 +9 的時區),如果今天是美國西岸跟台灣互相合作的話,只用 date 就會產生很明顯的理解問題了...

算是這陣子用 Trac 1.2 而對 Due Date 設計有不一樣的理解...

總算把手上的 Trac 1.0 升級到 1.2 了...

就如同上一篇提到的,Trac 在 1.1.1 後新增了 time 格式,所以本來的 DateFieldPlugin 有些資料要轉換。我這邊只有用在 Due Date,所以就是轉 due_date 的資料而已。

先把 due_date 都改成 due_date_bak

UPDATE ticket_custom SET name = 'due_date_bak' WHERE name = 'due_date';

然後重新計算資料,這邊是因為所有的系統都是 UTC,所以直接轉就可以了:

INSERT INTO ticket_custom (ticket, name, value) SELECT ticket, 'due_date', LPAD(UNIX_TIMESTAMP(STR_TO_DATE(value, '%Y-%m-%d')) * 1000000, 18, '0') FROM ticket_custom WHERE name = 'due_date_bak';

而我的 Report 有用到 due_date 欄位的東西,本來是 c.value 直接輸出,現在要改成:

FROM_UNIXTIME(CONVERT(c.value / 1000000, UNSIGNED INTEGER), '%Y-%m-%d') AS due_date

Trac 1.2 相較於 1.0 最不習慣的地方應該是修改界面的位置改變了,現在 Add Comment 變成在 Modify 下面,有點不太習慣,但之後用久了應該就會習慣了。其他的修一修改一改都會動了...

Trac 1.1 增加的 time 欄位,以及 Due Date 資料的轉移

Trac 的版本玩法跟早期 Linux Kernel 的模式有點像,也就是版號偶數是正式版,奇數是開發版... 雖然現在 Linux Kernel 已經不玩這套了,但 Trac 還是維持這樣的開發方式。

先前一直都是用 Trac 1.0,其中 Due Date 的功能則是用「DateFieldPlugin」這個套件,讓 Trac 支援 date 格式,於是就可以在 [ticket-custom] 裡面指定 Due Date 了:

due_date = text
due_date.date = true
due_date.date_empty = false
due_date.label = Due Date
due_date.value = <now>

在套件的頁面也有提到在 Trac 1.1.1 後就有內建的方式可以用了:

Notice: This plugin is deprecated in Trac 1.2 and later. Custom fields of type ​time were added in Trac 1.1.1.

連結是連到 1.1 的,我要測 1.2 的,所以往現在的版本翻資料,可以看到在 TracTicketsCustomFields 這邊的說明:(這邊就懶的照原來 html 排了,用 pre 直接放縮排)

time: Date and time picker. (Since 1.1.1.)
    label: Descriptive label.
    value: Default date.
    order: Sort order placement.
    format: One of:
        relative for relative dates.
        date for absolute dates.
        datetime for absolute date and time values.

這樣一來設定就會變成:

due_date = time
due_date.format = date
due_date.label = Due Date
due_date.value = now

但底層資料怎麼存?先看 ticket_custom 這個表格的結構,可以看到是 EAV 的架構:

+--------+------------+------+-----+---------+-------+
| Field  | Type       | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+-------+
| ticket | int(11)    | NO   | PRI | NULL    |       |
| name   | mediumtext | NO   | PRI | NULL    |       |
| value  | mediumtext | YES  |     | NULL    |       |
+--------+------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

隨便拉一些可以看出來放法很簡單:

+--------+----------+------------+
| ticket | name     | value      |
+--------+----------+------------+
|      1 | due_date | 2016-10-03 |
+--------+----------+------------+

改成 Trac 1.2 內建的 time 後,塞 2018/02/28 變成:

+--------+----------+--------------------+
| ticket | name     | value              |
+--------+----------+--------------------+
|      1 | due_date | 001519776000000000 |
+--------+----------+--------------------+

拿掉後面的六個 0 後可以看到就是 2018/02/28 了,要注意的是,這邊會受到時區影響,我一開始測試的時候沒調整,寫進去的時間是用伺服器預設的時區計算的。另外也大概能理解前面放兩個 0 的目的,是為了讓 string 比較時的大小就會是數字實際的大小。

$ date --date=@1519776000
Wed Feb 28 00:00:00 UTC 2018

這樣就知道要怎麼做人工轉換了...