Skip to content

2010 年的书、电影和音乐

照例用 doubanlet 统计了一下 2010 的书、电影和音乐。

书籍阅读量比去年数字上有44%的增加,不过貌似大量都是小说和漫画凑数导致的;电影数量略有下降,跟今年网络状况比较烂有关系;比较诡异是都是六月看电影最少,难道两年的六月都是在外面旅行么?音乐比较悲剧,基本没啥进展懒得整理了。:S

今年得在阅读质量上多下工夫,少看闲书啊。

介绍JVM虚拟机实现的培训PPT

前段给公司同事简单介绍了一些JVM虚拟机实现方面的知识,主要是针对某个产品希望自行研发类似引擎的需求,以JVM为例大概分析了一下虚拟机的架构,以及在静态模型和动态执行环境方面的一些设计思路。

J2SE 5.0和CLR 2.0之后,在虚拟机层面Sun和MS就基本没啥大改动,可以说这个领域基本上已经属于非常稳定和成熟。更多的关注被放到企业级应用的各种框架,以及动态语言和DSL领域特定语言的支持上。

但我始终以为,学习和了解一个类似JVM/CLR这样平台,最好的办法就是从底层静态文件结构着手,进而分析和理解其动态执行环境。这种学习方法虽然前期学习曲线较陡,但优点是可以完全无视各种文档里面的忽悠成分,直面语言和环境在设计之初的各种设计理念。毕竟你后期市场宣传忽悠的再天花乱坠,如果技术架构无法提供支持都是白扯。

最典型的案例就是CLR 1.0刚出来时,无论从静态文件结构还是IL指令集,都提供了对泛型的良好支持。因此当时在大家纷纷猜测时我就能非常确信,CLR 2.0或后续版本肯定会提供良好的泛型支持,而且大概知道能支持到什么程度。相反Java对泛型的支持,基本都只是通过annotation等机制模拟,缺乏JVM和byte code一级的有力保障,注定其实现方式倾向于在编译器层面模拟。江山轮流转,JVM对动态语言的支持,则是实实在在通过一系列JSR来完成;对应CLR反而是通过语言层面的DLR来模拟。

这方面比较靠谱的中文书籍并不多《深入Java虚拟机》关注JVM的架构,《虚拟机:系统与进程的通用平台》则是介绍更广泛意义上虚拟机的实现思路。如果只是希望深入了解Java和JVM,阅读《JAVA语言规范》虽然枯燥但确是最权威的。
深入Java虚拟机
JAVA语言规范
JAVA语言规范

Tagged

Gearman 性能调优

Gearman是最早由LiveJournal内部开发并使用的一个通用并行任务调度框架,允许不同语言直接通过非常简单的方式进行互操作。前台提交工作任务(Task)和参数,由后台工作进程(Worker)完成实际工作。

How Does Gearman Work?

例如前台提交用户需要进行渲染的图片,由Gearman调度到后台提供渲染服务的工作进程,在完成工作后返回结果给前台进行展示。提交工作和完成工作的代码只需要通过预先协商好的参数格式进行交互,具体任务的调度、负载均衡、可靠性等,由Gearman服务器来确保。而针对大规模应用,可以很容易进行多路节点的集群部署。

Gearman Cluster

在正式对外发布后,Danga Interactive用C重写了整个服务器代码,支持PHP, Perl, Python等常见脚本客户端,支持用memcached, sqlite, postgresql, tokyocabinet等作为任务持久化队列,基本上来说是便宜量又足。

线程模型

在大规模使用的时候,需要针对应用类型进行参数设置,以使Gearman的性能达到最优,这首先应该了解Gearman的线程模型。

为确保具备对海量任务调度的支持能力,Gearman毫无悬念的选择libevent作为网络操作支撑库。因此Gearman的服务器Gearmand提供了三类线程角色:

    端口监听和管理线程,接受新连接请求并将之交给IO线程,1个
    IO线程,完成实际的任务处理,包括命令解析,队列操作等,n个
    处理线程,完成内部数据结构的管理,无系统调用尽可能简单,1个

