從Disucz能學到什麼

2021-09-19 16:52:41 字數 3602 閱讀 5606

其實吧,我脫離技術大概五年多了,五年沒有coding,沒有code review,沒有跟員工討論具體技術實現問題,(啊,不是完全沒有,有一次半夜急了跟開發商調bug,就那麼一次,手生的厲害,所幸搞定了)。偶爾遇到一些圈裡朋友諮詢技術問題,都是靠當年帶出來的徒弟或者其他朋友幫忙應付。所以今天我去談技術,都只是談一些上古時代的東西了,那麼多技術網紅都在寫一線的東西,好多新東西我都沒聽說過,**敢冒出來露醜。

再說,以前寫過的技術系列,訪問量和傳播率都不是那麼可觀,大概也反映了讀者的態度。

如何應對併發(1) - 關於資料索引

如何應對併發(2) - 請求合併及非同步處理

如何應對併發(3) - 需求裁剪

如何應對併發(4) - 分布式資料庫及反正規化設計

如何應對併發(5) - 關鍵的關鍵,是認識負載

如何應對併發(6) - 瑣碎的日常

史上最簡單的推薦系統設計

我在舊文中多次提到discuz,比如下面這篇。

從cnzz歷史講創業與打工的區別

因為第一呢,當年大部分php程式設計師都接觸過這個**,所以面試的時候我也喜歡從中找問題點。第二呢,當時我們對這個**吃的還是比較透的,確實學了很多東西。

那麼,今天,就從這裡入手,講講我當初,通過discuz體會和領悟到的一些技術細節,雖然是上古時期的技術,但是對於一些應屆生或者是新入行的服務端程式設計師,我個人認為,還是有一點價值的。

當然,如果您是技術高手,可能會覺得本文很low,煩請自行忽略,謝謝。

1、資料索引的設計,特別是復合索引

discuz的索引設計和sql**都寫的非常好,從純粹的資料庫索引優化來說,基本達到極致,索引這問題說簡單也簡單,會者不難,但是很多很多初入行的和大學剛畢業的並不是很理解索引效率的關鍵,我上面列的文章有專門一篇講這。

當年面試有個送分題,mysql裡,乙個資料查詢可以用到幾個索引,乙個索引可以用到幾個字段,這個居然也會有不少人搞不清楚。(當然,上古時期的mysql和現在又有了區別,據說新版本的mysql已經可以支援一條查詢多個索引了,具體情況我沒有測試和驗證過。)

基於此,復合索引,索引欄位的選擇,順序的設計,效能的分析,其實我對復合索引很多認識的啟蒙和認知的校驗,都是通過discuz的資料結構體會到的。

2、二分查詢

discuz關於使用者所在地區的查詢,我常用的乙個經典面試題,通過ip表快速反查位址,每秒效率要求千次以上,我專門扒過discuz的**,有一部分是用二分法查詢實現的,但實話說,discuz**執行效率並不高,原因是因為這是乙個通用系統,沒有用到共享記憶體機制,所以源資料載入這塊效率浪費很大。

但二分查詢是乙個對有序佇列快速定位查詢非常有效簡單的演算法,當然,我這麼說出來,肯定很多人覺得很簡單,但是遇到實際場景,還是有很多人想不到用這樣的解決思路。

3、安全儲存

discuz在使用者資訊儲存中,在密碼加密環節用了隨機salt,很多知名**都沒有意識到隨機salt的意義和目的。簡單重述一下,這是你資料庫被扒之後仍能保證使用者密碼安全的有效方式。

我一開始對這個策略也有點糊塗,後來隔了一段時間才明白過來。

資訊保安常識科普

創業公司如何做好資訊保安(上)

創業公司如何做好資訊保安(下)

4、不迷信記憶體效率

這個純粹從**和資料結構來看,可能真的看不到,但我記得戴志康好像分享過心得,說正確使用資料表結構,比使用記憶體效率更高,當時分享的是針對是discuz的使用者session表設計思路,開始聽上去覺得不可思議,但後來發現這是對的。

這個其實給我們後續研發有了很大的啟發,就是不迷信記憶體的效率,我們都知道記憶體讀取寫入的效率遠高於物理硬碟,但是如果我們無結構的讀取並處理資料,可能就明顯不如有正確結構的資料表操作,在後續的優化過程中這樣的範例數不勝數。

後來我們研發工程師(我帶出來的哦),也跟我說,經過實測分析,通過memcache讀取大塊資料並獲得其中的細節資訊,效率遠不如讀取正確索引設計下的資料庫記錄。

另乙個典型範例是,當時我們用到的一些快取表最初是myqsl的heap引擎,因為這是記憶體引擎麼,想當然很快,後來使用過程中發現存在嚴重問題調整為物理儲存的innodb引擎。原因其實很簡單,heap引擎是表級鎖,大量查詢請求時經常鎖死,而innodb是行級鎖,併發查詢下執行效率更優。

那麼有人會說,innodb的寫入效率是災難,哦,其實用非同步機制寫入,效率可以和myisam不相上下的。

