May
20th,
2015
##前言: 本週進入第二個禮拜,開始有一些分散式系統的備份與替換的問題還有論文. 加油吧!! MIT 6.824 分散式系統 系列文章 6.824: Distributed Systems [MOOCS][Golang]MIT6_824 Distributed Systems Week2(Lec2/Lab2A) [MOOCS][Golang]MIT6_824 Distributed Systems Week2(Lec2/Lab2A) [MOOCS][Golang]MIT6_824 Distributed Systems Week2(Lec2/Lab2B) [MOOCS][Golang]MIT6_824 Distributed Systems Week3- About Paxos Algorithm [MOOCS][Golang]MIT6_824 Distributed Systems Week4- 關於Consensus協定 Raft 學習(一): 簡介,資料格式與領導者選舉 ##第二週課程: ##關於筆記 Primary/Backup Replication (Remus) 盡量用理解後的中文紀錄,原始筆記在這裡: 關於容錯(Fault Tolerance): 希望能繼續服務儘管有問題發生. 特性如下: 可見性: 即使有問題發生,也希望服務能夠繼續. 正確性: 希望發生問題的時候,服務也跟單機一樣(無錯誤時)正確. 核心想法: 備份,透過兩個或是以上的備份伺服器來預防任何的問題產生. 重要問題: 備份機的狀態? 工作機的狀態如何轉移? 何時要切開與備份機的連接? 異常發生在切開之後? 如何修復與重新連接備份機? 兩個關於備份機的重要動作: State Transfer (狀態轉移) Replicated State Machine: (備份狀態機) ##論文 Remus: High Availability via Asynchronous Virtual Machine Replication 這裏有網頁版本 Remus 的系統特色: 整個系統備份 對於Application與Client而言是透明的. 當運行成功的時候,備份與切換機器就運作順暢 圖片元素解釋: Primary: 具有資料,會執行OS與App,並且負責跟Client溝通. Backup: 只有資料,但是不執行OS與App.只有跑一些Remus的code 流程簡介: (1) Primary 跑完 Completed Execution (E1),並且先不回傳E1結果回client. (2) Primary把結果備份到Backup (背景執行) (3) Backup同步所有目前資料跟Primary一樣. (4) Primary 執行Speculative Exection (E2),並且先不回傳給client (5) Backup 複製所有結果 (6) Primary放出E1結果 (7) Backup 把結果存入RAM/Disk. Remus 特性與檢討: Remus系統的估計 速度為單機系統的1/2~1/4 Check point時間過久 為了要能夠與client溝通,保留結果的時間不能太久 缺點 速度不快: 由於每個Exection都必須等待Backup 複製好相關資料。 Check point 至少等花上100ms 如何改善: 減少主機儲存資料 減少狀態的資料量,或是優化資料格式 試著傳送指令而非狀態 ##關於Lab2 Part A:ViewService 這一篇有點困難,所以稍微做點筆記: ###題目解釋: 主要要implement 一個具有faul-toerant的key/values services- Viewservice.這個Service有以下的幾個功能: 監控 Primary (指的是原始service) 與 Backup(備份用的Service)是否是正常工作. 正常而言,如果Primary壞了,會自動地把Backup promoted成 primary.此時如果有空的server就會拉近來變成新的Backup. 當新的Primary與Backup上線後,Primary還有一個工作: 備份所有資料庫給Backup 所有的command...
繼續閱讀
May
14th,
2015
##前言:
主要是Golang.Tw上面有人在問,加上這門課程的作業本身是使用Golang來開發.就還蠻有興趣玩玩看.
課程鏈結在這裡.6.824: Distributed Systems
MIT 6.824 分散式系統 系列文章
6.824: Distributed Systems
[MOOCS][Golang]MIT6_824 Distributed Systems Week2(Lec2/Lab2A)
[MOOCS][Golang]MIT6_824 Distributed Systems Week2(Lec2/Lab2A)
[MOOCS][Golang]MIT6_824 Distributed Systems Week2(Lec2/Lab2B)
[MOOCS][Golang]MIT6_824 Distributed Systems Week3- About Paxos Algorithm
[MOOCS][Golang]MIT6_824 Distributed Systems Week4- 關於Consensus協定 Raft 學習(一): 簡介,資料格式與領導者選舉
##第一週課程:
###Paper1: 鼎鼎大名的Google Mapreduce 論文:
課程內容主要是要讀鼎鼎大名的mapreduce系統論文.
###Lab1: 寫一個簡單的Map跟Reduce
然後來寫一個Lab1 Word Count的小程式.裡面主要要完成兩個functions:
Map: 把文章裡面的字拆出來後,放入一個List. List 裡面的內容是文字與出現的次數.
Reduce: 就每個檔案裡面的所以出現單字找出來,並且回傳它的加總.
課程算很簡單,主要是要對於mapreduce有基本的了解.我一開始不是很了解,比對了參考文章內的內容跟論文演算法就看懂了.
其實還挺有趣的. 寫完裡面還有go test 可以去驗證你的想法有沒有問題.
###簡單介紹RPC
第一週後半段其實還有一部分是RPC的部分,還好最近有點研究.所以也很快地讀完筆記.
主要講解內容如下:
什麼是RPC Server.
RPC 架構下會有什麼問題? (斷線,命令未收到,命令未完成)
如何解決:
“最少一次”:
優點: 可以確認server有執行到.
使用範圍:
可以用: 重複性質的讀取
不能使用: 存款
“最多一次” (Go RPC就是這種)
會把重複的需求挑出來,直接回答上一次的結果而不是再跑一次.
怎麼分辨是不是重複: 透過unique ID.
Lab2 要玩這部分.
“剛好一次”:
也就是最多一次的系統加上unbounded retries跟容錯設計.Lab3要玩這個.
Go thread:
何時使用Go channel 何時使用 shared memory + lock:
Channels: 確定要兩個thread互相溝通,一個等待另一個回傳.
Shared memory + locks: 需要共用資料,但是不需要等待另一個結果.
##參考文章:
關於MapReduce的Invert Index
繼續閱讀
May
12th,
2015
Steps
Connect to Apple iTune
// iOS Http code
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters addEntriesFromDictionary:[credentials dictionary]];
// receipt is an object of my own making, but base64String just returns an
// NSString representation of the receipt data.
parameters[PURCHASE_RECEIPT] = [receipt base64String];
NSURLRequest *request =
[[AFHTTPRequestSerializer serializer]
requestWithMethod:@"POST"
URLString:urlString
parameters:parameters];
AFHTTPRequestOperation *operation =
[[AFHTTPRequestOperation alloc]
initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
<snip>
[operation start];
// Json data
{"status":0,
"environment":"Sandbox",
"receipt":
{"receipt_type":"ProductionSandbox",
"adam_id":0,
"bundle_id":"<snip>",
"application_version":"1.0",
"download_id":0,
"request_date":"2013-11-12 01:43:06 Etc\/GMT",
"request_date_ms":"1384220586352",
"request_date_pst":"2013-11-11 17:43:06 America\/Los_Angeles",
"in_app":[
{"quantity":"1",
"product_id":"<snip>",
"transaction_id":"1000000092978110",
"original_transaction_id":"1000000092978110",
"purchase_date":"2013-11-12 01:36:49 Etc\/GMT",
"purchase_date_ms":"1384220209000",
"purchase_date_pst":"2013-11-11 17:36:49 America\/Los_Angeles",
"original_purchase_date":"2013-11-12 01:36:49 Etc\/GMT",
"original_purchase_date_ms":"1384220209000",
"original_purchase_date_pst":"2013-11-11 17:36:49 America\/Los_Angeles",
"is_trial_period":"false"}
]
}
}
Reference
Validating Receipts With the App Store
iOS7 - receipts not validating at sandbox - error 21002 (java.lang.IllegalArgumentException)
Validate Mac App Store receipt server side
Validating iOS In-App Purchases With Laravel
繼續閱讀
May
11th,
2015
##前言 為了要寫一個Web Service但是有可能會發生以下的需求: 不同Server,有不同的設定參數 不同的OS有不同的command set 想要快速的開啟或是關閉debug log 在有以上的需求的時候,一開始都是使用OS偵測或是configuration file來區隔.但是到後其實是希望能透過不同的build config能夠產生不同的binary. 決定研究了一下: go build 有以下兩種方式可以達到部分的效果. ##Go build -ldflags 這可以在go build的時候,先設定一些變數的名稱.通常我自己比較習慣透過OS環境變數來設定,然後程式裡面再去讀取. 在你的主程式裡面,可以先定義一個變數flagString: package main import ( "fmt" ) var flagString string func main() { fmt.Println("This build with ldflag:", flagString) } 透過外在go build來設定這個變數 go build -ldflags '-X main.flagString "test"' 這樣你的結果會是 >> This build with ldflag: test 這個方式可以直接設定參數,讓initialize value透過外部設定來跑. ##Go build -tags 透過go build -tags 可以達到加入不同的檔案在compiling time.由於這樣,你能夠放在這個檔案裡面的東西就有很多.可以是: 不同系列的define (達到ifdef的效果) 不同的function implement (達到同一個function 在不同設定下有不同實現) 以下增加一個簡單的範例,來達到不同的build config可以載入不同的define value. file: debug_config.go //+build debug package main var TestString string = "test debug" var TestString2 string = " and it will run every module with debug tag." func GetConfigString() string { return "it is debug....." } 請注意: //+build debug 前後需要一個空行(除非你在第一行) 另外,我們也有一般的設定檔 release_config.go //+build !debug package main var TestString string = "test release" var TestString2 string = " and it will run every module as no debug tag." func GetConfigString() string { return "it is release....." } 最後在主要的main裡面,可以直接去參考這兩個define value...
繼續閱讀
May
6th,
2015
(pic: source from here) 以上的圖是利用Redis 達到 Message Queue 的方式,也是Disque要達到的事情. ##前言 這一兩個月,比較常聽到大家討論的就是Disque的使用方式與疑問.本來我對於Message Queue的系統(尤其是backend那一塊)比較不熟.於是還是花了一點時間把Disque裝起來,並且把sample code跑了一下.希望對於基本架構有一些了解. ##關於Disque Disque 是 Redis原作者Salvatore Sanfilippo根據大家在Redis上面針對Message Queue處理的部份來加強,並且下去拿Redis的source code加以修改,改造出這套專門處理Message Queue的系統. 主要特色如下: (參考這裡) 消息發送可以選擇至少一次或者最多一次。 消息需要消費者確認。 如果沒有確認,會一直重發,直至到期。確認信息會廣播給擁有消息副本的所有結點,然後消息會被垃圾收集或者刪除。 隊列是持久的。 Disque默認只運行在內存裡,持久性是通過同步備份實現的。 隊列為了保證最大吞吐量,不是全局一致的,但會儘力提供排序。 在壓力大的時候,消息不會丟棄,但會拒絶新的消息。 消費者和生產者可以通過命令查看隊列中的消息。 隊列盡力提供FIFO。 一組master作為中介,客戶端可以與任一結點通信。 中介有命名的隊列,無需消費者和生產者干預。 消息發送是事務性的,保證集群中會有所需數量的副本。 消息接收不是事務性的。 消費者默認是接收時是阻塞的,但也可以選擇查看新消息。 生產者在隊列滿時發新消息可以得到錯誤信息,也可以讓集群非同步地複製消息。 支持延遲作業,粒度是秒,最久可以長達數年。但需要消耗內存。 消費者和生產者可以連接不同的結點。 ###優缺點與比較: 優點其實蠻容易被瞭解的: 容易安裝使用,而且小.本身就有資料庫(類似 redis) 當不需要太複雜的傳輸格式與介面的時候,disque效能應該不差 (base on Redis v.s. RabbitMQ) 幾個缺點,可能需要注意: disque 目前還是alpha disque 目前只有單線程 關於與Kafka的比較,Salvatore Sanfilippo在他的推特有以下有趣的回應: Salvatore Sanfilippo: Disque VS Kafka is the new Redis VS PosgreSQL which was the new Apple VS Orange :-) ##安裝與使用 ###安裝與使用Disque git clone https://github.com/antirez/disque make make test (make sure port and compiling result success.) cd src run disque-server ###簡單的操作 當你跑disque之後,就會自動連接local disque server. //Add a job by producer ADDJOB job1 "This is sample job1" 0 #create job1 with comment ->DI3b2954204f8f86168198266221515fb011a1eea005a0SQ #server response task id. //Get a job by consumer GETJOB from job1 ->1) 1) "job1" ->2) "DI3b2954204f8f86168198266221515fb011a1eea005a0SQ" ->3) "This is sample job1" 透過Golang 來測試job-queue 主要是使用go-disque的source code 來當作job-queue 的機制. 以下有三段程式碼,分別是兩個worker跟一個發送者,發送者(disque-enque)會發送兩個訊息排程給disque,當worker上線或是開始抓取訊息後,就會執行該訊息定義的事項. 主要程式碼並沒有做太大修改: Worker(Consumer 消費者): Downloader :...
繼續閱讀
April
23rd,
2015
給自己做個筆記….
關於 Heroku
以下指令都需要安裝Heroku Toolbelt後登入Heroku. heroku login
查詢Server 目前的log: heroku logs -t 其他更多指令在這裡
Heroku App/Worker crash如何重啟: heroku restart web.1 更多指令
如何在Heroku上面快速的rollback: 到control panel 下 [activity] 選擇你要的change旁邊有[roll back to here].
Performance Status: 可以透過add-on Librato來監測你目前在Heroku的webapp.
關於Golang
Golang 的scope是依照package,所以同目錄下面的檔案,只要package一樣都會被歸在一起.
init() 跑的順序是依照 alphabet axxx.go bxxx.go …… zxxx.go
關於go import 更多使用要看這(好像是FAQ)
import _ “xxx”: 代表的是使用 Init 但是不把整個package 套進來(不會有compiler error if no use)
import . “fmt”: 打所有function 不用加上namespace
import m “fmt”: fmt.Println 變成 m.Println
參考資料
Stackoveflow: heroku - how to see all the logs
Heroku: What to do when your dyno/worker crashes?
Heroku: Releases and Rollbacks
繼續閱讀