其中第1, 3种线程对全局处理性能没有直接影响,虽然处理线程有可能成为瓶颈,但他的工作足够简单消耗可忽略不计,因此我们的性能调优主要目标是在IO线程的数量。
对每个IO线程来说,它都会有一个libevent的实例;所有Gearman的操作会以异步任务方式提交到处理线程,并由IO线程获取完成实际操作,因此IO线程的数量是与可并行处理任务数成正比。Gearmand 提供 -t 参数调整总IO线程数,需要使用 libevent 1.4 以上版本提供多线程支持。

进程句柄数

另外一个影响大规模部署的是进程句柄数,Gearman会为每一个注册的Worker分配一个fd(文件描述符),而这个fd的总数是受用户限制的,可以使用 ulimit -n 命令查看当前限制

flier@debian:~$ ulimit -n
1024
flier@debian:~$ ulimit -HSn 4096 // 设置进程句柄数的最大软硬限制
4096

也就是说gearman缺省配置下,最多允许同时有小于1024个worker注册上来,fd用完之后的Worker和Client会出现连接超时或无响应等异常情况。因此,发生类似情况时,我们应首先检查 /proc/[PID]/fd/ 目录下的数量,是否已经超过 ulimit -n 的限制,并根据需要进行调整。而全系统的打开文件设置,可以参考 /proc/sys/fs/file-max 文件,并通过 sysctl -w fs.file-max=[NUM] 进行修改。

flier@debian:~$ cat /proc/sys/fs/file-max
24372
flier@debian:~# sysctl -w fs.file-max=100000
100000

更详细的设置请参考 Linux increase the maximum number of open files or file descriptors

Gearmand 本身也提供了调整句柄数量限制的功能,启动时则可以通过 –file-descriptors 参数指定,但非特权进程不能设置超过soft limit的数额。

-f, –file-descriptors=FDS Number of file descriptors to allow for the process
(total connections will be slightly less). Default
is max allowed for user.

The soft limit is the value that the kernel enforces for the corresponding resource. The hard limit acts as a
ceiling for the soft limit: an unprivileged process may only set its soft limit to a value in the range from 0
up to the hard limit, and (irreversibly) lower its hard limit. A privileged process (under Linux: one with the
CAP_SYS_RESOURCE capability) may make arbitrary changes to either limit value.

轮询调度

此外,Gearmand 还提供了一些增强任务调度公平性的参数,例如 0.13 里面新增的 round-robin 模式,允许将任务公平的调度到多个 Worker,而不是用缺省按 Worker 注册函数的顺序进行调度,避免工作过于集中在少数设备上。

-R, –round-robin Assign work in round-robin order per
workerconnection. The default is to assign work in
the order of functions added by the worker.

Gearmand 内部通过一个 Worker 队列,在 RR 模式下动态调整 Worker 的调度次序。

  if (server_con->thread->server->flags.round_robin)
  {
    GEARMAN_LIST_DEL(server_con->worker, server_worker, con_)
    _server_con_worker_list_append(server_con->worker_list, server_worker);
    ++server_con->worker_count;
    if (server_con->worker_list == NULL) {
      server_con->worker_list= server_worker;
    }
  }

受限唤醒

而通过 –worker-wakeup 参数,则可以指定收到任务时,需要唤醒多少个 Worker 进行处理,避免在 Worker 数量非常大时,发送大量不必要的 NOOP 报文,试图唤醒所有的 Worker。

-w, –worker-wakeup=WORKERS Number of workers to wakeup for each job received.
The default is to wakeup all available workers.

