[TIL] Summarize about Mesos and Kubernetes

A slide to summarized some features comparison about Mesos and Kubernetes.

這篇投影片整理了 mesos 與 Kubernetes 的一些比較. 內容有包含:

  • 這兩年的發展
  • 基本架構圖
  • 整理最久的就是近兩年的版本功能發表的時間軸

希望能幫助一些人

[TIL] Kubernetes Device Plugin

NVIDIA 官方 REPO: Kubernetes Device Plugin

說明:

Kubernetes 在設計上有著相當程度的擴充性,在當初有 plugin 的架構就可以看出來. 比如說: Network Plugin 讓 CNI 可以輕鬆地整合. 1.8 版剛開放 alpha 的新功能 “Device Plugin” 更強,可以讓 GPU, 高效能網卡, FPGAs 甚至是 InfiniBand 輕鬆的整合在 Kubernetes 之中

原本在 Kubernetes 內預設只能抓取到 CPU 與 Memory 的狀態(不然,就得很辛苦.. 你懂的) 但是透過了 Device Plugin 你就做以下的事情:

  • 輕易的讓 Kubernetes 內所有的 container 可以存取該裝置
  • 輕易抓取到 GPU (或是高效率網卡) 的訊息
  • 透過 Kubernetes 的 Health check 來檢查裝置狀態

有興趣的可以再看看 Kubernetes 文件: https://kubernetes.io/docs/concepts/cluster-administration/device-plugins/

[Coursera] Deep Learning Specialization: Neural Networks and Deep Learning (一)

起源

本來就想把 Deep Learning 學一下, 因緣際會下看到這一篇 Coursera 學習心得 試讀了七天,除了提供 Jupyter Notebook 之外,作業也都相當有趣,就開始繼續學了. 目前進度到 Week2 相當推薦有程式設計一點點基礎就可以來學.裡面的數學應該還好. 學習的過程中還可以學會 Python 裡面的 numpy 如何使用,因為裡面主要就是要教導你如何使用 numpy 來兜出 Neural Network .

課程鏈結: 這裡

學習鏈結:

課程內容:

