再见 2016

又到了该写年终总结的时候了。往回翻翻前几年的年终总结,忽然发现去年(2015年)怎么忘了写呢?赶紧把今年的写了,免得放假又给忘了。

2016年最大的惊喜莫过于摇号中签了。摇中后的第一个周末就跑了两家 4S 店,要不是因为赠送的东西太少,LD 不满意,差点就直接开车回家了。第二个周末跑到第三家店,LD 直接把车型从轿车升级成了SUV,而且因为妞妞选中的颜色没有现车,还把排量也给升级了一档。说起来买车这事,我只负责选品牌和车牌号,妞妞负责选颜色,LD 负责选车型,外加最后刷卡。不到一年的时间,车跑了小一万公里,其中大部分是 LD 和妞妞在姥姥家度夏,我每周或每两周回去看她们,再加上回北京的时候,绕着怀柔密云北部山区跑山的路程。五一去了一趟大同看石窟,暑假结束的时候去了一趟北戴河看海游泳。到了冬天,加上优步被卖,滴滴加价,终于开始开车上下班。虽然一年下来,停车,加油,保险,保养等等开销不小,但比起为生活增添的乐趣,买车还是非常划算的。

再来总结一下工作方面。2015年来到雪球,上半年遇上好年景,A股蹭蹭蹭的涨,雪球的各种指标也跟着涨。到了7月,忽然股灾就来了,一切戛然而止。大行情不好,技术上也使不上什么力气:做基础公共 jar 包,做 RPC 服务化拆分,做微服务改造,做底层服务代码重构,做可用性改进,一直磨蹭到年底,依然找不到努力的方向。转过年到了 2016,刚组建的平台组,人一下子全换了一遍。不过还好,基础设施、底层服务、大数据平台三大块业务撑起了平台的架子,主推的新做的推荐系统点击率还行,但在大数据平台上尝试做用户画像以及提升用户活跃度的各种尝试,收效都没能达到预期。下半年在大数据平台上开发了一个数据统计后台,总算找回一点场面。咬咬牙重构了一把搜索系统,为明年的“大数据+搜索+推荐”三大效果改进方向打下了基础。倒腾大数据的那段时间,从 Java 工程师转变成了 SQL 工程师和 Excel 工程师,也算是一段值得回味的经历:写一段超过一百行,join 6个表的 SQL,居然不用测试,一次完成,这个牛我可以吹三个月!

今年在公司组织了两次 hackathon,上半年全民量化交易炒股大赛,下半年全栈开发小程序,遗憾的是我自己一个奖都没有拿到。去年在冲绳年会抽奖,大奖是我们自己发的私募基金的份额,我还是一如既往的不中。看来,我的运气大约都用在了别的地方,都用光了吧。

为了补贴养车的支出,这一年,利用业余时间在“极牛”和“在行”上接了不少技术咨询的单。说是接单,其实就是约在一个咖啡馆里,聊聊天,给一些技术上的建议和意见。在这个过程中,我自己也涨了不少见识:看着各种行业的先行者们,揣着梦想和点子,义无反顾的冲进“互联网+”大潮里。有卖粮食的,有提供临时储物空间的,有用大疆飞行器做远程工地监控的,还有为开锁通下水道的师傅们提供 o2o 的,不一而足。这些传统行业的精英们,看到了自己行业的问题,也看到了“互联网+”带来的解决问题的办法,只是,他们对互联网的了解太少,有的甚至都不知道如何安装 App ,更别说怎么开发一个了。个人预计,接下来的一两年里,很多传统行业都会被“互联网+”给颠覆掉,不过,最后的胜出者,不一定是最先抢跑的先行者罢了。

生活上,这一年算是比较顺利的。去年十一去了一趟泰国清迈,全家人都是第一次出国。年底公司年会组织去了一趟日本冲绳。春节全家又去了柬埔寨暹粒。清明节我回了一趟东安。五一去的大同看云冈石窟。十一去的贵州黄果树瀑布。今年春节计划去普吉岛。妞妞已经能在地球仪或者地图上找到所有去过的城市,能用中文数到一百,用英文数到十。九月开始上幼儿园,虽然每个月有一半的时间缺勤:下雨不去,雾霾不去,咳嗽流鼻涕不去,每周三累了要休息不去。但每次早晨送去幼儿园的时候,都是开开心心的;每天傍晚接的时候,也很少闹脾气。在幼儿园里学会了穿衣服穿鞋,拉拉链,系纽扣。昨天晚上还开始一个人独自睡自己的床。后天幼儿园新年活动,还将人生第一次上台表演节目。

八月份终于鼓足勇气把左边的智齿拔了。医院开了单子让九月去拔右边的,到了约定的日子,我假装忘记了,正常上班去了。公司包午餐,直接后果就是这两年我又开始长肉了,体检开始指标三高了。公司零食管够,开始还经常去吧台淘点好吃的,后来渐渐的就很少去了。健身设备也是,刚来的时候新鲜一阵,后来就视而不见了。不过每周四下午公司组织踢足球,我还是几乎每场都到。虽然技术很烂,还硬要踢着前锋的位置,偶尔捡漏进一个两个球,冒充一下大牌球星,感觉也不错。

依然岁月静好。依然现世安稳。

转:各大互联网公司架构演进之路汇总

原文地址:各大互联网公司架构演进之路汇总 by HollisChuang
请转载时务必保留文章的上述原始出处。

Web

支付宝和蚂蚁花呗的技术架构及实践
支付宝的高可用与容灾架构演进
聚划算架构演进和系统优化 (视频+PPT)
淘宝交易系统演进之路 (专访)
淘宝数据魔方技术架构解析
淘宝技术发展历程和架构经验分享(视频+PPT)(2.3日更新)
高德——快速转型时期的稳定性架构实践(视频+PPT)(2.3日更新)
秒杀系统架构分析与实战
腾讯社区搜索架构演进(视频+PPT)
京东峰值系统设计
京东咚咚架构演进
新浪微博平台架构
微博图床架构揭秘
微博推荐架构的演进
当当网系统分级与海量信息动态发布实践
当当网架构演进及规划实现(视频+PPT)
LinkedIn架构这十年
Facebook’s software architecture(英文)
从0到100——知乎架构变迁史
豆瓣的基础架构
搜狗搜索广告检索系统-弹性架构演进之路(视频+PPT)
小米网抢购系统开发实践
小米抢购限流峰值系统「大秒」架构解密
海尔电商峰值系统架构设计最佳实践
唯品会峰值系统架构演变
1号店电商峰值与流式计算
蘑菇街如何在双11中创造99.99%的可用性
麦包包峰值架构实践
苏宁易购:商品详情系统架构设计
携程的技术演进之路
篱笆网技术架构性能演进(视频+PPT)
从技术细节看美团的架构(1.26日更新)
美团云的网络架构演进之路(2.3日更新)
百度开放云大数据技术演进历程(视频+PPT)(2.3日更新)
途牛供应链系统的架构演进(视频+PPT)(2.3日更新)
Airbnb架构要点分享(2.3日更新)
12306核心模型设计思路和架构设计(2.20日更新)

无线

阿里无线技术架构演进
支付宝钱包客户端技术架构(2.3日更新)
手机淘宝构架演化实践
手淘技术架构演进细节
手机淘宝移动端接入网关基础架构演进之路
微信后台系统的演进之路
微信红包的架构设计简介
微信Android客户端架构演进之路
Android QQ音乐架构演进(视频+PPT)
快的打车架构实践
Uber 四年时间增长近 40 倍,背后架构揭秘
Uber容错设计与多机房容灾方案
大众点评移动应用的架构演进(视频+PPT)
饿了么移动APP的架构演进

其他

魅族实时消息推送架构
魅族云端同步的架构实践和协议细节


欢迎补充!~

