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。遂去找來看了??赐旰髮に枷?,其實兩篇文章背后的情況,兩次轉型的文章背后的原因,也就可以揣測一二了。
作為兩大主流開源數(shù)據(jù)庫,MySQL 和 Postgres 的 “戰(zhàn)爭” 從來沒有停止過,雖然硝煙不似程序語言之間的斗爭那么濃烈。你可以去 Quora 或者 Stack Overflow 上搜相關的 MySQL v.s. Postgres 帖子,特別多。我的感覺是,各有各的優(yōu)勢和實用場景,并沒有一種比另一種有壓倒性優(yōu)勢的存在。
對于大部分程序員來說,公司用哪個 DB,基本不太輪到你來做決定。你加入一個公司的時候,除非是創(chuàng)業(yè)公司,或者你是 CTO、VP、Director 級別的,否則大部分的技術選型都應該早已經(jīng)塵埃落定了的。尤其是 DB,一旦選擇,再遷移的代價就很大。所以除非有了顛覆性的優(yōu)勢或者問題,很少有公司會去費時費力做這種大的遷移。而不論是選型還是轉型,一個不可忽略的因素,就是你招到的工程師更能駕馭哪一種技術,或者有話語權的決策者們傾向于哪一種技術。這其實和程序語言的選型多少有著異曲同工的類似。
其實 Uber 兩次高調(diào)轉型,類似的事情在 Square 也發(fā)生過。雖然 Square 最早是使用 MySQL,但是在大概在 2012 年間,因為 Postgres 的各種優(yōu)勢(如對 geospatial 數(shù)據(jù)及搜索的支持等),以及當時幾位比較 senior 的工程師的大力倡導,很多新的 service 都嘗試性地選擇了使用 Postgres。所以當時公司的架構是 MySQL 和 Postgres 并存。對于那時候的我而言,不過是有機會學習、了解、和比較兩個不同的技術。兩者各有特點,有些東西在 MySQL 里似乎更方便,另一些則反之??傆蟹桨溉崿F(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)里相關問題也經(jī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)站也就掛了好幾個小時。
最后這個版本聽國內(nèi)一個大公司的朋友說的,細節(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),很經(jīng)常就會有整個 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)站,內(nèi)容很精彩,有技術有情懷。文章寫的比我好多了。
雷鋒網(wǎng)注:本文由作者授權雷鋒網(wǎng)發(fā)布,轉載請聯(lián)系授權并保留出處和作者,不得刪減內(nèi)容。
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權禁止轉載。詳情見轉載須知。