作技术选型时,要注意些什么?

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 等几款进入下一步深刻调研。

写在最后

咱们进行技术选型,有的团队会根据社交媒体上的讨论来决定选择哪一种架构,有的团队会跟风走,哪一个热门就选哪一个,这些都不是正确的方式,咱们应该按照方法论执行。此外,咱们做为团队管理者,一边要督促本身不断学习新技术,本身可以上手使用,也要结合实际团队状况,规划新技术的预研、落地步骤,让团队成员既能享受到稳定技术的红利,也能不断地尝试新事物,让你们可以看到将来,不担忧本身逐渐落后于行业的发展,更能提高对于公司的归属感。作到这些,真不容易,加油,诸位。