《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 人工智能 > 業(yè)界動(dòng)態(tài) > 基礎(chǔ)軟件“好用”指南:必須跨越這兩道鴻溝!

基礎(chǔ)軟件“好用”指南:必須跨越這兩道鴻溝!

2021-10-26
來(lái)源:CSDN

  最近有一件事情讓我印象特別深刻,作為引子和大家嘮一嘮:我們?cè)趦?nèi)部做一些極端的流量回歸仿真實(shí)驗(yàn)時(shí),在 TiKV(TiDB 的分布式存儲(chǔ)組件)上觀(guān)測(cè)到了異常的 CPU 使用率,但是從我們的 Grafana Metrics、日志輸出里面并沒(méi)有看到異常,因此也一度困惑了好幾天,最后靠一位老司機(jī)盲猜并結(jié)合 profiling 才找到真兇,真兇出現(xiàn)在誰(shuí)都沒(méi)有想到的地方:Debug 用的日志模塊(澄清一下:目前這個(gè) Bug 已經(jīng)修復(fù)了,而且這個(gè) Bug 的觸發(fā)是在非常極端壓力的場(chǎng)景下+日志級(jí)別全開(kāi)才會(huì)出現(xiàn),請(qǐng)各位用戶(hù)放心)。

  這篇文章并不是做 Bug 分析,我覺(jué)得更重要的是,找問(wèn)題過(guò)程中我們使用的工具、老司機(jī)的思考過(guò)程。作為一個(gè)觀(guān)察者,我看到年輕的同事看著老司機(jī)熟練地操作 perf 和在各種各樣工具和界面中切換那種仰慕的眼神,我隱約覺(jué)得事情有點(diǎn)不對(duì):這意味著這門(mén)手藝不能復(fù)制。

  事后,我做了一些關(guān)于基礎(chǔ)軟件用戶(hù)體驗(yàn)的調(diào)研,發(fā)現(xiàn)該領(lǐng)域的理論和資料確實(shí)挺少(大多數(shù)是 ToC 產(chǎn)品的研究,系統(tǒng)軟件相關(guān)的大概只有 UNIX 哲學(xué)流派),而且缺乏系統(tǒng)化,依賴(lài)于作者個(gè)人「品味」,但是軟件體驗(yàn)的好和壞顯然存在,例如一個(gè)有經(jīng)驗(yàn)的工程師看到一個(gè)命令行工具,敲幾下就知道是否好用,是不是一個(gè)有「品味」的工具。

  很多時(shí)候「品味」之所以被稱(chēng)為「品味」,就是因?yàn)檎f(shuō)不清道不明,這固然是軟件開(kāi)發(fā)藝術(shù)性的一種體現(xiàn),但是這也意味著它不可復(fù)制,不易被習(xí)得。我覺(jué)得這也不好,今天這篇以及可能接下來(lái)的幾篇文章(雖然后幾篇我還不知道寫(xiě)啥,但是先立個(gè) Flag)會(huì)試著總結(jié)一下好的基礎(chǔ)軟件體驗(yàn)到底從哪里來(lái)。

  作為第一篇,本文將圍繞可觀(guān)測(cè)性可交互性兩個(gè)比較重要的話(huà)題來(lái)談。至于為什么把這兩點(diǎn)放在一起聊,我先賣(mài)個(gè)關(guān)子,最后說(shuō)。

  可觀(guān)測(cè)性

  可觀(guān)測(cè)性是什么?這可從我兩年前發(fā)表的《我眼中的分布式系統(tǒng)可觀(guān)測(cè)性》[1]一文中可見(jiàn)一斑,相同的內(nèi)容我在這里就不贅述。隨著在 TiDB 中對(duì)可觀(guān)測(cè)性實(shí)踐的深入,對(duì)這個(gè)話(huà)題有了更深的理解,為了更好的理解,我們首先先明確一個(gè)問(wèn)題:當(dāng)我們?cè)诹目捎^(guān)測(cè)的時(shí)候,到底是誰(shuí)在觀(guān)測(cè)?

  是誰(shuí)在觀(guān)測(cè)?

  很多朋友可能會(huì)一愣,心想:這還用說(shuō),肯定是人,總不能是機(jī)器。沒(méi)錯(cuò),的確是人在觀(guān)測(cè),但就是這么一個(gè)淺顯的道理往往會(huì)被軟件設(shè)計(jì)者忽略,所以這兩者的區(qū)別到底是什么?為什么強(qiáng)調(diào)人這個(gè)主體很重要?

  要回答這個(gè)問(wèn)題,需要清楚一個(gè)現(xiàn)實(shí):人的短期工作記憶是很有限的。大量的心理學(xué)研究表明,人類(lèi)工作記憶的容量大致只有 4,即在短期同時(shí)關(guān)注 4 項(xiàng)信息[2],再多的信息就要靠分模塊的方式記憶,如我們快速記憶電話(huà)號(hào)碼的方式,以 13800001111 為例,我們通常不是一個(gè)個(gè)數(shù)字背,而是形如:138-0000-1111 進(jìn)行分組。

  在了解人的心智模型的一些基礎(chǔ)假設(shè)和帶寬后,我想很多系統(tǒng)軟件開(kāi)發(fā)者大概不再會(huì)炫耀:我的軟件有 1000 多個(gè)監(jiān)控項(xiàng)!這不僅不是好事,反而讓更多的信息破壞了短期記憶的形成,引入了更多的噪音,讓使用者在信息的海洋里花很多時(shí)間找關(guān)鍵信息,以及不自覺(jué)的分類(lèi)(我相信大腦的一個(gè)不自覺(jué)的后臺(tái)任務(wù)就是對(duì)信息建索引和分類(lèi),注意這同樣是消耗帶寬的),所以第一個(gè)結(jié)論:軟件應(yīng)用一屏的界面里面最好只有 4 個(gè)關(guān)鍵信息。那么,接下來(lái)的一個(gè)問(wèn)題是:哪些是關(guān)鍵信息?什么是噪音?

  區(qū)分關(guān)鍵信息和噪音

  這個(gè)問(wèn)題沒(méi)有標(biāo)準(zhǔn)答案。對(duì)于系統(tǒng)軟件來(lái)說(shuō),我的經(jīng)驗(yàn)是:跟著關(guān)鍵資源走。軟件其實(shí)很簡(jiǎn)單,本質(zhì)就是對(duì)硬件資源的使用和分配,講究平衡的藝術(shù)。關(guān)鍵的硬件資源無(wú)非也就下面幾個(gè),對(duì)于下面每一個(gè)關(guān)鍵資源在某個(gè)采樣時(shí)間段(單點(diǎn)沒(méi)有太多意義),都可以通過(guò)一些簡(jiǎn)單的問(wèn)題的詢(xún)問(wèn),得到對(duì)系統(tǒng)運(yùn)行狀態(tài)的大致圖景:

  CPU:哪些線(xiàn)程在工作?這些線(xiàn)程都在干嘛?這些線(xiàn)程各自消耗了多少 CPU Time?

  內(nèi)存:當(dāng)前內(nèi)存中存儲(chǔ)了哪些東西?這些東西的命中率情況?(通常我們更關(guān)注業(yè)務(wù)緩存)?

  網(wǎng)絡(luò) I/O:QPS/TPS 有異常嗎?當(dāng)前主要的網(wǎng)絡(luò) I/O 是由什么請(qǐng)求發(fā)起的?帶寬還夠嗎?請(qǐng)求延遲?長(zhǎng)鏈接還是短鏈接(衡量 syscall 的開(kāi)銷(xiāo))?

  磁盤(pán) I/O:磁盤(pán)在讀寫(xiě)文件嗎?讀寫(xiě)哪些文件?大多數(shù)的讀寫(xiě)是什么 Pattern?吞吐多大?一次 I/O 延遲多大?

  關(guān)鍵日志:不是所有日志都有用,只有包含特定關(guān)鍵字的日志,人們才會(huì)關(guān)心。所以,有沒(méi)有特定關(guān)鍵字的日志出現(xiàn)?

     通過(guò)以上標(biāo)準(zhǔn)問(wèn)題的靈魂拷問(wèn),必定可以對(duì)系統(tǒng)運(yùn)行狀態(tài)有一定的了解。

   更進(jìn)一步的關(guān)鍵是,這些系統(tǒng)的指標(biāo)一定要和業(yè)務(wù)上下文聯(lián)系在一起才能好用,舉例說(shuō)明,對(duì)于一個(gè)支持事務(wù)的數(shù)據(jù)庫(kù)來(lái)說(shuō),假設(shè)我們看到 CPU 線(xiàn)程和 call stack,發(fā)現(xiàn)大量的 CPU 時(shí)間花在了 wait / sleep / idle 之類(lèi)的事情上,同時(shí)也沒(méi)有其他 I/O 資源瓶頸,此時(shí),如果只看這些的數(shù)字可能會(huì)一臉懵,但是結(jié)合事務(wù)的沖突率來(lái)看可能柳岸花明,甚至能直接給出這些 lock 的等待時(shí)間都花在了哪些事務(wù),甚至哪些行的沖突上,這對(duì)觀(guān)測(cè)者是更有用的信息。

  也并不是說(shuō)其他的信息就沒(méi)用,而是相當(dāng)多的信息的價(jià)值是后驗(yàn)的,例如:絕大多數(shù)的 debug 日志,或者那些為了證實(shí)猜想的輔助信息,其實(shí)在解決未知問(wèn)題時(shí)候幾乎沒(méi)有幫助,而且還需要觀(guān)察者有大量的背景知識(shí),這類(lèi)信息最好的呈現(xiàn)方式還是折疊起來(lái),眼不見(jiàn)為凈的好。

  如果打開(kāi) TiDB 的內(nèi)部 Grafana 就會(huì)看到大量這樣的指標(biāo),如 stall-conditions-changed-of-each-cf(雖然我知道這個(gè)指標(biāo)的含義,但是我猜 TiDB 的用戶(hù)里 99% 的人不知道),而且從名字里面我看到了寫(xiě)下這個(gè)名字的工程師內(nèi)心的掙扎,他一定很想讓其他人(或者自己)看懂這個(gè)名字指的是什么,但是比較遺憾,至少在我這里沒(méi)有成功。

  觀(guān)察的下一步是什么?作出行動(dòng)。

  在做出行動(dòng)之前想想,有行動(dòng)的前提是什么?我們處理問(wèn)題的行動(dòng)大致會(huì)遵循下面模式(我自己總結(jié)的,但任何一本認(rèn)知心理學(xué)的書(shū)都會(huì)有類(lèi)似的概念):觀(guān)察—>發(fā)現(xiàn)動(dòng)機(jī)—>猜想—>驗(yàn)證猜想—>形成計(jì)劃—>行動(dòng),然后再回到觀(guān)察,反復(fù)循環(huán)。

  這個(gè)里面人(或者是老司機(jī)的經(jīng)驗(yàn))體現(xiàn)比較重要地方是在從觀(guān)察到猜想這個(gè)環(huán)節(jié),至于觀(guān)察的動(dòng)機(jī)而言無(wú)非有兩種:

  1. 解決眼前的故障;

  2. 規(guī)避潛在的風(fēng)險(xiǎn)(避免未來(lái)的故障)。

  假設(shè)系統(tǒng)沒(méi)有問(wèn)題,也不太需要做出改變。  我覺(jué)得這兩步之所以重要,是因?yàn)榛旧掀渌h(huán)節(jié)都可以用自動(dòng)化,唯獨(dú)這兩步很難,因?yàn)樾枰玫剑喝说闹R(shí)/經(jīng)驗(yàn)和直覺(jué)。

  對(duì)于一個(gè)擁有好的可觀(guān)測(cè)性的系統(tǒng),通常都是能很好利用人直覺(jué)的高手,舉個(gè)小的例子:當(dāng)打開(kāi)一個(gè)系統(tǒng)后臺(tái)界面時(shí),我們?cè)囍蝗リP(guān)注具體的文字信息,如果界面中的紅色黃色的色塊比較多,我們的直覺(jué)會(huì)告訴自己這個(gè)系統(tǒng)可能處于不太健康的狀態(tài),更進(jìn)一步如果紅色和黃色大致都聚集在屏幕的某個(gè)具體位置上,我們的注意力一定會(huì)聚焦到這個(gè)位置;如果一個(gè)界面上全是綠色,那應(yīng)該是比較健康的狀態(tài)。

  怎么最大化利用人的直覺(jué)?或者說(shuō)要引導(dǎo)到什么地方?我認(rèn)為最好的點(diǎn)是:風(fēng)險(xiǎn)的預(yù)判。

  人的直覺(jué)用在哪?風(fēng)險(xiǎn)的預(yù)判

  此處需要利用一些先驗(yàn)知識(shí)。在聊這個(gè)話(huà)題之前,我想分享一個(gè)我之前聽(tīng)過(guò)的小故事,當(dāng)年福特工廠(chǎng)里有個(gè)電機(jī)壞了,然后找了個(gè)老師傅,他聽(tīng)了聽(tīng)聲音,看了看機(jī)器運(yùn)轉(zhuǎn)情況,最后用粉筆在電機(jī)上畫(huà)了一條線(xiàn),說(shuō)這個(gè)地方的線(xiàn)圈多繞了多少多少圈,將信將疑的工人們照做,果然問(wèn)題解決了,然后老師傅開(kāi)了個(gè) 1 萬(wàn)美元的維修費(fèi)(當(dāng)時(shí)算是天價(jià)),福特的老板問(wèn)他憑啥畫(huà)一條線(xiàn)就收那么多錢(qián),老師傅開(kāi)了個(gè)賬單:畫(huà)線(xiàn) 1 美元,知道在哪畫(huà)這條線(xiàn) 9999 美元。

  故事的真假暫且不聊,假設(shè)是真的,我們可以看到直覺(jué)和經(jīng)驗(yàn),真的是能產(chǎn)生很多的價(jià)值,我當(dāng)時(shí)聽(tīng)到這個(gè)故事的第一反應(yīng)是,這個(gè)老師傅肯定這種情況見(jiàn)的多了(廢話(huà)),而且這個(gè)問(wèn)題一定是常見(jiàn)問(wèn)題。

  其實(shí)解決問(wèn)題最難部分是通過(guò)觀(guān)察(尤其是一些特征點(diǎn))排除掉絕大多數(shù)不靠譜的方向,另外要相信常見(jiàn)故障的原因是會(huì)收斂的。這時(shí)一個(gè)具有良好可觀(guān)測(cè)性系統(tǒng)的第一步就是能給使用者的直覺(jué)指引方向,這個(gè)方向就需要前人的知識(shí)來(lái)給出可能性最大的故障點(diǎn)以及相關(guān)的指標(biāo)(例如 CPU 使用率等);第二步就是通過(guò)一些心理學(xué)小技巧把它展現(xiàn)出來(lái)。

  下面以 TiDB 中即將會(huì)引入的一個(gè)小功能 TopSQL 加以佐證。這個(gè)功能說(shuō)起來(lái)也很簡(jiǎn)單,我們發(fā)現(xiàn)很多用戶(hù)故障都和少量的 SQL 相關(guān),這類(lèi)的 SQL 的特征是擁有和別的 SQL 有明顯不同的 CPU footprint,但是每一條 SQL 的 footprint 獨(dú)立看起來(lái)還挺正常的,所以 TopSQL 的功能就是回答:CPU 到底消耗了多少?在哪些 SQL 上?我試著不去解讀下面這個(gè)截圖,我猜聰明的你馬上就能知道怎么用:

  微信圖片_20211026165148.jpg

  你的直覺(jué)會(huì)告訴你,后半段那段密集的綠色占比好像和其他有什么不一樣,將整體的 CPU 使用率推高了,感覺(jué)有問(wèn)題的樣子,沒(méi)錯(cuò),這大概就是正確的方向,好的可視化能夠利用人的直覺(jué)快速定位主要矛盾。

  什么叫做“一個(gè)操作”?識(shí)別操作的真正的生命周期

  剛才寫(xiě)第一點(diǎn)的時(shí)候想到還有一個(gè)經(jīng)常被人忽略的關(guān)鍵資源:時(shí)間。本來(lái)想把時(shí)間放到關(guān)鍵資源那節(jié)里面,但是想了想放在這里可能更加合適。

  稍微形而上一點(diǎn)來(lái)看,我們現(xiàn)在的計(jì)算機(jī)都是圖靈機(jī)的實(shí)現(xiàn),我小學(xué)就知道圖靈完備語(yǔ)言的最小功能集合:讀/寫(xiě)變量,分支,循環(huán)。用文學(xué)一點(diǎn)的說(shuō)法是:所謂程序就是無(wú)數(shù)個(gè)輪回,大輪回嵌套著小輪回(循環(huán)),每個(gè)輪回中根據(jù)現(xiàn)狀(變量)不斷的做出選擇(分支)。

  我說(shuō)到這里可能聰明的讀者會(huì)猜到我想說(shuō)什么:如果我們討論可觀(guān)測(cè)性脫離了周期,就毫無(wú)意義。而周期的定義又是靈活的,對(duì)于人而言,大周期顯然是一輩子,小周期可以是一年一日,甚至周期可以不用時(shí)間跨度作為單位,比如一份工作的周期…

  對(duì)于一個(gè)數(shù)據(jù)庫(kù)軟件而言,什么是一個(gè)合理的周期?是一條 SQL 的執(zhí)行周期?還是一個(gè)事務(wù)從 Begin 到 Commit ?這里沒(méi)有標(biāo)準(zhǔn)答案,但是我個(gè)人建議,周期越貼近終端用戶(hù)的使用場(chǎng)景越實(shí)用。

  譬如,在數(shù)據(jù)庫(kù)中,選擇單條 SQL 的執(zhí)行作為周期不如選擇事務(wù)的周期,事務(wù)周期不如應(yīng)用程序一個(gè)請(qǐng)求全鏈路的周期。其實(shí) TiDB 在很早就引入了 OpenTracing 來(lái)追蹤一個(gè) SQL 的執(zhí)行周期內(nèi)到底調(diào)用了哪些函數(shù),花費(fèi)多少時(shí)間,但最早只應(yīng)用在了 TiDB 的 SQL 層內(nèi)部(熟悉我們的朋友應(yīng)該知道我們的 SQL 和存儲(chǔ)是分離的),沒(méi)有在存儲(chǔ)層 TiKV 實(shí)現(xiàn),所以就會(huì)出現(xiàn)一條 SQL 語(yǔ)句的執(zhí)行過(guò)程往下追到 TiKV 就到了一個(gè)斷頭路;

  后來(lái)我們實(shí)現(xiàn)了把 TraceID 和 SpanID 傳到了 TiKV 內(nèi)部這個(gè)功能才算初步可用,至少把一個(gè)周期的圖景變得更加完整了,本來(lái)我們打算就止步于此,但是后來(lái)發(fā)生了一個(gè)小事情,某天一個(gè)客戶(hù)說(shuō):為什么我的應(yīng)用訪(fǎng)問(wèn) TiDB 那么慢?然后我一看 TiDB 的監(jiān)控,沒(méi)有啊,SQL 到數(shù)據(jù)庫(kù)這邊基本都是毫秒就返回了,但是客戶(hù)說(shuō):你看我這個(gè)請(qǐng)求也沒(méi)干別的呀,兩邊怎么對(duì)不上?后來(lái)我們把 Tracer 加進(jìn)來(lái)以后才知道客戶(hù)這邊的網(wǎng)絡(luò)出了點(diǎn)問(wèn)題。

  這個(gè)案例提醒了我,如果能做到全鏈路的 Tracing,這里的全鏈路應(yīng)該是從業(yè)務(wù)端請(qǐng)求開(kāi)始計(jì)算,去看待生命周期才有意義。所以在此之后我們?cè)?TiDB 里面通過(guò)拓展 Session Variable,能夠支持用戶(hù)將 OpenTracing 協(xié)議的 Tracer 信息通過(guò) Session Varible 傳入到 TiDB 的體系中,打通業(yè)務(wù)層和數(shù)據(jù)庫(kù)層,能夠真正實(shí)現(xiàn)的一個(gè)全生命周期的跟蹤,這個(gè)功能也會(huì)在很近的未來(lái)的版本中和大家見(jiàn)面。

  說(shuō)了這么多,總結(jié)幾點(diǎn):

  1. 時(shí)間也是重要資源。

  2. 抓 Sample 也好,做 Trace 也好,選對(duì)周期很重要。

  3. 周期越貼近業(yè)務(wù)的周期越有用。




1.png


本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀(guān)點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話(huà)通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話(huà):010-82306118;郵箱:aet@chinaaet.com。