顯示具有 group 標籤的文章。 顯示所有文章
顯示具有 group 標籤的文章。 顯示所有文章

2016年8月15日 星期一

AWS 筆記 - 在 AWS Billing 使用 Tag 關注各個服務的開銷

AWSBillingGroupByTag

前陣子在追一些花費時,跟同事花了不少功夫在節費,同事頗厲害,一下就看到不少可省錢的地方,只是省了一輪後,還是希望能夠查看各項服務的開銷,最好每月追蹤,然而,在 AWS Billing 預設報告都是以 AWS Service 為單位,而非依照我們自己的服務為單位,例如一個服務用到數台 EC2 跟一台 RDS 時,希望把這費用可以記在一起,特別又有流量等問題等。

結果翻一下 AWS Billing ,果然已有這類功能,頗夠用!只需在 EC2/RDS 的機器上都多一個 tag 來辨識,例如 tag=Price 且同一個服務就用一樣的數值(例如服務網址),並且在 Load Balancer 和 Auto Scaling 都可以添加 tag 。

接著在 AWS Billing 的 Cost allocation tags 上,挑選剛剛新增完的 Price 標籤並 Save 起來,等幾天後,就可以用 AWS Billing - Cost Explorer 看到漂亮的圖了(用 Group by Tag => Price),並支援以天或月顯示,並且會有明確地數字表格顯示各個服務花了多少錢。

2015年10月20日 星期二

透過 Bitbucket、Jenkins、Slack 打造持續發佈打屁等自動化架構

透過 Bitbucket 作為 git 版本控制的服務托管處,而 slack 則是工程師打屁好去處,而 Jenkins 則是打造一鍵發佈的便利介面。雖說連續動作也可以化簡成一隻 script,但能夠端出 Web UI 介面,還是大勝!

首先提一下 git 版本控制,透過 Bitbucket 服務,人多的話還是花一點小錢了!在 Bitbucket 可以建立群組概念,大概可粗略分成 Administrators、Developer、Deploy 三個個群組(若要細分則可以變成 iOS Developer、Android Developer、Web developer 或是甚至以專案為單位等),這邊設計讓所以有成員都進 Developer 並且 Developer group 預設對所有專案擁有 read only 權限。而埋了一個機器人在 deploy group 中,預設沒有任何權限(機器人不需進入 developer group)。當有專案要搭建自動發佈流程時,請專案擁有者或管理者,讓專案可供 Deploy Group 有 write 權限,這是為了 Jenkins 發佈新版時,能夠打個 tag 記錄狀態。而 Deploy group 裡的機器人,就只需添加個 ssh key 即可。

在 Jenkins Web UI:
  1. 建立作業 => 填寫作業名稱 => 建置 Free-Style 軟體專案 
  2. 設定 Slack Notifications => 進階設定 Team Domain、Integration Token 和 Project Channel => Test Connection
  3. 原始碼管理 => git => git@bitbucket.org:group/project.git => Credentials 搭配 Bitbucket SSH key => Branches to build 要指定 => Additional Behaviours => Advanced sub-modules behaviours => Recursively update submodules
  4. 建置環境 => Create a formatted version number => 設定 Environment Variable Name (VERSION) => Version Number Format String (1.0.0) 
  5. 建置 => 例如拉完程式碼後想要做的事,如 /path/project-build.sh project-name  $VERSION $BUILD_NUMBER $JOB_NAME 
  6. 建置後動作 => Git Publisher => Push Only If Build Succeeds => Tag to push (develop-$VERSION-$BUILD_NUMBER) => Target remote name (origin)
如此一來,開發者可以用 bitbucket 持續開發,並且用不同 branch 管理,如 develop branch、alpha branch、release branch 等,而 Jenkins 就建立三個任務,分別從上述 branch 取資料出來使用,而在 "建置" 跟 "建置後動作" 都可以對各個 branch 操作做細部的調整。

