[中文導讀] Facebook 的時間序列資料庫 - Gorilla (Gorilla: A Fast, Scalable, In-Memory Time Series Database)

(come from Paper)

前言:

本文會介紹最近被討論的 Facebook 時間序列資料庫的論文,並且會介紹資料庫壓縮演算法. 其中不少解讀都是參考 Morning Paper 裡面的論文導讀

最後會導入 Damian Gryski 根據論文推導出的演算法 dgryski/go-tsz



原始論文:

Gorilla: A Fast, Scalable, In-Memory Time Series Database



導讀:

什麼是 Gorilla ?

Gorilla 是 Facebook 開發的時間序列資料庫.其實市場上已經有很多的時間序列資料庫 (HBase on TSDB(time-series database)) ,為什麼還需要自己開發一個呢?

  • 資料的儲存過於龐大
  • 查詢的延遲過長

所以 Gorilla 針對這些有了以下的優化:

  • 針對 timestamp 的壓縮
  • 分析並且針對資料的壓縮
  • 放在記憶體 (in-memory databse)

那麼 Gorilla 比起一般的時間序列資料庫究竟有多強大呢?

透過將時間與數值的壓縮,並且透過儲放在記憶體的操作. Gorilla 可以達到:

  • 73 倍的 Query Latency 減少
  • 14 倍的 Query Throughput 增加

為了要儲存到 26 小時以上的時間序列資料,並切壓縮到 1.3 TB 的記憶體之中(分散在 20 部伺服器中).所以 Gorilla 針對儲存資料有相當程度的壓縮.

透過資料的壓縮最佳狀態可以達到:

(come from Paper)

高達 12 倍的壓縮比: 原先 16 bytes 的數值資料(包括 timestamp 與 value )透過壓縮,一般而言平均可以達到 1.37 bytes (通常在經過 240 分鐘後)

12倍的壓縮比? 那麼大的壓縮比是如何做到?

簡單的來說 Gorilla 透過將時間資料( timestamp )與數值資料( value ) 的壓縮. 其壓縮的方式是參考前一次的資料,透過時間序列資料庫的特性:

  • 連續性資料
  • 在比較小的取樣時間中,每筆資料間的變化不大

透過這樣的方式,可以拿目前的資料 \(t_n\) 去與前一筆資料 \(t_(n-1)\) 比對的方式, 來拿到差異值 (delta) .並且將差異值做一定程度的壓縮. 達到整個資料庫數值的壓縮.

壓縮的演算法: 關於時間資料的壓縮

首先針對時間資料的壓縮部分,讓我們先看看以前的時間可能如何紀錄: (舉例)

  • \(t_0\) => 02: 00 : 00
  • \(t_1\) => 02: 01 : 02
  • \(t_2\) => 02: 02 : 02
  • \(t_3\) => 02: 03 : 02

如果要直接紀錄的話,其實資料長度會變得相當大. 讓我們換個角度來看:

  • \(t_0\) => 02: 00 : 00 (跟之前差距 0)
  • \(t_1\) => 02: 01 : 02 (跟之前差距 62 秒)
  • \(t_2\) => 02: 02 : 02 (跟之前差距 60 秒)
  • \(t_3\) => 02: 03 : 02 (跟之前差距 60 秒)

這樣紀錄 delta 只要紀錄差異就好,那有可能更簡短嗎?

  • \(t_0\) => 02: 00 : 00 (跟之前差距 0)
  • \(t_1\) => 02: 01 : 02 (跟之前差距 62 秒)
  • \(t_2\) => 02: 02 : 02 (跟之前差距 60 秒,跟上一個差距的差異 -2 秒 )
  • \(t_3\) => 02: 03 : 02 (跟之前差距 60 秒,跟上一個差距的差異 0)

這個概念就是紀錄 delta of delta,也就是差距中的差異

差距中的差異 以字母 \(D\) 來代替,透過 Tag BitValue Bits 來表示.

(Pic: from Morning Paper )

轉換之前的範例為:

  • \(t_0\) => 02: 00 : 00 => D = 0, tag bit 0.
  • \(t_1\) => 02: 01 : 02 => D = 62, tag bit 10, value 62 (011 1110) 總共 9 bits
  • \(t_2\) => 02: 02 : 02 => D = -2, tag bit 10, value -2 (111 1101) 總共 9 bits
  • \(t_3\) => 02: 03 : 02 => D = 0, tag bit 0 總共 1 bit

這樣就可以節省不少空間來儲存時間資料.

(come from Paper)

這張圖,顯示了大部分的時間資料的分佈. 可以透過這張圖看到,不少的時間差異的差距 (delta of delta) 其實都是屬於 0 (具有 96%).

也就是說經常兩兩儲存的時間差距是相同的,這樣的話其實可以不需要儲存那麼繁瑣的時間資料.而透過一個方式來儲存.