此外,寫入效率影響很大的乙個環節是binlog檔案處理,這裡跟**余峰學了一招,順便分享給大家,binlog是順序寫,索引檔案是隨機寫,順序寫比隨機寫效率要高乙個數量級,所以正確的解決方案是,用單獨的物理硬碟儲存binlog,可以有效避免同時寫binlog和索引檔案的不必要開銷。

余峰的大招很多,比如還有如何充分挖掘多核cpu的快取載入原理來提公升mysql查詢和同步效率等等,類似這樣的,但限於我的技術基礎薄弱,以及我們應用場景畢竟沒有那麼苛刻,這類的黑科技完全沒學會。(由於沒學會,可能描述不夠嚴謹)

這裡引申乙個問題,不迷信記憶體效率,要正確理解不同資料儲存引擎,儲存型別的特點和適用場景。

我們當年對discuz, + ucenter + uchome的**做了比較深度的優化和處理,主要處理思路也可以分享一下。

這套系統的主要瓶頸在於是一套通用系統,為了便於安裝,全部基於請求響應和資料庫處理,在通用系統裡,效能已經非常強大,所以優化點在於充分利用系統的邏輯來優化。

第一呢,加快取,也就是在常用sql前加了一層 memcache,減少重複查詢請求,減少資料庫的查詢壓力,順便把ip位址反查的二分處理,全部記憶體化了。

第二呢,非同步化,一些非實時需求的資料儲存請求非同步處理,通過crontab設定定時任務,與memcache聯動。非同步處理後,資料寫請求被裁減了很多,資料庫寫入壓力極大降低。

當時比較笨,還沒研究redis,其實後來發現redis的資料型別更豐富,比memcache要更靈活。

第三,摘聯表,所有聯表查詢單錶化,單錶sql完不成的設計冗餘結構。

目的是為了下一步資料庫的分布式。這步犯的錯誤最多,造成各種線上事故。

第四,分表分庫,

不摘聯表是做不了分表分庫的。分表分庫,通過中介軟體做資料庫的請求分發和傳遞,整個資料支撐體系就擴充套件開了。

基於以上四步,系統的支撐性,資源可擴充套件性上了乙個數量級。

但說起來容易,當時也是步步驚心,犯了很多錯誤,出了很多事故,個人能力不足是最主要的原因。不過對負載,對資料結構的理解也是從中提公升很大。

不過再怎麼說,那也是上古時代的事情了,現在,可能大家看看也就過去了,但我覺得有些思路還是通用的。

吃透資料索引的機理,吃透資料結構的邏輯,吃透系統儲存的機制,吃透查詢響應的整個流程,然後在這中間,去分析潛在的優化點。

你會分析並優化乙個查詢響應  0.01秒的sql麼? 在當時,這是我日常的事情。

場景如下,我們知道在中國,如果我們做乙個論壇,社群,必須有乙個遮蔽詞表,如果使用者發表的文章包含遮蔽詞而系統沒有過濾,一旦被網監發現,性質是很嚴重的,而基於大家都懂得原因,遮蔽詞表越來越長,內容越來越多。

那麼問題來了,如果乙個論壇,每天有大量新的帖子和內容產生,而遮蔽詞表裡內容又很多,那麼,如果你來設計系統遮蔽詞自動審核過濾的程式,你會怎麼做來減輕系統壓力,提公升支撐能力。

你可以認為這是discuz系統的延伸問題,但discuz**裡這部分處理的效率我印象裡並不高。

以後的文章我會給出答案。

最後,如果您不是技術研發,但是您的公司也遇到一些諸如併發,優化的問題,可以酌情考慮**本文給貴司研發人員,當然,有一定概率您也許會遭遇如下答覆,「這麼low的東西就別轉了。」

大染坊 從陳壽亭身上能學到什麼?

程式設計間隙重溫了2003年播出的電視劇集 大染坊 跳著看了10集就被男一陳壽亭的智慧型深深折服。現在對陳做事的風格分析一下此人。藤井希望盡快把從日本運來的一船坯布,但一直找不到買家。陳壽亭問東家盧家駒誰能吃下,家駒回答只有元亨的孫明祖有這個能力,陳壽亭認同。從陳盧的對話可以看出,二人對競爭對手的實...

從Azure雲服務故障中我們能學到什麼?

azure遭雷擊後業務停擺 本月初,azure因遭遇雷擊,造成長時間的業務停頓。隨後又因為伺服器宕機,而再次暫停2小時服務。是否因為azure 流年不利 其實業內人士都了解,這只是意外,而我們無法 意外什麼時候會發生,就跟無法 會因為什麼而發生意外一樣。對於事故勇於承擔並予以解決無疑是令人欣慰的。a...

從Kenshi身上能夠學到什麼

2個人的製作組花費了12年的時間 研發的 廢土沙盒硬核遊戲。遊戲性還那麼好玩。帶給我們的啟示到底是什麼?kenshi 可以近似地看作 騎馬與 模擬人生 輻射 神界 原罪 的集合體。但我可以說市面上沒有一款與 kenshi 相似的遊戲,因為它實在是太獨特了。那麼 做出類似相關 的遊戲 是否能夠以此為鑑...