Skip to main content

· 3 min read

連結: https://buoyant.io/service-mesh-manifesto/

一篇關於 Service Mesh 的好文,發布已經有段時間了不過還是值得一讀, 文章作者是非常早期 Service Mesh 項目: Linkerd 的核心開發成員之一也是新創公司 Buoyant 公司的 CEO 相信大家應該對於 Service Mesh 一詞已經不陌生,可能對於這個名詞比較熟悉的朋友大多是從另一個 Service Mesh 項目: Istio 去了解 Service Mesh 的面貌,從這篇文章你可以從不同觀點認識 Service Mesh , 全文非常長內容涵蓋:

  • Service Mesh 詳盡介紹
  • 為什麼 Service Mesh 可以被施行?
  • 為什麼 Service Mesh 是個好的 idea (比起其他方法)?
  • Service Mesh 幫助了什麼?
  • Service Mesh 有解決掉所有問題嗎?
  • 為什麼在現今 Service Mesh 可以被施行?
  • 為什麼人們那麼愛談論 Service Mesh?
  • 身為一個謙虛的開發者需要關注 Service Mesh 嗎?
  • 一系列F&Q 這裡對 Service Mesh 的需求做個小結,Service Mesh 帶來了三大好處:
  1. Reliability: 包含提供請求重試、超時、金絲雀部署(Traffic shifting/splitting) 等功能
  2. Observability: 包含提供請求成功率、延時、粒度到個別服
  3. Security: ACL 及 Mutual TLS (客戶端及服務端互信) 值得一提的是,本篇作者 William Morgan 對於 istio 持負面的態度,並不是因為 istio 與 linkerd 處於競爭關係的兩個產品,而是對於 istio 在 service mesh 做了太多的商業性 marketing 操作(大部分來自Go ogle的操作) 有興趣的朋友也可以在 Podcast 上聽到作者在 Podcast 上的訪談: https://reurl.cc/N6GbW9

· One min read

連結: https://www.cncf.io/blog/2020/09/09/how-to-enforce-kubernetes-network-security-policies-using-opa

不知道大家是否都有使用 Network Policy 來設定 Kubernetes 內部的 ACL? 這邊有個叫做 OPA 的工具可以用幫你驗證你的 Network Policy 是否運作良好,甚至當有新的應用服務要部署的時候,也會確定是否有跟 Network Policy 衝突 有興趣的人可以研究看看

· 2 min read

連結: https://medium.com/swlh/amazon-eks-upgrade-journey-from-1-17-to-1-18-e35e134ca898

這邊跟大家分享一篇 EKS 升級的心得文章,該文章記錄了 EKS 從 k8s 1.17 到 1.18 的過程,並且先分享了幾個 1.18 主要新功能,包含了

  1. Topology Manager (Beta)
  2. Service Side Apply (Beta)
  3. Pod Topology Spread (Beta) ... 等 詳細升級過程看起來無痛輕鬆,有興趣的可以參考全文 當然升級 K8S 最重要的還是要注意 Resource 的 API 版本是否有變,譬如 1.16 就讓很多人採到 Deployment 使用 extensions/v1beta1 的錯誤,所以每次升級請先檢查有沒有哪些過舊的 API 版本被丟棄,以免升> 級後現有的服務部屬不上去 題外話: ingress 如果還是使用 extensions/v1beta1 的話,建議都換成 networking.k8s.io/v1beta1 (k8s 1.14+), 到了 1.22 後本來的 extensions/v1beta1 就不能用囉

· 3 min read

