[MOOCS][Golang]MIT6_824 Distributed Systems Week4- 關於Consensus協定 Raft 學習(一): 簡介,資料格式與領導者選舉

論文: Raft Paper

image

(這是Raft Consensus Algorithm 的展示工具Raft Scope)

MIT 6.824 分散式系統 系列文章

6.824: Distributed Systems

前言

持續學習MIT分散式系統課程的時候.學完了Paxos,接下來就要學習很多系統都有使用到的Raft系統. 這次一樣直接看Paper後,試著把整個邏輯實現出來.這裡先把演算法根據我瞭解的部分在記錄一下學習心得.

Raft介紹

這裏整理出一些關於Raft的介紹.

什麼是Raft Consensus

RaftPaxos一樣,都是為了讓多個log伺服器的備份機制所產生出來的溝通演算法.

不過,根據RaftPaper裡面提到的,為什麼會提出一個新的演算法.就是因為Paxos真的太難理解了(這裏引用的已經是簡化過的演算法,但是還是相當難理解).所以他們提出Raft演算法,並且針對兩個主要的目標:

  • 可理解性: 務必讓Raft的理論容易了解.
  • 容易實現: 必須讓整套系統是容易被實現並且是容易建置的.並且能達到所保證的效能.

Raft機制用在哪裡

如同前面說的,由於Paxos本身太過於困難了.所以Raft演算法在2014發布後迅速地成為許多分散式伺服器對於資料的同步協調最佳的應用. 以下列出幾個最近比較知名的伺服器架構:

  1. etcd: 相當知名的分散式key/value的資料庫
  2. cockroachdb被稱為是小強資料庫,不論有沒有連到Server都可以保證你可以使用.並且在連線後自動同步與協調相關資料.

這邊只挑出兩個最近比較紅的,其實還有相當的多. 基本上分散式資料庫近幾年都會採用Raft架構.

Raft主要關鍵:

在Raft系統裡面,主要分成三個關鍵的功能:

  • Leader Election (領導者選舉):
    • 這裏講的是關於領導者的選舉過程,還有其他角色(候選人, 跟隨者)如何轉換角色的過程.
  • Log Replication (資料複製):
    • 這裏提到對於log的相關記錄與處理方式,主要是要確保每一台伺服器的資料能夠精確同步而達到資料最少的遺失率.
  • Safty(安全性):
    • 透過Raft可以達到資料的準確性與資料可恢復性.

主要角色:

image

(圖片來自: Raft Paper,本圖主要講解三個角色關係切換示意圖)

再來要提到提到主要的角色:

  • Follower (追隨者): 基本上一開始每一台機器都被設定成為追隨者的角色.但是有一台收到來自狀態機的指令後,就會開始競選成領導者.
  • Leader (領導者): 主要接受來自於狀態機(在Raft中,狀態機就是我們的client,由狀態機發送每一個指令的log.透過Raft來達成多台同步的效果)
  • Candidate (候選人): 領導者不一定永遠都是完好的狀態等待狀態機的發送,某些狀況下如果領導者發生斷線或是系統出問題的時候.就會有一個跟隨者跳出來要競選成領導者. 相關的細項之後會提到.

關於資料結構(Log Structure) (ch. 5.3)

image

這裏先解釋一下,這一張圖主要表示的就是在多台Raft伺服器中,主要資料Log的儲存方式:

  • log index: 是一個流水號碼,代表你處理的的資料個數.
    • 產生的人:每個Server自己保留一份log index
  • term: 也就是在每個小方格上面的號碼,代表的是處理的第幾個指令集(複數個指令).
    • term的產生是由狀態機(state machine: 在這裏也可以說是client)產生出來的. 也就是說term是由 領導者收到後傳給每個跟隨者,而不是跟隨者自己產生的.
    • 這裏要注意的是一個指令集可能會有兩三個指令. 比如說 領導者的 Term 1: 就有 x <- 3, y <- 1, y <- 9. 但是他們代表的資料Index (Log Index各不相同)
  • operation: 也就是主要的log資料,代表的是Client傳過來的指令(單一個). 比如說是 x <- 3
    • 產生的人: 也是由狀態機(client)產生.

回過頭來解釋,這一張圖想要代表的意思:

  • 每個橫向代表著一台伺服器儲存資料的內容. 第一個為領導者,其餘都是跟隨者
  • 正常而言: 每一個伺服器的資料之間,如果term的數值是相同的,並且log index也相同就會認為兩個伺服器是相同的資料. 舉例而言, 領導者跟 跟隨者(2) (第三橫列)是相同的

關於資料的比對

兩個伺服器如何比較自己所擁有資料比較齊全呢?

這裏是先提到,基於這樣的資料結構,我們要怎麼說伺服器A所有的資料比伺服器B還要多,還要新呢? 以下這邊有一些原則:

  • LogIndexLogTerm組成伺服器本身的權重代表,擁有最多的LogIndex與最多的LogTerm就代表擁有教多的權重.
  • 比較上,會先比較LogTerm再去比較LogIndex

主要指令

Raft系統者要只有兩個RPC Call:

  • 一個是負責選舉領導者的RequestVote():
    • 主要是由候選人來發起.發送給所有的跟隨者來尋求大家的投票成為接下來的領導者
  • 另一個是負責傳遞資料的 AppendEntitries()
    • 主要是由領導者來發起,主要是管理Log Replicate的工作.
  • HeartBeat()負責領導者與`之間確認是否有存在的協定.
  • Request() 也就是由狀態機發送過來的資料,裡面存放著狀態機指令的log.

這邊只大概講解一下,這兩個RPC Call是做什麼的,之後每一個章節會透過這兩個指令將Raft整個系統兜出來.

領導者選舉 (Leader Election):

主要內容:

Raft 的領導者選舉,主要就是講解如何在跟隨者中讓某些人成為候選人並且順利的成為領導者的過程.由於一開始全部的伺服器都是跟隨者,有可能同時產生許多組候選人. 那麼如何要在這些候選人中挑選就是一件重要的事情.

啟動領導者選舉的時間點:

讓所有的Raft伺服器群組產生選舉的時間點,有以下幾個時機:

  • 一開始的時候,這時候每個跟隨者 權重(rank)都是相同的.只是看各個Server 何時送出訊息.
  • 領導者Hearbeat()指令間隔太久,這裡要提一下.根據論文,每個伺服器對於Heartbeat()的忍受時間間隔可以是不同的.這樣一來才不會造成一次有一堆跟隨者吵著要參加競選.

跟隨者 參加Leader Election 流程:

image

根據這張示意圖, 從跟隨者變成領導者的流程.我簡單地用條列式把該做的事情講一遍.

  • 根據剛剛提過的當跟隨者發現太久沒有收到Heartbeat()的時候,就會增加自己手上的term
  • 將自己角色由跟隨者轉換成候選人
  • 發送RequestVote()除了自己以外的跟隨者 (裡面會帶有候選人自身的termLastLogIndexLastLogTerm)
  • 等待每個跟隨者的回覆,如果同意的人超過大多數(就consensus algorithm裡面,”大多數”就剛好是 1/2m + 1其中m為總伺服器個數) 就將自己身份改成 領導者
  • 如果沒有成功,則等待這段的term時間過了,在來發送一次.

這樣的選舉機制會不會造成多人參選?無法選出領導者? 或是如何挑選出擁有最多commited log的候選人? 以下的部分會更詳細的解釋:

安全性 (Safety):

選舉(election)的限制 (5.4.1)

RequestVote 的限制與安全性

所有與具有領導者角色的溝通演算法中,領導者最重要的角色就是必須具有所以已經交付(committed)的紀錄(log). 所以如何讓選舉出來的領導者能具有越多已經交付的紀錄越好,就變得是重要的方式. 每個準備參與選舉的候選人必須要透過以下的方式來保證:

  • 每一個候選人必須透過RequestVote來顯示目前自己擁有最新(update-to-date)的紀錄.
    • 這邊使用的是RequestVote()裡面的lastLogIndexlastLogTerm來傳遞溝通.
    • 資料的比對上主要以lastLogTerm為主要比對項目.如果相同的時候,就會比對資料的總個數lastLogIndex
  • 跟隨者在回覆投票結果的時候,除了要回覆’贊成’或是’否決’外,還必須要回覆自己最新交付的紀錄(如果否決的話).

當候選人收到其他伺服器的要求

這裏有幾個例外可能性:

  • 如果候選人在發送RequestVote()的時候,忽然收到其他成為領導者的人送來的AppendEntitries()
    • 如果候選人收到的termlogIndex比自己高,這時候候選人就會轉回跟隨者的身份.
    • 反之,則候選人會繼續自己的選舉流程.
    • 最後有一種可能是都沒有候選人能夠獲得大多數的同意,所以等到time out之後就必須要重選.
  • 此外,如果候選人收到其他候選人的需求.這個時會有以下的狀態:
    • 兩個候選人會相互的比較權重(rank),這裡的權重就是前面有介紹過的LogIndexLogTerm的比較.透過這兩個數字可以比較出來哪位候選人比較有多一點的資料,也就是說獲得比較高的權重.
    • 比較低權重的候選人會轉換身份回跟隨者,而高權重的候選人會得到回應正確的投票(RequestVote()).

解決分散投票的問題

  • 每個跟隨者的time out都不相同,事實上每一個伺服器在起來的時候都會隨機從一個範圍中挑選自己的time out時間(舉例 150~300 ms).
  • 這個機制幫助我們在選舉機制裡面,大多數的狀況下只會有一個跟隨者先跳出來變成候選人並且順利地贏得選舉.

接下來:

接下來,我打算開始整理關於Log Replica部分的心得. 也順便會把一些pseudo code擺上來.

全部文章列表:

相關鏈結

[iOS][XCode][AutoBuild]建立XCode Build Script 來自動產生連接好的多平台Libraries

主要問題:

在iOS上面要編譯 C/C++ Static Library,除了有必要的轉換之外.最麻煩的大概就是先把多個平台iphoneosiphonesimulator的產出library透過lipo 結合成一個所謂的 fat library之後,在複製到某個地方.

但是在Windows VC開發已經習慣使用Post Build Process的我,當然在XCode開發上面也要找出一套自動的方式來幫我完成這件很蠢的事情.

解決流程:

建立一個Aggregate

透過編輯器 [Editor] -> [Add Target] 來建立一個Aggregate (記得之後要build就要選擇這個target). 至於選擇Mac 或是 iOS的沒有差異. 這邊只需要輸入一個target 名稱後就可以了.

建立一個 Run Script

image (圖片來自 Apple Developer)

如同上圖所示,在Target 選擇設定,選擇剛剛建立的Aggregate,然後到 [Build Phase]裡面去 點擊+ 來新增 “Run Script”

以下為範例的Build Script,主要是把專案”ABC”的Debug-iphoneos 跟 Debug-iphonesimulator 的輸出結合到另外一個目錄.

    xcodebuild -project abc.xcodeproj -scheme ABC -sdk iphonesimulator -configuration Debug
    xcodebuild -project abc.xcodeproj -scheme ABC -sdk iphoneos -configuration Debug
    
    # make a new output folder
    mkdir -p ${TARGET_BUILD_DIR}/../outputABC
    
    # combine lib files for various platforms into one
    lipo -create "${TARGET_BUILD_DIR}/../Debug-iphoneos/libABC.a" "${TARGET_BUILD_DIR}/../Debug-iphonesimulator/libABC.a" -output "${TARGET_BUILD_DIR}/../outputCCS/libABC.a"

當然,你也可以把檔案輸出到專案目錄下面,方便你以後管理.

衍生應用

你可以每次build的時候增加版本號碼,這是其他人比較喜歡用的. 可以參考這篇

心得與應用:

這一篇文章,主要就是讓Engineer可以簡單地透過Cmd + b來編譯一個特殊的Aggregate target來執行一堆本來是透過CI來跑的 Script. 這樣一來,Engineer可以邊修改,邊把相關檔案編譯出來. 而最後要導入CI的時候,該Aggregate target也可以直接拿來編譯.

參考文章:

[MOOCs][coursera]R-Programming 學習心得

image

前言:

主要是想了解一下,R-Programming 有什麼樣在大型資料處理上的優點.以及為何許多Data Science 都會選擇使用R作為資料處理的主要程式語言.

這一篇是一個月來的修課心得,主要整理一些自己的筆記.

心得:

學習玩 R Programming 會覺得其實R是蠻值得花時間學習的.個人提供一些心得如下:

  • R的資料型態很特別,很”資料導向”. 詳細可以參考這篇R資料格式教學
  • R對於資料的操作也很特別,尤其是對於data frame的操作思維是其他語言不容易見到的. 透過 row 跟 col 直接來尋找,取出並且操作.
  • 許多函數都相當的直覺,很適合初學者學習.比如說想找有幾筆資料就打nrow()想知道欄位名稱就打colnames(),要算平均就打 mean().也難怪聽說R都是一些數學很好但是可能是程式設計的初學者.

課程筆記:

第一週

課程內容:

本週課程內容主要是教導基礎的R-Programming,R的資料格式提供了不錯的資料處理能力.舉幾個例子來說:

  • vector 產生指令: c( ... )
    • 產生出的vector會變成同一個class,不同元素會採取比較寬鬆的class來包括
    • 如果你打 x <- c(1, 'a') 則會把全部元素轉成 character (包括 1)
  • list 產生指令: list( ... )
    • 跟vector不同,每個元素可以是不同class
    • 操作方式:
      • 給值: x <- list('a', 2, TRUE)
      • 取用: x[[1]] # 'a'
  • matrix 產生指令: matrix( ... )
    • 每一個元素都是integer
    • 可以直接給值 x <- matrx(1:6, nrow=2, ncol=3)
    • 也可以透過 cbind() (column bind) 或是 rbind() (row bind) 來組合出matrix

資料處理上,R 其實還挺方便的:

x <- list(10, 5, 7, 20, 1, 3)

// 找出 所有 x > 10
x[x > 10]

[[1]]
[1] 20

// 找出 x>10的index
which(x>10)

第二週

課程內容:

主要講解control flow (if, for, while …) 跟Function and scope. 主要提提scope:

  • Function中可以define function:

        #cube 裡面還有一個 function  n*n
        cube<-function(n){
             sq<-function() n*n
             n*sq()
           }
    
  • Free variables

      #指的是並沒有被清楚assign 的變數
        cube<-function(n){
             sq<-function() n*n
             n*sq()+y
           }
        
      # 這個例子裡面 y就是 free variables
    
  • Lexical scoping v.s. dynamic scoping

    • lexical scoping: free variables resolved to search when function were defined.
    • dynamic scoping: free variables resolved to search when function were called.

關於作業

  • 作業者要是寫一些function,難度都還算簡單.不過也能充分體會R在處理資料上面的強大支援.
  • lapply 的功能很強大,可以把要處理的function 丟進去

      #load_files <- number of file name
      # read csv files into tables vector
      tables <- lapply(load_files, read.csv)
    
      # get mean value of each table, and also remove NA
      lapply(total_tables, mean, na.rm = TRUE)
    
  • NROW(na.omit(one_data_frame)) 可以算出data frame裡面

  • 針對data frame 的建立,可以用以下方式丟進for裡面來處理

      #data_length 為某個特定的size
      index <- numeric(data_length)
      numbers <- numeric(data_length)
      for (i in 1: data_length) {
          index[i] <- i
          numbers[i] <- i + 5 #任意資料
      }
      ret_data_frame = data.frame(index, numbers, stringsAsFactors=FALSE)
    
  • 這裏有用到計算correlation的函式cor (細節參考),使用上記得要加上 use = "complete.obs"避免使用到空白欄位.

第三週

課程內容

  • 對於反覆要對每一個資料表執行的指令,可以透過lapply來執行.
    • 底層loop用C,可能會比較快?
    • 範例:
      • lapply(x_list, mean): 針對x_list的資料,做平均值.(所已lapply回傳也都為一個list)
  • apply不一定比for還快,但是打的字可以比較少 (? 講義裡面是這樣講的 XD)
    • 範例:
      • apply(x, 1, sum) 對x資料中的第一個維度處理”加總”.
  • mapply可以一次將函式套用到多個資料表中,可以用於套用多個輸入參數的函式套用.
    • 範例:
      • mapply(rep, 1:5, 5:1) 對於rep兩個輸入參數 第一個循序加入1, 2…5,第二個參數 5,4 … 1.
  • tapply更可以指定index 與資料還有其套用的函數
    • 範例:
      • tapply(x, f, mean)
  • split可以根據輸入的資料與索引來拆該原來的資料,通常會搭配lapply來找出資料.拆出資料會有點像Group By
    • 範例:
      • lapply(split(x, x$f), mean)
      • split如果透過一個維度來分割就是group by,也可以依照兩個維度來切, split(x, list(a, b)) 這樣會切出 a=1, b=1; a=1, b=2 …
  • 關於R Debugging
    • traceback()可以列出發生最近錯誤的最後幾行,沒有錯誤就沒有資料回傳.
    • debug(fx)可以試著去debug某些函式,方式有點像是gdb.可以一行一行跑(n) 然後查看資料.

關於作業

  • 要拆解資料,很多時候不一定要用split,也可以透過 data.frame來操作. 比如說 找尋某些資料表中 $a == “Good”的第二個欄位的平均.可以是: mean(data_x[data_x$a == "Good", 2])

關於Peer Assignment

關於範例的理解

以下講解是根據範例而不是作業解答:

     #函式 makeVector 會將輸入的數列回傳一份向量list
     #這份list 就像是 class一樣有以下功能
     # $get() 取得這份向量的cache
     # $set() 重新設定這份向量
     # $getmean()  取得這份向量的均值,注意預設是不會幫你計算.需透過setmean()寫入
     # $setmean()  寫入均值
     makeVector <- function(x = numeric()) {         
                m <- NULL
                set <- function(y) {
                        x <<- y      # (1) This writes x in global?
                        m <<- NULL   # (2) This writes m in global?
                }
                get <- function() x  # (3) Redefines get() locally?
                                     # (4) What does x do here?
                setmean <- function(mean) m <<- mean
                getmean <- function() m
                list(set = set, get = get,
                     setmean = setmean,
                     getmean = getmean)
        }

另外一個函式cachemean,解釋如下:

    #主要是將makeVector傳回的資料加以套入,如果沒有均值就會算出後加入裡面.
    cachemean <- function(x, ...) {
            m <- x$getmean()
            if(!is.null(m)) {
                    message("getting cached data")
                    return(m)
            }
            data <- x$get()
            m <- mean(data, ...)
            x$setmean(m)
            m
    }

看完可能一頭霧水,先看看要如何使用好了.

    #建立一個數列,由1,2,....25
    x <- seq(from=1,to=25,by=1)
    #將向量做出,指向z
    z<- makeVector(x)
    
    #注意,這時候無法直接取用 z
    #不過可以透過 z$get() , z$set(xxx), z$getmean() 與 z$setmean(xxx) 來使用
    
    
    z$get()
    # [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
    
    #如果要正常取得mean,需要以照以下的指令:
    cachemean(z)
    #[1] 13

這樣應該就瞭解該怎麼寫peer program的作業了.剩下的只有矩陣的操作.

關於矩陣(matrix)的操作
  • 建立一個矩陣:
    • x <- stats::rnorm(16)
    • dim(x) <- c(4,4)
  • 關於Inverse Matrix: 使用 solve(matrix_x)
  • 矩陣相乘: matrix_a %*% matrix_b

第四週

課程內容

  • 關於str()顯示資料的結構,summary()可以顯示資料本身的總結(軍職,最大,最小…等等).
    • 但是str()對於複雜的結構顯示上更加的緊湊容易了解.比如說顯示data.frame或是function.建議對於不了解的資料形式都可以適用str()來查詢.
  • 關於隨機產生數值的函式:
    • rnorm():產生隨機數值,並且可以指定由多少的均值來產生.
    • pnorm():根據某些給予的機率來產生隨機數值
    • dnorm():根據給予的密度來產生隨機數值
    • qnorm():根據分位數來產生隨機數值
  • 關於set.seed():
    • 可以設定亂數種子.注意,如果剛設定完亂數種子則拿到的亂數會與前一次剛設定好相同. 建議每次取亂數前都要設定,方便以後使用(重複使用或是取出不重複)

        set.seed(1)
        rnorm(1)
        // 0.18..
        rnorm(1)
        // 0.44..
              
        //重新設定
        set.seed(1)
        rnorm(1)
        //0.18..
      
  • 關於透過亂數帶入線性代數部分:

        //x 為100個常態分佈數值的亂數
        x <- rnorm(100)
        //設定y與x 的關係
        y <-3+5x
        //在圖形上畫點
        plot(x, y)
    
  • 需要在某些數值中取樣 sample(來源, 個數):
    • 需要20~50取五個亂數: sample(20:50, 5)
    • 將1~10以亂數以不重複的順序,取出直到取完: sample(1:10)
    • 抽十個會重複 sample(1:10, replace=TRUE)
    • 需要小寫英文字母中取五個單字: sample(letters, 5)
  • R Profiler(分析那些部分耗時):
    • 不需要在一開始考慮,先把事情做正確在做得快.
    • system.time() 可以產生某些函式耗時多久
    • 可以使用Rprof()來幫助你分析,不過一旦執行他會把每個含式都加以評估(會變更慢)
      • 透過 Rprof()開始,跑一些要測試的功能後,跑summaryRprof()看結果.

關於作業

一些需要注意的部分:
  • 型態轉換:
    • data.frame 讀進來可以都設定是character,但是資料得要好好的轉換才好判斷.
    • as.numeric()可以把字串轉成數字來取最小值min(),相反的要比較的時候記得要用as.character()轉回字串.
  • data.frame資料的擷取:
    • 想要做出select SQL語法的話,可能要經過以下的轉換…
    • data.frame[data.frame[,rol]=="VALUE", ] 可以挑出欄位rol符合 VALUE的data.frame
    • 如果只要挑選某些項目,可以透過data.frame[,rol] 來找出.
  • 刪選資料(Transform your source):
    • 一般而言,資料裡面可能會有NA的資料數值,但是這次的資料更奇怪.裡面有“Not Available”.這樣造成不論是轉換上或是判別上變得相當困難. 因為 is.na(“Not Available”) == FALSE
    • 轉換方式是建議先把不希望出現的資料清理掉.也就是一般人家說的Big Data ETL(Extract, Transform, Load) 中的Transform (也就是清理不需要的資料).
  • 資料型態轉換上的失真:
    • 很多時候對於資料轉換上,要小心有可能造成的失真.比如說: as.numeric("6.0") == 6 所以當你要回頭找資料的時候,可以建議先做一些轉換sprintf("%1.1f", 6) == "6.0"
  • 關於資料排序(order):
    • 排序其實就還挺簡單的,主要就是使用order()來排序.唯一比較需要注意的是,由於order()提供字元與數字排序法,但是兩者的排序邏輯是不同的,記得要把數值先轉回數字(numeric)而不是拿到文字(character)來使用.
    • 在排序的時候要注意,其實可以依照兩個欄位來排序.比如說透過欄位13來遞增找,又可以透過欄位2來遞減. dataf[order(dataf[,13], -dataf[,]), ]
關於 swirl

這其實是使用swiri的教學課程,裡面有15段R Programming的基本教學課程.有點多,不過依照指示可以有完整的了解.

不過總共有15段課程其實還真不少,大概也得花個一兩個小時不斷的看才看得完. 要注意修業時間是否趕得上….

參考鏈結

[新聞與心得]微軟開源winobjc

本日最紅的github (不到24h 超過2000+ star),莫過於微軟的winobjc,玩了一天分析一下:

###先講結論:

####想使用的話.. 還不用急著用.. 除非你想幫微軟土炮iOS 所有foundation XDDD

  1. 首先這是一個把你的iOS App ObjectC的code 透過vsimporter轉出一個 VS solution.然後透過VS2015 的clang compiler 編譯成 Windows Universal App (or Windows Phone App)
  2. 你能想到的 UIKit AVFoundation 都是土法透過DX11自幹出每一個功能(reverse engineering)… 所以要開源請大家一起幫忙土炮 3.除了github 上面提到的一狗票還沒成功之外,其實就算是UIKit 也有很多基本的class功能也都沒有土炮出來.. 更複雜的BLE 跟Map當然也都還沒有 (等你幫忙XD,有人說.. 路還很遠)
  3. License 採取MIT不過不少人看到裡面的程式碼都是copy & paste 很多其他的人的心血 BigZaphod/Chameleonmono/CocosSharp .. 應該有更多….
  4. 根據微軟說的.. 這部分的核心 clang compiler 不會 open source XDDDD

參考資料

[Golang]透過brew來做Golang的版本切換

前言:

本來想在Mac OSX上面使用gvm來管理Golang 的版本切換,主要是因為想切到 Go 1.5 beta來玩玩新東西.

不過昨天去GTG聚會之後,學到brew switch之後,覺得整個很威啊… 這裏把幾個筆記記錄一下:

###指令集:

使用brew安裝Golang

    //把brew的fomulae更新到最新版本
    sudo brew update

    //使用brew安裝Go
    brew install go

更新版本

    //拿目前最新版本 Go 1.5 beta3 舉例
    brew upgrade go -v=1.5beta3 --devel
    
    //注意.. 就的版本 Go 1.4.2  不會從你的brew位置移除
    //可以查詢
    brew info go:
    
    
    //目前系統有安裝兩個版本.... 使用的是1.4.2
    go: stable 1.4.2 (bottled), devel 1.5beta3, HEAD
    Go programming environment
    https://golang.org
    /usr/local/Cellar/go/1.4.2 (4584 files, 276M) *
        Poured from bottle
    /usr/local/Cellar/go/1.5beta3 (5357 files, 277M)
        Built from source
    From: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/go.rb

切換版本

    //使用brew switch來切換        
    brew switch go 1.5beta3
    
    //螢幕顯示
    Cleaning /usr/local/Cellar/go/1.2.1
    Cleaning /usr/local/Cellar/go/1.4.2
    Cleaning /usr/local/Cellar/go/1.5beta3
    3 links created for /usr/local/Cellar/go/1.5beta3
    
    
    //如此就可以切換.... 不過檔案不會移除

反安裝版本

    //使用brew uninstall
    brew uninstall go
    
    //只會移除目前使用的版本... 不過由於原本目錄沒有指向新的,所以功能都無法使用
    //將目前使用的版本切換到 1.4.2
    brew switch go 1.4.2 

可能會發生的錯誤

切換Go版本,然後跑go build可能會發生以下的錯誤:

    package .
    	imports runtime: C source files not allowed when not using cgo or SWIG: atomic_amd64x.c defs.c float.c heapdump.c lfstack.c malloc.c mcache.c mcentral.c mem_darwin.c mfixalloc.c mgc0.c mheap.c msize.c os_darwin.c panic.c parfor.c proc.c runtime.c signal.c signal_amd64x.c signal_unix.c stack.c string.c sys_x86.c

解決方式(solution for “C source files not allowed when not using cgo or SWIG”):

這裏提供我的解決方式:

  1. 刪除 %GOPATH%下的pkg資料夾
  2. 重新開啟 console 或是確認 go env有讀到正確 go 1.5的設定.

##心得

gvm主要是給Ubuntu(linux-like)來管理Golang版本套件的.既然是Mac OSX就要用最好使用的homebrew

搞定 brew switch 切換Go 版本真的是很方便… 不過c-shared MAC也沒有 想玩還是有點麻煩… 還是在Win上面弄docker玩…

[研討會心得][GTG14][Golang]第十四次的Golang Taiwan聚會

前言

小孩出生後難得可以參加研討會GTG#14,主要也是想看看Go 1.5的一些新功能介紹.

第一階段: tka - 用 Golang 幫 Ruby 加速

筆記:

  • buildmode=c-shared:
    • 啟動版本: Golang 1.5 beta2
    • 環境: linux / android (win/mac 不支援)
  • 資料結構不同:
    • GoInt8 -> signed char
    • GoString -> char *p, int length
  • Ruby FFI:
    • ruby package to load dynamic libraries.

呼叫方式:

    require 'ffi'                                                                                                                           
    require 'benchmark'                                                                                                                     
                                                                                                                                            
    module LibGo                                                                                                                            
      extend FFI::Library                                                                                                                   
      ffi_lib './libgo.so'             
      //               (fn) (input) (output)                                                                                                     
      attach_function :fib, [:int], :int             
    end  

效能比較

  • 簡單功能 Ruby > golang 五倍
  • fibinacci Golang > Ruby 二十倍

參數挑選

  • 使用GoString 與 使用C.String
    • 結果:
      • C.String 會比較快
    • 原因:
      • Ruby 轉 Golang string 需要配置兩個參數 (char * 與 length)

Q&A

  • C-Shared GC
    • Not tested yet.
  • C++ binding with Go
    • 速度應該沒差

其他:

有介紹到的golang Language package看起來很好用

第二階段: 用 Go 寫前端, GopherJS 優劣分析

Slide:

Full-stack go with GopherJS from Poga Po

筆記

** Fullstack Go**

  • GopherJS
    • Goroutines works in JS
  • JS s signle-thread
    • GopherJS provide roroutine scheduler.

Examples:

  • DOM
  • Callback

效能:

測試五千個goroutine來選轉圖片是可以接受.

Gocha

  • No dead code elimation
    • Use js not fmt to reduce size.
  • Callback should not block
    • JS is single thread. (main thread)

會後心得:

  • 使用brew 來管理Go版本,好像很酷

參考資料: