1. 程式人生 > >做技術選型時,要註意些什麽?

做技術選型時,要註意些什麽?

相關 zookeepe 閑聊 基本 新語言 tpi ear 工作態度 復制

FROM https://36kr.com/p/5097526.html

編者按:本文來自微信公眾號"InfoQ"(ID: infoqchina),作者:周明耀,浙江大學工學碩士,13 年軟件研發經驗,近 10 年技術團隊管理經驗,4 年分布式計算、大數據技術經驗,出版書籍包括《大話 Java 性能優化》、《深入理解 JVM&G1 GC》、《技術領導力 - 碼農如何才能帶團隊》;36氪經授權發布。

對於技術選型,有些建議供你參考。此外,還有一個實踐案例供你借鑒。

寫在前面

對於一名熱愛技術的工程師來說,很容易出現非常熱衷於使用新技術的情況,記得有一次和一位做平臺應用的同事閑聊,他問我最近在搞什麽,我說在研究 Hadoop,正在用 MapReduce 處理海量圖片的智能分析,他一臉羨慕:“能搞新技術,真好!”。

作為一名工程師,我可以理解大家的心情,我們都是熱愛嘗試新技術、拋棄過時技術的人。但是首先得明確,到底技術是不是過時的,還是僅僅是你認為它過時了。這篇文章我想談談我對技術選型的理解。

這篇文章不僅僅是寫給工程師,更多是寫給技術團隊負責人(大多數也是從工程師升職上去的,起初思維和工程師差距不大),因為你們具體負責技術選型的方向、方法、過程、結論明確。

技術選型的註意事項

先來看看軟件開發領域的變化,變化實在是太快了。在 JavaScript 裏,幾乎每天都有新框架誕生。Node.js(關鍵詞:事件編程),React 編程,Meteor.js(關鍵詞:共享狀態),前端 MVC,React.js…… 你可以隨便舉例。軟件工程領域裏新概念也層出不窮:領域驅動開發,六邊形架構理論,DCI 架構(數據 - 場景 - 交互)。

洛克希德•馬丁公司的著名飛機設計師凱利•約翰遜所提出的 KISS 原則,指出架構設計能簡單絕不復雜,堅決砍掉任何華而不實的設計,不要因為 3 年後可能怎樣甚至是一些現實中根本無法出現的場景,加入到當下的架構設計中,導致系統無比復雜。有時候看似引入的是一個很簡單很容易解決的問題,可能在具體的執行過程中帶來一系列不必要的麻煩。技術選型其實遇到的問題和系統架構設計類似,也容易出現人為因素導致的偏差,進而出現和系統架構過度設計類似的麻煩。

對於技術選型,有以下幾個建議:

選擇你最熟悉的技術

記得看過一篇文章,裏面提到一個新項目最好不要使用超過 30% 的新技術,我覺得這有一定道理,因為對於你完全不知道的技術,你不可能控制使用過程中出現的風險。我在技術管理中的向下管理裏提起過,任何一位技術 Leader,如果你不能得到下屬的技術尊重,你必將受到懲罰。

也不能說完全不能使用新技術,前幾天和朋友聊天,他提到了另外一位總監下屬有幾個人轉崗了,都是技術牛人,最主要的原因是這位總監堅決排斥新技術,堅持自己熟悉 的十年前的框架和編寫代碼規範。他對於一個新技術的天然不信任,在技術接受程度還不夠高,並且認為公司內沒有人能吃透這個技術的情況下,不願意讓自己的業務做第一個吃螃蟹的人,這種做法不能說完全錯誤,至少對於他自己來說很穩健,但是卻壓制了一些有追求人的內心。

謹慎是個美德,不過如果在一個非常追求速度的業務裏,這可能也意味著過於保守,會延誤時機。

那我們應該怎樣做到選擇技術呢?我認為,在選擇技術時有兩個大原則。第一,要取其長避其短;第二,要關註技術的發展前景。每種技術都是有它特定的適用場景,開發者經常犯的錯誤就是盲目追新,當一個新語言、框架、工具出現後,特別是開發者自己學會了這種新技術後,就會有種“拿著錘子找釘子”的感覺,將新技術濫用於各種項目。

記住,技術選型是穩定壓倒一切。