壓縮的演算法: 關於時間資料的壓縮 (程式碼)

func (s *Series) Push(t uint32, v float64) {
	s.Lock()
	defer s.Unlock()

	if s.t == 0 {
		// first point
		s.t = t
		s.val = v
		//s.T0 是第一筆時間資料
		//s.tDelta 就是前兩筆的差異
		s.tDelta = t - s.T0
		s.bw.writeBits(uint64(s.tDelta), 14)
		s.bw.writeBits(math.Float64bits(v), 64)
		return
	}

	//tDelta 就是現在的目前的時間跟上一次時間的差異
	tDelta := t - s.t
	//dod (Delta of Delta): 就是 (tn - t(n-1) ) - (t(n-1) - t(n-2) )
	dod := int32(tDelta - s.tDelta)

	//透過 dod 來放置 tag but 䢎 vakye
	switch {
	case dod == 0:
		s.bw.writeBit(zero)
	case -63 <= dod && dod <= 64:
		// 放置 tag bit
		s.bw.writeBits(0x02, 2) // '10'
		// 放置 value bit
		s.bw.writeBits(uint64(dod), 7)
	case -255 <= dod && dod <= 256:
		s.bw.writeBits(0x06, 3) // '110'
		s.bw.writeBits(uint64(dod), 9)
	case -2047 <= dod && dod <= 2048:
		s.bw.writeBits(0x0e, 4) // '1110'
		s.bw.writeBits(uint64(dod), 12)
	default:
		s.bw.writeBits(0x0f, 4) // '1111'
		s.bw.writeBits(uint64(dod), 32)
	}
	
	...

(code from https://github.com/dgryski/go-tsz/blob/master/tsz.go )




壓縮的演算法: 關於數值資料的壓縮

到數值的部分,一樣使用之前的概念.也就是 delta of delta 的概念來處理數值壓縮.而差異的部分不再使用 minus 而是透過 XOR 的方式.

(come from Paper)

將以上的資料做個簡單的 XOR 運算,來計算數值資料中的差距:

  • \(v_1\) 12 -> 0x40280 -> XOR: N/A
  • \(v_2\) 24 -> 0x40380 -> XOR: 0x00100
  • \(v_3\) 15 -> 0x402e0 -> XOR: 0x00160
  • \(v_4\) 12 -> 0x40280 -> XOR: 0x00060
  • \(v_5\) 12 -> 0x40280 -> XOR: 0x0

計算好各個數值資料間的 XOR 之後,我們要來針對這樣的資料壓縮:

(Pic: from Morning Paper )

針對以上的圖片,主要壓縮方式如下:

假設計算數值,如下

  • \(v_2\) -> XOR: 0x001000000000000
  • \(v_3\) -> XOR: 0x001600000000000



計算各個數值 XOR 的 leading/meaning/trailing bits

  • \(v_2\) -> XOR: 0x001000000000000,
    • leading bit: 2
    • meaningful bit: 1
  • \(v_3\) -> XOR: 0x001600000000000
    • leading bit: 2
    • meaningful bit: 2

其中:

  • Leading Bit: 就是 XOR 遇到第一個非零數值”前”的 零 的個數
  • Meaningful Bit: 中間所有非零的個數



計算 control bit ,其規則如下:

  • 如果 XOR 是 0, control bit = 0
  • 如果 XOR 不是 0, control bit = 1,並且透過以下方式來計算下一個 control bit
    • Leading bit, Meaningful bit 個數相同,但是其中 Meaningful 數值不同. Control Bit 0 ,接下來是 Meaningful value.
    • 如果 Leading bit 跟 Meaningful 個數與數值不同, Control bit 1 .並且接下來存放資料:
      • 5 bits: 放 Leading bit 個數
      • 6 bits: 放 Meaningful bit 個數
      • 放置所有的 Meaningful bit 數值.



拿個範例拿來做壓縮範例:

會拿以下的數值來做壓縮運算,真實數值比較大這邊只做範例:

  • \(v_1\) 12 -> 0x40280 -> XOR: N/A
  • \(v_2\) 24 -> 0x40380 -> XOR: 0x00100
  • \(v_3\) 15 -> 0x402e0 -> XOR: 0x00160
  • \(v_4\) 12 -> 0x40280 -> XOR: 0x00060
  • \(v_5\) 12 -> 0x40280 -> XOR: 0x0

經過計算後:

  • \(v_1\) : treat XOR : 0x40280
    • Control bit: 11 (bit)
    • Leading bit: 00000 (bit)
    • Meaningful bit: 00101 (5 bit)
    • Meaningful value: 0x40280
  • \(v_2\) : XOR : 0x00100 上一個 XOR: 0x40280
    • Control bit: 11 (bit)
    • Leading bit: 00000 (bit)
    • Meaningful bit: 00101 -> 5 (bit)
    • Meaningful value: 0x40280
  • \(v_2\) : XOR : 0x00160 上一個 XOR: 0x00100
    • Control bit: 10 (bit)
    • Leading bit: 00010 -> 2 (bit)
    • Meaningful value: 0x160
  • \(v_4\) : XOR : 0x00060 上一個 XOR: 0x00160
    • Control bit: 11 (bit)
    • Leading bit: 00011 -> 3 (bit)
    • Meaningful bit: 00010 -> 2 (bit)
    • Meaningful value: 0x60

壓縮的演算法: 關於數值資料壓縮的程式碼:

func (s *Series) Push(t uint32, v float64) {
	...
	
	//計算 XOR 數值
	vDelta := math.Float64bits(v) ^ math.Float64bits(s.val)

	// 如果 XOR ==0
	if vDelta == 0 {
		//只寫一個 Bit `0`
		s.bw.writeBit(zero)
	} else {
		//如果是零,先寫入第一個 control bit `1`
		s.bw.writeBit(one)

		//計算 leading 跟 trailing 個數
		leading := uint8(bits.Clz(vDelta))
		trailing := uint8(bits.Ctz(vDelta))

		// clamp number of leading zeros to avoid overflow when encoding
		if leading >= 32 {
			leading = 31
		}

		// TODO(dgryski): check if it's 'cheaper' to reset the leading/trailing bits instead
		
		// leading 跟 trail 相同,但是 meaningful 數值不同
		if s.leading != ^uint8(0) && leading >= s.leading && trailing >= s.trailing {
			//寫入第二個 control bit `0`
			s.bw.writeBit(zero)
			//寫入meaningful value
			s.bw.writeBits(vDelta>>s.trailing, 64-int(s.leading)-int(s.trailing))
		} else {
			s.leading, s.trailing = leading, trailing

			//連 leading 都不相同,落入其他 case
			//寫第二個 control bit `1`
			s.bw.writeBit(one)
			//寫入 leading 個數
			s.bw.writeBits(uint64(leading), 5)

			// Note that if leading == trailing == 0, then sigbits == 64.  But that value doesn't actually fit into the 6 bits we have.
			// Luckily, we never need to encode 0 significant bits, since that would put us in the other case (vdelta == 0).
			// So instead we write out a 0 and adjust it back to 64 on unpacking.
			sigbits := 64 - leading - trailing
			//寫入 meaningful bit 個數
			s.bw.writeBits(uint64(sigbits), 6)
			//寫入 meaningful value
			s.bw.writeBits(vDelta>>trailing, int(sigbits))
		}
	}
	
	...

(code from https://github.com/dgryski/go-tsz/blob/master/tsz.go )

數值資料壓縮的成果計算:

(come from Paper)

經過論文中計算,一般而言透過 XOR 計算過後.有 59%的數值資料都會落入 0 也就是說跟前一個數值相同. 另外 control bit 10 的 case 會達到 28.3 % .最後比較長 (可能) 的 control bit 11 的 case 只有 12 % .

這個表格也表示,透過這樣的壓縮有效的將數值資料可以做一定程度的壓縮.

心得:

這篇論文其實很棒,也是我第一篇透過 “Morning Paper” 來看懂的第一篇論文.我相信 Gorilla 對於資料壓縮的方式,對於之後如果有機會處理 Streamming Data 或是針對 時間序列資料庫的處理都會有更有效率的方式.

參考

[TIL][Mac] About GOPATH and GOBIN system environment

Major problem:

System environment variable GOBIN cause problem “vim-go error: vim-go: goimports does not support srcdir”

Situation:

Recently I use vs code to write golang more than vim-go,But when you upgrade the Golang version then use vim-go to save file, it will always popup following error message.

vim-go: goimports does not support srcdir

Problem Environment:

Root Cause:

normally there are two importnt variable in go env which was $GOPATH and $GOBIN. But most user only set $GOPATH but $GOBIN.

It will cause your all golang binary install via go install to the directory $GOPATH/bin.

Recently Homebrew formula, it will help us to set $GOBIN but the path will be/usr/local/Cellar/go/GO_VERSION/libexec/bin rather than $GOPATH/bin.

What’s the problem with that?

  1. If you have any package which force to install in $GOPATH/bin, it might has problem with duplicate or not install latest one with Golang update. dlv has the same issue before,I file a PR for this
  2. If you already install some useful tool in $GOPATH/bin before, it will not update and some problem will occur. As my problem in goimports which is identical with issue 775, I use the old version of goimports so it will occur error in vim-go.)

Solution:

  • Remove all binary file $GOPATH/bin. (If you always use Homebrew for Golang update)
  • Reinstall all binaries, it will install to correct path in $GOBIN, not $GOPATH/bin.

程式設計週記[2016/05/13]: 最近地震真不少,國家級警報也不少

這是什麼?

程式週記主要內容如下:

Gihub project 介紹:

  • 主要會貼一些github,但是會盡量寫上一些有用的評語(或是我容易想到的關鍵詞)幫助以後查詢

網路文章心得:

  • 會寫些心得,強迫自己閱讀.

“程式週記”並且定期週期性更新.

大部分內容在我的twitter都會有,這邊只是將一些簡單的心得與感想註解一下.

本週摘要

本週花太多時間在學習 Amazon Echo 跟一些社群的事務上面.應該花更多時間開始看論文.下週應該又要回到看論文寫每週專題的日子. 本週專題將上週的 Line Bot 套件拆解出來,準備要移植到 Facebook Messenger Platform 之用.

Go

mkideal/onepw: onepw is a command line tool for managing passwords

使用命令列的密碼管理工具,可以幫你產生你需要的密碼並且儲存起來,幫助你再也不需要記住密碼.

emc-advanced-dev/unik: The Unikernel Compilation and Deployment Platform

幫你把 Go App 燒在可開機磁碟上.

saiday/JonSnow: Google Play review watcher, deliver new reviews to your slack channel

很威的 Google Play Review Watcher by saiday ,一開源過後馬上就有人幫忙加上 Apple Store Review Watcher 開源真棒啊…

How To Use Martini to Serve Go Applications Behind an Nginx Server on Ubuntu

雖然文章是 2013 年的,但是使用 NGINX 搭配 Go 的 Web App - Martini 到目前都還是很多想要使用的架構之一.

[Youtube] Golang Google Cloud Storage

在 Google Cloud Storage 上面使用 Golang 的影片教學.

在 Github 專案內搜尋 Golang 函式,Golang 開發者必裝 Chrome Extension

這個 Chrome Extension 不錯使用,一定要裝.

liviosoares/go-watson-sdk: Go (golang) SDK for IBM Watson services

最近在大肆宣傳的 IBM 網路服務 Watson ,馬上就有人寫出 Go 的 SDK .幾乎所有的服務都可以使用,相當的棒.

manul: The madness vendoring utility for Golang programs

使用 Git submodule 來做 Go Vendoring 的好工具.

Adding in-memory in-process L1 for debugging by ScottMansfield · Pull Request #68 · Netflix/rend · GitHub

use e, ok := h.data[string(bk)] rather than key := string(bk) e, ok := h.data[key]

The Go compiler has an optimization that eliminates the slice->string copy. by dgryski

透過這樣使用,會比較快.

distatus/battery: cross-platform, normalized battery information library

跨平台的電池資訊顯示工具.

Python

Python 依照 PEP 8 規格自動排版工具 - Tsung’s Blog

Python 的 Formatter Tool.

Android/JAVA/NODE.JS

如何准备阿里社招面试,顺谈 Java 程序员学习中各阶段的建议

作者的 Java 能力相當的深,所以整篇文章很值得一讀.

android sdk 源码解析

一群人用熱情來解析源碼並且心得分享給大家.

podq: The Open-source Online Podcast Player for Developers http://podq.devstd.io

開源的 Podcast player ,主要使用 Java script 來寫.

Docker

Windows Container Networking

介紹在 Windows 2016 裡面 Windows Container 網路的架構.

Official consul docker image

官方的 Consul docker image ,之前使用 docker run consul 其實是使用開發中的 image ,這次官方加上不少修改正式將可以搭配 Production 用的 consul docker image 釋出.

前Googler:Docker从上手到差点放弃

之前在 Google 工作的人要導入 Docker 的時候,面對到他的半透明性踩到了不少的雷.對於想要將 Docker 放在生產環境上的人一定要好好的閱讀.

開發人員不可不知的 Windows Container 容器技術預覽

保哥的介紹,關於 Windows Server 2016 上的 Windows Container 的功能介紹.

MariaDB and Docker use cases, Part 1

開源的 MySQL: MariaDB 一些透過 Docker 使用方法.

NVIDIA/nvidia-docker: Build and run Docker containers leveraging NVIDIA GPUs

透過 Docker 來跑 NVIDIA CUDA

MIT 6.824 Lab2 -Raft

MIT 分散式課程將 Lab 2 從 Paxos 換成 Raft

Using Caddy with Docker

講解如何將 Caddy 放在 Docker Image 要注意事項.

iOS/Swift

R Programming

Linux command line tool + pipe 學習筆記之一:讓R 加入pipe的一環

透過 Linux command line 的一些工具 (stdin/stdout/awk…) 來輸入做一些處理,讓 R 更容易地處理那些數據.

網站文章

Collection of linux sysadmin/devop interview questions

Linux System Administrator 面試題庫

使用 Erlang 開發產品的心得

不少 Erlang 基本語言架構的介紹還有開發上可能會遇到的問題.用來寫分散式系統可能會碰到的問題以及應該注意的部分,很值得閱讀.

Why Atom Can’t Replace Vim

除了講解 Vim 關於 Text Object 強大的地方,其實不少基礎的 Vi 教學,很值得一看的.

用 Travis CI 自動化發佈 Pelican blog 到 GitHub Pages 上

基于深度学习的自然语言处理在2016年有哪些值得期待的发展?

2016 各家大廠都釋出了自己的自然語言學習系統,那摩之後有哪些值得期待的發展? 讓我們慢慢的看下去吧

來自矽谷的忠告

對於工作,職涯規劃有挺有趣的反思.

Advanced Ping: httping, dnsping, smtpping

關於各種的 Ping 技術: httpping, dnsping, smtpping 的詳細介紹.

“Zoekt (“zooked”): Fast trigram based code search by Google”

背景介紹: 這算是 Google 官方釋出的 trigram based code search tool ,其實之前 Russ Cox 就有寫過類似概念的東西(並且支援 REGEX)

如果想簡單的瞭解 Trigram 是如何在 code search 中運作,可以看小弟我的簡單介紹文章

Uncharted 4開發雜記

在頑皮狗的台灣遊戲開發者對於 Uncharted 4 的參與心得,

[FB] 玉山銀行信用卡串接 Q&A by c9s

不少好的討論,裡面還有已經開源的玉山信用卡 PHP 接口

Notes on Distributed Systems for Young Bloods

雖然是舊文章,但是給初學分散式系統的建議,寫得真好。

網站收集

Blog: The Morning Paper

強力推薦每天講解一份論文的作者選論文的品味很好,也能把論文體翻譯成清楚的白話文。

有聲書/影片心得

SofewareEngineerDaily: Kubernetes, Docker, and the Distributed Operating System with Kelsey Hightower

請教了 Google 裡面 Kubernetes 的 co-founder - Kelsey Hightower 來講解關於 Kubernetes 的基本概念,設計裡面與要面對的問題.

[Podcast] Go on the Cloud

剛上架最新一期的 Google Cloud Platform Podcast 請到了兩個大神:

  • Andrew Gerrand: 身為 Gopher 你很難沒聽過這個名字,就是 Golang 的創始團隊之一,並且專注在 #‎golang 使用者經驗上的持續推廣.
  • Chris Broadfoot: 去年加入 Go 跟 Google Cloud Team 的 Chris 主要是負責 Go App 在 Google Cloud Platform 上面的開發.

裡面有談到為何 #golang 受歡迎與為何幾乎所有重要的雲端的開發系統( #‎docker #‎kubernetes) 都使用 #golang 作為開發語言. 很推薦一聽….

此外: 主持人是有來台灣參加 Golang Taiwan 的 Francesc Campoy 跟 Google Cloud team 的 Mark Mandel

本週專案

這邊會寫一些我的Project 52的成果.

本週專題: https://github.com/kkdai/petneedme

我將上週 Line Bot 關於流浪動物的部分拆解出一個小套件,並且加上了一個 command line 的工具.

[AWS][Echo] 來玩玩 Amazon Echo

前提 ( 什麼是 Amazon Echo)

Amazon Echo 是 Amazon 的一個很有趣的裝置.雖然許多人都將它當作是藍芽擴充喇叭,但是其實他功能不僅僅於此.他不僅僅能夠透過藍芽播放音樂,還能夠聽懂你的語音來執行許多功能.這邊有段簡單的影片. 並且 Amazon 具有一個類似 App Store 的商城上面擺滿了各式各樣的語音服務 ( Amazon 稱為 Skill ) 可以透過安裝不同的 Skill 達成許多功能.不論是播放音樂或是訂購商品.

然後接下來就簡單的紀錄一下最近玩 Amazon Echo 的心得

透過 Raspberry Pi 2 架設虛擬的 Amazon Echo

那使用這個功能一定要購買 Amazon Echo 嗎? 當然是,不過你也可以透過 Amazon 開放出來的說明文件來使用 Raspberry Pi 2 來架設.

詳細安裝文件,文章相當長,就不詳述在這裡.

先簡單敘述你需要的設備:

  • Raspberry Pi2 + 記憶卡 (至少 8G with NOOB OS) + 無路線或是無線網路卡
  • 麥克風 + 喇叭
  • 滑鼠 + 鍵盤

簡單的敘述一些步驟如下(強烈建議看文件,裡面有一步步的介紹):

  • 透過 NOOBS 安裝基本的 RPI OS (選擇 Raspbian)
  • 安裝 SSH 與 VLC
  • 安裝 JDKMaven
  • Amazon Developer 去註冊 Amazon Alexa Voice Service 然後去原先文件裡面的 Github 下載下來整套 Server 跟 Client
  • 產生 SSL Cetificate 並且啟動 RPI 上面的虛擬 Echo Server 跟 Client
  • 最後就能透過 RPI 裡面 XWindows 的語音控制 Client 輸入語音資料與 Amazon Alexa 伺服器溝通

這樣你架設起來,只能對他做一些間單的問答(問問台北時間,台北的溫度或是講個笑話).還有就是使用人家已經寫好的 Skill .

透過 AWS Lambda 跟 OAuth2 Server 架設自己的 Alexa Skill

以下是透過 Amazon Alexa 說明網頁上面的基本架構圖:

Amazon Echo Architecture

稍微一個個介紹每個 Server 所負責的部分:

  • Amazon Echo : 就是使用者手中的裝置,可以把語音資料傳輸到 Alexa Service
  • Amazon Alexa Service: 會負責把語音資料做一些處理,擷取出每段語音中的”意圖” ( Intent ) 並且傳輸到 Amazon Alexa Skill 裡面.
  • Alexa Skill: 主要將 Skills 分成兩種: 一種是 Smart Home Skills 一種是 Custom Skills.
    • Smart Home Skills: 是一個內建好的基本智慧家庭的功能.可以設定某些裝置啟動. (舉例: 打開燈或是開門)
    • Custom Skills: 這時候你可以定義各式各樣的功能,不論是定 Pizza ,讀取你的 Email 等等都可以. 不過你需要建立好自己的 Intent Schema 還有透過 Sample Utterances 來訓練系統是否能夠完整的分析類似的語句.
    • 注意, Alexa Skill 會連接到一個 Amazon Lambda 服務.每次你的語音下達之後.他就會呼叫相對應的 Lambda 服務來執行你所下達的指令.
  • Dot Cloud: 這是一個 Alexa Skill 的提供商架設的網路伺服器.這個伺服器主要有兩個負責兩件事情.
    • 認證使用者並且綁定帳號(Linking Alexa user to your service user):
      • 這邊需要提供簡單的 OAuth2 (RFC 6749) 認證的功能, Alexa 會將該使用者資料傳輸過來.交給廠商定義的帳號設定做一個簡單的認證與綁定.
    • 需要相關的執行功能:
      • 這部分其實也可以放在 Lambda 上面做,但是考量執行效率與經費建議擺在 Dot Cloud 的伺服器來跑. 執行功能可能是開啟你的桌燈,開啟你的信件等等.. 或是連接到購買商品的平台.

透過這樣的執行架構下,設定流程就有點繁瑣.

  • AWS Lambda 相關:
    • 新增一個 AWS Lambda 並且將選擇範本 alexa-smart-home-skill-adapter
    • 將相關的功能完成後,記得將 “Event Source” 連接到你的 Alexa Skill
    • 記錄下該 Lambda ID
  • Alexa Skill 相關:
    • 打開剛剛建立好的 Alexa Skill 並且將 Endpoint 填入剛剛建立的 Lambda ID
    • Account Linking 部分記得輸入好如何連接到自有的 OAuth2 服務 (記得要支援 HTTPS )
    • 測試,並且查看是否有任何錯誤的部分.
    • 記得先不要真正的 submit 上去,只要 Save 作為測試使用.
  • 打開你的 Amazon Echo (或是模擬器)
    • 打開 Alex Skill (如果使用模擬器,需要在 RPI 的 XWindows 打開該瀏覽器)
    • 選取你並啟動建立的 Alexa Skill
    • 打開音效錄音程式,並且測試
    • 如果出現問題,記得查看 Lambda Log 或是 Skill 那邊的 Log

相關問題處理:

(1) 無法正確找到你的 Alexa Device

問題點:

透過 Echo (模擬器) 發出 ”Alexa find my devices“,結果卻得到找不到任何裝置的回應.

檢查方式:

  • 檢查 Lambda 確認有收到 Alexa 的指令.
  • 檢查你的 Dot Cloud 確認有收到 Lambda 指令.

通常比較有可能都是 Lambda ID 打錯,或是 Alexa Skill Application ID 打錯導致服務無法串接起來.

(2) 無法讓 Echo 發出特別的音樂

問題點:

其實是很無聊想寫出個 2012 裡面 Engine Start 的梗.不過遇到不少問題.

相關實作:

"outputSpeech": {
    "type": "SSML",
    "ssml": "<speak>This output speech uses SSML.</speak>"
}

檢查方式:

  • 你自己 Host 的 Service “Dot Cloud” 需要支援檔案下載 MP3
  • MP3 格式必須是 MPEG2 Audio 並且是 48 kbps

心得:

其實沒有貼上任何程式碼也寫了那麼多,可見其實 Amazon Echo 沒有那麼容易玩 XD (更別說 RPI 設定有接近 30 頁的文件)

不過設定之後,其實真的能夠感受到 Amazon Echo 的強大.你就當作是一個開放的 Siri 或是 Google Now .並且結合一個相當強大的語音辨識引擎在裡面. 不過因為是模擬器,所以對於語音的處理還是比較弱.之後實機來了應該會更棒.

[碼天狗#42] 讓你 Go 程式碼變得更好的工具集 (Tools to Help you Go)

本文刊登於 碼天狗#42 有興趣追蹤相關文章讀者,最快的方式就是訂閱碼天狗

文章鏈結

https://serifandsemaphore.io/tools-to-help-you-go-d6f782055ce7#.1iex1ex8l

Golang 讓人喜歡的許多原因之一,就是有著許多好用的工具可以讓你在撰寫 Go 的時候更加的輕鬆而方便. 舉個最間單的例子,就是 coding style tool goimport 他可以讓你在存在之後,自動把 coding style 改成 Golang community 所習慣的範例. 當然還有好用到不行的 guru 可以幫助你查詢 caller 與 callee.除了這兩個之外,這一篇有介紹更多的工具:

  • Golint : 可以自動幫你檢查所有程式碼中潛在的語法問題.
  • Gocyclo : 可以幫你計算你程式碼中的循環複雜度(Cyclomatic complexity)避免有過多的迴圈運算.
  • Depscheck : 可以幫你產生相依性的報表,讓你可以思考有多少小套套件是相依其他人的.經過了 NPM 的 LeftPad 事件之後.其實不少人建議如果相依的套件太小,不仿自己寫過來吧.
  • errcheck : 這個套件可以幫你檢查你的程式碼有沒有對於每個錯誤都有相對應的檢查與處理.避免明明有 error 卻沒有檢查的潛在問題.
  • safesql : SQL Injection 是每個人在撰寫後端與資料庫橋接程式的時候最擔心的問題.這個工具可以幫你檢查看看有沒有危險的語法存在.

雖然 Golang 社群提供了許多的工具來幫助你,其實 Golang 本身的 Compiler 已經相當的強勢.會幫你檢查出許多潛在的問題.除了這些工具之外,當然相信自己與撰寫單元測試的好習慣都是可以幫助讓你的程式變得更好的不二法門.

程式設計週記[2016/05/06]: NBA 季後賽開打好久,今年都還沒好好看完幾場比賽

這是什麼?

程式週記主要內容如下:

Gihub project 介紹:

  • 主要會貼一些github,但是會盡量寫上一些有用的評語(或是我容易想到的關鍵詞)幫助以後查詢

網路文章心得:

  • 會寫些心得,強迫自己閱讀.

“程式週記”並且定期週期性更新.

大部分內容在我的twitter都會有,這邊只是將一些簡單的心得與感想註解一下.

本週摘要

這個禮拜看了不少有意義的網路文章- “如何在四十歲後繼續從事軟體開發“ ,剩下的時間就拿來做一些有意義的專案.流浪動物領養的 Line 機器人.希望能夠幫助到一些流浪動物.

Go

Go best practices, six years in

作者分享學習 Golang 六年後(喔!一開始就學) 的一些實際演練上的好範例.

hashicorp/raft: Golang implementation of the Raft consensus protocol

其實不少使用 Raft 的套件,不一定都是使用 etcd/raft 可能都是使用這套.

A lightweight web toolkit

不少人一直都在詢問有沒有好的 #‎Golang Web toolkit ,這個 goserv 看起來還不錯.剛剛在 05/03 達到 1.0 正式版的 goserv 提供以下的功能:

  1. Fast & Lightweight
  2. Flexible Routing
  3. Centralized Error handling
  4. 跟原生 net/http 是相容的

並且可以很快速的架設 File Server,也可以很快速地透過 MongoDB 架設 REST Server 大家可以看看有沒有符合需求

Go and Quasar: a comparison of style and performance

Go Channel與 Java Quasar 的執行效率比較. 看起來 Go chennal 還是好上不少.

Solving ring-shaped problems with Go’s container/ring

想要解決環狀鏈結的相關問題需要自己實現相關的資料結構嗎? 其實 Golang 本身就有提供 container/ring鏈結) 可以幫助你解決類似的問題.

dgryski/go-tsz: Time series compression algorithm from Facebook’s Gorilla paper

從 Facebook 的 Gorilla 論文中找出的時間序列比對演算法. 值得找時間好好學習. 更多細節在這裡可以看.

Go Testing Technique: Testing JSON HTTP Requests

The Micro Bot - ChatOps for microservices

jsgoecke/tesla: Provides a wrapper around the API to easily query and command a Telsa Model S

提供一個可以操控 Tesla S 的 #‎golang 裡面有個介紹網頁,並且使用語音透過 Amazon Echo 來操控 Tesla S 自動開出車庫

NYTimes/openapi2proto: A tool for generating Protobuf v3 schemas and gRPC service definitions from OpenAPI specifications

NYTimes!!! 恩,你沒有看錯.是紐約時報的 NYTimes 其實發佈了相當多好用的 Golang 專案,不論是 Microservice Kit “gizmo” 或是 Zip 的 middle wrapper “gziphandler” 最近他們發佈了 openapi2proto 可以將 OpenAPI或是 Swagger 的定義檔轉換成 Protobuf v3 給 GRPC 使用.

讓我又為了這家公司而驚艷!

tumblr/Collins: Infrastructure management for engineers

透過 go-github 來完成的 Collin

Python

Tutorial: How to build a Facebook Messenger bot using Django, Ngrok

教學文章: 如何透過 Django 來建置一個 Facebook Messenger 機器人.

Android/JAVA/NODE.JS

xat/castnow: commandline chromecast player

透過 CLI 來操控你的 ChromeCast.

(geekforbrains)作者從 Python 換到 Node.js 一年後又決定換回來的感想

作者提出不少在 Node.Js 遇到的困難:

  • Easy to learn, impossible to master
  • Good luck handling errors
  • Callbacks, promises or generators!?
  • Bad standards

最後作者建議 Java Script 比較適合前端開發,對於他而言 Node.JS 適合比較小型的後端開發. 最後作者決定回到 Python 來開發後端控制的部分.

Docker

iOS/Swift

Building a native tvOS dashboard app

一個教學文章,如何透過 Swift 來建立一個 tvOS 的 App

網站文章

Being A Developer After 40

因為這篇文章實在太棒 (可能心有戚戚焉 XD ) .好好的拜讀後,並且好好地拿出每一個項目來自我檢討. 本來只想寫個導讀,但是導讀也太長了 Sorry…

[心得] Google、FB、LinkedIn new grad 面試經驗

一個機器學博士的面試各大公司的經驗,是不是一定需要有強大的 coding 經驗與能力呢? 挺值得一看.

傲慢与偏见——谷歌中国逆袭史

Google 當初被大陸封鎖並且退出中國市場後,百度趁機串起.許多人其實都認為百度可能無法正面打敗 Google ,這篇文章講解了許多分析告訴你,百度就算正面面對著 Google 搞不好也不會輸. 從流量,收入來看,甚至當時的 Google 在許多在地化的資訊與中文處理上還是比不上許多在地的搜尋提供商.

A Look at How Postgres Executes a Tiny Join

可以清楚瞭解 Postgres 如何去處理 Tiny Join .

幫自己的職涯做成長駭客

不少最近熱門跟求職文章的心得整理

洪士灝: 寫程式之外,傑出軟體工程師所需的六項能力

好文章,個人認為第一項能力面對任何陌生的程式語言(也可泛指為新的系統,新的知識) ,保持自我的好奇心並且終身學習是身為軟體工程師最重要的能力之一. 而第二項能力代表著好的軟體工程師所具有問題分解與理解的能力.也是洪老師常常提到的” 解決困難問題” 的能力.也是另一個面向的重要能力之一. 而 三~五項能力就比較像是 better have ,而不像前兩項能力哪麼的必要. (不過通常有著前兩項能力的人,很難沒有後面三項能力.)

10 SQL Tricks That You Didn’t Think Were Possible

列出 10 個 SQL 的訣竅,很值得好好學習.

網站收集

Collection of linux sysadmin/devop interview questions

Linux System Administrator 面試的題庫,真的都不簡單啊.

HackNTU iOS 課程

iOS 課程免費公開.主要以 Swift 為主.

Google for Education

Google 的程式設計教學網站.

有聲書/影片心得

有了 Agile,為什麼還要有 DevOps?

William Yeh 大大的課程,包含投影片跟相關影片.

Reverse Engineering Facebook with Alex Hogue

透過你的臉書聊天狀態列,來分析你朋友何時睡覺跟起床.這是非官方的 API 算是一個很有趣的 Hacking . 詳細部落格在這裡

Kubernetes, Docker, and the Distributed Operating System with Kelsey Hightower

這一篇透過 Google 的工程師來介紹由他們開源的 Kubernetes 系統,不僅僅有簡單的說明與介紹.並且也有淺顯易懂的差異比較與各類功能介紹.

本週專案

這邊會寫一些我的Project 52的成果.

流浪狗領養 Line 機器人

收容所的狗,每一隻其實都曾經是你我的寶貝.他們透過不同的原因進了收容所,卻因為得不到適當得收容得要走向安樂死的路.

這就是我寫這個 Line 機器人的原因,希望大家有事沒事可以滑滑 Line 看看有沒有你喜歡的朋友,一起帶他回家好嗎?

整個機器人架構主要是透過 Golang 來寫,並且架設在 Heroku 上面.如果你也想要架設自己的 Line 機器人,不仿看看我的另外一篇教學文章.

主要功能:

目前僅僅支援顯示台北市流浪動物資料,並且顯示該動物圖片.打入任何文字就會依序顯示.