4
| 本文作者: 朱赟 | 2016-08-01 12:09 |
雷鋒網(wǎng)注:作者朱赟,硅谷 Airbnb 資深美女程序媛一枚。

題圖:Mark Bird
前兩天 Uber post 了一篇文章,說他們從 Postgres SQL 轉到使用 MySQL 了。blog 寫得不錯,科普了一些 DB indexing 和 replication 的基本常識。當時轉給一個朋友看,朋友說,其實 Uber 2013年才發(fā)了一篇文章說他們從 MySQL 轉 Postgres SQL。遂去找來看了??赐旰髮に枷拢鋵崈善恼卤澈蟮那闆r,兩次轉型的文章背后的原因,也就可以揣測一二了。
作為兩大主流開源數(shù)據(jù)庫,MySQL 和 Postgres 的 “戰(zhàn)爭” 從來沒有停止過,雖然硝煙不似程序語言之間的斗爭那么濃烈。你可以去 Quora 或者 Stack Overflow 上搜相關的 MySQL v.s. Postgres 帖子,特別多。我的感覺是,各有各的優(yōu)勢和實用場景,并沒有一種比另一種有壓倒性優(yōu)勢的存在。
對于大部分程序員來說,公司用哪個 DB,基本不太輪到你來做決定。你加入一個公司的時候,除非是創(chuàng)業(yè)公司,或者你是 CTO、VP、Director 級別的,否則大部分的技術選型都應該早已經塵埃落定了的。尤其是 DB,一旦選擇,再遷移的代價就很大。所以除非有了顛覆性的優(yōu)勢或者問題,很少有公司會去費時費力做這種大的遷移。而不論是選型還是轉型,一個不可忽略的因素,就是你招到的工程師更能駕馭哪一種技術,或者有話語權的決策者們傾向于哪一種技術。這其實和程序語言的選型多少有著異曲同工的類似。
其實 Uber 兩次高調轉型,類似的事情在 Square 也發(fā)生過。雖然 Square 最早是使用 MySQL,但是在大概在 2012 年間,因為 Postgres 的各種優(yōu)勢(如對 geospatial 數(shù)據(jù)及搜索的支持等),以及當時幾位比較 senior 的工程師的大力倡導,很多新的 service 都嘗試性地選擇了使用 Postgres。所以當時公司的架構是 MySQL 和 Postgres 并存。對于那時候的我而言,不過是有機會學習、了解、和比較兩個不同的技術。兩者各有特點,有些東西在 MySQL 里似乎更方便,另一些則反之。總有方案去實現(xiàn),并沒有覺得非要哪一種才行。
DB 若安好,便是晴天。
一個公司,如果 DB 從來不出問題。那肯定是因為沒有業(yè)務或者流量。所有的技術,都有它設計的應用場景。除了一些 happy case,就一定有坑。能夠盡可能地避免這些坑,或者在出問題的時候能夠最快修復,就成了至關重要的因素。Square 兩種 DB 并存的期間,公司里 Postgres 的牛人寥寥無幾。但是 MySQL 的 experts,卻有幾個極為靠譜的。大部分工程師,并不是數(shù)據(jù)庫專家,Postgres 和 MySQL 的相對優(yōu)勢,對我們而言,都比不過出問題的時候有人解惑或者救火來的重要。何況一個公司維系兩套同類的數(shù)據(jù)庫系統(tǒng)本身就是個負擔。因此,這些使用 Postgres 的 service 后來又都慢慢轉成 MySQL 了。
因為我們做支付的需要強 transactional 的支持,所以不太會用 NoSQL 類型的,主要用的還是 MySQL 或者 Postgres。雖說數(shù)據(jù)庫相關的知識和技術,現(xiàn)在工作中因為用得多,慢慢也了解了不少,但如果真的線上出了問題,自己還是不太擺得平。好在每個公司都會有一些數(shù)據(jù)庫大牛,有的公司叫做 DBA。很多中小公司并沒有專職的 DBA,都是做系統(tǒng)的人監(jiān)管。有幾位私交甚好。加上自己平時系統(tǒng)里相關問題也經常需要請教,所以一來二去知道了好些好玩的事情。
對數(shù)據(jù)庫大牛我一向是抱景仰的態(tài)度的。公司只要稍具規(guī)模,數(shù)據(jù)庫這塊做不好,基本也就沒啥好玩的了。這一塊不出問題也罷,一出問題,基本就是見血封喉,網(wǎng)站直接掛掉。那么平時最常見的都有哪些問題呢?
首先就是選型。
每個公司因為業(yè)務的不同,數(shù)據(jù)庫系統(tǒng)應用場景不一樣,哪一種最合適就不一樣。沒有哪一個系統(tǒng)一定是最好的。比如做支付的一定要強事務性、一致性的支持,而很多社交平臺更多時候其實是需要高可用;有的業(yè)務 writes 特別 heavy,有的業(yè)務更重要的是 reads;有些業(yè)務可以只關心最近幾天的數(shù)據(jù),因此可以 tradeoff 老數(shù)據(jù)讀寫的低效,有的卻要頻頻 access 歷史數(shù)據(jù);有些業(yè)務可以通過加 index 解決 query 效率,有些卻只能通過加緩存等等。。這也是為什么很多公司有多個數(shù)據(jù)庫系統(tǒng)并存,以最優(yōu)化對每個場景和業(yè)務的支持。
選型錯了,基本就掉在坑里了,也沒有頻頻踩坑一說了。
另外一個就是相關架構。
什么意思呢?這里包括數(shù)據(jù)庫上層的 cache 系統(tǒng)的設計,程序語言對 DB connection 的處理,proxy layer(如果存在)的功能,以及和 binlog 等相關的 data pipeline 的搭建。當然,也包括數(shù)據(jù)庫系統(tǒng)的分區(qū)、備份等的具體設計。很多公司早期所有的 table 都在一個 DB 里面,因為各種 connection pool 和 throughput 的限制,這其實基本沒法 scale。能夠合理的安排不同 table 的分離,讓數(shù)據(jù)相關的留在一起,不相關的或者不太相關的放在另一個 DB 里。類似這些很簡單的道理,很多時候卻可以很大程度上緩解 scalability 的問題。
而平時我們遇到的最多的問題,還是 human mistake.
再好的系統(tǒng),使用姿勢不對,也是枉然。何況并不是所有的工程師都是數(shù)據(jù)庫專家。
人為錯誤分成兩種。
一種是 DB operation 中犯的錯誤。
這種概率比較低,但是通常危害卻最大。幾乎所有的公司都會有類似的傳奇,常見的版本有:
某某工程師或無意或有意,“不小心” 刪掉了數(shù)據(jù)庫某 core table 中所有的數(shù)據(jù)。不是開玩笑,這種事 Facebook 也發(fā)生過,還是一個朋友。好在后來恢復了。這事也成了他的工程師歷史上光輝的一筆。
某某工程師做 online schema change 的時候,不小心有一步誤操作。結果數(shù)據(jù)庫被 lock 長達幾個小時。該公司網(wǎng)站也就掛了好幾個小時。
最后這個版本聽國內一個大公司的朋友說的,細節(jié)還真是不記得了。只是記得兩臺服務器,做 master slave switch 還是什么的時候,拔錯了一個電源插頭,然后......就沒有然后了。
另一種是程序員程序里或者腳本里犯的錯誤。
這個就很常見了。舉個很簡單的例子。我們知道 Ruby on Rails 對數(shù)據(jù)庫的 access 基本是通過 Active Record 來完成的。Active Record 可以通過一個 connection pool 來限制每個 application 到 DB 的 connection。如果某一個程序或者腳本中的 query 是查詢沒有被 index 的數(shù)據(jù),而導致 full table scan,加上一些 web server 的并行的實現(xiàn),很經常就會有整個 DB 的所有 connection 被占用,連 kill query 都沒法執(zhí)行。只能人肉的去做一些類似重啟的操作。還有更常見的,就是程序里的 N+1 query。這些都很無語,但若說你從沒遇到過,那可能是……呵呵。
最后一種,也就是自然流量增長或者流量突增造成的數(shù)據(jù)庫訪問瓶頸。
只要是數(shù)據(jù)庫,就有 throughput 的限制。只要你的業(yè)務在增長,總有一天數(shù)據(jù)庫訪問就會達到一個上限。所以在這個預警到來前,就要做各種 horizontal 或者 vertical 的 scale 來不斷提升這個上限?;蛘呤峭ㄟ^緩存等其他機制來對訪問量進行分流。這里面可以做的東西就多了。覺得可以單獨寫一篇了。
另一種就是類似 DDoS、Marketing 等等帶來的各種流量的突增。如果是有計劃的 Marketing 等,就需要提前做好各種戰(zhàn)斗準備。如果是惡意攻擊,那就只能靠各種防御工程(如 IP blocking 等等)擋掉這些訪問來保證數(shù)據(jù)庫正常工作了。
最后,推薦一個 DBA 寫的博客網(wǎng)站,內容很精彩,有技術有情懷。文章寫的比我好多了。
雷鋒網(wǎng)注:本文由作者授權雷鋒網(wǎng)發(fā)布,轉載請聯(lián)系授權并保留出處和作者,不得刪減內容。
雷峰網(wǎng)原創(chuàng)文章,未經授權禁止轉載。詳情見轉載須知。