FROM https://36kr.com/p/5097526.htmlhtml
編者按:本文來自微信公衆號"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 等幾款進入下一步深刻調研。
咱們進行技術選型,有的團隊會根據社交媒體上的討論來決定選擇哪一種架構,有的團隊會跟風走,哪一個熱門就選哪一個,這些都不是正確的方式,咱們應該按照方法論執行。此外,咱們做爲團隊管理者,一邊要督促本身不斷學習新技術,本身可以上手使用,也要結合實際團隊狀況,規劃新技術的預研、落地步驟,讓團隊成員既能享受到穩定技術的紅利,也能不斷地嘗試新事物,讓你們可以看到將來,不擔憂本身逐漸落後於行業的發展,更能提高對於公司的歸屬感。作到這些,真不容易,加油,諸位。