创业公司需要基础架构团队吗?[极牛编辑修改版]

关于「真格 · 极牛技术分享」

「真格 · 极牛技术分享」- 极牛为真格基金投资公司打造的定期技术分享交流活动,采用“微信群分享 + 线下沙龙”的方式,分享和讨论新技术优秀应用实践、知名创业项目架构分析、技术工具评测和分析等技术话题。极牛愿与真格基金投资公司一起努力,共同提高中国创业技术含金量,打造一流技术能力。

关于唐福林

雪球首席架构师,前微博技术委员会成员,微博平台架构师;Java 后端程序员,已经不写 PHP,C 和 Pascal 很多年;ACM/ICPC 和 NIO 比赛深度参与者。

技术交流欢迎在微博上关注我 @唐福林

炒股,理财,资产管理,量化交易相关,欢迎在雪球关注我 @唐福林 xueqiu.com/fulin


近期,在极牛举办的「真格 · 极牛技术分享」上,唐福林集中分享了在微博和雪球做架构师和带架构团队的经历,并且对创业公司是否需要基础架构团队这个问题给出了深度解答。以下是唐福林分享文字内容。

1. 基础架构团队到底做些什么

要解答创业公司到底需不需要基础架构团队这个问题,首先我们来来聊一聊基础架构团队的职能是什么。

基础架构团队到底做些什么?

  • 为实现业务功能:技术选型,决策
  • 为了更好的实现业务功能:引入新技术/做法,提供内部支持
  • 解决历史遗留的技术债务:发现问题,找出解决方案,并推动解决
  • 业务开发 与 线上运维 中间有很宽的“三不管”地带需要填充,还需要坚实的基础设施支持

架构组工作的特点有哪些?

  •  基础架构团队存在的价值是解决非业务逻辑的技术相关问题,没有产品或运营驱动
  • 从技术角度看,每个问题都有很多种解决办法
  • 这些问题一般都是重要不紧急,短期内不解决也不会崩
  • 解决这些问题带来的价值对于非技术人员(特别是老板)不是很直观

 

2. 基础架构团队是创业公司技术发展的必然产物

在“社会主义初级阶段”,还不需要独立的基础架构组。比如,一开始,1~3 人小团队team leader 自己做决策,出问题 team leader 解决,用啥语言?cache?db?上不上云?这些问题直接导致了团队后续技术力量的升级。

到了Demo阶段,也就是3~5 人小团队,这时候应该有个架构师了,技术问题就会留给架构师解决,比如用啥框架?第三方库怎么选择?

后期发展到上线阶段,大概是5~10 人小团队,可以分组了,每个组都要有一个架构师,解决的问题就变成相互之间怎么配合?怎么保持公共基础部分的一致性?怎么解决互相依赖问题?

做好了前期的准备工作,到了公司的发展阶段,技术团队变成10~30 人,就应该有专人负责基础架构了,主要负责业务无关的技术基础设施维护,服务化框架以及治理,上线的流程等一系列问题。

如果业务到了爆发阶段,有了30~100 人的团队,就应该设置专门的基础架构团队了,开始负责技术基础设施及服务,提供内部的 PaaS,或者 SaaS等。

最后到了100+人的“高级阶段”–平台阶段,应该设置平台团队了,将公司的主体核心业务功能做成服务,供商业化或创新业务使用。在平台内部设置架构组,提供高附加值的技术支撑,异地多机房部署,大规模虚拟化平台这些宏观上的部署和组建就要开始认真思索了。

 

3,基础架构能做的再好一点吗?

 

2012年,我在微博的个人的职责从工程师转变成了架构组的组长,最重要的职责从自己写代码,转变成了“如何创造条件让团队成员更好的写代码”。这一年,微博平台壮大,职责划分逐渐明晰,我开始真正从管理领导层面思考怎么才能让基础架构做的更好一点。

首先是怎么做的问题,最重要的要求是要主动多想,没有外力驱动的时候要自我驱动,提高主动性,寻求目标,进行自我评价,没有外力驱动,没人外人评价,我们很容易陷入一种自我满足的困境:看,我做好了,我做的很牛,这回肯定可以评个优,年底多发奖金了吧。

而实际上,大部分时候,我们做的都还不够好。这里的好有两层意思:从技术本身的角度评价,跟周边公司横向比较等等;另外,就是你做的东西有没有真正的完全解决问题,不是从做的人的角度看,而是从碰到问题需要解决的人的角度看,比如业务开发团队是不是觉得好用,是不是觉得这正是他们想要的?

其次在做事的态度上,要力往一处使,因为解决一个技术问题可能有很多种办法,基础架构团队的职责就是找出一种办法,并推行到所有适合的场合,在这个取其精华去其糟粕的过程中一定要见识一起改进,禁止另起炉灶。

做任何事都要讲求方式,做基础架构的方式就是用数据说话,找到合适的评价数据指标,比如写了一个牛B的rpc框架?到底好不好,好在哪里?

另外很重要的是对于选人的要求,要能耐得住寂寞,尤其是在业务爆发式增长时,基础架构团队更需要耐得住寂寞。组建一支牛B的基础架构团队,让业务开发人员跳槽到另外一家公司以后,还会想起你们的好。所有从 Google 出来的人,都会怀念 G 家的内部基础设施。

对创业公司来说,基础架构极其重要,尤其是小的创业团队应尽早安排一个“架构师”的职位,招聘或内部培养一个架构师,如果发现一个架构师忙不过来,那就是时候扩大成一个基础架构团队了。

漫谈基础架构团队的价值 [分享稿文字版]

漫谈基础架构团队的价值
@唐福林 weibo.com/tangfl
陆续在微博和雪球做了几年的架构师,也带了几次基础架构团队,因而在多个场合被问到类似创业公司需要基础架构团队吗”“基础架构团队怎么招聘,如何管理一类的问题。于是前些天在极牛举办的「真格 · 极牛技术分享」上集中分享了我做架构师和带架构团队的经历,以及我个人对架构团队的价值的理解和思考。现将分享的内容整理成文如下,请大家指正。
  • 关于我
     首先简单介绍一下我自己:
    • 雪球首席架构师
    • 前微博技术委员会成员,微博平台架构师
    • Java 后端程序员,已经不写 PHPC  Pascal 很多年
    • ACM/ICPC  NIO 比赛深度参与者
    • 技术交流欢迎在微博上关注我 @唐福林 weibo.com/tangfl
    • 炒股,理财,资产管理,量化交易相关,欢迎在雪球上关注我 @唐福林 xueqiu.com/fulin
  • 微博平台架构组经历分享
    • 2010年底加入微博平台部
      • 当时名称为微博开放平台
      • t.sina.com.cn 为两套独立体系

Description: weibo.png

     左边是当时的 t.sina.com.cn,内部一般称为主站PHP 写的。右边是我们的基于 Java  API 体系,当时称为 OpenApi,因为我们当时主要面向外面的第三方开发者,为他们提供 open apiOpenApi 主站之间通过 Queue 互相同步数据。微博当时选择的是内部开发的 MemcacheQ,简称 MCQ 。这种模式下最大的好处是互不影响,最大的问题呢,就是数据不一致,甚至业务逻辑不一致。
     当时我个人的职责是重构和维护微博短链接服务t.cn 。事实上,我最开始接手项目的时候,还是 sinaurl.cn,是用 PHP 写的,我拿过来用 Java 重写了一遍,正准备上线,老板说要把域名换成 t.cn,然后我就一通狂改代码。当时平台内部容器都是用 Tomcat 6,短链项目是第一个尝试用 Jetty,但后来失败了又换回 Tomcat 了。
     这一年最大的收获是:学会了怎么写好的业务实现代码。
    • 2011年微博平台化
      • 统一一个平台底层,为上层 OpenApiWeb主站和无线App端提供 api
      • 平台负责稳定性,性能和扩展性

Description: weibo2.png

     当时我的个人职责是负责引入Redis来实现计数器和关系缓存功能。微博大约是国内第一家大规模应用Redis 的公司了吧,到2011年底的时候,我们已经部署了超过100台服务器,总计超过8T的内存。我们有自己修改过的RedisCounter专门用来高效的存储计数(用户的关注数粉丝数,每条微博的转发数,评论数,赞数等等)。我在Jedis client 的基础上包装了内部使用的客户端,增加了大量的异常处理,HAFail Fast等功能,还开发了一个支持滚动删除旧数据的 Redis 集群功能。
     这一年最大的收获是:学会了怎么设计并实现一个大的模块功能,做到高可用,以及如何应付高并发流量。
     PS,这也是我现在给创业公司推荐的架构,后端HttpHttps Rest Api,优先推荐Java技术栈实现,Cache 推荐使用RedisDB推荐使用Mysql,前端WebAndroid iOS、微信公众号等等都独立实现,或者共享某些 H5 页面。如下图所示

Description: commonArch.png

 
    • 2012年,平台壮大,职责划分
      • 用户关系
      • 内容
      • 私信IM
      • 公共:通知,提醒,导航 etc
      • 架构
     当时我个人的职责从工程师转变成了架构组的组长,最重要的职责从自己写代码,转变成了如何创造条件让团队成员更好的写代码。那一年微博平台架构团队最重要的几个产出包括:
      • 新版聚合框架 poly
      • redis 二次开发
      • 多机房同步队列 weibus
      • 数据管道firehose
      这一年,我最大的收获是,在摸索中逐渐理解了基础架构团队应该做什么,应该怎么做,并且逐渐的学习如何带基础架构团队,如何为团队中的其它人创造更好的条件,帮助他们写更好的代码。
    • 2013年,微博高可用改进
      • 压测平台 touchstone
      • 平台SLA体系
      • 平台多机房隔离部署
    • 2013年,微博平台服务化
      • RPC 框架 motan
      • 服务化治理体系:config servicetrace 系统,monitorCI & CD
     2013年因为人员变动,我从架构组组长空降到用户关系组任组长。虽然换到了业务组,但还是主导了平台的多个重大技术改造项目,比如压测平台touchstonerpc框架motan,以及motan上线后的服务化治理体系。
     这一年,我最大的收获是,从业务组的角度观察架构团队,更清晰的感受到了架构组的作用和价值,也更深的理解了架构组如何做项目,如何将项目成功落地推广。
    • 2014年,微博上市
      • 商业化:各种商业化需求支持
      • 成本缩减
      • feed流性能优化
     2014年主要的技术工作是feed流性能优化,和成本缩减。在feed流性能优化项目中,我负责探索从 App 客户端到 PHP 再到 Java Api 再到 Cache 最后到 DB 的全链路耗时监控统计;而成本缩减项目最后演变成了 Docker 应用预研。后来我离职后,Docker 的应用转交给用户关系组的接任组长继续进行了。
     这一年,我最大的收获是,学会了从更高层(部门,公司,甚至行业)的角度去理解基础架构团队的工作,去决策做什么,以及更重要的:不做什么。
  • 雪球平台组经历分享
    • 2015年,雪球首席架构师
      • 上半年牛市:性能优化,可用性改进
      • 下半年熊市:大数据平台,推荐,反垃圾,流式计算平台
      • 对外分享,招聘面试
      • 对内建立技术规范,上线流程
     在2015年底,雪球基础架构组升级成了平台组。当前负责维护雪球内部多个重要服务,包括用户关系服务,IM服务,搜索服务,大数据平台,推荐服务,反垃圾服务,以及开发流程和代码质量改进等等。
     这一年,我最大的收获是理解了基础架构团队在不同的公司中,以及公司的不同发展阶段的差异,包括价值观,做事方式,评价方式等等。
  • 基础架构团队的价值与思考
首先来聊一聊基础架构团队应该做什么
    • 做什么
      • 为实现业务功能:技术选型,决策
      • 为了更好的实现业务功能:引入新技术/做法,提供内部支持
      • 解决历史遗留的技术债务:发现问题,找出解决方案,并推动解决
      • 业务开发  线上运维 中间有很宽的三不管地带需要填充,还需要坚实的基础设施支持
从团队发展历程的角度看
    • 一开始,1~3 人小团队
      • team leader 自己做决策
      • 出问题 team leader 解决
      • 用啥语言?cachedb?上不上云?
    • Demo阶段,3~5 人小团队
      • 应该有个架构师了
      • 技术问题架构师解决
      • 用啥框架?第三方库选择?
    • 上线阶段,5~10 人小团队
      • 应该分组了
      • 每个组有一个架构师
      • 怎么配合?怎么保持公共基础部分的一致性?怎么解决互相依赖问题?
    • 发展阶段,10~30 人团队
      • 应该有专人负责基础架构了
      • 业务无关的技术基础设施维护
      • 偏技术的
        • 性能,高可用等等
        • docker
        • HadoopELK
      • 偏工程的
        • 重构
        • 服务化框架,治理
        • 公共第三方依赖管理,升级:jvmtomcatlog4j
      • 偏运维的
        • trace 系统
        • monitor
        • alert
        • 线上开关系统
      • 偏流程的
        • 开发流程规范
        • 代码质量保证:UTcode review
        • 上线流程:CI & CD
    • 爆发阶段,30~100 人团队
      • 应该设置基础架构团队了
      • 技术基础设施即服务
      • 提供内部的 PaaS,或者 SaaS
        • DB / Cache / Queue Service
        • 虚拟化平台
        • 大数据平台
        • 流式计算平台
    • 平台阶段,100+ 人团队
      • 应该设置平台团队了
      • 平台即服务
      • 将公司的主体核心业务功能做成服务,供商业化或创新业务使用
        • 用户服务
        • 帖子服务
        • 商品服务
        • 评论服务
      • 在平台内部设置架构组
      • 提供高附加值的技术支撑
        • 异地多机房部署
        • 大规模虚拟化平台
    
     再往后?我也不知道,大概是设立研究院之类的吧
    • 架构组工作的特点
      • 基础架构团队存在的价值是解决非业务逻辑的技术相关问题,没有产品或运营驱动
      • 从技术角度看,每个问题都有很多种解决办法 
      • 这些问题一般都是重要不紧急,短期内不解决也不会崩
      • 解决这些问题带来的价值对于非技术人员(特别是老板)不是很直观
    • 怎么做
      • 最重要的要求:主动,多想
        • 没有外力驱动:自我驱动
        • 没有产品KPI:自己寻找目标
        • 没有外人评价:自己评价
        • 有哪些要做的,哪些应该先做,哪些应该延后做
        • 最后一公里:我能做的再好一点吗
     没有外力驱动,没人外人评价,我们很容易陷入一种自我满足的困境:看,我做好了,我做的很牛,这回肯定可以评个优,年底多发奖金了吧。而实际上,大部分时候,我们做的都还不够好。这里的好有两层意思:从技术本身的角度评价,跟周边公司横向比较等等;另外,就是你做的东西有没有真正的完全解决问题,不是从做的人的角度看,而是从碰到问题需要解决的人的角度看,比如业务开发团队是不是觉得好用,是不是觉得这正是他们想要的?

 

      • 做事的态度:力往一处使
        • 解决一个技术问题有很多种办法
        • 基础架构团队的职责就是找出一种办法,并推行到所有适合的场合
        • 觉得不满或有意见?一起改进,禁止另起炉灶
      • 做事的方式:数据说话
        • 找到合适的评价数据指标
        • 写了一个牛Brpc框架?到底好不好,好在哪里?
        • 服务质量数据指标三板斧
        • qpsp99响应时间,error rate
      • 选人的要求:耐得住寂寞
        • 业务爆发式增长时,基础架构团队需要耐得住寂寞
        • 业务不增长时,基础架构团队更需要耐得住寂寞
    • B的基础架构团队
      • 让业务开发人员跳槽到另外一家公司以后,才想起你们的好
      • 举例:所有从 Google 出来的人,都会怀念 G 家的内部基础设施
  • 简单总结
    
     简单总结一下,结论就是
    • 基础架构很重要,应尽早安排一个“架构师”的职位,招聘或内部培养一个架构师;如果发现一个架构师忙不过来,那就应该扩大成一个基础架构团队了
    • 架构师自己要有想法,知道要做什么,知道先做什么,知道要做成什么样
    • 架构师自己要动手写代码
    • 架构团队不能离业务太远,要适当负责一些底层业务
    • 用数据说话,不仅架构团队,整个技术团队都应该这样
 
啰嗦了很多,回过头一看,自己感觉还是有些凌乱,大概是自己也还有很多没有想清楚的地方吧。欢迎大家就这个话题一起来讨论。

从LinkedIn,Apache Kafka到Unix哲学

原文链接:
http://www.confluent.io/blog/apache-kafka-samza-and-the-Unix-philosophy-of-distributed-data
作者:Martin Kleppmann
译者:杰微刊-macsokolot(@gmail.com)

当我在为我的书做研究时,我意识到现代软件工程仍然需要从20世纪70年代学习很多东西。在这样一个快速发展的领域,我们往往有一种倾向,认为旧观念一无是处——因此,最终我们不得不一次又一次地为同样的教训买单,这真艰难。尽管现在电脑已经越来越快,数据量也越来越大,需求也越来越复杂,许多老观点至今仍有很大的用武之地。

在这篇文章中,我想强调一个陈旧的观念,但它现在更应该被关注:Unix哲学(philosophy)。我将展示这种哲学与主流数据库设计方式截然不同的原因;并探索如果现代分布式数据系统从Unix中学到了一些皮毛,那它在今天将发展成什么样子。

LinkedIn,ApacheKafka,Unix

特别是,我觉得Unix管道与ApacheKafka有很多相似之处,正是由于这些相似性使得那些大规模应用拥有良好的架构特性。但在我们深入了解它之前,让我稍稍跟你提一下关于Unix哲学的基础。或许,你之前就已经见识过Unix工具的强大之处——但我还是用一个大家相互都能讨论的具体例子来开始吧。
假设你有一个web服务器,每次有请求,它就向日志文件里写一个条目。假设使用nginx的默认访问日志格式,那么这行日志可能看起来像这样:
216.58.210.78 – – [27/Feb/2015:17:55:11 +0000] “GET /css/typography.css HTTP/1.1”
200 3377 “http://martin.kleppmann.com/” “Mozilla/5.0 (Macintosh; Intel Mac OS X
10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36”
(这里实际上只有一行,分成多行只是方便阅读。)此行的日志表明,服务器在2015年2月27日17:55:11从客户端地址216.58.210.78收到了一个文件请求/css/typography.css。它还记录了其他各种细节,包括浏览器的用户代理字符串。
许多工具能够利用这些日志文件,并生成您的网站流量报告,但为了练练手,我们建立一个自己的工具,使用一些基本的Unix工具,在我们的网站上确定5个最热门的网址。首先,我们需要提取出被请求的URL路径,这里我们可以使用awk.
awk并不知道nginx的日志格式——它只是将日志文件当作文本文件处理。默认情况下,awk一次只能处理一行输入,一行靠空格分隔,使之能够作为变量的空格分隔部件$1, $2, etc。在nginx的日志示例中,请求的URL路径是第7个空格分隔部件:

LinkedIn,ApacheKafka,Unix

现在我们已经提取出了路径,接下来就可以确定服务器上5个最热门的网站,如下所示:
这一系列的命令执行后输出的结果是这样的:
4189 /favicon.ico
3631 /2013/05/24/improving-security-of-ssh-private-keys.html
2124 /2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
1369 /
915 /css/typography.css

LinkedIn,ApacheKafka,Unix

如果你并不熟悉Unix工具的话,上述命令看起来有点难懂,但它真的很强大。这几条简单的命令能够在几秒钟内处理千兆字节的日志文件,而且你可以根据需要,非常容易地更改分析内容。比如说,你现在想统计访问次数最多的客户端IP地址,而不是最热门的那几个网页,只需更改awk的参数'{print $1}’
按需求使用这些组合命令awk, sed, grep, sort, uniq , xargs的话,海量数据分析能够在几分钟内完成,其性能表现让人出乎意料。这不是巧合,是Unix设计哲学的结果。

LinkedIn,ApacheKafka,Unix

Unix哲学就是一套设计准则, 在20世纪60年代末与70年代初,这些准则是在设计和实现Unix系统时才逐渐出现的。关于Unix哲学有非常多的阐述,但有两点脱颖而出,由Doug McIlroy, Elliot Pinson 和Berk Tague在1978年描述如下:
1. 每个程序只做好一件事。如果有新的任务需求,那就编写一个新的程序而不是在一个旧的程序上加一个新的“功能”,使其越来越复杂。
2. 期望每个程序的输出都能是其他程序的输入,即使是未知的程序。
这些准则是能把各种程序连接成管道的基础,而有了管道就能完成复杂的处理任务。这里的核心思想就是一个程序不知道或者说不需要关心它的输入是从哪里来的,输出要往哪里去:可能是一个文件,或者操作系统的其他程序,又或者是完全由某个开发者开发的程序。

LinkedIn,ApacheKafka,Unix

操作系统附带的工具都是通用的,但是它们被设计成能够组合起来执行特定任务的较大的程序。
Unix的设计者遵循这种程序设计方法所带来的好处有点像几十年后出现的Agile 和DevOps的成果:脚本与自动化,快速原型编码(rapid prototyping),增量迭代,友好的测试(being friendly to experimentation),以及将大型项目分解成可控的模块。再加上CA的改变。(Plus ?a change.)

LinkedIn,ApacheKafka,Unix

当你在shell里为2个命令加上管道的标示符,那么shell就会同时启动这2个命令程序,然后将第一个程序处理的输出结果作为第二个程序的输入。这种连接机构由操作系统提供管道系统调用服务。

请注意,这种线性处理不是由程序本身来完成的,而是靠shell——这就使得每个程序之间是“松耦合”,这使得程序不用担心它们的输入从哪里来,输出要往哪里去。

LinkedIn,ApacheKafka,Unix

1964年,管道(Pipe)由Doug McIlroy发明,他首次在Bell实验室内部备忘录里将其描述为:“我们需要一些连接各种程序的方法就像花园里的软管——当它成为另一种必要的消息数据时,需要拧入其他的消息段。” Dennis Richie后来将他的观点写进了备忘录

LinkedIn,ApacheKafka,Unix

他们也很早就意识到进程间的通信机制(管道)与读写文件机制非常相似。我们现在称之为输入重定向(用一个文件内容作为一个程序的输入)和输出重定向(将一个程序的结果输出到一个文件)。
Unix程序之所以能够有这么高的组合灵活性,是因为这些程序都遵循相同的接口:大多数程序都有一个数据输入流(stdin)和两个输出流(stdout常规数据输出流和stderr错误与诊断信息输出流)。

LinkedIn,ApacheKafka,Unix

程序通常除了读stdin流和写stdout流之外,它们还可以做其它的事,比如读取和写入文件,在网络上通信,或者绘制一个用户界面。然而,该stdin/stdout通信被认为是数据从一个Unix工具流向另一个的最主要的途径。
其实,最令人高兴的事莫过于任何人可以使用任意语言轻松地实现stdin/stdout接口。你可以开发自己的工具,只要其遵循这个接口,那么你的工具能和其他标准工具一样高效,并能作为操作系统的一部分。

LinkedIn,ApacheKafka,Unix

举个例子,当你想分析一个web服务器的日志文件,或许你想知道来自每个国家的访问量有多少。但是这个日志并没有告诉你国家信息,只是告诉了你IP地址,那么你可以通过IP地理数据库将IP地址转换成国家。默认情况下,你的操作系统并没有附带这个数据库,但是你可以编写一个将IP地址放进stdin流,将输出国家放进stdout流的工具。
一旦你把这个工具写好了,你就可以将它使用在我们之前讨论过的数据处理管道里,它将会工作地很好。如果你已经使用了Unix一段时间,那么这样做似乎很容易,但是我想强调这样做非常了不起:你自己的代码程序与操作系统附带的那些工具地位是一样的。
图形用户界面的程序和Web应用似乎不那么容易能够被拓展或者像这样串起来。你不能用管道将Gmail传送给一个独立的搜索引擎应用,然后将结果输出到wiki上。但是现在是个例外,跟往常不一样的是,现在也有程序能够像Unix工具一样能够协同工作。

LinkedIn,ApacheKafka,Unix

换个话题。在Unix系统开发的同时,关系型数据模型就被提出来了,不久就演变成了SQL,被运用到很多主流的数据库中。许多数据库实际上仍在Unix系统上运行。这是否意味着它们也遵循Unix哲学?

LinkedIn,ApacheKafka,Unix

在大多数据库系统中数据流与Unix工具中非常不同。不同于使用stdin流和stdout流作为通信渠道,数据库系统中使用DB server以及多个client。客户端(Client)发送查询(queries)来读取或写入服务器上的数据,server端处理查询(queries)并发送响应给客户端(Client)。这种关系从根本上是不对称的:客户和服务器都是不同的角色。

LinkedIn,ApacheKafka,Unix

Unix系统里可组合性和拓展性是指什么?客户端(Clients)能做任何他们喜欢的事(因为他们是程序代码),但是DB Server大多是在做存储和检索数据的工作,运行你写的任意代码并不是它们的首要任务。
也就是说,许多数据库提供了一些方法,你能用自己的代码去扩展数据库服务器功能。例如,在许多关系型数据库中,让你自己写存储过程,基本的程序语言如PL / SQL(和一些让你在通用编程语言上能运行代码比如JavaScript)。然而,你可以在存储过程中所做的事情是有限的。
其他拓展方式,像某些数据库支持用户自定义数据类型(这是Postgres的早期设计目标),或者支持可插拔的数据引擎。基本上,这些都是插件的接口:

你可以在数据库服务器中运行你的代码,只要你的模块遵循一个特定用途的数据库服务器的插件接口。
这种扩展方式并不是与我们看到的Unix工具那样的可组合性一样。这种插件接口完全由数据库服务器控制,并从属于它。你写的扩展代码就像是数据库服务器家中一个访客,而不是一个平等的合作伙伴。

LinkedIn,ApacheKafka,Unix

这种设计的结果是,你不能用管道将一个数据库与另一个连接起来,即使他们有相同的数据模型。你也不能将自己的代码插入到数据库的内部处理管道(除非该服务器已明确提供了一个扩展点,如触发器)。
我觉得数据库设计是很以自我为中心的。数据库似乎认为它是你的宇宙的中心:这可能是你要存储和查询数据,数据真正来源,和所有查询最终抵达的唯一地方。你得到管道数据最近的方式是通过批量加载和批量倾倒(bulk-dumping)(备份)操作,但这些操作不能真正使用到数据库的任何特性,如查询规划和索引。
如果数据库遵循Unix的设计思想,那么它将是基于一小部分核心原语,你可以很容易地进行结合,拓展和随意更换。而实际上,数据库犹如极其复杂,庞大的野兽。Unix也承认操作系统不会让你真的为所欲为,但是它鼓励你去拓展它,你或许只需一个程序就能实现数据库系统想要实现所有的功能。

LinkedIn,ApacheKafka,Unix

在只有一个数据库的简单应用中,这种设计可能还不错。
然而,在许多复杂的应用中,他们用各种不同的方式处理他们的数据:对于OLTP需要快速随机存取,数据分析需要大序列扫描,全文搜索需要倒排索引,用于连接的数据图索引,推荐引擎需要机器学习系统,消息通知需要的推送机制,快速读取需要各种不同的缓存表示数据,等等。
一个通用数据库可以尝试将所有这些功能集中在一个产品上(“一个适合所有”),但十有八九,这个数据库不会为了某个特定的功能而只执行一个工具程序。在实践中,你可以经常通过联合各种不同的数据存储和检索系统得到最好的结果:例如,你可以把相同的数据并将其存储在关系数据库中,方便其随机访问,在Elasticsearch进行全文搜索,在Hadoop中做柱状格式分析,并以非规范化格式在memcached中缓存。
当你需要整合不同的数据库,缺乏Unix风格的组合性对于整合来说是一个严重的限制。(我已经完成了从Postgres中用管道将数据输出到其他应用程序,但这还有很长的路要走,直到我们可以简单地用管道将任一数据库中的数据导出到其他数据库。)

LinkedIn,ApacheKafka,Unix

我们说Unix工具可组合性是因为它们都实现相同的接口——stdin,stdout和stderr——它们都是文件描述符,即:可以像文件一样读写的字节流。这个接口很简单以致于任何人都可以很容易地实现它,但它也足够强大,你可以使用它做任何东西。
因为所有的Unix工具实现相同的接口,我们把它称为一个统一的接口。这就是为什么你可以毫不犹豫地用管道将gunzip数据输出WC中去,即使开发这两个工具的作者可能从来没有交流过。这就像乐高积木,它们都用相同的模式实现节位和槽位,让你堆乐高积木的时候能够随心所欲,不用管它们的形状,大小和颜色。

LinkedIn,ApacheKafka,Unix

Unix文件描述符的统一接口并不仅仅适用于输入和输出的过程,它是一个非常广泛的应用模式。如果你在文件系统上打开一个文件,你将得到一个文件描述符。管道和Unix套接字提供一个文件标识符,这个标示符能够在同一机器上为其它程序提供一个通信通道。在Linux中,/dev下的虚拟文件是设备驱动程序的接口,所以你在这里面可以跟USB端口甚至GPU打交道。/proc下的虚拟文件是内核的API,但是它是以文件形式存在,你可以使用相同的工具,以普通文件的方式访问它。
即使是通过TCP连接到另外一台机器上的程序也是一个文件描述符,虽然BSD套接字API(最常用来建立TCP连接)不像Unix。Plan 9显示,即使是网络可以被完全集成到相同的统一接口中去。
可以做这样一个类比,所有东西在Unix里都是一个文件。这样的统一性从逻辑上来说将Unix下的工具就像一根线分成了很多段,使其更加能够灵活组合。 sed 根本就不需要关心与其交互的是一个管道还是其他的程序,或者一个套接字,或者设备驱动程序,又或者是一个真正在文件系统上的文件。因为这些都是一样的。

LinkedIn,ApacheKafka,Unix

一个文件是一些字符流,或许在某个位置会有文件末尾(EOF)的标识,这就说明这个字符流到此为止了(字符流可以是任意长度,因此程序不能提前预知这个输入流有多长)
一些工具(如gzip)纯粹是操作字节流,而不关心数据的结构是什么样子。但是大多数工具需要对输入流进行转码,以便能做更有用的事情。为此,大多数Unix工具在一行的每个记录上,在制表符或空格或逗号分隔的区域上使用ASCII码。
如今,这种字节流文件显然是一种很好的统一接口的体现。然而,Unix的实现者对文件的处理却是截然不同的。例如,他们也许用函数回调接口处理方式,使用一个事务在进程与进程之间传递记录。或者他们用共享内存的方式(像之后的System V IPC ommap一样)。又或者使用比特流而不是字节流的处理方式。
在某种意义上讲,字节流是能够达统一的最低标准— —可能是最简单的接口。一切都可以用字节流来表示,但是对于传输媒介来说根本不知道它是什么(与另一个进程连接的管道,磁盘文件、TCP 连接、磁带等等)。这也是一种劣势,我们稍后再讨论这个问题。

LinkedIn,ApacheKafka,Unix

我们看到Unix为软件开发带来了很多很好的设计原则,而数据库系统走的却是另一条大道。我很高兴能够看到这样一个未来:我们能从这两家学习到各自的核心思想,然后将它们结合起来。
那么怎么样把Unix哲学运用到21世纪的数据系统中,使其变得更好呢?在接下来的内容中,我将探索数据库系统的世界到底会变成什么样。

LinkedIn,ApacheKafka,Unix

首先,让我们承认,Unix并不完美。尽管我认为简单,统一接口的字节流是非常成功的,这使得这个生态系统拥有灵活性,可组合性,以及拥有功能强大的工具,但Unix也有一定的局限性:
1.  它只能在单一机器上使用。随着应用程序需要处理更多数据和流量,并要求更高的正常运行时间,因此分布式系统将成为必然趋势。虽然TCP连接似乎能够被当成文件处理,但我不认为这是合理的方案:因为这只在双方连接都已经打开的情况下工作,而且这里还有一点语义混乱的味道(somewhat messyedge case semantics)。
纵然TCP很好,但作为分布式管道的实现,它过于低级了。
2. Unix中管道被设计成只有一个发送者进程和一个接受者进程。你不能通过管道将输出发送到多个进程,或者从几个进程中收集输入。(你可以用tee分支一条管道,但一个管道本身就是一对一。)
3. ASCII文本(或者,UTF-8)能够很好使数据更加可控(explorable),但这很快就会变得很糟糕。每个进程需要给各自的输入进行转码:首先,将字节流分解成记录(通常通过换行符分隔,当然有人主张用 0x1e-ACSII记录分割器)。然后将记录再分解成各个域,就像在前文awk提到的$7。出现在数据中的分隔字符需要以某种方式进行转义。即使是一个相当简单的工具如xargs,约有大半的命令选项来确定输入需要怎样进行解析。基于文本接口使用起来相当好,但回想起来,我敢肯定,更丰富的数据模型,清晰的事务模式会更好些。
4. Unix处理进程通常不能长久的运行。例如,如果处于管道中间的处理进程崩溃了,那么没有办法从当前输入管道恢复,使得整个管道任务失败,必须从头开始运行。如果这些命令运行只有几秒钟那是没有问题的,但如果一个应用程序预计需要连续运行多年,这就需要更好的容错能力。

我想我们可以找到一个解决方案,既克服这些缺点,又传承Unix哲学。

LinkedIn,ApacheKafka,Unix

最令人兴奋的事是,这样的解决方案其实早就存在,那就是这两个开源项目——KafkaSamza,它们协同工作能够提供分布式流处理服务。
你也许在这个博客其他文章中已经了解到这两个项目,Kafka是一个可扩展分布式消息代理,而Samza是一个框架,这个框架让你的代码能够生产和消费数据流。

LinkedIn,ApacheKafka,Unix

事实上,当你用Unix标准去剖析Kafka,它看起来很像一个管道——将一个进程的输出与另一个进程的输入相连。Samza看起来更像一个标准的库,这个库可以帮助你读stdin流和写stdout流(还有一些有用的功能,如部署机制,状态管理,度量工具(metrics)和监测)。
Kafka 和Samza中,流处理任务的风格,有点像Unix传统的精简且可组合的工具。
1.  在Unix中,操作系统内核提供了一个管道,一个进程从另一个进程中获取字节流的传输机制。
2.  在流处理中,Kafka提供了发布-订阅流(publish-subscribe streams),一个流处理任务能够从另一个流处理任务获取消息的传输机制。

LinkedIn,ApacheKafka,Unix

Kafka解决了我们前面讨论过的有关Unix 管道的缺点:
1. 单机限制被解除:Kafka本身就是分布式的,并且任何使用它的流处理器也可以分布在多台机器上。
2. Unix管道连接一个进程的输出与一个进程的输出,而Kafka流可以有多个生产者和消费者。多输入对于在多台机器上分布的服务至关重要,而多输出使卡夫卡更像一个广播频道。这非常有用,因为它允许相同的数据流独立地、因为不同的目的而被消耗(包括监控和审核的目的,这些往往是外部应用程序本身)。在Kafka中,消费者往往来去都比较自由,而不会影响其他消费者。
3. Kafka还提供了良好的容错性:数据被复制到多个Kafka节点,所以如果一个节点失败,另一个节点可以自动接管。如果某个流处理器节点出错并重新启动,那它可以在其最后一个检查点恢复处理操作。
4. Kafka提供的是一个消息流而不是字节流,这个消息流存储了第一步输入的转码状态(将字节流分解成序列化记录)。每个消息流其实是一个字节数组,因此你可以使用你最喜欢的序列化格式来定制你的消息:JSON, XML, Avro, Thrift或者Protocol Buffers,这些都是合理的选择。将一种编码标准化是非常有意义的,Confluent为Avro提供了一种非常好的架构管理支持。这使得应用程序能用有意义的字段名称的作为处理对象,不必担心输入解析或输出转义。它还提供良好的事务推进支持而不会破坏兼容性。

LinkedIn,ApacheKafka,Unix

关于Kafka与Unix管道还是有一些不同的,这里指的提一提:
1. 上文提到,Unix管道提供字节流,而Kafka提供的是消息流。特别值得注意的是,如果有多个进程同时对相同的流进行写入:在一个字节流,来自不同作者字节流可以交叉存取,将导致出现无法解析错误。因为消息具有粗粒度(coarser-grained)和自包含(self-contained)的特性,它们就可以安全地进行交叉存取,使其多个进程能够安全地同时写入相同的流。
2. Unix管道只是一个较小的内存中的缓冲区,而Kafka持续地将所有消息都写入到磁盘。在这方面,Kafka不太像一个管道,更像是一个写临时文件的进程,而其他几个进程不断地读取这个文件,通过的尾缀-f(每个消费者独立的跟踪该文件)。Kafka的这种方式提供了更好的容错性,因为它允许在消费者出错并重新启动的情况下,不跳过消息。Kafka自动能将这些“临时”文件分割成段,并能在日程配置里配置旧段垃圾收集计划。
3. 在Unix中,如果在管道中的消费进程读取数据非常缓慢,导致缓冲区已满并阻塞了管道中的发送进程。这是背压式(backpressure)的一种。在Kafka中,生产者和消费者都更解耦: 慢消费者有输入缓冲池,所以它不会使生产者或其他消费者慢下来。只要缓冲区在Kafka的可用磁盘空间内,较慢的消费者也能后来居上。这使得系统对个别缓慢组件的不太敏感,而组成更强大的整体。
4. 在Kafka中数据流称为一个topic,你可以参考它的名字(这使它更像Unix中被称之为的管道pipe)。一个Unix程序管道通常是运行一次,所以管道通常不需要确切的名字。另一方面,一个长期运行的应用程序随着时间的迁移通常有比特添加,删除或替换,所以你需要名字,以告诉系统你想连接到哪里。命名也有助于检索和管理。
尽管有这些不同,我仍然认为Kafka是作为分布式数据的Unix管道。例如,他们有一个共同点是,Kafka让信息有一个固定的顺序(就像Unix管道,使字节流有一个固定的顺序一样)。对于事件日志数据,这是一个非常有用的属性:事件发生的顺序通常是有意义的,这需要保护好。其他类型的消息代理,像AMQP和JMS,就并没有这种有序性。