選擇擁有強大社區支撐的開源技術

沒有人喜歡“alone in the dark”的感覺,同樣,也很少有工程師喜歡孤獨地面對代碼缺陷。我們之所以喜歡在 Apache 上挑選合適的新框架嘗試使用,是因為 Apache 始終保持運作著強大的社區,每天都有很多新建的框架,也設計了一整套生命周期管理標準,讓一個項目能夠從孵化項目逐漸一步步地走向頂級項目。除了像 Apache 這樣的社區,我們也可以評估是否存在一些商業公司提供針對該技術或者框架的有償支撐,一般來說,有公司願意圍繞該技術布局,也能說明確實存在使用空間。例如 Apache Cassandra,目前就有 Datastax 和 LastPickle 兩家公司對它提供技術指導和有償輔助軟件支撐。

其實看一項技術活不活躍,只要去 StackOverflow 這樣的網站看看提問的人多不多就知道了。

確保技術前進步伐

選擇一個技術的最低標準是,技術的生命周期必須顯著長於項目的生命周期。

為什麽需要確保所選擇的技術不斷前進?因為這個世界是發展的,科技發展更是非常得快速,你可以看看,所有的成功的科技公司都是因為跑在了別人前面,而不是慢悠悠的工作態度,這就是科技界的殘酷,也正是為什麽 FaceBook 辦公室裏貼著:“要麽做到最好,要麽死亡”。

技術的前進不僅僅取決於它本身,而是和大環境發展、上下遊用戶也密切相關。比如 AI,60 年代其實就已經提出了相應概念,為什麽直到今年才進入發展元年?因為芯片的計算效率、數據樣本規模沒有達到要求。而 Functional Language 為什麽這麽多年一直默默無聞,而從前幾年開始逐漸盛行?因為機器學習來了,AI 來了,它們有了用武之地。

總的來說,你需要使用你所選擇的軟件技術,快速地實現應用程序的構建。記住一句話:好的技術棧永遠跑在用戶需求前面。

學會從業務端開始思考

技術選型必須貼著業務來選擇,不同業務階段會有不同的選型方式。處於初創期的業務,選型的基準是靈活。只要一個技術夠用並且開發效率足夠高,那麽就可以選擇它。初創的業務往往帶有風險性和不確定性,朝令夕改、反復試錯是常態,技術必須適應業務的節奏,然後才是其他方面。等業務進入穩定期,選型的基準是可靠。技術始終是業務的基石,當業務穩定了技術不穩,那就會成為業務的一塊短板,就必須要修正。當業務進入維護期,選型的基準是妥協。代碼永遠有變亂的趨勢,一般經過一兩年就有必要對代碼來一次大一點的重構。在這種時候,必須得正視各種遺留代碼的遷移成本,如果改變技術選型會帶來遺留代碼重寫,這背後帶來的代價業務無法承受,那麽我們就不得不考慮在現有技術選型之上做一些小修小補或者螺旋式上升的重構。

正因為技術選型和業務相關,我們能夠觀察到一些很明顯的現象:新技術往往被早期創業團隊或大公司的新興業務使用;中大型公司的核心業務則更傾向於用一些穩定了幾年的技術;一個公司如果長期使用一種技術,就會傾向於一直使用下去,甚至連版本都不更新的使用下去。這現象背後都是有道理的。

回到我們的主題,學會從業務端思考。首先我們需要充分地理解業務,理解用戶需求,理解當下需要解決的首要問題,以及可能的風險有哪些,再將目標進行分解,進行具體的技術選型、模型設計、架構設計。

舉個例子。假設我們需要解決的核心問題是並發,則可以通過各種緩存手段(本地緩存、分布式緩存),來提高查詢的吞吐,這樣雖然會一定程度上需要在數據一致性上做出犧牲,由強一致性變為最終一致性。

但是,如果數據一致性不是核心需要解決的問題,那麽,此問題的優先級則可以先放一放,反過來如果核心問題變為數據的一致性,如交易系統,那麽再怎麽強調數據的一致性都不為過,由於分布式環境下為了應對高並發的寫入以及海量數據的存儲,通常需要對關系型數據庫進行分庫分表擴展,這也給數據一致性帶來了很大的挑戰,原本的單庫事務的強一致性保障,在這個時候升級為跨庫的分布式事務,而通過二階段或者三階段提交所保障的分布式事務,由於分布式事務管理器與資源管理器之間的多次網絡通信成本,吞吐及效率上很難滿足高並發場景下的要求,而這實際上對於交易系統來說,又是一個很難回避的問題。