第一週: Introduction to deep learning

  • 基本上就介紹 Machine Learning 與 Deep Learning 的基本常識. 比如說 (ReLU activation functionReLU activation function
  • 介紹了近幾年 Deep Learning 會如此發展快速的原因 (計算速度的進展..)
  • 最後有採訪 Geoffrey Everest Hinton (也就是將 Backpropagation 導入了 Deep learning 的人,並且發明了 Boltzmann machine ) .
    • 有不少有趣的事情,比如作者認為自己作出的 Boltzmann machine 很美麗,但是無法實作.
    • 所以後來作者加上了一些限制後,衍生出 restricted Boltzmann machine ,該系統就被 Netflix 拿來使用.

第二週: Neural Networks Basics

  • 從頭開始教,一開始就教導你什麼是 binary-classification .
    • 透過簡單的影像判斷是不是貓,來教導.
    • 透過不同的資料(R, G, B) 來判斷是不是貓.
  • 教導一些 Deep Learning 的基本:
    • Logistic Regression
    • Ligistic Regression Cost Function
    • Gradient Descent
    • Dervatives
  • 透過一個 Jupyter Notebook 來教導你如何透過 numpy 來寫一個簡單的二元分類器 (classifier) 來分辨輸入的圖片是不是貓. 實際流程是:
    • 先做一個 sigmoid function
    • 再來實作 propagate function.
      • 拿到 X
      • 做出 forward propagate:
        • 算出 A = sigmoid($$w^TX+b)
        • 再來算出 cost function J = \(-1/m \sum_{i=1}^m y^i * log(a^i) + (1-y^i)log(1-a^i)\)
      • 再來做出 backward propagate:
        • 計算出 dw 與 db.
        • \[dw = 1/m (X (A-Y)^T)\]
        • \[db = 1/m \sum_{i=1}^m (A-y^i)\]
    • 再來要做 optimize function
      • 透過 gradient descent algorithm 來優化 w, b
      • 透過 iteration 的 loop
        • 透過 propagate 來找出新版的 dw, db
        • 透過 dw, db 來修正目前的 w, b
          • \[w = w - learning_rate * dw\]
          • \[b = b - learning_rate * db\]
        • 進行下一回合的 propagate
    • 再來就要透過計算出來的 w, b 來預測 (predict) 是否是貓
      • 透過 \(A = sigmoid( (X * w) + b)\)
      • 如果 A > 0.5 (threshold) 我們就認為這張圖片是貓
    • 整個 Model 的部分,就是做以下的事情:
      • 初始化 w, b (在此是設定為 0, 其實有更好的方式)
      • optimize 找出 w, b
      • 透過 w, b 來跑 predict
      • 作 training accuracy 鑑驗

我必須得說,最後這個 Jupyter Notebook 真的太有趣了…

NN 的常用符號解釋:

  • \(m\): 表示所有的訓練資料個數 (traning set)
  • \(n\): 每一個資料集中所具有的資料量
  • \(X \in \R\) 並且 \(X=(n_x, m)\)
  • \(Y\) 代表是結果 \(Y \in {0, 1}\)
    • (0: 代表不是, 1: 代表是)

關於一些 numpy 的基礎教學

由於這次課程不會用到比較複雜的 NN (Neural Network) 套件,而是直接使用 numpy 來打造一個 NN ,這裡有不少的 numpy 教學部份.有提到一些類似於:

import numpy as np

  • numpy 的 a=np.random.randn(5) 產生出來不是一個具有 transporm matrix 的 array 而是一個 a.shape = (5,)
    • 要正確產生一個 5,1 的 array 需要輸入 a=np.random.randn(5,1)
    • 建議加上 assert(a.shape==(5,1)) 作為檢查,確認沒有漏打.

透過 numpy 與 math 來學 sigmoid

\[sigmoid(x) = \frac{1}{1+e^{-x}}\]
import math

def basic_sigmoid(x):
    sig = 1 / (1 + math.e ** -x)
    return sig

由於 math 不能直接處理 array ,要改成 numpy

import numpy as np

def np_sigmoid(x):
    sig = 1 / (1 + np.exp(-x))
    return sig

usig numpy for norm

x_norm = np.linalg.norm(x, axis=1, keepdims=True)
normalize_x = x/x_norm

Softmax implement by numpy

def softmax(x):
    exp_x = np.exp(x)
    sum = np.sum(exp_x, axis=1, keepdims=True)
    s = exp_x/sum
    return s  
    

numpy 的效能評比

針對 vector 比較大量的時候,其實 numpy 的效能反而比起直接透過 for-loop 來運算快得多.並且整個代碼都清楚多了.

L1, L2 loss implement by numpy

def l1(yhat, y):
    loss= np.sum(np.abs(y-yhat))
    return loss
    
def l2(yhat, y):
    loss2= np.sum(np.dot(y-yhat, y-yhat))
    return loss2

記住 np.dot 是將兩個矩陣相乘,所有要求平方就是自己跟自己相乘.

使用 numpy 來做 propagate

# GRADED FUNCTION: propagate

def propagate(w, b, X, Y):
    m = X.shape[1]
    A = sigmoid( np.dot(np.transpose(w),X) + b )                                   # compute activation
    cost = -1 / m * np.sum( np.multiply(Y, np.log(A)) + np.multiply(1-Y, np.log(1-A)))
    
    dw = 1/m * np.dot(X, np.transpose(A-Y))
    db = 1/m * np.sum(A-Y)

    assert(dw.shape == w.shape)
    assert(db.dtype == float)
    cost = np.squeeze(cost)
    assert(cost.shape == ())
    
    grads = {"dw": dw,
             "db": db}
    
    return grads, cost

Numpy 裡面處理 matrix 需要注意的部分

  • 加法可以直接處理 [3,2] + [3,1]
  • 關於乘法(*) (跟 np.multiply 相同) 第一個維度需要相同
    • [4,3]*[3,1] –> Error
    • [4,3]*[4,1] –> [4,3]
      • 註解: 此狀況會產生 broadcasting
  • np.dot(): 注意第一個的第二維度需要跟第二個的第一維度相同(矩陣相乘)
    • np.dot([4,3], [3,1]) –> [4,1]
    • np.dot([4,3], [4,1]) –> Error

Interview with Pieter Abbeel

Pieter Abbeel 是處理 Deep Reinforcement Learning 的專家,這篇有提到他如何進行相關研究.

[中文導讀] Are You a Software Architect?

原文: infoq: Are You a Software Architect?

[你是一個合格的軟體架構師嗎?] 快速中文導讀..

最近看的文章之中,這篇文章相當適合推薦給大家.不論你已經是軟體架構師,或是你正想將你的專業領域網軟體架構師來邁進,都建議來看一下.

其中的許多部分加入了我個人的經驗與觀點,請觀看時斟酌思考,如果有錯誤的部分,歡迎提供任何意見.

本文部分

身為一個軟體架構師,最重要的兩個能力如下:

  • Definition of the software architecture
  • Delivery of the software architecture

以下開始解釋這兩種能力的細節,以及為何需要這兩種能力.

A. Definition of the software architecture (定義出軟體架構)

裡面建議在勾勒出整個軟體架構的時候必須要有的幾個面向為:

  1. Management of non-functional requirements
  2. Architecture definition
  3. Technology selection
  4. Architecture evaluation
  5. Architecture collaboration

以下開始逐一解釋每個細項的部分

1. Management of non-functional requirements (管理非功能面的需求)

這裡解釋一下,所謂的”非功能面需求” (non-functional requirements) 一般指的就是跟功能本身無關的需求,比如說: 系統的反應速度,系統容納上限,是否有 HA 與 Fault-tolerance? .

要針對功能面向來定義與管理比較容易,要有相當的經驗的人才能了解 non-functional requirements 的重要.

在設計軟體架構的第一個面向應該馬上將功能面以外的需求加以管理,並且確認清楚,不要讓該需求無限擴張. 比如說你的系統如果不需要 24x7 的營運保證,或許就可以讓他有系統更新與修改的時間與機會.或是可以釐清究竟需要多少的連線速度.

2. Architecture definition (定義出軟體架構)

當你透過管理而清楚地條列出非功能性需求後,你對於整個系統的效能與容錯率有了一個定義與概念.

接下來就是要定義出你的軟體架構,不論是透過將原先已經有的軟體架構加以修改,或是重新定義出一個軟體架構.

3. Technology selection (技術的選擇)

如何選擇你的架構,主要有以下的考量點:

  • 舊的技術有什麼缺點? 是否一定要使用新的技術?
  • 每個服務之間是透過哪一種的 licensing
  • 如果使用開源該社群活不活耀?
  • vendor 支援如何?

每一個係項都是需要好好思考的問題,你思考的越多在技術的選擇上就會有更多的考量,自然之後就更不容易有遺漏的地方.

4. Architecture evaluation (架構的評估)

關於評估(evaluation),這裡有兩個面向:

  • “假設”系統會如預期的運行
  • “證明”系統會如預期般的完美運行

不論是功能性的需求或是非功能性的需求(Non-Functional Requirement)對於系統架構的建置評估上,都是具有相當風險.

再評估系統架構上,我們可以透過各種的分別的服務壓力測試來給予我們足夠的信心來評估我們的系統架構. 比如說,在決定 Message Queue 系統架構時,可以考量 Kafka, Redis, 或是其他 MQ 給予的壓力測試數據,加上該系統可以裝載的資訊類別來評估是否符合你的系統設計.

所以根據前面的範例,在設計上我們都會先“假設” Kafka 能夠符合你的系統設計需求再來查看 Kafka 的可以乘載的資料類別與限制,加上他的壓力測試數據.來”證明“系統架構上是可行的.

5. Architecture collaboration (架構上的合作與溝通)

一個好的服務架構往往需要跨組織,跨區域性的合作.很多時候需要許多系統內部甚至是外部的參與者的合作才能造就整個系統的穩定與完整. 比如說:

  • 外部資料提供者需要給予足夠文件的說明
  • 外部服務提供者(或是需求者)能夠了解系統的架構與限制

所以,這時候良好的文件與溝通就無法省略.雖然不容易,但是這是一個很軟體架構師重要的工作職責,確認讓所有的合作夥伴能夠無縫的溝通與合作.

B. Delivery of the software architecture (將定義出來的軟體架構交付出來)

如何能夠將軟體架構交付出來的部分,也有列出以下幾個所需要的能力:

  1. Ownership of the bigger picture
  2. Leadership
  3. Coaching and mentoring
  4. Quality assurance
  5. Design, development and testing

這幾個項目其實在這幾年的專案管理過程中,不斷的有運用到所以相當推薦這些項目給軟體架構師.

1. Ownership of the bigger picture (隨時都具有廣大願景與目標)

身為一個好的軟體架構師,你的軟體架構要能夠被交付出來.這時候,你需要:

  • 確保團隊的每個人對於系統設計的目標與願景有清楚的了解
  • 完全地參與專案的進行,能夠不斷地將目標與願景植入團隊的每一個人心中.

這兩個部分相當的重要,舉例而言: 如果你要打造一個反應速度相當迅速的電商平台,那麼團隊中的夥伴們都要能夠清楚的體認這個大方向的概念,才能避免在一些細節上做出會讓整體效能延遲的決定.

2. Leadership (展露你的領導能力)

在軟體專案進行的時候,身為軟體架構師也要能夠適時地展現你的領導能力.需要透過參與實際的專案運作,了解每個成員目前的狀況,開發是否有任何困難.並且適度的扛起責任,當團隊成員有任何疑慮或是需要抉擇的時候做出許多的決定.

3. Coaching and mentoring (教導與指導)

在軟體開發流程上教導與指導雖然是有些過度干涉的成分,但是身為軟體架構師要能夠在架構的討論上,對於團隊有足夠的教導與指導.不是針對團隊面對的程式邏輯的問題,要能夠處理系統相關與設計架構上可能造成的效率取捨.對於架構流程上的教導,並且指導團隊方向引領到正確的設計方向.

4. Quality assurance(品質的確保)

不論是哪一種完美的軟體架構都有可能因為交付的品質而毀於一旦,品質的確保就相當的重要.這裡分享以往在軟體開發的經驗,就是要能夠仔細地將足夠的測試資源投資在正確的地方.比如說: 你的系統是電商系統,那麼你就必須要有足夠的安全性測試,然後再投資到使用者的使用流程.

5. Design, development and testing (設計,開發與測試)

你是一個親自參與(hand-on)的軟體架構師嗎? 許多公司不會讓軟體架構師參與整個開發的流程,因為他們太珍貴.在作者的建議裡面,這不是一個好的態度.一個好的軟體架構師必須要能親自動手做,要能夠在團隊裡面了解相關的程序,做出必要的貢獻.

然後親自參與也不是要軟體架構是必須要把所有的時間都花在代碼的編寫上.親自下來參與並且了解整個專案建置的流程也是很重要的.

你是一個軟體架構師嗎?

軟體架構師不是一個就達成的職業,他需要不斷的參與軟體的開發流程,並且具有實際動手做的能力與毅力. 要能檢視自己是不是足夠的軟體架構師,就要能不斷的檢視自己的每個實作的能力與對於系統的透徹程度.

心得:

之前在網路上有個有趣的討論,究竟前端工程師需不需要了解演算法.這就讓我思考到,一個好的專案管理人員與一個好的軟體架構師到底需不需要自己下來動手做? 答案當然是肯定的,不斷的參與專案的開發流程,並且適度的參與是軟體開發人員必備的能力.

Keep coding….

[論文解讀][Bloom Filter] Cuckoo Filter

(Image: Coolshell)

[Cuckoo Filter: Practically Better Than Bloom] [slide]

接續前文, Bloom Filter 深入討論

複習一下 Bloom Filter 與 Counting Filter

Bloom Filter 快速的搜尋索引結構,具有以下優點:

  • 能夠在 \(O(1)\) 的時間複雜度下快速確認該物品有沒有存在(* 具有 False Positive)

缺點:

  • 但是只支援新增節點卻無法刪除節點. (* 需要透過重新建立 Bloom Filter)
  • False positive 的問題,需要透過增加節點(m)來減少,但是這樣又會造成空間複雜度的增加.

為了要解決刪除節點需要重新建立整個 Bloom Filter 的缺點, Counting Filter 就因為這樣而產生.

Counting Filter 缺點

空間過大

原先 Couting Filter 藉由增加一個資料欄位來讓 Bloom Filter 無法刪除資料點的限制去除.但是卻又因為每個節點需要增加一個資料欄位而讓空間使用上變得相當沒有效率.

空間的利用率上,根據這篇論文提到. 你可能需要使用到 3~4 倍的空間使用率來維持相同的 False Positive Rate .

為何使用 Couting Filter 的空間複雜度會增加 3~4 倍

主要是因為要能夠符合 dynamic deletion 這個條件限制,所以在插入資料的時候會選擇 \(k\) 的個數來插入你的資料. (也就是一份資料 duplicate 到 \(k\) 份)

原因如下:

  • 由於需要符合 dynamic deletion ,雖然增加了一個數值單位來記錄總共有幾個.但是如果只有一份的話,再刪除的時候很容易刪除掉其他 hashing collision 的資料
  • 避免這樣的問題,只好多複製幾分來做為 hashing collision 的解決方式.

細談增加 3~4 倍的原因

在這裡列出一些符號如下:

  • 第 i 個 counting filter 被增加 j 次的機率
  • \(n\) 元素個數
  • \(k\) hashing 個數,也就是你需要複製幾份
  • \(m\) 為原來的 couter 的表現大小的個數.
\[P(c(i) = j) = (^nk _j) (1/m)^j (1-1/m)^nk-j\]

之前的 Bloom Filter 對於 \(k, m, n\) 的限制: \(k ≤ (ln2)m/n\) ,所以式子可以改成:

\[P( (max)_i c(i) >= j) <= m ((e ln 2)^j/ j)\]

所以如果 counter \(i\) 是 4 個,那麼 \(j\) 就得 16 才能滿足以上的式子.

透過這樣的方式來計算,大概需要 3~4 倍的空間複雜度,來滿足原先 Bloom Filter 的條件.

Cuckoo Filter

優點:

在提到更多的 implement 的過程中,我們先來查看整個 cuckoo filter 的優點.

  • 支援動態的新增,刪除節點(跟 Counting Filter 相同)
  • 當整個結構接近使用完畢的時候, Cuckoo Filter 具有更好的 Lookup 效能 (95% 空間利用率)
  • 比起 quotient filter 更容易實現
  • 具有 False Positive Rate 比 Bloom Filter 更小 (< 3%) 並且具有更少的空間使用率

與其他結構的比較一覽:

(image from paper “Cuckoo Filter: Practically Better Than Bloom”)

這一張列表清楚列出 Cuckoo Filter 的優點.可以看得出來, 以下稍微做個條列式:

  • Bloom Filter 與 Blocked Bloom Filter 都不知元 deletion (指的是動態支援)
  • Counting Filter 需要到 3~4 倍左右的空間成本.

原理:

Cuckoo Filter 的原理相當簡單:

  • 透過 footprint 來計算每個資料的特徵值(作為插入節點用得值),再次要注意一下, footprint 的存在使得 Cuckoo Filter 的 loopup 效能相當的快.
  • 當要插入的 bucket 已經有值的時候,就會學 Cuckoo 把原先的鳥踢出去依樣. 將原先的數值踢走,該數值再透過另外的 hashing function 找到下一個位置.如果又有人,就把它踢掉.(以此類推)
  • 如果踢走元素的次數,超過了自定義的 MaxCount .代表整個資料已經滿了,還是需要增加節點,重現建構.

缺點:

還是有一些缺點,可以分享一下:

  • 由於進行 XOR 的運算,使得 Filter 個數必須為 2 的整數次冪(也就是 2 的某個次方數)
  • 儲存 footprint 在 filter 內當作該數值的特徵值,雖然有一些好處.但是也多了另外一個方面的碰撞機會而造成 false positive

Source Code

這裡有寫了一個簡單的範例,當然我推薦看看這個很棒的範例

Reference

[TIL] Kubernetes all traffic between pod or between pod to node are drop

Symptom:

  • Service/Pod could create success, but could not connect to pod.
  • Could not connect to another pod in another node (even in the same node)
  • All kubectl status works well
  • Your docker is newer than 1.13 (it works well if your docker version is 1.12)

It will happen on “kubeadm” but not happen in “minikube”.

Diagnosis:

Check iptable rule.

sudo iptables-save

-A INPUT -j KUBE-FIREWALL
-A FORWARD -j DOCKER-ISOLATION
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -
j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j DROP
-A FORWARD -i docker0 -o docker0 -j DROP
-A OUTPUT -j KUBE-FIREWALL
-A DOCKER-ISOLATION -j RETURN

As you could observe “A FORWARD -i docker0 ! -o docker0 -j DROP

Root cause:

Refer to moby issue 40182 (still not resolve until kubernetes 1.8)

Solution:

  1. Downgrade to docker v1.12.x
  2. Add iptable forward rule to all (not suggest)
    • sudo iptables -P FORWARD ACCEPT
  3. Start every container with docker --iptables=false (not easy when you use kubernetes)

Refer great slide “All The Troubles You Get Into When Setting up a Production-ready Kubernetes Cluster” by Jimmy Lu

Reference: