可以做個小實驗,弄個 signed url 出來,再對它做 HTTP HEAD:
qty:~ qrtt1$ curl -v -I -X HEAD 'https://s3-ap-southeast-1.amazonaws.com/qty.tmp/e9e3acb6029562f3d69f095261927974.tgz?X-Amz-Date=20150330T204136Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=d4414cbefd5bd56849c72eb48cd1afc8a99c5ac44aa9d31f91f1a0199fd2e22d&X-Amz-Credential=ASIAJSCVIGYRJA5YJNBA/20150330/ap-southeast-1/s3/aws4_request&X-Amz-SignedHeaders=Host&x-amz-security-token=AQoDYXdzEE4agAIuZA1qmnpim80oIvcP0N7h78BrNwItM9vkB2Xbez6S1zoxTDHMs1FFh%2B5Hl86JctsglYJj3wYn75i0XM8c15xdMoa53Eax7khC1jFUHR9aaEVj0TNLRdsYKxf53SacgwNE8SHERy1mN2gBgYOjNRJGnSgFJtvQpb9Qd553NnGjJTJjaI2w1TpQ8/zeDWHbzxY8J7RsdfOy0j81GHfiz/lX%2BMXHGKNlVxd1%2BdkTR31sve09RvnUqmsFNC4VaAcpOPQngyiEJTZRGSRa3/eT7hdlSNkdx40Zz02qoRfryrypx7sYxEi1ka7KTxQw5wND9lfZDK70ijPglOZ1q55Fc48oINfp5qgF'
* Hostname was NOT found in DNS cache
* Trying 54.231.241.112...
* Connected to s3-ap-southeast-1.amazonaws.com (54.231.241.112) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate: *.s3-ap-southeast-1.amazonaws.com
* Server certificate: VeriSign Class 3 Secure Server CA - G3
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> HEAD /qty.tmp/e9e3acb6029562f3d69f095261927974.tgz?X-Amz-Date=20150330T204136Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=d4414cbefd5bd56849c72eb48cd1afc8a99c5ac44aa9d31f91f1a0199fd2e22d&X-Amz-Credential=ASIAJSCVIGYRJA5YJNBA/20150330/ap-southeast-1/s3/aws4_request&X-Amz-SignedHeaders=Host&x-amz-security-token=AQoDYXdzEE4agAIuZA1qmnpim80oIvcP0N7h78BrNwItM9vkB2Xbez6S1zoxTDHMs1FFh%2B5Hl86JctsglYJj3wYn75i0XM8c15xdMoa53Eax7khC1jFUHR9aaEVj0TNLRdsYKxf53SacgwNE8SHERy1mN2gBgYOjNRJGnSgFJtvQpb9Qd553NnGjJTJjaI2w1TpQ8/zeDWHbzxY8J7RsdfOy0j81GHfiz/lX%2BMXHGKNlVxd1%2BdkTR31sve09RvnUqmsFNC4VaAcpOPQngyiEJTZRGSRa3/eT7hdlSNkdx40Zz02qoRfryrypx7sYxEi1ka7KTxQw5wND9lfZDK70ijPglOZ1q55Fc48oINfp5qgF HTTP/1.1
> User-Agent: curl/7.37.1
> Host: s3-ap-southeast-1.amazonaws.com
> Accept: */*
>
< HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
< x-amz-request-id: 41201436C5FA04B9
x-amz-request-id: 41201436C5FA04B9
< x-amz-id-2: lyx9cRmrFkr3MbeBzIMKBoOXlQNWoIaUSuTVWnIO23ecE+mWgp1IL3EGwSCZbOqRNu3Y+4+RYVM=
x-amz-id-2: lyx9cRmrFkr3MbeBzIMKBoOXlQNWoIaUSuTVWnIO23ecE+mWgp1IL3EGwSCZbOqRNu3Y+4+RYVM=
< Content-Type: application/xml
Content-Type: application/xml
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Date: Mon, 30 Mar 2015 20:49:55 GMT
Date: Mon, 30 Mar 2015 20:49:55 GMT
* Server AmazonS3 is not blacklisted
< Server: AmazonS3
Server: AmazonS3
<
* Connection #0 to host s3-ap-southeast-1.amazonaws.com left intact
實驗結果就是不行,那麼這是為什麼呢?回頭翻手冊就會明白了。 因為 signed url 是連 HTTP 的 Method 一起進去的1,而 signed url 是對 HTTP GET
的動作做 signed url,所以換成用 HEAD 時,比對的資訊就會是錯誤的(簡單說,它在 server side 無法 reproduce 你的計算結果)。
不過 List 難用大家都知道啦,我們都會放個主要的 key 在 db 上,另外以這組 key 的 listing 清單另外放 cassandra 上,算是二層 map 的查詢的做法 (二個 O(1) 就找到資料嚕),要等 list 不知等到何年何月了。
狀態一致性的問題是分散式系統都要面對的,不過在面對之前可以先想一下「這件事對我們的產品來說,重不重要」。
如果開發者真的在意要花多久時間達到一致,那就得乖乖的 log 並觀察問題是否會影響他們的產品。並且運用一下該產品提供的特性,與調整設計來避開一些問題。
以我在開發上多採用只有新增,沒有 update 來利用 S3 非 us-east-1 提供新 object 的 read-after-write 特性,就能避開最終一致性,但在實際的實作上仍會在「重要的」情況,多加幾次 HTTP HEAD 檢查一下有沒有 object。
PS. signed url 就不能打 HTTP HEAD,用 HTTP GET 取代.
因為二個月前有試過在上面部署服務,只是覺得網路卡那時也沒太在意,只當作個「不意外」處理。
剛好最近在寫新的服務架構,想說再上去試一下它的品質。依然發生升級 ubuntu 後變慢的問題。雖然最終的服務不會弄上 HiCloud,但至少研究一下是哪個部分變慢的。還沒能確定是不是升級後才變慢的,所以有開一台未升級的 instance 來試驗,發現它「相當順暢」。另外試了,是不是只有我要下載的 AWS S3 變慢了?對 Google 首頁下 curl 依然要等個 5 秒多才回應。那麼應該就是系統設定的問題了。
不過,怎麼調整 DNS 順序都無法把 8.8.8.8 弄到第 1 順位,只好弄個 DNS Cache 服務,速度馬上有所提昇。目前只知道問題出在 DNS,但仍覺得這應該不是最終的解決,只是稍為記錄下來給有需要的人知道一下(是說,有人會除了它網路便宜而想用它嗎?)。