2020 年度個人回顧

  1. 美國工作順利活下來,已達一年六個月
  2. 美國總共搬家四次,其中只有一次跟我有關
  3. 洗衣機卡門事件讓我領悟到世事難料
  4. 年度公開演講 8 場,其中六場是個人自給自足的線上演講。而且有五場是美國時間早上六點起來準時分享。必須說真的滿累的,一大早又要講底層的東西常常會恍神
  5. 年度公開文章 58 篇,其中 30 篇是 2020 參加鐵人賽完賽的文章。今年度有增加更多 devops 相關的文章,也還是有保持幾篇研究 kernel 等底層的文章
  6. 參加 2020 鐵人賽,今年運氣不錯得到佳作,同時團體賽也順利完賽!
  7. 續約微軟 MVP
  8. 開設三門線上課程,講述 kubernetes 各類資訊,課程總長度將近33小時
  9. 參加兩次 podcast 閒聊
  10. 一整年剪頭髮次數: 2 次
  11. 美國遠端工作八個月,回台的14天隔離根本小case
  12. 八個月沒有進入健身房,覺得人生少了一點什麼,實測發現硬舉最大重量少了70公斤 :(
  13. 脫魯
  14. 感謝前國手們的閒聊,最後開設個人粉絲頁分享各類資訊,累積人樹目前 2k

2021 展望

  1. 美國工作繼續順利
  2. 繼續保持線上演講的衝勁與動力,希望至少一年六次
  3. 文章希望內容可以廣度與深度兼具
  4. 今年我要成為 ebpf 王
  5. 繼續參加鐵人賽
  6. 剪頭髮次數: 3 次
  7. 繼續開設三門線上課程
  8. 撰寫第一本書籍
  9. 粉絲頁固定每兩天一篇文章分享長達一年
  10. 街頭健身完成前水平
  11. 保持脫魯

結語

2020 受到疫情影響,導致有八個月的時間都長期遠端工作,整體工作生活習慣改變,包含工作,煮飯,運動等彼此的時間調整。

也因為如此有更多的彈性時間去思考自己要的東西,同時準備課程與鐵人賽文章。整體的時間管理能力目前還算滿意

· 10 min read

2020 年是個多事之秋的一年, COVID-19 於全球肆虐,根據 worldometer 的統計,到 2020/09/25 已經造成全球三千兩百萬人感染,將近一百萬人死亡。其造成的經濟影響更是空球絕後,美國股市一波三折,一年多次熔斷已經是歷史紀錄。企業則是面臨各種收入減少的困境,申請破產與力拼轉型的新聞則是沒有停止過。

今天就來跟大家分享一下,這六個多月以來遠端工作 (Work From Home, WFH) 的一些想法與心得

個人經驗

個人目前對於遠端工作是秉持利大於弊的心得,接下來從不同點來探討利弊

交通

矽谷灣區最著名的一個特色就是塞車,上班塞車,下班塞車,永遠都在塞車,所以過往很多人都會採取彈性上班的方式來避免車流,或是採取大眾運輸工具的方式來通勤。

以我個人為例,過往每天上班的通勤時間大概平均兩個小時,主要分成開車與大眾運輸

  1. 大眾運輸: 腳踏車配上火車通勤,由於火車時刻表固定,所以上下班時間比較沒有彈性
  2. 開車: 開車的話大概可以將時間縮短到單趟 40 分鐘左右,但是整個高速公路都是一片紅,其實開起來很悶

遠端工作後,每天可以省下大約兩個小時的時間,這部分可以拿來上班工作,也可以拿來處理私人事情,時間上更加彈性

工作

遠端在家工作後,最大的幾個變化就是

  1. 工作自律 基本上一整天就是在電腦前面,所以沒有開會的時候,其實都是自己去控制自己的工作節奏,這部分好壞的意見都有聽過,大家也會彼此分享如何讓自己工作更加專心,而不會被家裡的舒適環境給影響。

  2. 會議全面遠端化且數量上升 過往一些小事情要討論時,可能就直接現場約一約,到小會議室直接討論。然而目前則是因為遠端會議,所以全部都要事先預約時間來確保對方目前在電腦前。有時候一個小事情卻要花更多的時間來定案,我個人認為效率是不如過往的。 此外之前也出現如 Zoom Fatigue 這樣的說法,過多的會議內容導致大家開會疲倦,分心

就我個人的心得來看,自己能夠維持好工作的節奏,該完成的工作事項能完成就好,此外被打擾中斷工作的機會也更少了,整體而言利大於弊,

互動

員工之間的會面都是透過線上會議,缺少實體見面的互動,這部分也是見仁見智。有些人不喜歡交流,覺得 「上班當同事,下班不認識」是其工作原則,那應該會滿喜歡這種模式的。但是也有人喜歡實體交流,每天吃個一起吃個午餐,聊聊一些工作以外的事情,分享彼此的事情也都是一種生活。

這部分我就沒有太大意見,有好有壞,偶而還是會透過 slack 與同事聊聊幹話,分享最近的生活,只是少了聲音的互動。

福利

遠端工作以後,公司內本來的福利近乎全滅,什麼咖啡,零食,飲料,冰箱內各種飲品,甚至免費午餐等都不再擁有,一切都要依賴自己處理。

對於一個自住的邊緣人來說,變成每天都要煩惱該怎麼處理今天的飲食,「每餐叫外送,荷包先消瘦」是一個顧慮點,自己煮飯又是一個額外的挑戰,買菜/備料/烹飪/善後四個步驟往往也花費不少時間在處理,如果將這個時間與通勤時間組合起來,未必可以省下時間。

我個人平常就習慣煮飯,已經練就如何快速料理與一次準備多日便當,所以這個情況比較不會有太大問題。 倒是我有聽過朋友因為沒有公司零食的迫害,遠端工作期間被迫減肥,也算是一個附加好處

一個美好的夢想就是辦公室可以縮編,「公司省租金,員工可加薪」

美國現況

疫情以來,各大公司陸陸續續宣布相關的遠端工作政策,而規範的工作日期也隨者疫情的擴散而延後,下面就整理目前我知道部分公司的工作內容,此外政策不一定適用於所有員工,必要性的情況下,部分員工還是要定期前往辦公室。

Apple: 員工可以遠端工作直到 2021 初期 Google: 員工至少可以遠端工作到 2021/07 Facebook: 員工至少可以遠端工作到 2021/07 Twitter: 員工可以選擇永遠遠端工作 Fujitsu: 員工可以選擇永遠遠端工作 Microsoft: 可以遠端工作直到 2021/02 Amazon: 員工至少可以遠端工作到 2021/01 Netflix: 員工遠端工作直到全面接受疫苗

此外,也有人對於遠端工作提出了一些負面說詞,譬如 Netflix 董事長則認為遠端工作沒有帶來正面效果,反而使得討論工作更加困難。

這部分真的就是沒有定案,完全見仁見智,而 Google 最近的調查則顯示只有 10% 不到的員工想要回到過往天天進辦公室的日子,

以下節錄自 Google 官方推特

除了公司本身政策的變動外,居住地遷移最近也是活動頻繁,譬如 Oklahoma 洲則有 Tulsa Remote 計畫,向所有遠端工作者提供一萬美元的獎勵,只要你願意搬來這邊即可。 根據報導指出,舊金山的兩房公寓每個月可能略低於四千美金,而 Tusla 則不到一千美金,再租金花費方面可以說是節省不少開銷。

心得

就我過去五年的台灣工作經驗,我認為台灣公司要跟進遠端工作政策實屬不易,幾個原因如下

  1. 勞基法規定下,公司都要提出員工上下班出勤時間的紀錄,這部分會用來評估是否有加班超時 對於遠端工作者來說,要如何打卡來滿足這些紀錄是一個行政上的問題,而不是技術上的問題 更多時候是公司行政團隊願不願意嘗試探討可能性,並嘗試看看
  2. 沒人監督,老闆放不下 這種情況下,我認為信任是最基本的基礎,老闆信任員工可以遠端工作依然保持良好效率,員工也真的能夠滿足一定的效率來證明制度可行。過往就有聽過台灣發生過老闆接受遠端工作,結果員工私下兼差來賺錢,最後兩邊信任破壞,一切回歸辦公室制度。

Reference

· 4 min read

本身算是 Costco 愛好者,每個禮拜的蛋白質基本上都是從 Costco 取得

常買的有

  1. 雞胸肉
  2. 雞腿排
  3. 牛奶
  4. 蛋白丁
  5. 蝦仁
  6. 鮭魚

這篇文章主要用來記錄冷凍鮭魚排的資訊,每一份的大小以及熱量等資訊

來源

Costco 基本上有滿多的鮭魚可以購買,有在冷藏處比較新鮮的挪威鮭魚,也有在冷凍庫的冷凍鮭魚。 由於我大部分都是製作便當,因此任何的食材在烹飪完畢後都會冷藏並且隔天透過微波爐來加熱飲食 因此在選擇上我都還是以冷凍鮭魚為主,只有特別想要當天吃才會選擇冷藏鮭魚

本篇主要以冷凍鮭魚為主,其包裝如下 Imgur

大小

根據 Imgur 包裝背後的標示,本包裝大概含有 2KG 的鮭魚,然而實際上裡面的包裝物並不是真的如其所說有 20 份這麼多,其實每片鮭魚大小都頗大的。

實際上拿出一片使用電子秤來進行實測,測出來的重量大概是 300g 左右 Imgur

因此一整包的份量大概會落在7片左右,畢竟每片鮭魚的大小都會有點差距,不過大概可以記住一片300g就好

營養

本篇就直接使用該包裝背後所提供的成份表來計算每片鮭魚排的營養素 Imgur

將常見的營養素基於 100 以及 300 公克列舉出來

100公克300公克
熱量149 KCal447 KCal
蛋白質17.9 g53.7 g
粗脂肪8.5 g25.5 g
飽和脂肪2.2 g6.6 g
碳水化合物0.1 g0.3 g
59 mg177 mg

這樣來看如果今天一餐吃一片冷凍鮭魚排的話,,攝取的蛋白質大概是 54 g 左右,熱量450卡,如果單純考慮價錢與蛋白質的比例的話,還是雞胸/雞腿的比例比較好,不過換換口味吃個鮭魚也不錯

烹調

基本上好好的煎就沒有什麼問題了,唯一要注意的是要確認內部比較厚的部分需要比較長的時間才會熟透,可以切半去料理會比較快。

· 3 min read

本身算是 Costco 愛好者,每個禮拜的蛋白質基本上都是從 Costco 取得

常買的有

  1. 雞胸肉
  2. 雞腿排
  3. 牛奶
  4. 蛋白丁
  5. 蝦仁
  6. 鮭魚

這篇文章主要用來記錄雞腿排的資訊,包含來源,熱量等資訊

來源

基本上 Costco 雞腿肉的來源有兩家,分別大成 以及 卜蜂 這兩家供應商。

購買時包裝上面都會顯示這兩家的名稱與Logo,除了供應商名稱不同外,其價格與大小大致上並沒有差異。

大小

根據 Costco 線上官網 的圖示說明,每包 Costco 去骨雞腿都是一次六包為一個單位

如下圖

六包的重量大概都是落在 2.5kg 上下左右,平均下來每包平均 400多克左右。

但是實際上在食用時,每一包內的去骨雞腿牌數量則是 2-3 片,這部份就是隨機的。

為了能夠簡單的估算每一包雞腿排的營養素,我們必須要先知道每一塊的重量

這邊實際拿電子秤來實測看看這兩片雞腿排的重量

Imgur Imgur

根據上述的結果,每片雞腿排的重量大概落在 170 公克左右

營養

根據食品藥物消費者知識服務網 提供的食品營養素估算表

我們使用肉類->雞類 ->清腿 這個分類來估算營養成分

將常見的營養素基於 100 以及 170 公克列舉出來

100公克170公克
熱量157267
粗蛋白18.531.4
粗脂肪8.714.8
飽和脂肪2.54.3
總碳水化合物00

這樣來看如果今天一餐吃包,攝取的蛋白質則介於 60 ~ 90 公克之間,取決於你那一包裡面有多少片雞腿排

烹調

雞腿肉相對於雞胸肉來說料理非常簡單,基本上只要現煮(烤/煎/)等各式料理方法都不會太難吃,所以就邊就不多述相關的料理方式了

#參考來源

· 7 min read

blktrace is a block layer IO tracing mechanism which provide detailed information about request queue operations up to user space.

blkparse will combine streams of events for various devices on various CPUs, and produce a formatted output the the event information. It take the output of above tool blktrace and convert those information into fency readable form.

In the following, We will use those tools blktrace and blkparse to help us to observe sector numbers which has been written by fio requests. We will use the fil to generate two diffenrt IO pattern requests, sequence write and random write.

Environment

OS: Ubuntu 14.04 Storage: NVME FIO: fio-2.19-12-gb94d blktrace: 2.0.0 blkparse: 1.1.0

you can use following commands to install blktrace and blkparse

apt-get install -y blktrace

Experiment

Step1

In order to make the output of blkparse more easily to read, we set the numjobs to 1. Following is my fio config

[global]
iodepth=256
numjobs=1
direct=1

time_based
runtime=120
group_reporting
size=5G
ioengine=libaio

filename=/dev/nvme1n1
[rw]
bs=4k
rw=randwrite

[sw]
bs=64k
rw=write

After we setup the fio config, use the fio to generate the IO request. In this example, we ask the fio to generate the IO via sequence write pattern.

fio ${path_of_config} section=sw

During the experiment, you can use the tool iostat to monitor the I/O information about the device we want to observe.

Step2

Open other terminal and use blktrace to collection the data, there are two parameter we need to use, First one is -d, which indicate what target device blktrace will monitor to. Second, is -w, we use it to limit the time (seconds) how long blktrace will run. So, our final command looks like below.

blktrace -d /dev/nvme1n1 -w 60

In the end of blktrace, you can discover some new files has created by blktrace and its prefix name is nvme1n1.blktrac.xx The number of files is depends how may CPUs in your system.

-rw-r--r--  1 root     root         821152 Jun  2 10:39 nvme1n1.blktrace.0
-rw-r--r-- 1 root root 21044368 Jun 2 10:39 nvme1n1.blktrace.1
-rw-r--r-- 1 root root 462864 Jun 2 10:39 nvme1n1.blktrace.10
-rw-r--r-- 1 root root 737960 Jun 2 10:39 nvme1n1.blktrace.11
-rw-r--r-- 1 root root 865872 Jun 2 10:39 nvme1n1.blktrace.12
-rw-r--r-- 1 root root 755248 Jun 2 10:39 nvme1n1.blktrace.13
-rw-r--r-- 1 root root 4675176 Jun 2 10:39 nvme1n1.blktrace.14
-rw-r--r-- 1 root root 4471480 Jun 2 10:39 nvme1n1.blktrace.15
-rw-r--r-- 1 root root 5070264 Jun 2 10:39 nvme1n1.blktrace.16
-rw-r--r-- 1 root root 5075040 Jun 2 10:39 nvme1n1.blktrace.17
-rw-r--r-- 1 root root 5062104 Jun 2 10:39 nvme1n1.blktrace.18
-rw-r--r-- 1 root root 5586936 Jun 2 10:39 nvme1n1.blktrace.19
-rw-r--r-- 1 root root 3718848 Jun 2 10:39 nvme1n1.blktrace.2

Step3

Now, we can use the blkparse to regenerate human-readable output form the output we get via blktrace before.

We need to indicate source files, you can just use the device name without .blktrace.xx, for example, nvmen1, it will search all files which match the pattern nvmen1.blktrace.xx and put together to analyze. Then, the -f option used to foramt the output data, you can find more about it via man blkparse

OUTPUT DESCRIPTION AND FORMATTING
The output from blkparse can be tailored for specific use -- in particular, to ease parsing of output, and/or limit output fields to those the user wants to see. The data for fields which can be output include:

a Action, a (small) string (1 or 2 characters) -- see table below for more details

c CPU id

C Command

d RWBS field, a (small) string (1-3 characters) -- see section below for more details

D 7-character string containing the major and minor numbers of the event's device (separated by a comma).

e Error value

m Minor number of event's device.

M Major number of event's device.

n Number of blocks

N Number of bytes

p Process ID

P Display packet data -- series of hexadecimal values

s Sequence numbers

S Sector number

t Time stamp (nanoseconds)

T Time stamp (seconds)

u Elapsed value in microseconds (-t command line option)

U Payload unsigned integer

For our observation, we use %5T.%9t, %p, %C, %a, %S\n to format our result containing timestamp, command, process ID, action and sequence number.

Since the data I/O contains many action, such as complete, queued, inserted..ect. we can use option -a to filter actions, you can find more info via man blktrace. In this case, we use the write to filter the actions.

In the end, use the -o options to indicate the output file name.

barrier: barrier attribute
complete: completed by driver
fs: requests
issue: issued to driver
pc: packet command events
queue: queue operations
read: read traces
requeue: requeue operations
sync: synchronous attribute
write: write traces
notify: trace messages
drv_data: additional driver specific trace

The command will look like below and it will output the result to file output.txt.

blkparse nvme1n1 -f "%5T.%9t, %p, %C, %a, %S\n"  -a write -o output.txt

open the file, the result looks like

    0.000000000, 22890, fio, Q, 1720960
0.000001857, 22890, fio, G, 1720960
0.000005803, 22890, fio, I, 1720960
0.000009234, 22890, fio, D, 1720960
0.000036821, 0, swapper/0, C, 1996928
0.000067519, 22890, fio, Q, 1721088
0.000068538, 22890, fio, G, 1721088
0.000071531, 22890, fio, I, 1721088
0.000073102, 22890, fio, D, 1721088
0.000093464, 0, swapper/0, C, 1994624
0.000123806, 0, swapper/0, C, 1785472
0.000147436, 22892, fio, C, 1784576
0.000159977, 22891, fio, C, 1997312
0.000166653, 22891, fio, Q, 2006912
0.000167632, 22891, fio, G, 2006912
0.000169422, 22891, fio, I, 2006912
0.000171178, 22891, fio, D, 2006912
0.000188830, 22892, fio, Q, 1817728
0.000189783, 22892, fio, G, 1817728
0.000191405, 22892, fio, I, 1817728
0.000192830, 22892, fio, D, 1817728
0.000202367, 22891, fio, Q, 2007040
0.000203160, 22891, fio, G, 2007040
0.000205969, 22891, fio, I, 2007040
0.000207524, 22891, fio, D, 2007040
0.000227655, 22892, fio, Q, 1817856
0.000228457, 22892, fio, G, 1817856
0.000231936, 22892, fio, I, 1817856
....

Since the fio will fork to two process to handle the process, we use the grep to focus on one specific process (pid=22892).

grep "22892, fio" output.txt | more

Now, the result seems good, we can discover the sequence number (fifth column) is increasing. One thing we need to care about is the row which action is "C", which means the completed, since we don't know how NVME handle those request and reply to upper layer. we only need to focus on other action. such as "Q (queued This notes intent to queue i/o at the given location. No real requests exists yet.)" or "I (inserted A request is being sent to the i/o scheduler for addition to the internal queue and later service by the driver. The request is fully formed at this time)".

    0.000147436, 22892, fio, C, 1784576
0.000188830, 22892, fio, Q, 1817728
0.000189783, 22892, fio, G, 1817728
0.000191405, 22892, fio, I, 1817728
0.000192830, 22892, fio, D, 1817728
0.000227655, 22892, fio, Q, 1817856
0.000228457, 22892, fio, G, 1817856
0.000231936, 22892, fio, I, 1817856
0.000233530, 22892, fio, D, 1817856
0.000360361, 22892, fio, Q, 1817984
0.000361310, 22892, fio, G, 1817984
0.000364163, 22892, fio, I, 1817984
0.000366696, 22892, fio, D, 1817984
0.000536731, 22892, fio, Q, 1818112
0.000537758, 22892, fio, G, 1818112
0.000539371, 22892, fio, I, 1818112
0.000541407, 22892, fio, D, 1818112
0.000670209, 22892, fio, Q, 1818240
0.000671345, 22892, fio, G, 1818240
0.000673383, 22892, fio, I, 1818240
0.000676260, 22892, fio, D, 1818240
0.001885543, 22892, fio, Q, 1818368
0.001887444, 22892, fio, G, 1818368
0.001891353, 22892, fio, I, 1818368
0.001895917, 22892, fio, D, 1818368
0.001934546, 22892, fio, Q, 1818496
0.001935468, 22892, fio, G, 1818496
0.001936891, 22892, fio, I, 1818496
0.001938742, 22892, fio, D, 1818496
0.001965818, 22892, fio, Q, 1818624

Now, we can do all above command again and change the section to rw for fio using the randon write pattern. The blkparse result will show the random sequence number.

Summary

In this article, we try to use tools blktrace and blkparse to analysiz the block level I/O for fio request. We observe the filed sequence number to make sure thhat the fio can generate the sequence or random according to its config.

Reference

· 5 min read

本文主要嘗試分析 drbd(9.0) 於 kernel運行時的效能分析,希望藉由 perf 這個 tool 來分析整個程式運行的狀況,藉此觀察其運行時各 function 的比例。

Testing Environment

為了進行效能上的分析,首要條件就是先將 DRBD 給衝到效能瓶頸才有機會去觀察,所以本文採用下列的環境與工具來進行這項作業

Environment

CPU: Intel(R) Xeon(R) CPU E5-2695 v3 @ 2.30GHz Storage: Non-Volatile memory controller(NVME) Tool: fio OS: Ubuntu 16.04 with linux 4.4.0-78-generic

Setup

為了更方便觀察 drbd 的運行,我們將 drbd 創造的 kernel thread 都分別綁在不同的 cpu 上,這樣可以讓每隻 kernel thread 盡可能去使用cpu。

  1. 透過 ps or htop 取得 kernel thread 的 pid,這邊可以關注的有
    • drbd_s_r0 (sender)
    • drbd_r_r0 (receiver)
    • drbd_as_r0 (ack sender)
    • drbd_a_r0 (ack receiver)
    • drbd_w_r0 (worker)
  2. 透過 taskset 這個指令將上述程式分別綁到不同的 cpu 上
taskset -p 0x100 18888
...

Stress

本文使用 fio 來進行資料的讀取,下方提供一個簡易的 fio 設定檔,可依照自行的環境變換修改。

[global]
iodepth=512
numjobs=3
direct=1

time_based
runtime=30
group_reporting
size=5G
ioengine=libaio

filename=/mnt/beegfs/fio1.test
[rrw]
bs=4k
rw=randrw
rwmixread=75

[rr]
bs=4k
rw=randread

[rw]
bs=4k
rw=randwrite

[sr]
bs=64k
rw=read

[sw]
bs=64k
rw=write

我們 fio 採用 client/server 的架構,要是可支援多台 client 同時一起進行資料讀取,提供更高的壓力測試。

假設該設定檔名稱為 fio.cfg,並且放置於 /tmp/fio.cfg 則首先在 node-1 上面執行下列指令以再背景跑一個 fio server

fio -S &

接下來要運行的時候,執行下列指令來運行 fio,其中若想要改變測試的類型,可透過 --secion進行切換。

/fio --client=node-1 /tmp/fio.cfg --section=rw

這時候可以透過 htop 以及 iostat 的資訊去觀察,如下圖 當前透過 iostat 觀察到的確對 drbd0 有大量的讀寫動作 同時由 htop (記得開啟 kernel thread觀察功能),可以看到 drbd_s_r0 以及 drbd_a_r0 都各自吃掉一個 cpu,大概都快接近 100% 的使用率。

Profile

有了上述的環境後,我們就可以準備來分析 drbd 程式碼運行狀況。

Environemnt

這邊使用 perf 這套程式來分析,基本上 kernel 新一點的版本都已經內建此功能了,比較舊的 kernel 則需要自己重新開啟該 kernel config然後重新 build kernel,所以這邊使用 Ubuntu 16.04 with linux 4.4.0-78-generic 相對起來非常簡單。

直接執行 perf 這個指令,若系統上有缺少 linux-tools-4.4.0-78 相關 tool 的話會有文字提示你,如下所示,按照提示使用 apt-get 將相關的套件安裝完畢後,就可以使用 perf 了。

WARNING: perf not found for kernel 4.4.0.78

You may need to install the following packages for this specific kernel:
linux-tools-4.4.0-78-4.4.0-78
linux-cloud-tools-4.4.0-78-4.4.0-78
Run

perf 的功能非常強大,可以參考 wiki, 這邊我們使用 perf top 的方式來觀察結果。 為了可以順便觀看 call graph 的過程,再執行perf的時候要多下-g這個參數

指令為 perf top -g -p $PID,如 perf top -g -p 18888

在這邊我嘗試觀察 drbd_a 這隻,結果如下列

drbd_a

這邊可以觀察到三隻吃比較兇的 function 都吃很兇,分別是 native_queue_spin_lock_slowpathtr_release 以及 idr_get_next

這邊比較麻煩的是你看這個只能知道就是卡在 spin_locK,系統上是不是 multithread,然後有太多的資料要搬移導致 spin_lock ? 這些搬移的資料是誰放進去的?,這些資料是什麼?

以及更多的問題都必須要看程式碼去理解其整體設計架構,才有辦法講出一套完整的流程說明這個結果。

這部份等之後能夠完整理解整個 drbd 的 write-path 或是 read-path 時再重新來看一次這張圖,到時候應該會有完全不一樣的思維。

· 2 min read

不久前有一篇文章https://daniel.haxx.se/blog/2017/04/22/fewer-mallocs-in-curl/指出, curl 開發者嘗試將 malloc 呼叫的次數減少,結果對整體的影響帶來的顯著的提升

使用 curl http://localhost/512M 當作第一個比較 原始版本的 curl 關於 malloc 相關數據如下

Mallocs: 33901
Reallocs: 5
Callocs: 24
Strdups: 31
Wcsdups: 0
Frees: 33956
Allocations: 33961
Maximum allocated: 160385

而修改後的版本為

Mallocs: 69
Reallocs: 5
Callocs: 24
Strdups: 31
Wcsdups: 0
Frees: 124
Allocations: 129
Maximum allocated: 153247

比較起來可以發現, malloc 呼叫的次數有急遽的下降,從 33901 降落到 69,而整體使用的記憶體也少了 7KB 左右 此外,若比較兩者傳輸的速度,抓取一個 80GB 的檔案

Original: 2200MB/sec
Modified: 2900MB/sec

在傳輸方面提升了 30% 左右的速率,非常驚人 若使用 time 指令來比較新舊版本抓取 80G 檔案的差別

Old code:

real 0m36.705s
user 0m20.176s
sys 0m16.072s
New code:

real 0m29.032s
user 0m12.196s
sys 0m12.820s

修改相關的 commit 如下

簡單來說就是將 malloc 的部分都拔除,盡量使用 stack 來提供記憶體,藉此減少呼叫 malloc 的部分。 主要是因為 curl 在傳輸的過程中,會有非常大量且小空間的 malloc 被呼叫到,這部分拖慢的整體的運行速度