標籤:

為什麼你不用AWS,還是需要了解一些AWS的技術?

前一段,國內的某個雲服務商出了故障(據說是交換機,我沒有看詳細的報告),導致網路癱瘓,一大堆構建在其上的應用遭遇了宕機,數小時無法訪問,慘不忍睹。我朋友的項目正好在此之前發布,苦不堪言。國內的雲服務商還很年輕,還有很多坑要踩 —— 要知道,即便是2006年就發布的AWS,在商用了6個年頭之後的2012年,還發生過一次大的事故,導致quora等服務都無法訪問。

我知道,AWS因為一些旁的原因,目前在國內還無法很好地使用,國內團隊的首選也並非AWS。但,如果你有一顆做個好的app的心,AWS的技術(以及這些技術背後的思想和商業目的)最好還是了解一下。

容災

既然我們講到了雲服務商的事故,那麼,就先從容災講起。AWS在此踩了很多坑,也收穫了很多寶貴的經驗。

首先是availability zone。availibility zone是容災的最重要一環。在aws分布全球的若干個region里,每個region都有若干個物理上相隔一定距離但又不太遠(大概5-15miles)的數個獨立的data center,也叫availibility zone(AZ)。物理上獨立的意義是:獨立的機房,獨立的供電系統,獨立的ISP接入系統等。這保證在一個AZ完全掛掉的情況下(比如電力故障,網路故障,甚至修路施工隊的愚蠢的「實習生」挖斷了光纜導致的ISP故障等),你的應用在另一個AZ還能正常使用。這一點很重要。若干AZ保持距離但又不太遠保證了能夠物理容災的同時,你還可以將其幾乎等同於同一個data center進行應用層面的容災,比如說database的master/savle分別架在兩個不同的AZ而不必過分擔心網路層面的性能(round trip幾乎可以忽略不計,也就幾百us到至多幾個ms,請自行用光速和距離計算)。

當然一個城市的電力系統可能整體出故障,一個國家的跨海光纜可能被海嘯切斷,所以AWS還有region的概念。這些region分跨數個大洲,保障物理上一個region整體掛掉的情況下,如果應用做了跨region的容災,還能繼續服務。但應用程序跨region的容災不好做,距離上增加了兩個量級,使得region之間的網路傳輸可能高達上百ms至幾百ms,量變到質變,一些簡單的應用層容災手段(比如直接採用資料庫的master/slave),便無法使用。

不過說句實話,大部分使用雲服務商的應用程序還到不了需要跨region容災的程度(到了這個程度,應該有一隻強悍的devops team來處理這種happy sorrow了),所以,考慮跨AZ就好。

如果你選擇一個雲服務商,問問他們是否有類似AZ的概念,你的web server,database server能不能跨AZ部署。這是一個應用過了種子期(有了上千用戶)首先該考慮的事情。當然,如果你直接上AWS,那麼基本的容災無憂了。

容災的另一個層面是數據備份。你需要合適的backup/restore機制。AWS提供了S3/Glacier來存儲文件類型的數據。數據備份是應對Murphy』s law的,當最壞的事情發生(數據丟失),對於服務恢復,你究竟有多大的容忍度,決定了你有多大的操作空間。如果你能容忍丟失至多一個小時的數據,那麼,起碼設置每隔10-30分鐘的數據(增量)備份,這樣,當DBMS上的數據被惡意刪除(並且被同步到了slave),或者出現掉電文件系統corrupt的情況,備份就是你可耐的七舅老爺。

但是,備份一定不要僅僅放在本地,請務必存儲在某個靠譜的,像S3這樣的自帶數據冗餘的雲存儲服務上。這樣的服務一般是把一份數據分成N個切片存在不同的物理位置,只要其中K個切片可用,就能還原出文件。基本上,存儲在類似的系統上的文件可以認為是不會丟失的。當然,關鍵性的數據最好分級備份甚至線下備份,AWS就為此提供了glacier這樣的慢速存儲,存儲空間幾乎無限,價格便宜(S3的1/3),但如果想從中恢複數據,需要幾個小時數據才能準備好(因此有wikipedia上有推斷glacier是用tape,或者blue ray disk這樣的離線方式存儲數據)。

陳舊的備份的數據也可以定期清除,節省開銷。

安全

一個好的雲服務商不僅僅要為你提供合適的計算能力和存儲能力來部署你的應用,還需要提供某些安全保障。我們看AWS提供了哪些安全手段。

