2016年10月23日 星期日

Apache Traffic Server & Varnish Cache 之我見. (Part 1)

最近因為任務需要,需要自己弄一套 proxy/cache 的系統。

至於為什麼要自己弄?

  1. 當地國際頻寬貴,如果能在當地弄一份 static replica,可以省下很多錢。
  2. 但是在偏遠的地方自己弄 storage,光想營運成本就很高,尤其每樣都要做 HA 的時候,成本跟硬碟幾乎都是一路 * 2 * 3 上去。
  3. 既然不能搞 storage,那弄一份 cdn 總可以吧,基本上解決 20% 的 content,就省掉了 80% 的 cost。
  4. cdnetwork 之類的,幾乎都沒有在當地有 edge server。
  5. 所以即使用了 cdnetwork,還是要走國際頻寬出去,一樣貴。
原本想像中的架構如下:
  1. 最前面擋台 l4 load balancer,將流量 round robin 散到下面的 l7 load balancer 上。
  2. l7 load balancer 理論上會用 Apache Traffic Server 加上自己寫的 plugin,將前面進來的 request,透過 consistent hash 算過之後,平均導到後面的 storage 上面。
  3. consistent hash 只是個說法,重點是每台 l7 load balancer 自己要維護一份後面的 storage 的健康狀況表。
  4. storage 相對起來簡單,但是要能根據後面 Origin Server 的不同產生不同的 header 之類的,例如如果 Origin Server 是 S3,要能自動生出 s3 request header。
  5. 這樣做的好處在於,如果其中一台 l7 load balancer 壞掉,起碼有一台可以撐住。而後端的 storage,也會因為 l7 load balancer 已經用 consistent hash 算過,固定的 url 會送往固定某台,cache hit rate 會拉高,Origin Server 假設是 300T 好了,每台 storage 基本上可以只是部分就好,一旦任意一台 storage 壞掉,起碼可以先將 request 由隔壁來分擔,而不是全部養好的 cache 就全部掛光。





























剛才講到會用 Apache Traffic Server 來實做這些東西,為什麼呢?

  1. 畢竟我也是 ex-yahoo 呀。
  2. 畢竟我也摸了好一陣子的 yts & uff 呀。
  3. 畢竟我也是受到業界知名的嫩哥的薰陶。
Consistent Hash 就用 google 提出的 Jump Consistent Hash,而後端機器健康程度,要就是 plugin 自己開個 thread 定期去維護,不然就是透過 lmdb or mmap file 之類的,讓另外一支程式來幫你維護。

plugin 寫了一半,看到其實 Apache Traffic Server 有 cluster 的功能,看起來大方向其實跟我想做的雷同,只是方法不同。
ats cluster 的做法是,根本不分 l7 load balancer 還是 storage,全部都是 storage,只是一個 request 近來,會先查查自己肚子裡面有沒有 hit,沒有就發 udp multicast 出去問隔壁的有沒有人有 hit,有就直接抓來往 client 送。

諮詢嫩哥對於 ats cluster 的看法之後,他說 "cluster? 快要 deprecated 了呀" "現在你要用 carp 啦!"

carp 是什麼呢? 是 yahoo 針對這類的需求開發出來的一個 ats plugin,並且已經有送 pull request 給 ats 了,目標是在下一個版本的 ats 會包含這個 plugin。
想嚐鮮的可以先到 https://github.com/ericcarlschwartz/trafficserver/tree/TS-4723/plugins/experimental/carp 去查看。

既然 yahoo 都這麼有心,放出了方案給大家用,似乎不去試試看,好像還頗對不起 MM 的。

carp 光看設計,其實頗不錯的,health check 幫你做,也做 consistent hash,基本上我想要的他都做到了。很棒,立馬抓來 compile,load 進 ats 來試試看。

嗯嗯, 問題不大,最大的問題頂多是不會動而已!

對,他不會動,仔細查了一下相關的 code,寫法都是對的,但是他就是不會動!

好吧,一路追下去好了,TSContCreate,TSContSchedule,TSNetConnect 看起來每一樣都對呀!

不對,為什麼 TSNetConnect 裡面只要是 carp 要做 health check 的 connection,他就是直接不處理,然後最後等到 timeout?

喔,原來是 thread type 不對他就不處理呀!可是從頭到尾都沒有一個地方可以讓我自己決定要用哪種 thread 呀!

這個部分大概就卡了我三四天!!!

沒有留言: