Linux的cpu/power自動省電工具

剛好在Hacker News 上看到,記錄一下,也許以後會用得到。

有人分享了一個開源的cpu/電源自動化管理工具(auto-cpufreg),讓Linux的筆電的cpu可以電池模式下降件cpu的負載,而在插電模式下,又可以自動的提高cpu的運算能力。

如果有人有Linux的筆電,剛好也可以試試。

Reference:

Python concurrency的進展

在 Hacker News 上看到的資訊,目前有一位開發者最近實作出PoC版本的CPython multi-threading。

而會這麼說,主要是因為目前的Python在multi-thread方面的發展,還是受限於GIL(global interpreter lock)的影響,所以實際上在執行時,只會有一個thread 在運作。

而會有這樣的設計,也是跟GC(Garbage Collection)有比較大的關係,因為Python的GC是採用reference count的原理,當一個物件不再被任何其它物件所使用時,它就會是可以被回收的。而回收的方式就是透過GIL。

To avoid such problems, the GIL only allows one thread to be running in the interpreter (i.e. to actually be running Python code) at a time; that takes away almost all of the advantage of using threads in any sort of compute-intensive code.

A viable solution for Python concurrency [LWN.net]

不過目前這個設計有機會被改進了,即是社群開發者提供的那個 PoC版本CPython,而主要的改進方向是透過改進GC演算法,更詳細的作法可以直接參考這裡

相信這功能如果可以進到CPython之後的版本的話,這一定會大幅強化Python的優勢的,等之後看後續的發展了XD

Reference:

AWS Lambda的”冷啟動”時間

在Hacker News 上看到的一些相關比較,作者比較了現有AWS Lambda 的程式語言,並記錄每種語言在不同情境下的cold start的時間。

測試架構大概如下:

clients -> HTTP API -> Lambda function -> Dynamo DB

直接跳到測試結果

Cold start:

* All languages(except Java and .Net) have a pretty small cold start.
* Java even cannot start with 128Mb. It needs more memory. But GraalVM can help in this case.
* Rust beats all runtimes for all setups for cold start, the only exception is 128 MB where Python is the best.

AWS Lambda battle 2021: performance comparison for all languages (cold and warm start) | by Aleksandr Filichkin | Sep, 2021 | Medium

Warm start:

* Golang and Rust are the winners. They have the same brilliant performance.
* .Net has almost the same performance as Golang and Rust, but only after 1k iterations(after JIT).
* GraalVM has a stable great performance almost the same as .Net and a bit worse than Rust and Golang. But it doesn’t perform well for the smallest setup.
* Java is the next after GraalVM.The same as .Net, Java needs some time(1–3k iterations) for JIT(C1). Unfortunately for this particular use case, I was not able to achieve the expected great performance after JIT C2 compilation. Maybe AWS just disabled it.
* Python has stable good performance but works too slow for the 128 MB.
* Ruby has almost the same performance as Python, but we see some duration growing after 20 min invocations(after 15k iteration).
* NodeJs is the slowest runtime, after some time it becomes better(JIT?) but still is not good enough. In addition, we see the NodeJS has the worst maximum duration.

AWS Lambda battle 2021: performance comparison for all languages (cold and warm start) | by Aleksandr Filichkin | Sep, 2021 | Medium

Go與Rust是其中最穩定的且效能最好的,在幾乎所有的情境下,都是前2名。(唯一的例外是,Python在128MB RAM 的環境下是最快的)。

對我而言比較意外的是Node.js,沒想到會是最慢的!?

Reference:

AWS Lambda battle 2021: performance comparison for all languages (cold and warm start) | by Aleksandr Filichkin | Sep, 2021 | Medium

常用指令 – awk

awk 是個很強大的工具, 透過其特製的語法可以在很多變化上處理pipe或檔案內容;之前一段時間不碰後,又忘了之前使用過awk語法,趁最近又開始接觸來重新複習這個工具。

測試用檔案 – log.txt

假設一個log檔的檔名為log.txt,且內容如下:

2 this is a test 
3 Are you like awk 
This's a test
10 There are orange,apple,mongo

基本搭配print做格式化輸出

NOTE:

  • 值得注意的是,$0awk中代表的是整行文字
# 在print使用逗號,可以在輸出時用空白隔開$1與$4
awk '{print $1,$4}' log.txt

(上述指令針對每一行的log,截取第1個與第4個讀取到的文字)

2 a
3 like
This's
10 orange,apple,mongo

透過-F 更改分割字元

由於預設awk是使用空白當分割字元來處理同一行文字的,若要改變分割字元,則可以使用-F 這個flag。

aws -F , '{print $1,$2}' log.txt

(上述指令針對每一行的log,透過,分隔以後,截取分割後的第1個與第2個讀取到的文字)

2 a
3 like
This's
10 orange apple

(以這個log檔來看,只有最後一行才會被分割成多個arguments)

透過-v 來代入自訂的變數

透過預先定義好的變數

awk -v a=1 -v b=2 '{print $1,$1+a,b}' log.txt

(上述指令定義了a, b 2個變數與值,且在print時使用它們)

2 3 2
3 4 2
This's 1 2
10 11 2

透過運算符號來使用awk

支援的運算符號可以參考這裡

對每一行文字,過濾只有第一個參數大於2
awk '$1>2' log.txt

# output
3 Are you like awk
This's a test
10 There are orange,apple,mongo
對每一行文字,過濾只有第一個參數大於2,且第二個參數必須是"Are"
awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt

# output
3 Are you
對每一行文字,列出只有字元數大於20的行
awk 'length>20 {print $0}' log.txt

# output
10 There are orange,apple,mongo

搭配Regular expression使用

awk中,可以透過運算符號~!~來去搭配正規表示法使用。

對於每一行文字,當第一組參數不是數字時才會被print出來
awk '$1 !~ /[0-9]/ {print $0}' log.txt

# output
This's a test

對於每一行文字,只有當第一組參數是數字時才會被print
awk '$1 ~ /[0-9]/ {print $0}' log.txt

# output
2 this is a test
3 Are you like awk
10 There are orange,apple,mongo

對於每一行文字,只有符合正規表示法時才會被print

如果只是要對整行文字作匹配的話,則可以直接用這方式

awk '/re/ ' log.txt

#output
3 Are you like awk
10 There are orange,apple,mongo

或加個!來過濾掉匹配到的每一行文字

awk '!/re/ ' log.txt

#output
2 this is a test
This's a test

搭配awk的進階使用

awk常見可以使用的keyword可以參考這裡

過濾掉第一行的文字(通常可用於csv檔拿掉header)
awk 'NR != 1' log.txt

# output
3 Are you like awk
This's a test
10 There are orange,apple,mongo

(我猜NR指的應該是Nnumb of Row)

對文字檔的特定參數做數字加總,並且print出來
awk '{sum+=$1} END {print sum}' log.txt

# output
15

(如果每一行的第一個參數是數字的話,就會對它做加總並暫存在sum這個變數上)

針對文字檔中的每一行,來做分組與處理

假設我們有個文字檔如下,然後我們想要針對每個Category的值串起來在印出來

Category: OS
Windows
Liux
Unix
Category: CPU
x86
arm64
amd64
Category: RAM
1GB
2GB
4GB
8GB
16GB

awk '/Category/ {header=$0; if (v) print v; v=""; next} { v=(!v) ? header"="$0 : v","$0;} END {print v;}' support_sepcs.txt

# output
Category: OS=Windows,Liux,Unix
Category: CPU=x86,arm64,amd64
Category: RAM=1GB,2GB,4GB,8GB,16GB