因此,大家又想出很多的招來解決這個問題,通過可靠消息系統來保障不失為一種方式,變同步為異步,但是,又引入新的問題,消息系統為保證不丟消息,則很難保證消息的順序性以及是否重復投遞,這樣作為消息的接收方,則需要保障消息處理的冪等性,以及對消息去重。

先驗證,後使用

對於未經驗證的新技術、新理念的引入一定要慎重,一定要在全方位的驗證過後,再大規模的使用。新技術、新理念的出現,自然有它的誘惑,慎重並不代表保守,技術總是在不斷前進,擁抱變化本身沒有問題,但是引入不成熟的技術看似能帶來短期的收益,但是它的風險或者是後期的成本可能遠遠大於收益。

重視經驗

技術選型是個很需要經驗的活,得有大量的信息積累和輸入,再根據具體現實情況輸出一個結果。我們在選型的時候最忌諱的是臨時抱佛腳、用網上收集一些碎片知識來決策,這是非常危險的,我們得確保自己所有思考都是基於以前的事實,還要弄清楚這些事實背後的假設,這都需要讓知識內化形成經驗。

經驗的本質是什麽,有什麽方法能夠確定自己的經驗增長了,而不是不斷在重復一些很熟悉的東西。我現在的結論是,經驗等於知識索引的完備程度。

我們一生中會積累很多的知識,如果把我們的大腦比作數據庫的話,那我們一定有一部分腦存儲貢獻給了內容的索引,它能幫助我們將關聯知識更快的取出來,並且輔助決策。經驗增長等同於我們知識索引的增長,意味著我們能輕易的調動更多的關聯知識來做更全面的決策。

要想建立好這個知識索引,我們得保持技術敏感性和廣度,也就是要做到持續的信息輸入、內化,並發現信息之間的關聯性,建立索引,記下來。說起來容易,做起來還是挺有難度的。

首先難在信息輸入量大,忘記了怎麽辦。我們的大腦不是磁盤,不常用的知識就會忘記,忘記了就跟沒看過是一回事。我的經驗是一定要對知識進行壓縮,記住的是最關鍵的細節,並且反復的去回味這個細節。

我的實際案例

去年我做了一次對於分布式數據庫的選型工作。我們為什麽要做這次選型?因為存在明確的需求,我們需要解決大規模高並發數據存儲,單次數據不大,但是存儲頻率、讀取頻率都很高,並且要確保不丟失數據,這樣的需求對於關系型數據庫來說,出現了性能瓶頸。

我對於技術選型有自己的一套方法論,我知道,我不可能什麽技術都懂,所以我會按照自己的這套方法論來具體執行,避免出現選型誤差。我的步驟是:“列出需求”-“細分需求”-“明確搜索方向”-“網絡搜索”-“明確評判標準”-“分頭執行”-“匯總材料”-“初步選擇”-“進一步調研”-“會議評審”-“做出決定”。這些步驟太多,需求我已經介紹了,這裏具體再講講我這一次是如何進入下一步選型的,也就是“初步選擇”-“進一步調研”之間的過程。

我通過網絡搜索(進入 Google,搜索 Distributed Database、NoSQL Database 等關鍵詞),我找到了如下這些國內外專家推薦的分布式數據庫,他們的基本描述如下所示:

HyperTable: 一個開源、高性能、可伸縮的數據庫,它采用與 Google 的 BigTable 相似的模型。該數據庫數據按主鍵在物理上排序,適用於數據分析領域,采用 C++ 編寫,可以運行在 HDFS 上面。該數據庫受到 GPLV3 協議約束,考慮到它和 HBase 從系統架構上來說很相似,但是協議約束較多,所以放棄調研,轉而調研 HBase。

HBase: 即 Hadoop Database,是一個高可靠性、高性能、面向列、可伸縮的分布式存儲系統,采用主 / 從架構設計,利用 HBase 技術可在廉價 PC Server 上搭建起大規模結構化存儲集群。它是 Google BigTable 的開源實現。