例如"建置"中的 /path/project-build.sh 的程式,就可以包含建立 RPM 、更新 repos 等行為,同時有環境變數 $VERSION $BUILD_NUMBER $JOB_NAME 拿來輔助。

以上就是將程式碼編譯打包的流程,若要再添加上 deploy 流程時,可以再額外建置一個 Jenkins 工作,裡頭只需填寫 slack 通知和建置項目,而建置項目就可以一隻 script 處理發佈的動作即可,而在相對應工作中,把剛剛的 deploy task 建立相依性即可。

如此一來,當 Jenkins 每一次建置時,各個階段的都丟訊息至 slack 指定的頻道,等同通知相關人員。若需要做類似 git hook 來達成自動建置時,可以使用 Jenkins "建置觸發程式" 裡的輪詢  SCM 項目,例如每 10 分鐘確認一次 bitbucket 專案狀況等,達成類似 git hook 行為。

2015年1月29日 星期四

[SQL] select n rows from each group @ MySQL 5.6

假設有一張 table 名為 log 長這樣:

{
id INTEGER,
level VARCHAR(16),
user VARCHAR(32)
}

mysql> SELECT * FROM log
1, "SA", "admin1"
2, "SA", "admin2"
3, "SA", "admin3"
4, "SA", "admin4"
5, "RD", "programmer1"
6, "RD", "programmer2"
7, "RD", "programmer3"
8, "RD", "programmer4"
9, "RD", "programmer1"
10, "FAE", "programmerA"
11, "FAE", "programmerB"
12, "FAE", "programmerC"


有沒有一招可以撈出,讓每個 Level 只顯示 3 筆資料?假想成果:

mysql> SELECT ... FROM log GROUP BY level
1, "SA", "admin1"
2, "SA", "admin2"
3, "SA", "admin3"
5, "RD", "programmer1"
6, "RD", "programmer2"
7, "RD", "programmer3"
10, "FAE", "programmerA"
11, "FAE", "programmerB"
12, "FAE", "programmerC"


土法煉鋼法,用 UNION ALL 來處理:

mysql> SELECT * FROM (SELECT * FROM log WHERE level = 'SA' LIMIT 3) AS t UNION ALL (SELECT * FROM log WHERE level = 'RD' LIMIT 3) UNION ALL (SELECT * FROM log WHERE level = 'FAE' LIMIT 3);

所幸,問了一下強者我同學,得到個關鍵字:GROUP_CONCAT , http://dev.mysql.com/doc/refman/5.6/en/group-by-functions.html#function_group-concat

mysql> SELECT level, GROUP_CONCAT(user) FROM log GROUP BY level;
"SA", "admin1,admin2,admin3"
"RD", "programmer1, programmer2, programmer3"
"FAE", "programmerA, programmerB, programmerC"


如果想限制撈出的資料個數,要設定 group_concat_max_len:

mysql> SET group_concat_max_len = 2;
mysql> SELECT level, GROUP_CONCAT(user) FROM log GROUP BY level;
"SA", "admin1,admin2"
"RD", "programmer1, programmer2"
"FAE", "programmerA, programmerB"


雖然上述結果還不太適合再做 JOIN 來處理,但,已經算佛心了... XD

其他 Google 用的關鍵字:"select top n rows from each group",會看到一些 RANK() OVER(PARTITION BY level) ,但對 MySQL 應該不適用 XD 強者我同學說,若在 PostgreSQL 可以用:

postgrel> select level, array_aggr(user)[0:1] from table group by level;

看來該多給 PostgrelSQL 機會 XD (當初案子用到 GIS 相關 plugin 才有用它...)

此外,跟強者我同學閒聊時,發現去年的一些經驗還滿適合使用的,有些查詢很久的指令,可以考慮定期產生並儲存在另一張 tabel,降低一般 client 觸發複雜的 SQL Query,像是 JOIN, GROUP 等,這也是在大型服務中也常用到的方式。算是此次閒聊最大的心得,因為去年也有應用這個架構來處理服務,驗證自已的(偷懶)做法無誤 XDDD