摘要:回頭一想嚇一大跳自己并不是后臺工程師科班出身,從來對語言和框架的爭論無感無力,網絡編程的基礎知識更是差強人意,但是憑著小米步槍,憑著奇技淫巧,憑著持續思考和不斷嘗試,居然也能搭建起一個支撐千萬級別用戶的后臺框架。
三年前,原本我只是個不學無術的數據小碼農,空有一腔熱情;而當時公司也處在艱難的轉型期,舊產品不見起色,新產品前途未卜。想見著也不可能用這么小的數據玩出花來,而新產品的數據也不是一時半會能成規模。還是本著最大限度學習的心思,鼓足勇氣和老板提換崗,要去扛后臺開發的大旗,最大程度參與到產品的一線去。一個小決定,換來的是整整半年的不眠之夜,眼見著第1個用戶到第500萬個用戶,眼見著1臺到4臺再到10臺服務器,眼見著后臺業務由單一的播放到能播放能上傳再到有完整的社交交互。從剛開始三天兩頭崩潰出事故,到最終一點不怕市場的同事搞拉新的活動,什么狀況都能做到心中有數、遇事不慌。回頭一想嚇一大跳:自己并不是后臺工程師科班出身,從來對語言和框架的爭論無感無力,網絡編程的基礎知識更是差強人意,但是憑著小米步槍,憑著奇技淫巧,憑著持續思考和不斷嘗試,居然也能搭建起一個支撐千萬級別用戶的后臺框架。總結那半年,留下了5條事關生死的建議,在這里泣血奉上。
數據的讀寫是服務器性能的核心一個完整的后臺服務,組件其實就只分3種:接入、邏輯和數據。這好比一家飯店,后臺工程師就是開店的老板,客人數量小于1萬,服務流程是第一位的,老板們吭哧吭哧忙著寫邏輯;1萬到10萬之間,接入組件的設計會是重中之重:一個店的服務能力有限,老板們忙著多開幾個分店,讓客人分流,而決定客人到哪一個分店的,就是接入組件;但是用戶一旦大于10萬,數據的讀寫能力就決定了這家超級飯店的服務容量,不管開多少個分店,都要保證數據是一致的,讀起來又快又準,而寫數據不會影響到讀的性能。表結構怎么設計,數據庫怎么分布(主從、讀寫分離、分庫、分表),緩存怎么選怎么分布,就是老板們最重要的工作(讓老板高興的是,名片也可以改印個高大上的抬頭:架構師)。
一旦用戶量過了十萬,要再想光靠數據庫一部卡車打天下就不太現實了,而緩存(物理存儲地在內存,天生比數據庫讀寫性能強)這匹野馬的出現就滿足了我們對于速度的極致需求。緩存對服務器的架構帶來了兩個深遠的影響:一是熱數據和冷數據的分離:熱數據訪問的人多,緩存擋在前面,為數據庫分擔巨大的讀壓力;而熱數據從產品的角度也更應獲得快速的響應。二是數據一致性的門檻提高,更新數據庫的同時必須更新緩存,一旦緩存更新失敗,數據庫也一定要回滾而保證數據的一致性,不能鬧給客人上冷菜的笑話。當然緩存存什么、怎么存,也是大有一番學問,容我下一小節再講。但緩存的重要性總結一句話:沒有緩存是萬萬不能的。無論你是選老馬Memcached還是火熱的頭馬Redis,一定要在數據庫感受到壓力之前上馬,并且做好緩存備份和恢復的預案。當然,平安無事你是沒辦法感受到緩存的好處的,它就像一個平時提醒你吃飯睡覺多喝熱水的備胎,只有當她棄你而去之時,你看著服務器嘩嘩成百倍上漲的響應時間,恨不得找塊豆腐一頭撞死。
列表、實體和冗余Web時代,由于翻頁前后用戶出現了界面的切換,用戶對于列表本身的變化并不敏感(假如翻頁的同時列表新加入了內容,只要保證用戶瀏覽的這個片段沒有重復就可以),但是移動端這種滾動列表的設計簡直就是所有后臺工程師的夢魘(加入用戶上拉列表獲取更多的同時新加入了內容,那用戶會看到相鄰兩個重復的內容,然后就氣炸了,什么破APP!),應對「列表重復」這個難題的方法出一本書都夠了。因為這個需求,我們只能放棄了原有的自增ID,采用時間戳作為獲取列表片段的方式:簡單來講,就是客戶端每次都上報一個當前頁最后一個內容的時間戳,服務器再去取比這個時間更舊的若干個內容。這里必須要感謝Redis的作者提供了如此豐富的緩存使用的API,我覺得Redis最出色的一點就是把列表的所有使用場景都設想得很通透。
實體就是熱數據,熱數據的緩存有兩問:一是存什么?有人會說簡單,把整個結構體轉化為一個JSON存進去不就得了?但這其實是有問題的,當你的服務器要面對數十萬同時到來的用戶,可能短短一瞬就要做數以千萬計的JSON到結構體之間的來回切換,而這個過程的效率實際上是很不理想的,那么也許你要想一些更快的方案(此處買個關子)。二是怎么存?雪崩效應并不罕見,一旦源數據改變,一時間許多個線程同時去訪問更新緩存的API,服務器瞬間堵死,想到后臺工程師會因此而失業,我默默加了一個鎖。
小張是端菜的服務員,這次上菜,他要先去涼菜區取個土豆絲、再去葷菜區取個東坡肉、順到素菜區取個手撕包菜、最后到飲料區再拎兩瓶果汁,聽起來很低效,對不?這和數據獲取的過程是類似的,數據庫的表設計首要考慮的是歸類,比如用戶的信息存一張表,用戶和小組的關系再存一張表,那么如果有一個場景需要讀用戶以及他最后訪問過的小組,就得做兩次的數據表讀取,一旦這個場景頻繁出現,適當的數據冗余(把用戶最后訪問的小組ID加入到用戶表的字段中)就能夠降低數據庫的讀取壓力。所以表設計一定一定一定(重要的事情說三遍)要考慮業務場景。
異步,是不是真異步?有的小盆友跑來問我,我這個服務器框架選的牛啊,異步多線程的,單進程并發一萬多輕而易舉,怎么還是慢啊?我說,「異步」這個詞可不要說得太輕松,底層異步了,流程里的每個步驟是不是異步的呢?數據庫讀寫、緩存讀寫、外部接口的訪問,這些都不能異步吧?既然不是異步,卡在哪里你還不知道呢,還不趕緊打日志。還是說說最令我崩潰的一個案例:某次服務器炸了,打多少次日志都沒辦法定位到卡住的原因。最后猜是怎么著?竟然是日志組件(Log4j)就不是異步的,打日志這個步驟就卡住了,欲哭無淚。
日志、監控和有損服務一個高級飯店要有廚師,要有大堂經理,要有端盤子的,要有收銀的,但千萬別忘了還要有保安。他雖然不是飯店成功與否的核心因素,但是如果缺了他,危機時刻就會應付不來。下面這三位哥們就是服務器的保安:日志、監控和有損服務。
先說日志,日志是很微妙的,打多了不行,影響性能、占據空間,打少了,關鍵問題排查不出原因。那么哪些是必打的呢?我認為有三點:一是行為的基本屬性,無非是何時何地何人,時間、用戶ID、IP、版本(存下來除了排錯,還可以用來做數據分析);二是往返的參數,尤其是客戶端上報的參數,服務器返回的數據也許會很大,不建議所有都打印,可以打印統計數據,比如返回了多少個小組之類;三是報錯信息,底層一定要catch所有的出錯信息,并把它打到多帶帶的日志里。
再說監控,日志是一旦發現了問題幫助我們找出問題的原因的工具,那么什么能幫我們發現問題呢?答案是監控和告警。監控與日志不同,要抓核心的數據,不能多,我建議取三個數據:用戶的并發訪問數、讀取的人均響應時間、寫入的人均響應時間,告警的話再加上服務器的崩潰、重啟的次數,以及主機性能相關的指標(CPU、內存、硬盤等)。
「發生這種事,大家都不想的。餓不餓,我給你煮碗面?」,服務器運氣不好崩潰了,我便常常用這句TVB的經典臺詞與小伙伴們調侃。其實無論事前機關算盡,成長期的APP總會遇到服務器出狀況的。但是,以我有限的經驗,服務器的問題往往不出在自身,而是它所依賴組件導致的問題,比如Memcached機器dump、轉碼服務隊列阻塞、或者圖片存儲空間爆滿等等。那么在問題被解決之前,總不能干瞪眼,看著用戶投訴一波波來吧?我們會想,對于現在的業務來說,最不能崩潰的場景是什么?比如播放是我們的最基礎服務,那我們死也要保證任何外部組件的崩潰都不能影響熱門內容的播放,因此我們要把這部分少而重要的熱數據加載到內存,以防止外部存儲出了什么問題,服務器自己還有碗面吃。真正是,自己的事情自己干,靠天靠地靠祖宗,不算是好漢。
服務分離與復制服務器體系越長越大,我們首要做的事情是分封,兒子長大了,總要給他一塊地盤,當個小王,從此自己打拼去。于是數據讀寫被抽象成服務了,同時對APP和前端負責,做最大的一個王;編碼解碼抽象成服務了,反正編碼解碼是給UGC用戶提供的,想當明星的人總要等得起;日志存儲和解析也抽象成服務了,反正有少許的丟失我們也不介意。表面看來服務器被拆得支離破碎,增加了網絡時延,是一筆不劃算的生意,但實際上對服務器的穩定性大有助益。為什么?一是大王國被拆成小王國了,定位問題更容易,遷移和復制也更簡單,數據讀寫有壓力?沒問題!再給兩塊地盤。二是在整個鏈條上,任何一個環節都是多點,俗話說,不把雞蛋都放在一個籃子,任何一臺服務器dump都不會要了我們的命。
細枝末節且不提,總結當時半年內服務器高速發展期留下來的經驗,我認為最重要的就是這五點,業務場景不同,服務器的架構和側重點也肯定會略有差異;不過這五點基本等同于錦囊,等同于基石,等同于保命符,做好了,這飯店生意一定蒸蒸日上。恭喜你,老板!
更多精彩內容,歡迎關注微信公眾號「碼農咖啡館」
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17489.html
摘要:回頭一想嚇一大跳自己并不是后臺工程師科班出身,從來對語言和框架的爭論無感無力,網絡編程的基礎知識更是差強人意,但是憑著小米步槍,憑著奇技淫巧,憑著持續思考和不斷嘗試,居然也能搭建起一個支撐千萬級別用戶的后臺框架。 三年前,原本我只是個不學無術的數據小碼農,空有一腔熱情;而當時公司也處在艱難的轉型期,舊產品不見起色,新產品前途未卜。想見著也不可能用這么小的數據玩出花來,而新產品的數據也不...
摘要:所以通過設置一個適中的拉取注冊表以及發送心跳的頻率,保證大規模系統里對的請求壓力不會太大。在注冊表發生變更的時候會在內存中更新變更的注冊表數據,同時過期掉。上述就是架構中,作為微服務注冊中心可以承載大規模系統每天千萬級訪問量的原理。 歡迎關注微信公眾號:石杉的架構筆記 周一至周五早8點!精品技術文章準時送上!! 往期文章1.拜托!面試請不要再問我Spring Cloud底層原理! 目...
摘要:所以通過設置一個適中的拉取注冊表以及發送心跳的頻率,保證大規模系統里對的請求壓力不會太大。在注冊表發生變更的時候會在內存中更新變更的注冊表數據,同時過期掉。上述就是架構中,作為微服務注冊中心可以承載大規模系統每天千萬級訪問量的原理。 歡迎關注微信公眾號:石杉的架構筆記 周一至周五早8點!精品技術文章準時送上!! 往期文章1.拜托!面試請不要再問我Spring Cloud底層原理! 目...
摘要:量化派是一家數據驅動的科技金融公司,通過人工智能大數據機器學習等前沿技術提供消費信貸撮合及消費場景下的白條服務,每年處理千萬級用戶信用及信用消費申請。 「小楊」最近裝修房子,準備去銀行貸款,但是聽說好多人會因為個人征信問題被銀行拒絕貸款!于是,他先查了一下自己的央行征信,發現竟然沒有自己的征信信息,「小楊」陷入了沉思,自己經常在淘寶、jd 上買東西,也有淘寶花唄和京東白條,怎么會沒有征...
閱讀 3960·2021-11-24 09:38
閱讀 1225·2021-10-19 11:42
閱讀 1829·2021-10-14 09:42
閱讀 2154·2019-08-30 15:44
閱讀 544·2019-08-30 14:04
閱讀 2888·2019-08-30 13:13
閱讀 1949·2019-08-30 12:51
閱讀 956·2019-08-30 11:22