根据 Gearman 协议设计, Worker 如果发现队列中没有任务需要处理,是可以通过发送 PRE_SLEEP 命令给服务器,告知说自己将进入睡眠状态。在这个状态下,Worker 不会再去主动抓取任务,只有服务器发送 NOOP 命令唤醒后,才会恢复正常的任务抓取和处理流程。因此 Gearmand 在收到任务时,会去尝试唤醒足够的 Worker 来抓取任务;此时如果 Worker 的总数超过可能的任务数,则有可能产生惊群效应。

  /* Queue NOOP for possible sleeping workers. */
  if (job->function->worker_list != NULL)
  {
    worker= job->function->worker_list;
    noop_sent= 0;
    do
    {
      if (worker->con->options & GEARMAN_SERVER_CON_SLEEPING &&
          !(worker->con->options & GEARMAN_SERVER_CON_NOOP_SENT))
      {
        ret= gearman_server_io_packet_add(worker->con, false,
                                          GEARMAN_MAGIC_RESPONSE,
                                          GEARMAN_COMMAND_NOOP, NULL);
        if (ret != GEARMAN_SUCCESS)
          return ret;

        worker->con->options|= GEARMAN_SERVER_CON_NOOP_SENT;
        noop_sent++;
      }

      worker= worker->function_next;
    }
    while (worker != job->function->worker_list &&
           (job->server->worker_wakeup == 0 ||
           noop_sent < job->server->worker_wakeup));

    job->function->worker_list= worker;
  }

除此之外,针对应用特点合理使用持久化队列,在大并发任务量的情况下对性能也会有直接影响。

归根结底,需要根据自己的应用场景,合理设计一些测试用例和自动化脚本,通过实际的运行状态进行参数调整。

Tagged ,

GCC和VS2010中对C++ 0x的支持

根据GCCVS2010的文档,大致整理了一下几个主流编译器对C++ 0x标准的支持程度。

Tagged , , ,

函数式编程入门培训PPT

上周给公司同事做了一个函数式编程 (Functional Programming) 的介绍,原以为可以随便到网上找一个ppt讲讲,结果发现居然没有合适的可以直接用,只好根据 wiki 结合 python 示例自己整理了一个培训PPT。大概涵盖了FP的发展历史、基本概念和一些简单例子,回头有空再把它细化一下,看看是否有必要继续深入讲。

说起来函数式编程 (Functional programming) 这个话题基本是个无底洞,属于在常青藤高校也能开几年课挂掉无数人的领域。如何在短短一个多小时的时间内,让听众有一些直观印象,进而有兴趣继续深入学习下去,这是让我最为头疼的事情。因此我基本放弃了对那些较为复杂概念的介绍,甚至连 Closure 都只敢简单提及,跟别提什么 Monad 这种我自己都挠头的概念。

开讲前在几十个听众中做了个简单调查,果然是听说过和使用过 FP 的人基本都是个位数。这基本上可以说是天朝 CS/EE 教育失败的体现,要知道欧美大学第一年就会讲 Structure and Interpretation of Computer Programs 这种被 Joel 视为是否适合就读 CS 专业过滤器的 BT 课程 (在线课程)。

因此在一开始的时间里,基本上都是集中在对 FP 的鼓吹上,基本集中在 (1) 应对复杂性,(2) 降低维护成本和 (3) 增强自信心三个角度。前面两个基本上是洗脑用套话,个人最赞同也最想灌输的是第三点。

如果实际参与开发过代码量上百万行,代码维护历史在5-7年以上,先后参与人数几十上百的产品,最直观的感受是应该就是对其自身复杂性的本能恐惧。因为对绝大多数技术人员来说,我们更倾向于参与具有确定性的工作,也就是说我们潜意识里认为,我们做的事情应该是有可预测结果的。但一旦代码复杂到了一定程度,解耦没有到位过过于到位,我们就会发现所有的修改,都有可能引发不确定的影响。为了缓解这种影响,我们搞出了各种各样的最佳实践,TDD、CI、peer review,blabla;但归根结底我们只是试图用这些尝试来确保,我们有胆量继续修改那些我们自己也逐渐无法控制的代码,就好象在黑夜中无助的抓住一个火把,却又大声喊叫说自己不怕黑暗。

FP 在这方面可以说具有天然的优势,在去除 side effect 和复杂控制逻辑后,我们通过 Pure functions 和 Recursion 表达的是我们真正的计算目的,而非达成目标的方法。这也是声明式语言 (Declarative programming) 与命令式语言 (Imperative programming) 最大的差别所在。这也是为啥我在开发 rabbitmq-memcached 时,真正能把大部分时间用在编写代码上的原因,实际上线调试反而只是简单而且直接的结果而非过程。

Tagged , ,

2009 年的书、电影和音乐

doubanlet 统计了一下 2009 的书、电影和音乐。果然是上半年比较闲,每个月读书在10-15本;不过电影倒是一直很勤奋的在看,除了中间五六月时忙于换工作交接旅行啥的,只能偷空听听音乐。

Tagged , , ,

Google 是如何定义“开放”这个概念

2010年不期而至的第一场冬雪,打乱了原本出门看展览吃大餐的计划,宅在家里断断续续读完《Google将带来什么?》这本书,发现自己对 Google 核心理念的理解仍不是很到位。

这本书从内容上来看基本是个博客文章合集,在吹捧了一下 Google 的商业模式和众所周知的成功后,开始把成功经验往各行各业套用,预测在应用类似的开放、合作的理念后,会给行业带来哪些新变化。内容本身也还靠谱,有些思路也算有道理,但不成体系也不够严谨。

麻烦的是这种博客文章的形式,看完基本得不出太多结论反而引出一堆问题,刚好Google 官方博客前段放出一篇文章,负责产品管理的副总裁 Jonathan Rosenberg 的 The meaning of open 一文,解答了我的部分疑惑。

文中提到,Google 相信开放系统是双赢的,并将带来创新、价值、客户自由选择的权利,以及更有活力、可盈利和竞争性的商业生态系统。

At Google we believe that open systems win. They lead to more innovation, value, and freedom of choice for consumers, and a vibrant, profitable, and competitive ecosystem for businesses.

如果是其他某些公司有人这么说,我可能觉得里面虚伪做作的成分比较多,毕竟开放的代价是触及现有既得利益者,国内某些公司反反复复的“开放”就是最好写照。但对 Google 这样一个商业和社区的宠儿来说,我相信他们是真心坚守这个信念,因为他们实际上是这个开放商业生态系统的最大受益者。从 Google 打通了他的流量向广告变现能力的任督二脉开始,他实际上已经将开放作为推动产业和自身发展的原动力。

There are two components to our definition of open: open technology and open information. Open technology includes open source, meaning we release and actively support code that helps grow the Internet, and open standards, meaning we adhere to accepted standards and, if none exist, work to create standards that improve the entire Internet (and not just benefit Google). Open information means that when we have information about users we use it to provide something that is valuable to them, we are transparent about what information we have about them, and we give them ultimate control over their information. These are the things we should be doing. In many cases we aren’t there, but I hope that with this note we can start working to close the gap between reality and aspiration.

Google 把 open 定义为两个层面:开放技术(open technology)和开放信息(open information)。开放技术包括开源软件(Open Source)和开放标准(Open Standard),通过自身发布开源软件和鼓励员工和社区对开源软件的支持,推动Internet的发展;通过采用和创立开放标准,来改善整个Internet的环境。开放信息则被用来向用户提供更多价值,并在确保信息透明度的情况下,将控制权交给用户。

从开放系统中获得双赢的思想,实际上是和传统MBA教育相违背的,因为那些教科书都是针对封闭系统进行分析和设计的。Jonathan 在文中分析了开放系统的优劣,无非是开放则对市场需求响应速度快,封闭则利润空间大可控性强等等老生常谈。他提到了水果商在 iPod 和 iPhone 上的成功,也举了人类基因组工程和 GNU C 编译器的例子。

In an open system, a competitive advantage doesn’t derive from locking in customers, but rather from understanding the fast-moving system better than anyone else and using that knowledge to generate better, more innovative products. The successful company in an open system is both a fast innovator and a thought leader; the brand value of thought leadership attracts customers and then fast innovation keeps them.

最为关键的是他提到的如何将 open 理念变现的能力保障,也就是失去封闭系统里被锁定客户的竞争优势后,如何为对快速变化的系统持续提供更多更好的创新产品。快速创新者(fast innovator)、思想领导者(thought leader),没错,就是这两个已经被各种管理书籍说烂了的理念。通过思想领导者的品牌/口碑价值,吸引客户并通过快速创新“锁定”他们。这实际上是 Google 能够持续快速成长的关键因素,并不是什么简简单单的开源软件或者弄个 lab 头衔能够模仿的,而是通过快速而持续的创新能力,这个其他企业很难模拟的撒手锏,获得了开放系统中“锁定”客户的方法

所有的组织(organization)从成立开始,就在不断完善和演进之中。在这个自我进化的过程中,与热力学第二定律“封闭系统中熵永不减少”类似,组织规模越大时间越长,其结构和功能就会越趋于稳定,换句话说就是越来越僵硬。因而对 Google 的竞争者来说,在体制内想达到同等的创新能力,无论是成本还是效果上都很难保障,微软每年投入上百亿加几千人折腾的 Live!和现在的 Bing 就是最好写照。

在这个大前提下,Google 对开放的理解和策略制定,基本就水到渠成了。最根本的还是 Hal Varian 在其 Information Rules 一书中提到的:

Reward = (Total value added to the industry) * (Our share of industry value)

无论是 10% 的产业价值增加,还是 10% 的 Google 所占市场份额增加,对 Google 自身的推动作用都是同等的。Google 通过构建自身的外部动力,获得了推动产业发展同时带来自身发展的可能性。用比较直白的话说,internet用户使用网络越多,他接触和使用 Google 产品就会越多,相应 Google 获得的价值就会越大。这实际上是在通过创新能力锁定客户的同时,通过变现方法不同给竞争对手带来的第二道门槛。

以 Google 正在大举进入的手机领域为例。Google 通过开放的 Android 系统,以思想领导者的定位吸引厂商加入,然后通过各种免费创新应用吸引最终用户。这些“免费”和“开放”的应用,通过免费的 Gmail、GPS 和地图服务等传统厂商无法直接抗衡的方式,吸引并锁定目标客户,进而增加这个产业的价值和 Google 的份额。对传统厂商来说,他们缺乏持续创新的能力和动机,也缺乏在 GPS 和地图服务等领域进行对抗时,将用户数和流量变现的造血能力。「比免费更便宜」的商业模式一文中有更为详细的评述。

接下来就是如何将这些 open 的理念付诸实际,Jonathan 详细解释了开放技术和开放信息层面的理解。

开放标准和开源软件,是加快 Internet 发展的促进因素,因而 Google 有足够动力去推动他们,因为用的人越多他得到的越多。就好比 IBM 和 Intel 推动 Linux 和开源软件发展,归根结底是落实到卖自己的产品、服务和 CPU 上,你用的越多我卖的越好,资本家永远不是慈善家。这点前面讨论较多就不再罗嗦。

开放信息则较为敏感,因为这触及到了上述提及到的 Google 的另一个核心能力,将免费用户数和流量变现的强大能力。而支撑这一能力的根本,在于 Google 通过搜索引擎和各种免费服务,达到的对网络和用户的深刻理解。无论是之前的 AdSense 和 AdWords,还是发布不久的 Interest-Based Advertising,都需要能精确对网页内容和访问用户的行为记录,进行分析和匹配后选择合适广告投放来改善效果,最终变成维系 Google 千亿市值的涓涓细流。

另一方面,这些敏感的用户信息也是最容易让人对 Google 产生诟病的阿喀琉斯之踵,因而与开放技术不同这里有的只是对用户的解释。通过使用这些信息改善用户体验以增加价值,通过增加信息使用透明度降低用户反感,并通过将控制权交给用户来造成用户可以控制这些信息的假象。不过就如《Google将带来什么?》书中提到的,这种把控制权移交给用户的尝试,已经比其他行业正在做的好太多。而这些举措本身也从另一个角度改善了 Google 的 open 的定位和形象。

于是乎,Google 举着 open 这个大旗,通过引领变革维系品牌价值,以持续创新锁定用户,在促进产业发展带动自身,进而以开放信息洗白利用用户信息改善变现能力的本质,构建了一个贯彻整个行业的用户和流量变现大循环,将只能在某个环节困兽犹斗的传统企业踢出局,获得商业和社区层面的双丰收。好在以其 Don’t be Evil 的理念下,Google 相当长时间里也可以做到与其用户的双赢,只要上述的外部动力不变 Google 基本不会去得罪最终用户,这也是为什么他在各个领域严守道德底线,并不是因为企业有多么高尚,而是因为这维系着他大循环中一个最根本条件,也就是最终用户对他的信任。

你信任 Google 么?

Tagged , , ,
Get Adobe Flash playerPlugin by wpburn.com wordpress themes