首先是IAM(Identity and Access Management),也就是身份可許可權管理系統。安全的首要原則是least previlige。就像你永遠不該使用root來訪問一台遠程設備(最好disable root)一樣,當你訪問一個雲提供商,你也不應該將初始賬戶(相當於root)分享給每個團隊成員使用,你應該為每個不同的角色創建不同的賬號(如果雲提供商提供這樣的功能,如果沒有,你的雲提供商需要重新學習security 101),提供最低的訪問許可權。比如說,devops可以控制production環境,但dev/qa不能。不但許可權分離,任何操作都要有可以用於事後審計的log:誰在哪一天做了什麼操作(比如說創建了一個instance,誰disable了某個服務),需要一清二楚。

其次是內外網分離。絕大多數情況下,你的大部分伺服器,如database,是不需要暴露在公網上的。你最好部署一個(至多個)擁有公網IP的load balancer(LB),類似於AWS的ELB(Elastic Load balancer),將你N-tier的應用隱藏在LB之後。這樣,除了對外的LB之外,其他伺服器均在一個內網之內,沒有公有IP,阻斷黑客直接入侵的可能。

當然你的團隊需要訪問這些伺服器。你可以在網路的邊界部署跨內外網的伺服器,可以以這台伺服器為跳板,登入同一個子網內的內網的其他伺服器。更安全的方式是設置openVPN,通過SSLVPN的方式接入到內網,從而訪問這些設備(詳細信息請參考我之前的文章:應用開發中的網路安全)。

之後你需要認真考慮網路的訪問許可權,設置物理的或者虛擬的防火牆。AWS的Security Group(SG)就是這樣一個簡單的基於ACL(Access List)的防火牆,你可以在這個級別設置允許流入流出的埠,以及源IP地址。當然,在伺服器的iptables里,你也需要做相應的設置。安全是有層級的,不能打造了個無比強硬的門就高枕無憂了:城外的地壕,護城河,城牆,城內的翁城都是要配置的。

這一切還不夠,按照你的開發部署流程,你很可能需要dev環境,staging環境(QA testing),還有production的環境,每套按照上面的定義,都各自有不同的安全標準和訪問許可。在AWS里,VPC(Virtual Private Cloud)可以很方便地幫你定義出這些環境,你的雲服務商最好也有相同的概念,或者你通過劃分子網(和子網的訪問許可權),自行提供簡單的隔離。

服務可伸縮

很多人言及AWS,談到的首先是EC2的auto scaling。scaling不是簡單的computation scale up/out的概念,而是一攬子解決方案。在考慮scaling之前,最好先把基本的容災(起碼備個份),和安全(行行好,最起碼不要把你的資料庫裸奔在公網上,不要直接用密碼登陸你的ssh伺服器等等)做好,有了這個基礎,再談scaling。沒有容災和安全的scaling,就像在地震活躍帶,打個淺淺的地基,蓋了一個沒有門沒有窗,四處透風的摩天大廈。

AWS提供幾個層面的scaling:

  • Computation:EC2 auto scaling。配合ELB,可以讓服務的計算能力隨業務需求自動增減。

  • Storage:S3可以認為是一個無窮大的,訪問時間恆定的storage。

  • Database:無需做任何管理,只需關心業務邏輯和配額的dynamodb(NoSQL);以及需要基本的管理(但不需要做打patch這樣的事)的RDS(Relational)。

  • SQS:無需任何管理,可以認為容量無限大,訪問速度恆定的Message Queue

  • Cache:需要一定管理的Elastic Cache(使用memcached或redis)

這基本上是不需要大數據處理,不需要流媒體處理,不需要machine learning的應用的基本服務了(AWS都有對應的服務)。當然,在早期的產品里,面臨的scaling的問題還主要集中在web/app server和database server上,你更多地考慮在LB後面根據需要在不同的AZ下放置更多的web/app server(如果你的雲服務商能夠做auto scaling再好不過,沒有在早期也不是大事),然後資料庫除了跨AZ的Master/Slave的配置外,加上若干個Read replica。一寫多讀能應付大部分scaling的需求,除非你的應用是特殊的,寫多讀少的應用(此時考慮那些專門設計的,優先寫速度的資料庫伺服器,如cassandra)。

再往後的scaling,其實主要也是在數據層面騰挪:靜態資源放CDN,session store使用ElastiCache或者DynamoDB,某些複雜的查詢結果塞到ElastiCache里減少對資料庫的請求;然後資料庫進一步切分,根據讀寫的量級,把不同量級的表獨立在不同的資料庫,然後對讀寫頻繁的設置更多的read replica。這個一個資料庫切分多個資料庫,運行在不同的replica set里。

走過了這一步,如果數據層面無法換或者不想換DynamoDB,依舊使用RDS,AWS能幫你的也不多了。接下來就是應用程序的切分。應用的不同部分也許可以通過queue decouple,然後每個獨立發展,獨立scale out,就像資料庫所做的那樣。這便是所謂的micro service,或者service oriented architecture(SOA)。AWS提供了SQS幫你完成這個變化,如果你的雲服務商沒有類似的能力,也可依服務的需求部署kafka(沒用過),rabbitmq等消息隊列和消息分發軟體。