LinkedIn,ApacheKafka,Unix

所以我们知道Unix工具和流处理器看上去十分相似。都是读相同输入流,然后以某种方式修改或改转换它,并产生一个输出流,从某种程度上这都来自于输入。
更重要的是,处理工作不修改输入(input)本身:它仍然是不可改变的。如果你在相同的输入文件上运行AWK,该文件还是处于未修改的状态(除非你明确选择覆写它)。同时,大多数Unix工具是确定的,即如果你给他们同样的输入,他们总是产生相同的输出。这意味着你可以重新运行相同的命令,想多少次就多少次,然后逐步迭代成你想做的工作程序。这是个很棒的实验,因为如果你混乱地进行处理,你还是可以随时返回到你的原始数据。
这种确定性和无副作用的效果处理看起来很像函数式编程。这并不意味着你必须使用象 Haskell 那样的函数式编程语言 (如果你想这么做的话也非常欢迎),但你仍然能从函数式代码中收获很多。

LinkedIn,ApacheKafka,Unix

这种类Unix设计准则的Kafka,使其能够构建一个大型的可组合的系统。在大型的公司中,不同的团队能够通过Kafka发布各自的数据。每个团队能够独立的开发和维护处理任务——消费各种流和生产新的流。因为一个流可以有很多独立的消费者,产生一个新的消费者不需要事先协调。
我们将这种思想成为流数据平台。在这种架构中,Kafka数据流扮演的是不同团队系统沟通的通道。每个组在整个系统中只是负责自己的那部分,并且将这一块事情做好。正如Unix工具能够被组合而完成数据处理任务一样,分布式流系统也以被组合成一个超大规模的处理组织
Unix 方法是通过降低耦合性来控制大系统的复杂性: 多亏了流接口的统一性,每个部件能够独立的开发和部署。由于良好的容错性和管道的缓存性 (Kafka),当问题发生在系统的某个部分时,它仍然只是局部。并且策略管理允许对数据结构作出更改使其更加安全,以便每个团队可以加快脚步而不打乱其他团队的步伐。

LinkedIn,ApacheKafka,Unix

为总结全文,让我们思考下发生在 LinkedIn的 一个真实的例子。如你所知,公司可以在 LinkedIn 上发布他们空缺的职位,求职者可以浏览并申请这些职位。那么,如果 LinkedIn 会员 (用户) 查看了这些发布的职位,会发生什么?
知道谁看过哪些职位非常有用,因此该服务会处理职位浏览记录,随即发布一个事件给Kafka,类似于“会员123在789时刻浏览了编号为456的职位”。
现在这些信息都在Kafka里了,那么它将被用来干好多有用的事情:
1. 监视系统:公司用LinkedIn发布他们空缺的职位,因此确保该网站能够正常的工作很重要。如果职位浏览率意外地骤降,那么就应该给出警示,因为这暗示着这里存在问题,需要展开调查。
2.相关推荐:持续给用户看同样的一种东西,那他会很恼火,因此跟踪并统计用户浏览哪些职位和次数的是一种好的做法,这样就能将这些数据给评分程序。持续跟踪哪些用户浏览了什么也能够对推荐进行协同过滤(用户既浏览了X,也浏览了Y)。
3.防止滥用:LinkedIn并不希望人们能够把所有职位都浏览,然后提交垃圾邮件,或者违反网站服务条款。知道谁在做什么是检测和阻止滥用的第一步。
4.职位海报分析:发布职位空缺的公司希望看到统计数据(谷歌分析的一种方式),谁正在查看他们的帖子,例如,他们可以测试哪些措辞能够吸引最佳候选者。
5.导入到Hadoop和数据仓库:可以是LinkedIn的内部业务分析,可以为高层管理人员的提供向导,用于处理数字数据——能在华尔街进行发布,用于A / B测试评估,等等。
所有这些系统都是复杂的,由不同的团队来维护。Kafka提供了一个可容错,可扩展式的管道。基于Kafka的数据流的平台,允许所有这些不同的系统能够独立开发,并以强大的方式连接和集成。
如果你喜欢这篇文章,你将同样会喜欢由O’Reilly出版的Designing Data-Intensive Applications
感谢 Jay Kreps, Gwen Shapira,Michael Noll,Ewen Cheslack-Postava,Jason Gustafson, 和Jeff Hartley 为这篇文章的初稿提出了意见和建议,也要感谢Jay提供了“LinkedIn职位浏览”的这样一个例子。

人生夜航时那一盏温暖的照明灯

注:upyun 技术博物馆及架构与运维大会活动约稿。转载请注明出处。

【技术博物馆】独家签名 ACM 教程,夜航时的明灯

我有一本《算法艺术与信息学竞赛》,作者签名版。不是普通的作者签售,只签了作者名字的那种,而是写了我的名字作为抬头,有单独的寄语。这是我的书架中最宝贵的一本书。

我的书架

那是 2003 年底,我在北京过的第一个冬天,感觉很冷。身体冷,心也冷。刚刚过去的 2003 年夏天,高考失利的阴影依然未能散去,考的不如预期,分不低,但因志愿填的“不服从专业调剂”而落榜,依靠 NOI (国家信息学奥赛)的获奖而被补录到北师大。来到大学,曾经所有骄傲的过往都成了往事,再也不是老师眼中的尖子生,再也不能轻松拿高分,我变成了以前自己嘲笑的对象:非常努力的学习,却怎么也追不上前面的优等生。

唯一的安慰是,我还在做编程比赛。只是比赛的名字从 NOI 换成了 ACM,比赛的形式从单人作战变成了 3 人的队伍,比赛用的语言从 Pascal 换成了 c/c++。在师大的 ACM 集训队里,牛人很多,我依然不是主力,只能非常努力地追赶,努力地保持自己的位置。每天上完课后,我都会跑到位于演播楼里的集训队训练室里默默地码代码。一度短暂地上过 poj(北大在线题库)排行榜第一页。真怀念那些年在 poj 上玩各种搞笑 Nick Name。

那段时间那些牛人队友们给了我很大压力,同时也给了我很大的动力。还有一些经常一起做题一起讨论的朋友,和一些久闻其名但一直无缘得见的前辈。《算法艺术与信息学竞赛》的作者刘汝佳老师就是这样一位前辈,虽然我们年龄相仿,但他大一时即参加 ACM/ICPC 国际大学生程序设计竞赛,获得 2001 年亚洲-上海赛区冠军和 2002 年世界总决赛银牌(世界第四),并担任 2002 年和 2003 年北京赛区裁判。

我对他仰慕已久,终于因偶然的机会见了一面。当时我们相谈甚欢,临别时我主动跟他说希望能送我一本他新写的书,由于书还没有正式出版,他答应说等第一批样书印出来就送我一本,让我帮忙找找有没有印刷错误。后来果然收到快递送过来的书,打开一看,还有作者的亲笔签名和寄语。

扉页签名

这本书陪伴我度过了后来 ACM 所有的时光。ACM 比赛时,每道题都会分配一种颜色的气球。当某个队伍做出这道题后,就会在他们的桌子上挂上一个气球。比赛过程中可以抬头看见别的队都挂了哪些颜色的气球,从而知道他们都做出了哪些题。《算法艺术与信息学竞赛》,和我一起见证了那些飘荡在赛场中的五颜六色的气球,那些 Accept,Wrong Answer 和 Time Limit Exceeded1,那些快乐和失落,那些荣耀和沮丧。

两年后的 2005 年冬天,ACM-ICPC 北京赛区,我带领的 Bnu Arbiter 队获得铜牌。走出赛场后,我登录 poj,最后一次修改签名“停止做题,离开 acm--2005 年 11 月 13 日  晴”。从 2000 年高一第一次接触编程,到 2005 年底以这样一种方式结束,我觉得自己还有遗憾,但是已经可以结束了。

后来的日子里,我依然写着各种各样的代码,从 PHP 到 C,从 Java 到 ObjC 。偶尔我还会想起那些算法,虽然我再也没有写过它们。

———————–

本次,唐福林将在“UPYUN 架构与运维大会『北京站』”的架构产品专场发表主题演讲,UPYUN 也将在大会现场展出这本《算法艺术与信息学竞赛》——唐福林人生夜航时那一盏温暖的照明灯。

注1:AC,WA,TLE 等ACM专有名词含义解释见 http://poj.org/page?id=1000

大会详情:http://upyun-archops-beijing.eventdove.com/

转:从开发人员到管理者,我学到了什么

技术工程师的晋升之路

技术工程师的晋升之路大体上可以分为两个方向,一是在技术方向上作为Individual Contributor(IC)继续深造,二是以管理者的身份管理工程师团队。IC这条路比较单纯,能走多远主要取决于个人的技术实力与经验。与IC相比,转型为管理者可以说是一种颠覆性的变化。管理者的工作不再是以个人或项目的成功作为主要目标,而是专注于整个团队的成功。这种目标的变化将直接改变管理者的心态与工作方式,以及与他人的互动方式。可以说,向管理者的转型是一个具有更大挑战性的选择。

David Haney来自于Stack Overflow团队,他是开源软件dache的作者,也曾在InfoQ上发表文章。今年二月,Haney被提升为工程经理。在担任经理的几个月中,他感受到了许多完全不同的挑战。在近期的一篇博文中,Haney详细地记录了这段时间以来所领悟的管理方法心得。

信任第一

Haney认为:要成为一个成功的管理者,首要条件就是取得团队成员的信任。因为没有谁愿意为一个他所不信任的人工作,这一点往往是员工离职的首要因素,其重要性显而易见。但信任不是凭空得来的,你必须表现出你是一个值得依赖的管理者。在这一点上Haney有一定的优势,因为他已经在作为团队成员的一年时间内凭着良好的表现博得了大家的信赖。如果没有共同工作的经历,那么就需要更大的耐心去逐步建立你的信任度。

为了取得团队的信任,Haney特别列举了以下几个要点,这是作为一名优秀的管理者最重要的品质:

  • 与员工之间的对话是一种隐私,不要在人背后嚼舌根。
  • 保持一种开放的姿态,让员工感到可以无所顾忌地与你谈论任何话题。
  • 一言九鼎,说到的就要做到。
  • 不要承诺一些你办不到的事,较好的说法是:“我尽力而为,但无法保证一定能做到。”
  • 绝对不要撒谎!员工不仅会失去对你的信任,而且一见到你就会远远躲开。
  • 不要逃避困难,即使有些事情确实令你感到不舒服,但逃避只会令问题失控。
  • 不要对员工宣泄你的情绪,也不要在背后指指点点。如果确实需要宣泄一下压力,也应当寻找一种合适的渠道,而不是冲着你的员工发火。
  • 公开表扬,私下批评。不要在整个团队面前让人感到难堪。
  • 保持客观与公正,不要在团队中搞特殊化待遇。

人类无法像代码一样伸缩自如

作为开发者,Haney能够写出具有高度可伸缩性的代码。但一名管理者却无法像代码一样做到伸缩自如。正如你很难在20个与会者之间达成一致一样,要有效地管理好20个员工也是一件难以完成的任务。Haney认为,向管理者直接汇报的员工数量最好在4至10人之间。一旦超出了这个数量,你就无法对每个人都给予足够的关注,这会让员工感到被忽视,乃至怀疑自己在团队中的重要性。同时过多的人反而会降低工作效率,因此最好是启用另一名管理者来分担你的工作。

将处理人际关系作为工作重心

对于开发者来说,人际关系往往会对工作产生干扰,而成为一名管理者之后,这一点就成为了你的工作重心。在Haney看来,人际关系不仅限于你的团队,还包括与其它团队打交道,这同样也应当具有较高的优先级。同时应当尽量表现出一定的灵活性,以配合其它团队的时间安排。

另一项重要的工作是与员工定期进行一对一的谈话,让员工借此机会表达他们的想法、意见、困难,并且通过员工的反馈改进管理者的工作。Haney每隔三周就会与每位员工进行一次45分钟的谈话,在他看来,这对他的工作产生了很大的帮助。

要注意的是,如果无故地推迟或取消原定的谈话,会令员工感到遭受轻视。因此要尽可

能避免这种情况的出现,它会使员工的士气受到很大的影响。

接受令人不安的谈话

在Haney看来,当你还是一位开发者的时候,你可能会时常与其他人抱怨一些令你感到不爽的人或者公司政策,这很正常。而作为经理,你的工作就是帮助他们直接处理好这些问题。你应当鼓励员工之间开诚布公地对话,而不是与同事在私底下嘀咕。同时,优秀的管理者也应当为员工树立一个良好的榜样。

如果有某位员工直接找到你投诉某人,你应当做的是让双方坐到一起,让他们坦诚地表达他们的感受。然后居中调解,以解决他们的问题。这种对话开始时往往会令人感到尴尬与不安,但你必须接受它,并让它成为团队文化的一部分。Haney认为,经过数次这种对话之后,员工就应当能够做到在无需他参与的情况下自行开展这种对话。重要的是确保问题最终能够得以解决,而不是随着时间的推移而变得越来越严重。

衡量你的成功并不容易

开发者有一个很大的优势,他们的工作都是为了解决某个特定的问题,其范围总是确定的,并且其成果总是能够很快地显现出来。与之相比,管理者的工作似乎没有那么具体,因为这些工作的影响往往是无形的,例如员工的想法、感受、软技能以及他们的总体成长。并且这些工作没有一个具体的开始与结束时间,因为学习与进步是永无止境的。

Haney认为,管理者的任务总是与帮助员工成长有关,而这些工作的成就感通常来自于他人的反馈。比如有员工对于你的建议与反馈表示感谢,或是有人告诉你他看到团队产生了积极的变化,以及来自于团队外部的称赞等等。这些反馈能够有效地表现出你的工作是否达到预期,但管理者需要保持足够的耐心。

没有人了解你的实际工作

开发者的工作是非常透明的,其他人可以很清楚地了解你的工作内容和完成的任务,代码库里的签入记录也会清晰地反映出你的工作。与之相对的是,管理者总是在做一些幕后的工作,这很容易给别人造成一种印象:这家伙根本什么事都不干!而Haney认为,这种误解是因为他与员工的谈话往往是私下进行的,他坚持通过一对一的形式与员工谈论沟通技巧以及人际关系上的问题。由于这种交流的私密性,使其他人无法了解管理者的工作情况,因此产生了管理者不干活的误解。

在Haney看来,只有通过团队成员的各方面不断提高,才能够表现出管理者的工作价值。这是一个缓慢的过程,但当团队发现团队之间的人员互动正朝着积极的方面转变时,他们就会体会到管理者的辛勤工作。随着员工的成长与进步,团队将变得愈加强大与高效,员工们也会承认你为团队所做出的贡献。

你的成功就是他人的成功

在这篇博文的最后,Haney简单地总结了他的观点。管理工作最重要的是取得信任,通过直接的对话解决问题(虽然这种对话有时会令人不安),在幕后完成你的工作,同时保证工作方式的直接与公正性。管理工作具有很高的挑战性,同时也能够带来极大的回报。

最后,Haney引用了动画“飞出个未来”中的一名名言,它非常贴切地表现出了管理者的工作特性。

“如果某件事你做的足够出色,那么人们甚至不会感觉到它。”

 

转自 infoq http://www.infoq.com/cn/news/2015/08/developer-to-manager