1. 程式人生 > >從12306的崩潰,說說我們怎麼去做效能優化?

從12306的崩潰,說說我們怎麼去做效能優化?

開篇語

最近12306又崩潰了一次,但其實12306這樣的體量跟我們平常接觸的架構基本沒什麼太大的關係。

話又說回來,12306也是由一個個小功能組成的。

做好自己的小螞蟻,就能讓大部隊變得更快。

因為跟資料庫、資料倉庫、查詢打交道比較多,所以我就簡單說一下資料查詢的優化過程吧。

不客氣地說,在效能優化中,其實80%的問題都是源於資料查詢。

以下步驟是以優化代價、資料量級為衡量,從低到高開始,步步進推。

GO

(1)如果資料查詢緩慢,80%的原因都是因為SQL。先找出慢SQL,以Oracle為例,可以通過AWR報表的方式檢視。

(2)檢視慢SQL的執行計劃,看看查詢的關鍵欄位是不是缺失索引,新增索引。

(3)有索引,但是檢視執行計劃,並沒有走索引。此時有兩種方法,一是用hint,二是可能資料表最近被大批量的刪除、新增過,需要手動收集資料表的統計資訊,讓SQL優化器正常解析SQL。

(4)資料表太大,沒有合適的全域性索引。可不可以建設分割槽表?按照時間、地區進行分割槽操作。

(5)不能分割槽,或者分割槽效果也不顯著,需要考慮改動表結構了,有些欄位是不是可以拆出去?做成維表、擴充套件表?

【這是垂直拆分。缺點是查詢時如果要查詢擴充套件表字段,需要join操作,插入修改時要考慮多表,事物複雜。單表資料量還是太大。】

(6)或者可以考慮進行分庫分表操作。對於Oracle來說單張1億以下資料分割槽就夠了,不需要分庫分表。

【水平拆分。缺點是會導致事物一致性更為複雜,還需引入分庫分表的管理中介軟體。】

(7)進行歷史資料分離。將一些不常用的資料,例如兩年前的資料都拆分到歷史表中。

【即冷熱資料分離。】

(8)讀寫分離,再新建個數據查詢庫,oracle用OGG、mysql用binlog做資料同步,將查詢模組更換資料來源。

(9)增加資料庫的伺服器效能,升級硬體,例如磁碟換上SSD。這個方法是被驗證過了的,尤其是查詢批量資料、無高效索引的時候。

(10)從資料庫層面已經無法優化了,我們可以考慮在應用端使用並行查詢的方法爬出資料,然後再行合併。

【事實上,很多報表工具都是這麼做的。】

(11)並行查詢再高階點,用流行的話來說,叫分散式計算。

【12306就是用Pivotal的 GemFire,將單次查詢的最長時間從15秒下降到0.2秒以下。】

(12)這個資料庫效能就是達到瓶頸了,我們來更換資料庫吧,換成效能更好的資料庫,要做資料遷移,重新測試驗證,代價不菲。

(13)從業務上去優化,看看這樣查詢是不是有道理,這些欄位是不是確實需要?需不需要這麼精細?需不需要這麼頻繁?

大資料量報表每月一出就行了?那這樣就無所謂時效性了。嗯,那我們來做資料倉庫吧。

(14)我們用了Hadoop + RDBMS做了資料倉庫。

資料倉庫不能實時查詢怎麼辦?我們來做實時倉庫吧。

(15)我們用了kafka + spark + jstorm做了實時倉庫,結果你跟我說過時了?剛剛升級成了Spark Streaming ?嗯?又換成Flink了?

好吧,愛咋咋地。

結語

說到這裡沒啥可說的了,或者以後想起來什麼還可以再說說吧。

效能優化其實是一個持續迭代的過程,並非一蹴而就,也不是一步到位的工作。

有時候有很多方案,關鍵是看怎樣代價最小。(改造成本、硬體成本、緊急狀況)

每個人,還是先從寫好一個SQL,一段程式碼開始吧。

撒花,結束。

END.