VoltDB: 一個內存數據庫,提供了 NoSQL 數據庫的可伸縮性和傳統關系型數據庫系統的 ACID 一致性,支持單節點 53000TPS/s。該數據庫受到 GPLV3 協議約束。VoltDB 有兩個版本,一個開源社區版本和一個付費企業版本。付費企業版本除包含了所有開源社區版的功能,還有些其他特點,諸如計算機集群管理控制臺、系統性能儀表盤、數據庫宕機恢復、在線數據庫 Schema 修改、在線數據庫節點重新加入、JDBC 和 OLAP 導出支持、命令日誌。

由於該框架開源社區不活躍,主導者更加希望使用付費版本,所以決定放棄它,轉而調研類似的 Redis。

CloudData: 一個結構化數據庫,沒有中文資料,從系統架構、功能上分析,類似於 MongoDB。

Gridool: 一種基於 MapReduce 原理設計的網格計算引擎,不支持數據存儲,所以放棄。

Ddb-query-optimizer: 找不到資料,放棄。

Cages: 基於 ZooKeeper 實現數據協調 / 同步,不僅能性數據分布式存儲,放棄。

Redis: 一個開源的基於鍵值對和存儲系統,具備高性能特征。支持主從復制(master-slave replication),並且具有非常快速的非阻塞首先同步(non-blockingfirst synchronization)、網絡斷開自動重連等功能。同時 Redis 還具有其他一些特征,其中包括簡單的 check-and-set 機制、pub/sub 和配置設置等,以便使得 Redis 能夠表現得更像緩存(Cace)。絕大部分主流編程語言都有官方推薦的客戶端。

MongoDB: 一個開源的 C++ 編寫的面向集合且模式自由的文檔性數據庫,是 NoSQL 中功能最豐富、最像關系型數據庫的產品。

  • 核心優勢:靈活文檔模型 + 高可用復制集 + 可擴展分片集群;

  • 功能特點:二級索引、地理位置索引、aggregate、map-reduce、OridFS 支持文件存儲。

  • 不足之處:不支持事務,僅支持簡單 left join。

Spanner:Google 的可擴展的、多版本的、全球分布式的同步復制方式數據庫。Spanner 是第一個支持全球規模的分布式數據、外部一致性分布式事務的分布式數據庫。它是一個在遍布全球範圍的數據中心內部通過多套 Paxos 狀態機器共享數據的數據庫。復制被用於全局可用性和地理位置;客戶在副本之間自動切換。當數據量或者服務器數量發生變化時,Spanner 在機器之間自動共享數據,並且 Spanner 在機器之間自動遷移數據(甚至在數據中心之間),用以負載均衡和響應失敗。Spanner 被設計為在幾百萬臺機器之上橫向擴展,這些擴展穿過了數百個數據中心和萬億行數據。功能很強大,可惜沒有開源。

ElasticSearch: 一個基於 Lucene 的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基於 Restful Web 接口。ElasticSearch 是用 Java 開發的,並作為 Apache 許可條款下的開放源碼發布,是當前流行的企業級搜索引擎。

最終通過這些技術之間的互相相似度對比,並且我們設定了一些規則,例如開源協議的約束,這一點其實逐漸開始真正起到約束了,看看 FaceBook 針對 Reactor 的專利約束給大家造成的麻煩,你就懂了。最終,我選擇了 Cassandra、MongoDB、Reddis、MySQL、HBase 等幾款進入下一步深入調研。

寫在最後

我們進行技術選型,有的團隊會根據社交媒體上的討論來決定選擇哪種架構,有的團隊會跟風走,哪個熱門就選哪個,這些都不是正確的方式,我們應該按照方法論執行。此外,我們作為團隊管理者,一邊要督促自己不斷學習新技術,自己能夠上手使用,也要結合實際團隊情況,規劃新技術的預研、落地步驟,讓團隊成員既能享受到穩定技術的紅利,也能不斷地嘗試新事物,讓大家能夠看到未來,不擔心自己逐漸落後於行業的發展,更能提升對於公司的歸屬感。做到這些,真不容易,加油,諸位。

做技術選型時,要註意些什麽?