2015/11/10

特定情況下 PHP 可以比 awk 還要快

因為工作上的需要,會需要將 HTTP log 抓出來做統計,所以會遇到類似下方的 RESTful path:
GET /user/123/bio HTTP/1.1 ...
GET /user/456/bio HTTP/1.1 ...

如果取完整的 path 則無法辨別後端到底是使用哪一個 API,所以使用 awk 的 regex 辨識後 mapping 到 API 名稱上。寫完以後的 awk script 大約有 300 行左右,一份 log 大概要花 2 分鐘左右。

後來經高人指點,PHP 的 native library 好歹也是 C++ 寫的,理論上不會太慢,於是用 PHP 的 preg_match() 將相同的邏輯寫了一次。同一份 log 使用 PHP 來 parse 大約只需要 1 分 32秒。

另外 PHP 預設會載入已安裝的 extensions (mysql, mcrypt ...),既然只用到 native library 的話,其實這些也可以去掉不要用。改為「php -n」不載入任何 extension 再執行時,速度又快了一些,只要約 1 分鐘。

PHP 其實還有一些可以繼續調整的東西,像是把資料放在陣列裡面做搜尋時,如果把資料存成 array index 並使用 array_key_exists() 方式去判斷,會比 in_array() 還要更快 [Ref]

2015/11/09

同時追蹤多個 log 檔

通常我們會用「tail -f FILE」來將檔案新增加的內容顯示在螢幕上,不過要同時顯示多個檔案的新資料就有點麻煩了,會需要改成以下寫法:
tail -f FILE_1 -f FILE_2 ....

所以有人寫了個歡樂的工具叫做「multitail」可以一次監視多個檔案,甚至還會自動幫你切割視窗來顯示不同檔案的內容。

要做到同上的功能,只要這樣寫:
multitail FILE_1 FILE_2

若要觀察的檔案太多,多到分割視窗根本看不到東西時,也可以讓 multitail 不要做切割,全部顯示在一起就好:
 multitail --mergeall FILE_1 FILE_2

2015/09/16

寫 shell script 的一些平行處理工具

最近在處理數十 TB 的 HTTP server log 有感,記錄一些可以拿來做分散式運算的工具以及語法 (參數)。



gzip 一直是你的好工具,特別是儲存空間放在網路上時,可以大幅的減少讀取、寫入資料時所需要的 throughput。不過 gzip 一次只會用到一個 CPU core 壓縮資料,所以有人寫了 pigz ,在壓縮時建立多個 thread 同時運算。

還有不少針對 gz 的工具可以使用,像是:zcat、zgrep 和 zless (這超神奇,其實打 less 好像就會自動偵測是不是 gz 了  XD)


parallel


之前的筆記參考一下即可。


sort


排序大量資料也是會耗掉相當多的時間,幸好 sort 內建平行運算功能,只要加個參數即可。

$ sort --parallel=8 -S 4G unsort.list > sorted.list

「--parallel」可以指定要同時多少資源做排序,而「-S」則是設定要使用多大的記憶體來做排序。



xargs


感謝 Joe Horn 和 Wen-Shih Chao 提供指點,xargs 也有 parallel 的功能。使用「-P」參數就可以讓 xargs 自動做平行處理。

ls *.log | xargs -P 8 grep PATTERN




目前最常用的是這幾個,其他的就待以後用到慢慢補上。若有更好的做法也歡迎分享~

2015/08/24

語音通訊服務之差異與比較

更新版網路語音通訊軟體整理 round 2





最近常常開會,使用了各種不同的語音通訊服務,各有其優缺點和限制。做個筆記,以後可以依照不同的需求使用特定的特定的服務。


Hangouts:

  • 語音通訊同時通訊人數為 10 人
  • 有螢幕分享、白板、文件協作等功能
  • 音訊品質較差,容易有回音或是有雜訊

Skype:
  • 語音通訊人數好像沒上限 (目前沒遇到)
  • 有螢幕分享功能,但是超過 10  人就無法使用
  • 音訊較好,較少有雜音或回音 (大推)

LINE:
  • 音訊不差,但是時間延遲有時候會超過 3 秒鐘 (無法對話)
  • 請專心作貼圖服務

Steam:
  • 不是開玩笑的,Steam 的為了遊戲中的溝通,語音通訊不算差
  • 大家都需要有 Steam 帳號,小麻煩
  • 沒有螢幕畫面分享 (?)
  • 同時通訊的人數似乎不多 (不確定上限多少人)


不曉得還有沒有其他可以作為線上音訊討論的工具?真的有大量需求的話,其實花錢買解決方案應該也是可以的

2015/08/03

多核心主機搭配 GNU parallel

假如要將 apache log 中,包含某個 pattern 的記錄找出來,寫起來大概會像這樣子:
cat apache*.log | awk -f log-parser.awk

舊電腦就是放著一個檔案一個檔案慢慢跑,沒什麼問題。若新電腦現在不少都是多核心,看個 parser 慢慢跑,但是剩下的 3 個 CPU core 和 disk 都悠哉沒事做,感覺在浪費時間。

parallel 專門設計來讓 script 可以同時並行運作,使用電腦資源來節省時間的好工具。

假設今天 awk 非常吃 CPU 使用量 (規則較為複雜),處理一個檔案會花上很多 CPU 時間,則可以將 log 中的內容分散給多個 CPU 同時處理:
cat apache*.log | parallel --pipe awk -f log-parser.awk

此時,parallel 偵測到有 4 CPU cores,則會自動將 $FILE 內容分批轉送給 awk 處理 (一行為一個單位),這樣能讓 4 個 CPU 同時跑 awk 解析 log 內容。

不過以一行為一個單位轉送資料給 awk,也會耗掉一些運算資源,可以透過 --block 來要求 parallel 多少資料當作一個單位來轉送資料。以下假設一次送 10MB 的資料給 awk 處理:
cat apache*.log | parallel --pipe --block 10M awk -f log-parser.awk

倘若今天 awk 的要處理的東西並不複雜,可以輕鬆解決掉,上面的寫法反而會讓 CPU 閒閒沒事做,不如就讓一個 awk 負責處理一個檔案,且多個檔案同時進行。此時就可以讓檔案處理的部分轉交給 awk:
parallel --pipe -u --block 10M awk -f log-parser.awk ::: apache*.log

備註:parallel 預設會在所有工作執行結束才輸出結果,若要讓 parallel 即時將結果印出,則可加上參數「-u」。

另外一點要注意的是,parallel 預設會使用所有的 CPU 來處理工作,這在多人共同使用的主機上並不是一件好事,一跑下去大家都不用做事了。所以若在共用環境上請記得加上 -j (jobs) 參數,來限制 parallel 不要用掉所有的系統資源。


Reference:

2015/04/25

整理 git local / remote branch

先列出所有的 branch:
$ git branch -a
* api
  cleanCode
  dev
  master
  remotes/github/api
  remotes/github/dev
  remotes/github/master
  remotes/github/pub/anime
  remotes/github/pub/dev
  remotes/github/pub/lock

已知其中 "pub/*" 開頭的 branch 其實已經都不存在了,這時候如果刪除 remote branch 會出現錯誤訊息:
$ git push github :pub/lock
error: unable to delete 'pub/lock': remote ref does not exist
error: failed to push some refs to 'git@github.com:johnroyer/aniTrace-fuel.git'

表示 local container 已經和 remote 資料有差異了。

這時候可以用 prune 指令,讓 git 同步 local 和 remote 的資料:
git remote prune github

執行後,若 remote 已經刪除的 branch,也不會在 git branch -a 時顯示了。

2015/04/14

Case-insensitive in HFS+

因為某個 repo. 底下有二個大小寫不同的檔案:
$ ls
readme.md
README.md

git 顯示檔案有異動:
$ git status

    modified: readme.md

確定檔案內容有問題,強制從 repo. 中拉出 readme.md:
$ git checkout -- readme.md

checkout 以後,換成 README.md 有異動:
$ git status

    modified: README.md

看起來是 case-insensitive 的問題,先強制讓 git 區分大小寫:
$ git config --global core.ignorecase false

可惜還是沒有效果。

後來才知道 Mac OS 的檔案系統 HFS+ 中,預設是不區分大小寫的。
也可在格式化時可以另外設定成 case-sensitive,但有可能會造成部分程式無法正常運作。


Ref:

2015/03/30

Install Gems without Docs

使用 gems install 時,預設會下載並產生 gem 說明文件,但這個步驟會花掉不少時間。

若環境為 production,說明文件其實是沒有必要安裝的,可以在家目錄下新增 .gemrc 檔,要求安裝 gems 時忽略說明文件:
cd ~
echo 'gem: --no-rdoc --no-ri' > .gemrc

2015/03/18

irssi 快速鍵

無意間按錯,發現一些快速鍵可以用。

Ctrl + N / P:下一個 / 上一個 channel

Alt + N / P:該 channel 訊息下一頁 / 上一頁