再往後,用戶還在瘋漲,如果你已經成功切換到DynamoDB,那麼只需要提供更多的讀寫配額,讓AWS替你scale out,但如果還對SQL DB不離不棄,就要走資料庫表的sharding,不過這個時候,你可能已經接近於下一個instagram了。所以,即便切表切得肉疼,心情還是舒爽的,任何問題都不過相當於躺在馬爾地夫的沙灘椅上吹著海風,看著比基尼,享受精油按摩的時候,被不開眼的蚊子叮了個包而已。

稍微多說兩句DynamoDB。DynamoDB是AWS的私有技術,不過Amazon publish相關的paper,催生了riak這樣帶著同樣理念的開源產品。按照我粗淺的理解,這類可以無限擴容的NoSQL資料庫,其核心是consistent hashing:

consistent hashing的概念是我有一個足夠大的keyspace(2的160次方,比較一下:IPv6是2的128次方),我們記作X,然後將X放在一個環形的空間里劃分成大小相等的Y個partition,依次循環排列(如圖),每個partition由一個vnode(riak的概念)管理,當你有M個database server(node),Y個vnode再平均映射到M個node上。當數據要插入時,將其主鍵(hash key)映射到K中的一個地址(addr),對應到某個vnode,再進一步對應到某個node,如果這個數據需要N個replica,則將數據寫入addr(vnode a),addr + 1(vnode b), …,add + N(vnode n)。在這種設置下,M就是你的shards,N是replica。以後添加新的node時,映射發生變化,只需要把相應的變化了的vnode遷移到新的node上即可。在這種結構下,sharding/replica對程序員基本上是透明的。

所以看AWS的解決方案,想想它為何提供這樣的工具,有助於我們思考自己的application的架構,以及在不得已的情況下,尋找替代產品。

其他

monitoring是application必不可少又被忽略的東西。AWS提供了cloudwatch,基本功能包括CPU/IO/network/memory等系統層面的tracking,以及服務可達性(從DNS到LB,LB到web server等的監控),你還可以加入應用相關的monitor,讓cloudwatch統一處理。在這一塊上,可替代的工具很多,可以去awesome-sysadmin裡面尋找答案(monitoring和metric collection分類下面)。

logging和monitoring一樣,也常常被忽略。分散式系統最令人頭疼的就是log散布各處,所以你需要一個集中管理的工具。AWS沒有提供類似的解決方案。比較成熟的是ELK(Elasticsearch + Logstash + Kibana),還有fluentd + elasticsearch + kibana的變種。也可以在awesome-sysadmin的log分類下找。

configuration management和deployment這塊AWS從高到地分別提供了CodeDeploy,ElasticBeanstalk,OpsWorks,以及cloud formation,涵蓋應用級的部署一直到用代碼來一行行控制的部署腳本。你自己可以使用ansible,chef這樣的配置管理工具。

AWS的CloudSearch可以用開源的ElasticSearch替代,SNS可以用pusher這樣的第三方pub/sub + push notification的工具很方便地一對多發布數據。

嘩啦啦說了不少,就先這樣吧。總結一下對應關係:

  • EC2:你的雲服務商的VM

  • ECS:你的雲服務商的docker容器,或者自己構建

  • RDS:MySQL/Postgres

  • DynamoDB:riak

  • ElastiCache:memcached/redis

  • S3:我覺得你還是可以用S3作為備份方案的,國內也有不錯的某某雲存儲

  • SQS:RabbitMQ,Kafka

  • Route 53:DNSPod(好吧我相信大部分人用這個,所以不算廣告了)

  • IAM/VPC/SG:不要含糊,如果雲提供商沒有,考慮在適當的時候構建你自己的

  • CloudWatch:Riemann或者其他

  • CloudSearch:ElasticSearch

  • CodeDeploy,ElasticBeanstalk,OpsWorks,以及cloud formation:ansible / puppet / chef等

  • SNS:pusher

  • SES:sendgrid/mailgun,或者國內類似的郵件服務商

  • Elastic Mapreduce:hadoop

  • Machine learning:PredictionIO(這貨是個開源軟體,我以後專門辟文介紹)

如果您覺得這篇文章不錯,請點贊。多謝!

歡迎訂閱公眾號『程序人生』(搜索微信號 programmer_life)。每篇文章都力求原汁原味,北京時間中午12點左右,美西時間下午8點左右與您相會。


推薦閱讀:

黑客馬拉松
閑扯Tick Tock
談談用戶許可權系統
行者無疆:西雅圖,波特蘭及其它
奇博士的管理課 - 激勵

TAG:迷思 |