這個指令用了到幾個進階的功能:

  • /Category/ 用來匹配當遇到Category那一行的文字時,會在{header=$0 ...;next}中處理。(結尾的next是指說跳過後面的{v=(!v)…}相關的工作)
  • () ? : 用三元運算符號來去給v這個變數值。
  • END 用來處理最後的收尾。
  • 整個指令的邏輯是,當如果遇到文字中含Category時,則那行的文字會當作是接下去的header,然後如果v 目前是有值的情況下,則print v
    (這個情況v會是前面的字串組成的結果, 例如處理Category: CPU時,v這時會有值,且值會是Category: OS=Windows,Liux,Unix)。
    若沒遇到Category的話,則繼續append 目前的這一行文字到v這個變數上。
    最後一個Category: RAM則是透過 END { print v}來去print出來。
  • 如果在header後想要多處理else的話,會是這樣的語法:
    {header=$0; {if (v) { print v; v=""; next } else {v="";next}}

總結

整個awk的進階使用還更複雜,尤其是它支援許多語法,透過它的語法可以寫成另一個awk的script了,然後在指令中讀取來使用,像是awk -f cal.awk log.txt

reference

常用指令 – xargs

基本上常搭配其它linux指令 (find, awk, sed, grep…)一起使用,主要是因為一些linux的指令是沒直接支援pipe,所以可以透過xargs將前面pipe的輸出當成input arguments 給下一個指令使用;

xargs 後面沒有接任何的指令時,預設是以 echo 來進行輸出喔

將find的結果,透過xargs 來當作grep 主要要找的對象

find . -name "*.go" -print | xargs grep "src"

-0 flag

-0 flag主要是用來讓xargs 來讓可以去處理需要escape的字元,像是空白字元…

-n flag

-n flag 是用來指定每隔多少個要切割成一個pipe的arguments,也就是目前的pipe經過xargs以後會產生N/n 個pipe(N為目前pipe的argument數量)。如果沒有設定的話預設為把所有xargs 當下截取到的內容全部收集到目前這個pipe中。

舉例來說,一個env檔的內容如下:

FOO=123
BAR=456
LOCAL=127.0.0.1
PORT=3000

如果我們沒加-nflag時,用下面的指令:

cat env| xargs

則輸出結果會是 (env檔中的4個環境變數會被當成目前這個pipe的argument)

FOO=123 BAR=456 LOCAL=127.0.0.1 PORT=3000

但如果指令改成是下面這樣時

cat env| xargs -n 2

則輸出結果會是 (env檔的4個環境變數被切割成每2個是一組argument, 並且丟到下一個pipe中,所以這樣就fanout成2個pipe了)

FOO=123 BAR=456
LOCAL=127.0.0.1 PORT=3000

-I flag

-I 主要是可以用來將截取到的內容,暫存成一個變數名稱,來方便下個指令使用。

以下面的例子來說,會將所有找到的 *.conf檔案,透過xargs暫存到變數{}中,所以接下來的ls -al {}就可以這樣用…

find /etc/ -name "*.conf" | xargs -I{} ls -al {}

另個例子則是像是備份所有的.conf檔,則可以透過-I flag

find /etc/ -name "*.conf" | xargs -I{} cp {} {}.bk

integrate with bash

更彈性的用法是,它可以直接當作bash的輸入arguments;若一樣以前面的env 檔來當例子,透過以下指令我們可以透過一個簡短的bash來處理其中的第3個($2)環境變數。

cat env| xargs bash -c 'export $2'

Reference:

一本介紹給開發者用的數學書

很早之前從Hacker Daily News上看到的相關討論,主要是有人推薦了一本可以給開發者看的數學書,目標族群是沒有受過正規學校教育的開發者,或著是像我這種已經把大多數學的東西環給學校的開發者XD

As the title implies, the book is targeted towards programmers who do not have an academic math background. 

A Programmer’s Introduction to Mathematics – BIT-101

書的內容含蓋了下面的主題:

* Polynomials
* Sets
* Graphs
* Calculus with one variable
* Linear algebra
* Eigenvectors and Eigenvalues
* Multivariable calculus
* Groups

A Programmer’s Introduction to Mathematics – BIT-101

剛也稍微翻了一下,感覺書的重點是讓開發者可以較容易的去閱讀一些數學公式以外,並且用一些程式範例讓開發者理解一個數學公式其對應的程式碼大概會長怎麼樣。

感覺蠻值收著,以後可以當工具書參考用…

reference:

Cassandra 叢集狀態的計算機

網路上看到的一個Cassandra的簡易計算機,作者還有的提供原始碼在Github 上,所以如果有需要的話也可以自己fork一份自己架在自己的網頁上。

這個計算機的功能也很簡單,主要是提供使用者可以快速顯示在不同的cluster狀態下,根據keyspace的read/write 設定對於叢集的影響,像是:

  • 可以容忍多少個節點失效而不遺失資料。
  • 每個節點的資料分佈比例。
  • 每次寫入會連接到的節點數量。
  • 每次讀取時會連接到的節點數量。

reference:

  • https://github.com/jalkanen/cassandracalculator
  • https://www.ecyrd.com/cassandracalculator/

使用sshuttle來連接不同環境下的機器

最近由於專案快上線了,所以頻繁的連接在不同的環境下的機器,或是監看機器的使用狀態;在這樣的使用情境下,之前有試著使用Socks5 + SwitchyOmega 的組合來連接,這樣的組合在只用來連接內網的dashboard時是蠻堪用的,但如果其它類型的連線就無法了。

每當要使用像是TCP連線到內網的機器(像是連資料庫之類的),就都要在先連一次VPN,然後才再連線;但連線完VPN以後,又要把SwitchyOmega的設定關閉,不然VPN +Socks5 + SwitchyOmega 的組合無法讓我連到特定的Dashboard…
這其實蠻惱人的,尤其是頻繁的切換使用VPN網路時,或是在開會過程中,又需要連到特定環境下的機器…

通常這問題大概可以使用幾種方式克服:

VPN – Partial Routing

若是使用OpenVPN的話可以在導入Profile時加入以下設定來讓client端可以自訂路由的規則。

route-nopull
route X.X.Y.Z 255.255.255.255

這邊的範例是只有往x.x.y.z 時才會經由vpn。

但這個方案的缺點是,同時間也只能連到一台OpenVPN 伺服器,所以代表同時間也只能連到同一個環境下的機器。

但優點就是所有TCP/UDP的封包都可以經由路由連接到那個環境下的機器。

SSH Tunnel Proxy

其實ssh 已經提供了一個方便的解決方案了,即是使用-L 這個flag,讓我們可以透過中介的jump/proxy server,讓我們的本地主機與遠端主機建立一個虛擬通道。

ssh -NL 5432:staging-postgres.your-domain.com user@jumper-server.your-domain.com

(使用-f 可以讓這個tunnel 在背景下執行。)

透過上面的指令,我們就可以執行下面的psql 指令來連接staging postgres這個資料庫。

psql -U postgres -d postgres -h 127.0.0.1 -p 5432

這個方案的缺點就是,如果有多台主機需要連的話,可能要設定多個Tunnel Proxy。

sshuttle

在Stackoverflow 上剛好看到了這篇文章,其中回應有提到了sshuttle 這個開源的專案可以透過ssh tunnel導流所有TCP的流量到遠端的jump server,也就是類似TCP Proxy的功能。

試了以後還蠻方便的,它底層的原理即是使用了ssh tunnel proxy,所以也是需要一台中介的ssh jump/proxy server。除此之外,它可以讓使用者用根據網段來轉送流量,所以基本可以解決原本在ssh tunnel proxy的一些不方便之處。

安裝

# For Mac
brew install sshuttle

# For ubuntu
sudo apt-get install sshuttle

使用上的基本指令

sshuttle -vr user@jumper-server.your-domain.com 10.0.0.0/8

上面這指令即是把所有往10.0.0.0/8的TCP流量都自動轉往jumper-server.your-domain.com上送…

Reference:

如何提升不同程式語言的技能

在Hacker Daily News上看到的一篇文章,作者提到了,當他發了一個PR到某個專案上時,專業的維護者的一些review 評論對他來說非常受用,也讓他了解到一些程式語言上 的特性與knowhow。

透過這個經驗,作者也發現了,當他去翻一些開源專案上的merged/closed PRs時,也可以發現類似的撰寫建議;所以他歸納這可以是一個通用法則,並且可以用在各個程式領域上:

I learned so much from reading the comments and concerns on my PRs. But it doesn’t have to be my PR. It can be anybody’s.

How To Rapidly Improve At Any Programming Language (cbui.dev)

簡而言之,在一個成熟且大型的開源專案上,開發與維護者通常都會是非常聰明且有知識的開發者,所以透過學習這些PRs 的建議與評論可以挖掘到許多無價的經驗。

因此作者也給了一些如何開始的建議:

1. Every morning, take your favorite open source library or one from a language you’re learning, go to the closed PRs on Github and start reading them from the beginning. Just a few a morning for warmup while you drink your morning coffee and catch up on email.

2. When you want to level up, start reading the diff, and review the code and changes yourself before reading the comments.

3. Finally, when you start feeling more confident, start leaving those comments on new PRs so that the maintainer doesn’t have to. You’re starting to contribute to open source!

How To Rapidly Improve At Any Programming Language (cbui.dev)

原文可以參考這裡:

How To Rapidly Improve At Any Programming Language (cbui.dev)