上一篇忘了講,大部分的人弄 proxy,架構應該都是像下面這樣弄的:
流量由 l4 load balancer 導入,可能用 round robin 或者是一般的 hash 將流量散到各台去,這樣會有幾個問題可能發生:
- 如果是 round robin,任意一個 url 都可能導到任意一台,假設我有 100 台 storage,如果很不幸的每次都是導到沒有 cache 的某台 storage,這樣對 Origin Server 就是一百次的 request,並沒有真的解決問題。
- 如果是用一般的 hash,全部的機器都健康的時候,hash 都維持得很好,cache hit 也可能都會不低,但是一但某台機器掛點,會重新 re hash,原本養的 cache 全都報銷了。
再講回 Apache Traffic Server,其實它源自 Inktomi 的 proxy server,設計精良,當年被 yahoo 併購之後,yahoo 只看到 inktomi 的搜尋部分業務,其他的東西都被冷凍起來,後來有人挖寶之後,發現了 inktomi proxy server,一用之後驚為天人,轉身變成 Yahoo Traffic Server,並且大量部署在 yahoo cdn 上。
不過後來可能因為政策改變,yahoo 內部自行研發了 uff 這套原本想要取代 yts 的 proxy server,所以將 Yahoo Traffic Server 在 2009 年捐給 Apache Project,原本一些在內部做 yts 研發的人員,大部分也同時成為 apache committer 來改善 Apache Traffic Server。
後來的後來,由於 uff 最主要的開發者離職,Apache Traffic Server 在 open source 社群中大量被改善效能,原本只能跑在 32bits 的環境,也改成對 64bits 相容。所以後來 Yahoo 又將 cdn 相關的 solution 改回來 Apache Traffic Server。
剛才講到 Apache Traffic Server 設計精良,內部對於 thread/event/network 都有各自的 processor,像是 carp 做 health check 的部分,就是丟給 event processor,然後會去呼叫 thread/network 相關的 processor 做更低階的處理,最後再透過 callback 之類的將最終狀態丟回原本的 caller。
讓我整個卡住的部分,其實就是在這邊,怎麼樣看,他都應該幫我開一個 tcp connection 出去,但是程式判斷的地方,他會先判斷 thread event type,如果不是他要的,就直接不處理,等到 event timeout 之後,就會去 callback 原本的 caller 來做後續的處理。可是我找不到任何的地方去決定 thread event type 呀!!!
因為我的 c++ skill 實在太差,在卡住三四天之後,覺得這樣下去不行,雖然手上有最終解決方案,就是 Apache Traffic Server cluster,但是終究是要 deprecated 的東西。所以我就開始找尋下一個替代方案,nginx 不行,因為 proxy mode 比較厲害的東西都被放在 nginx plus 裡面。那 varnish 呢?以前稍微試用過的經驗並不好。不過市面上可以用的 proxy 幾乎沒有了,每一套宣稱自己多厲害多厲害的 proxy,終究就只是很單純的 proxy,很多連自己對 client request/response, origin server request/response 都沒辦法額外處理。更不要講 performance 了。
在抱著試試看以及捧個人場的心情下,試用了一下 varnish cache,為什麼說捧個人場?因為 varnish 是 phk@freebsd.org 最近這十年來的力作,他幾乎都沒有再碰 kernel development,全心全力的做 varnish cache 的開發。
varnish cache 有下列幾個我覺得很棒的地方:
- bsd-2 clauses license,去他媽的 gpl。
- 沒有設定檔,一些參數都用 cli 方式傳進去,然後如果不會寫 vcl 也沒關係,backend server 相關資訊一樣可以用 cli 傳進去。
- vcl 很簡單,會寫簡單 perl 的人都會。
- vcl 不是直譯式處理,而是在 start-up 的時候,直接轉譯成 c code,馬上 compile 成 .so,varnishd load .so 起來處理,只要專心做好自己想要判斷的事情就好,memory leak/performance issue 等相關的事情完全不要理會。
- builtin vcl function 不夠用的話,可以自己寫 vmod 來擴充 function。
- log 什麼鬼的,varnish 全部都扔到 shared memory 去,另外有一隻 varnishlog 會從 shared memory 讀資料之後寫黨,所以什麼 log rotate 之類的事情,不用 kill -HUP varnishd,服務完全不會中斷。
- reload vcl 之類的也是可以 online 做,一樣服務不會中斷。
- 相關的 utility 做得非常好,varnishadm/varnishstat 之類的,幾乎都是商業等級的水準。
- 內建 health check,可以做到失敗幾次才會算真的失敗這類的情境。
- 支援各種 director,可以簡單應付各種場景。
- fallback
- hash
- round robin
- random
- shard
不過 varnish 現在對我而言有一個瑕不掩瑜的缺點,雖然這個也可以用另外的程式做掉,但還是會覺得有點不舒服,那就是,他不支援 ssl,https 之類的要自己處理,這對於之後的 ios 可能會是個問題。
總之,varnish 算是簡單就達到我想要的功能,理論上會直接拿來使用。而 Apache Traffic Server 也不是完全沒有優點的,只是不會寫他的 plugin 的話,出廠預設的功能,其實是很難滿足需求。