一次内部Scala编程竞赛

今天在team内举办了一次Scala编程竞赛。

由于team每周都有自发报名的例行技术活动,某天突发奇想举办一次编程大赛活动,考虑到一些同事对Scala有兴趣,因此决定拿Scala来试验,可以让更多的同事了解Scala以及产生共同话题。因此活动就这么定下来。

提前2周发了预告,也给了相关参考资料和学习教程。期间不少同事也买了国内出版的几本Scala书。但个人喜欢的O’Reilly Programming Scala好像在国内没有出版。

为避免走进应试的误区,比赛题目并未提前公布。有很多网友也在微博上打听,由于此题还需要在其它team和场合用,因此暂不公开。大家可以参考下《编程之美》让CPU占用率曲线听你指挥那一章,比较相似。

学习期间恰好大家的工作都非常忙,白天没时间学习,晚上最近也常加班。计划找一个有经验的Scala讲师培训一次也未落实,因此后来又将学习时间延长了一周。

开赛前夕也有些忐忑,如果都不及格怎么办?因此比赛前将比赛规则放宽了一点,如用Scala完成有困难的team可以用其它编程语言参赛,但是仅在所有Scala选手都未合格完成题目情况下非Scala语言优胜者才能获奖。

比赛2个队员分成一组,可以一起查资料和讨论,比赛大约持续了2-3小时,比赛结果比预计的要好很多,大部分组队都用Scala的Actor Model完成了题目并取得了不错的结果。

比赛6点开始,9点之前比赛结束。有部分成员8点左右被电话匆匆叫走,估计在约会过程中还在心神不宁的想着如何优化自己的代码。

总结:

  • 2-3小时时间偏短,写一段好的代码从构思、开发到调优需要4-6小时。
  • 最好有一个免打扰的环境,我们竞赛过程中经常有电话过来打断队员去处理其它问题。
  • 由于Scala之类后端语言并不适合在笔记本上跑性能,因此不适合在咖啡馆等更放松的场合搞。
  • 选题的建议,有一定复杂度,避免有投机取巧者10-20行代码完成;门槛低,不同层次技术人员都能参与;优化的空间大,总是可以找到更优方法。


(图:边学边用)

2011互联网技术发展浅析

说明:这是2011年初发表在InfoQ《架构师》一篇文章,重新整理到博客上,相比原文有更新。

编程语言

由于iPhone及iPad的魅力,Objective-C获得了飞速发展。另外Python也在国外也得到稳步增长,Python在两个方面存在优势,在Web开发方面相对PHP编码更优雅,在后端服务可以充当粘合剂的作用,用于整合服务器资源及后端服务做一些快速开发,但根据观察Python在国内发展未有明显变化。其他主流语言在2010变化基本不大。

从2010年5月的Google I/O大会来看,Go语言在Google内部得到不少应用,但是社区关注点成功案例,在2010尚未明显突破。

函数式编程语言在分布式及互联网领域依然非常受重视,但是Haskell, Erlang, Scala等语言都缺少一个契机走向主流。其中Erlang现象值得思考,业界不少资深技术人员在前几年都非常看好,单从近几年发展来看未得到期望的业界大范围认可,可能跟学校教学或程序员入门语言是C/Java有关,造成程序员很难适应面向过程或面向对象之外的编程语言。

在TIOBE排行中,Java依旧是第一语言,但是由于Oracle收购Sun及Oracle与Google的Android官司事件给Java发展蒙上一层阴影。在年底,IBM和Apple都先后加入了OpenJDK项目,统一化了后续Java的方向。

点评:在编程语言选择上随大流未必是正确思路,另一方面以熟悉一门新兴语言而“物以稀为贵”的情况也很难持久,判断一个程序员的能力很多在语言之外。最经典的编程书《计算机编程艺术》中的例子基本都是伪代码写的。

数据及存储

根据国外知名技术站点HackerNews上半年前的一个投票”初创公司用什么数据库”,在1044个结果中,排行前4位是MySQL 433, PostgreSQL 249, MongoDB 138, Redis 59。从中看到MongoDB及Redis取得了众多初创公司的青睐。其中推荐关注Redis,在大量的benchmark测试中Redis基本战胜了Memcached。Redis是什么?如果你认为Redis是一个key value store, 那可能会用它来代替MySQL;如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary Server的缩写,在Redis在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems,这个定义偏向key value store。还有一些看法则认为Redis是一个memory database,因为它的高性能都是基于内存操作的基础。另外一些人则认为Redis是一个data structure server,因为Redis支持复杂的数据特性,比如List, Set等。对Redis的作用的不同解读决定了对Redis的使用方式。

在分布式存储领域,在2010年,Cassandra在年初的火爆没有持久,下半年Twitter暂停在主业务后Cassandra逐渐在业界淡出。到年底时,Facebook新的统一通讯产品突然宣布使用HBase,随后其他一些产品如淘宝的一淘也宣称使用了HBase,因此建议大型存储尤其是对Hadoop已有技术投入的公司可更投入适当力量研究HBase。

点评:在性能上新兴的NoSQL产品非常有优势,但是在周边工具、运维、扩容拆分方面传统的SQL更有优势。在使用一款新的NoSQL产品之前,先要问下自己是否有足够能力驾驭。

平台及应用

随着云计算及开放平台的发展,软件开发模式已经发生了很大的变化,传统的信息系统需要走向开放及社交平台化,需要连接Amazon, Facebook等平台。更多新的软件机会在Facebook,App Store等社交及移动平台浮现。在平台上开发软件和传统方式有很大差异,需具备快速开发能力,以及产品上线后应对用户急速增长的压力。很多初创公司并不具备大规模服务系统开发经验,因此使用云存储及云计算是在平台上开发应用最好的选择。在国外Amazon等厂商的服务已经非常成熟,从新开发的应用到上百万用户的系统都可以使用。初创项目尽量利用已有资源,切忌一切从头开发。

点评:平台和应用是近几年的业界方向,技术人员应尽早的切入这一领域。

技术动向

年初在北京举办了QCon 2010大会, Facebook及Twitter都分享了相关技术架构,从中可以看到大型Web 2.0系统的架构设计一些优秀经验,到年底以关注Web性能为中心的Velocity大会也来到了北京,Facebook分享的BigPipe等前端加速技术相信又会在业界带来前端优化的新思路。Web及前端开发不再是以Web页面开发为主,前端脚本优化为辅的思路,使用前端框架为中心驱动Web页面开发的思路才能满足动态应用速度及用户体验的要求。

点评:业界各种技术大会层出不穷,看多了未免有眼花缭乱之感。建议程序员静心关注某一个领域,往深度方面发展,关注太广泛会让人浮于表面。另外也不要迷信公开演讲的内容,演讲者的观点在另外一场合未必有价值。

本文已经首发于InfoQ中文站,版权所有,原文为2011互联网技术发展浅析(部分内容有更新),如需转载,请务必附带本声明,谢谢。

-EOF-
广告:如果对文章中提到的技术、方法、实践感兴趣可以给微博团队投简历,目前急需岗位有架构师(设计高性能后端服务)、系统开发工程师(开发高性能后端服务)、即时通讯服务端(我们用 XMPP)工程师。要求很简单,熟悉Java编程,对微博、即时通讯或互联网应用某一部分技术有深入研究即可。并且要对技术感兴趣,终身从事编程工作而不觉枯燥。第二个条件权重可能会更高一点。工作地点在北京中关村,简历或咨询可以发给

Redis新的存储模式diskstore

Redis作者antirez是一个非常勤奋的开发者,在Redis性能已经非常惊人的情况下持续不断开发新的特性,比如从新的cluster源代码看到,作者已经把Dynamo及Paxos一些核心的思想考虑进去并进行了一些简洁的实现。相比其它产品如Memcached则几年没什么大变化,在Web 2.0时代,Memcached已经非常不够用,技术人员需要考虑做很多额外工作才能让Memcached适应新的变化和需求。

antirez在1月5日Google Groups发表了一篇Redis diskstore文章,对Redis VM方式进行了反省,思考是否有更好的方式来大数据的Redis访问。

a few months after VM started to work my feeling about it started to be not very good… that VM was not the way to go for the future of Redis

适合Web 2.0数据访问最佳的方式就是完全基于内存,比如用Memcached或者Redis snapshot方式。但是更多的业务场景是数据规模会超过RAM容量,因此有几种不同的设计模式。

1. VM方式。将数据分页存放,由应用(如Redis)或者操作系统(如Varnish)将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中。应用实现VM缺点是代码逻辑复杂,如果业务上冷热数据边界并不分明,则换入换出代价太高,系统整体性能低。不少抢鲜的网友在微博上也反馈过使用VM种种不稳定情况。操作系统实现VM的缺点前文Redis几个认识误区已经有介绍。

2. 磁盘方式,所有的数据读写访问都是基于磁盘,由操作系统来只能的缓存访问的数据。由于现代操作系统都非常聪明,会将频繁访问的数据加入到内存中,因此应用并不需要过多特殊逻辑。MongoDB就是这种设计方式。这种方式也有一些已知的缺点,比如操作MMap写入磁盘由操作系统控制,操作系统先写哪里后写哪里应用并不知情,如果写入过程中发生了crash则数据一致性会存在问题。这个也是MongoDB饱受争议的单机Durability问题,

MongoDB is not designed around single-server durability, but rather multi-server durability.

不过MongoDB自己并不觉得这是一个问题,他们的意见是,在目前时代有必要考虑单机完全可靠吗?有必要吗?

3. 硬盘存储 + cache方式。实际原理和mysql+memcache方式类似,只不过将两者功能合二为一到一个底层服务中,简化了调用。

在上面几种方式中,除去VM,antirez觉得MongoDB方式也不太适合,因此选择了disktore方式来实现新的磁盘存储,具体细节是

1) 读操作,使用read through以及LRU方式。内存中不存在的数据从磁盘拉取并放入内存,内存中放不下的数据采用LRU淘汰。

2) 写操作,采用另外spawn一个线程单独处理,写线程通常是异步的,当然也可以把cache-flush-delay配置设成0,Redis尽量保证即时写入。但是在很多场合延迟写会有更好的性能,比如一些计数器用Redis存储,在短时间如果某个计数反复被修改,Redis只需要将最终的结果写入磁盘。这种做法作者叫per key persistence。由于写入会按key合并,因此和snapshot还是有差异,disk store并不能保证时间一致性。

由于写操作是单线程,即使cache-flush-delay设成0,多个client同时写则需要排队等待,如果队列容量超过cache-max-memory Redis设计会进入等待状态,造成调用方卡住。

Google Group上有热心网友迅速完成了压力测试,当内存用完之后,set每秒处理速度从25k下降到10k再到后来几乎卡住。 虽然通过增加cache-flush-delay可以提高相同key重复写入性能;通过增加cache-max-memory可以应对临时峰值写入。但是diskstore写入瓶颈最终还是在IO。

3) rdb 和新 diskstore 格式关系
rdb是传统Redis内存方式的存储格式,diskstore是另外一种格式,那两者关系如何?

  • 通过BGSAVE可以随时将diskstore格式另存为rdb格式,而且rdb格式还用于Redis复制以及不同存储方式之间的中间格式。
  • 通过工具可以将rdb格式转换成diskstore格式。

当然,diskstore原理很美好,但是目前还处于alpha版本,也只是一个简单demo,diskstore.c加上注释只有300行,实现的方法就是将每个value作为一个独立文件保存,文件名是key的hash值。因此diskstore需要将来有一个更高效稳定的实现才能用于生产环境。但由于有清晰的接口设计,diskstore.c也很容易换成一种B-Tree的实现。很多开发者也在积极探讨使用bdb或者innodb来替换默认diskstore.c的可行性。

在Redis几个认识误区中也介绍过,Redis优势是丰富的内存数据结构,这个特性和数据持久保存天生是矛盾的,如用diskstore保存大list/set(如排行榜)性能会很差,每修改一个list元素则需要将整个大list重新保存,开销比使用传统RDBMS高很多。

用MongoDB的一句设计哲学结尾

Databases are specializing – the “one size fits all” approach no longer applies.