害怕并不代表没有勇气,真正的行动才是最重要的。一个人究竟是英雄还是懦夫,由行动决定。
无论你是谁,你的一生都需要两类朋友。第一类是当你遇到好事时,你可以打电话与之分享喜悦的朋友。他的喜悦不是那种蒙着羡慕、嫉妒面纱的虚假喜悦,而是发自内心的真诚喜悦。他会比好事发生在他自己身上更高兴。第二类是当你身陷困境时,你可以打电话与之分担、向其倾诉的朋友。
如果我们不能公平、公正地对待那些即将离开公司的人,那些留下的人就永远不会再信任我了。
我继续前进,追求唯一的完美方向,不能因为恐惧而迷失方向。
每当大公司打算实施某一计划时,该计划总会落到某个人身上,而此人却极有可能延误整个计划。如果此人是工程师,他也许会因为等待上面的决策而踌躇不前;如果此人是管理者,他也许会因为自己无权做出关键性的购买决定而犹犹豫豫。这些看似微不足道的踌躇和犹豫很可能会造成致命的延误。
研发出好产品是创新者的职责,而不是客户的任务。客户只知道根据对现有产品的体验来判断自己想要什么。创新者虽然可以考虑到所有可能的因素,却往往要做出和自己所了解的事实相悖的举动。因此,创新是知识、技能和勇气的结合体。有时,只有创新者才有勇气忽略那些事实数据。 阅读全文…
创业是一件很不容易的事,各方面都不容易,招人尤其不容易,组建一个好的团队,是创业成功的基石。棒米从成立到现在,快一年半的时间,团队成员从最开始的两个人,到了现在的二十多个人,这期间有三位同事离职,一位是被我们主动Fire掉的,另外两位是因为各种原因,主动离职的。公司在招聘的岗位有不少,这一年多的时间也面了很多人,在这个过程中,自己也反思了很多,今天这篇文章就把这一年多在招聘过程中的一些心得体会做个记录。希望能够抛砖引玉。

阅读全文…
今天无意间打开博客,发现上一篇博文是近两年之前的事了,已是太久没有写了。自从决定创业,开始走上创业之路,整天忙于各种事务,像以前那样静下心来细细思考、总结的时间越来越少了。一直以来,都觉得博客对于我而言,是一个很不错的记录心境、梳理思绪的地方。是时候该好好理理了,希望今天这篇博文能起个好头,让自己每隔一段时间,能静下心来好好深思一番,既是记录创业路上的心路历程,也是为自己更好的走下一步理清楚思路。
过往在小米的三年,对于我的职业生涯而言,是到目前为止,是最为难忘三年。不单是因为经历了小米从40亿美金到450亿美金的快速成长,更为重要的是,跟一个中国IT行业最为优秀的技术团队(没有之一)一起,把小米的基础架构(云计算、云存储)平台,从无到有做起来,并且支持了小米如此快速的业务发展。对于一个技术人员来讲,这是莫大的幸福。 阅读全文…
[latexpage]
上一篇文章《Finite Field Arithmetic》介绍了有限域上的运算,理解有限域上的运算,是理解erasure编码的基础。今天这篇文章就来介绍一下erasure编码。在分布式存储系统中,通常会通过多副本的方式来保证数据的可靠性,但是多副本带来的成本问题也是显而易见的。在类HDFS这样的系统中,通常数据都会保留三副本,三副本可以容有两副本故障的场景,但同时成本也是一副本的三倍。如何在保证同等的数据可靠性的前提下,减少副本数,降低成本,是分布式存储系统中很重要的一个课题。Erasure编码正是用来解决这个问题的,它能将副本降到1.x的同时,保证同等的数据可靠性保证。本文会以最常用的Reed Solomon erasure编码为例来介绍。
基本思想

如上图所示,我们总共有$n$块盘,其中$k$块用来存放数据,m块用来存储erasure编码($k+m=n$),在上面的$n$块盘中,任意坏$m$块,都可以通过erasure编码将其余的恢复出来。也就是说,通常$k+m$的erasure编码,能容$m$块盘故障的场景,这时候的存储成本是$1+m/k$, 通常$m 阅读全文…
[latexpage]
在分布式存储系统中,通常通过多副本的方式来保证数据的可靠性。Erasure编码,是分布式系统中用来在保证跟多副本同等可靠性的前提下,减少副本、节约成本的标准做法。有限域(Finite Field)上的四则运算是Erasure编码在分布式存储系统中应用的基础。今天这篇文章介绍一下有限域(Finite Field)及其上面的运算, 后续文章再介绍Erasure编码。
什么是有限域(Finite Field)
大小为$n$的集合,在其上的任何四则运算(加、减、乘、除)的结果仍在这个集合中,表示为$GF(n)$
有限域(Finite Field)有什么样的性质
对于有限域GF(n)中的元素A(0除外), 均存在:
1. $A+B=0$, $B$称之为$A$的加逆, $-A$(Addition inverse, 可以跟相反数据类比)
2. $A*B=1$, $B$称之为$B$的乘逆, $A^{-1}$(Multiplication inverse, 可以跟倒数类比)
由上面的性质可以推论,在有限域上的减法都可以转化为加法,除法都可以转化为乘法
$GF(n)$($n$为素数)有限域上的运算法则
对于$GF(n)$, 如果$n$是素数,可以这样来定义$GF(n)$,及其上的四则运算:
$GF(n) = {0, 1, 2, \dots, n-1}$
加: $A + B = (A + B) \mod n$
减: $A – B = (A + (-B)) \mod n$
乘: $A * B = (A * B) \mod n$
除: $A / B = (A * B^{-1}) \mod n$
阅读全文…
Paxos是前段时间刚获得图灵奖的大神Leslie Lamport所提出的,是用来解决分布式系统中的一致性问题的算法。该算法对于分布式系统的重要性,在这里不再赘言。了解过Paxos的朋友应该都知道,要完全理解Paxos不是一件容易的事。本文是笔者在学习Paxos时,用来帮助自己更好的理解Paxos所梳理的一遍文章,希望能够通过通俗易懂的方式,把Paxos理解清楚。
Paxos要解决的问题
我们知道,Paxos要解决的问题,是分布式系统中的一致性问题。到底什么是“分布式系统中的一致性问题”呢?在分布式系统中,为了保证数据的高可用,通常,我们会将数据保留多个副本(replica),这些副本会放置在不同的物理的机器上。为了对用户提供正确的读/写/删/改等语义,我们需要保证这些放置在不同物理机器上的副本是一致,这就是Paxos所要解决的问题。
阅读全文…
写在前面:本文是对OSCon09的《Linux System and Performance Monitoring》一文的学习笔记,主要内容是总结了其中的要点,以及加上了笔者自己的一些理解。通过总结,一方面是为了加深笔者自己的理解,另一方面也是希望能对有需要的朋友有所帮助。
做为一名服务器开发工程师,经常会有分析系统性能,解决系统性能瓶颈的需求。通常我们所说的性能问题,不外乎就是CPU/Memory/IO/Network这四个方面,这四个方面每个都有各自独特之处,同时也都是相互关联的。下面就分别从这四个方面展开进行介绍。
CPU
基本概念
1. 内核调度的优先级:在Linux系统中,内核scheduler调度资源包括两种:threads(Process是由threads组成)和interrupt,这些被调度的资源是有特定的优先级的,以下从高到底:
- Interrupts: Interrupt被设备用来通知内核相关的事件,优先级是最高的
- Kernel(System) Processes:所有的系统进程都是以仅次于Interrupt的优先级被调度的
- User Processes: 所有的应用程序都是run在用户态空间,以最低的优先级被内核调度
阅读全文…

近年来,OAuth在各种开放平台的引领下变得非常流行,上图是OAuth协议认证的全过程,图本身已经比较详细,这里不再赘述。 阅读全文…
ZooKeeper是Hadoop Ecosystem中非常重要的组件,它的主要功能是为分布式系统提供一致性协调(Coordination)服务,与之对应的Google的类似服务叫Chubby。今天这篇文章分为三个部分来介绍ZooKeeper,第一部分介绍ZooKeeper的基本原理,第二部分介绍ZooKeeper提供的Client API的使用,第三部分介绍一些ZooKeeper典型的应用场景。
ZooKeeper基本原理
1. 数据模型

如上图所示,ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode。每个ZNode都可以通过其路径唯一标识,比如上图中第三层的第一个ZNode, 它的路径是/app1/c1。在每个ZNode上可存储少量数据(默认是1M, 可以通过配置修改, 通常不建议在ZNode上存储大量的数据),这个特性非常有用,在后面的典型应用场景中会介绍到。另外,每个ZNode上还存储了其Acl信息,这里需要注意,虽说ZNode的树形结构跟Unix文件系统很类似,但是其Acl与Unix文件系统是完全不同的,每个ZNode的Acl的独立的,子结点不会继承父结点的,关于ZooKeeper中的Acl可以参考之前写过的一篇文章《说说Zookeeper中的ACL》。 阅读全文…
Google MapReduce
MapReduce是由Google提出的一种软件架构,用于大规模数据的并行计算。Map和Reduce这两个概念,是从函数式编程语言中借鉴过来的。正如Google MapReduce Paper中所描述,MapReduce是这样一个过程:输入是Key/Value对A,用户指定一个Map函数来处理A,得到一个中间结果Key/Value集合B,再由用户指定的Reduce函数来把B中相同Key的Value归并到一起,计算得到最终的结果集合C,这就是MapReduce的基本原理,可以简单的表达为:
map (k1, v1) -> list (k2, v2)
reduce (k2, list(v2)) -> list (v2)
MapReduce的原理本身比较简单,但开发一套完备、易用性好的MapReduce系统,不是一件容易的事。这里会涉及分布式系统的故障容错、负载均衡等一系列复杂的问题。下面就结合在Google MapReduce Paper所讲的MapReduce的执行流程,来介绍一下MapReduce系统的基本工作原理: 阅读全文…
写在前面:不知不觉,来帝都已经一年整了,这也意味着从search转向分布式系统真正一年了。当初选择这个方向,也考虑到过会有很多不容易,但是既然决定了、选择了,就要努力去做好。过去的一年,也曾迷惘过,也曾沮丧过,但好在努力坚持了下来。总得来说,对所目前的状态,以及所做的事还是充满了信心。一直以来,都坚信只要是自己喜欢的事情,努力去做了,就一定能做好,这是支撑我不断努力、奋斗的信念。最近一直在考虑一个事情,过去的一年,在工作之余,陆陆续续零零散散看了不少分布式相关的资料,打算把这一块好好梳理一下,希望在接下来一年左右时间,通过系统地、深入地学习,对这个领域的理解能够更加全面、透彻。这也是今天写下这篇文章的一个初衷,一方面是给自己接下来的学习理清一个思路,另一方面,也是希望能够与有同样需求的朋友共勉。
接下的内容按几个大类来列: 阅读全文…
前几天看hdfs QJM的代码,里面看到一个ListenableFuture,说实话对于Java,目前我还只是通过看代码,遇到没见过的再去查的方式,也着实是没有时间和精力再去通篇研读诸如《thinking in Java》这样的大砖块了,现在这样的方式,目前来说应该是够用了。重点还是放在系统和业务上,语言本身本不应该成为障碍。言归正传,回到ListenableFuture, 在网上看了一下相关的资料,把它的来龙去脉了解了一下,在这里记录一下。
前面提到的ListenableFuture, 是google开源的自己的Java Library Guava(http://code.google.com/p/guava-libraries/)中的一个模块,它本身是继承是Java的Future。严格来讲,Future是一种Design Pattern, 它本身跟语言是没有关系的。最新的C++11中,也加入了Future的支持,不过笔者以前写C++的时候,C++11还没正式发布,加上它本身也是比较新的,主流的编译器支持的本身也不是很好,因此只是知道它的存在,并没有去研究过它是做什么的,怎么来使用的。接下来,我会通过一些Java的Future的例子,来一步步介绍Future及其用法。
简单来讲,Future是这样一种Pattern: 它本身表示‘将来(future)’,你提交一个异步的任务,比如提交到一个threadpool,与此同时拿到一个Future对象,任务的执行是异步的,这时候你可以去做其它的事情,等到异步任务结束的时候,你可通过前面的Future对象拿到异步执行的任务的结果。下面通过一个简单的例子来直观感受一下Future: 阅读全文…
1.基本原理
zk的基本特性:
(1) 可靠存储小量数据且提供强一致性
(2) ephemeral node, 在创建它的客户端关闭后,可以自动删除
(3) 对于node状态的变化,可以提供异步的通知(watcher)
zk在zkfc中可以提供的功能:
(1) Failure detector: 及时发现出故障的NN,并通知zkfc
(2) Active node locator: 帮助客户端定位哪个是Active的NN
(3) Mutual exclusion of active state: 保证某一时刻只有一个Active的NN
2. 模块
(1) ZKFailoverController(DFSZKFailoverController): 驱动整个ZKFC的运转,通过向HealthMonitor和ActiveStandbyElector注册回调函数的方式,subscribe HealthMonitor和ActiveStandbyElector的事件,并做相应的处理
(2) HealthMonitor: 定期check NN的健康状况,在NN健康状况发生变化时,通过回调函数把变化通知给ZKFailoverController
(3) ActiveStandbyElector: 管理NN在zookeeper上的状态,zookeeper上对应node的结点发生变化时,通过回调函数把变化通知给ZKFailoverController
(4) FailoverController: 提供做graceful failover的相关功能(dfs admin可以通过命令行工具手工发起failover) 阅读全文…
Access Control在分布式系统中重要性是毋庸置疑的,今天这篇文章来介绍一下Zookeeper中的Access Control(ACL)。
用了三四年的C++,转向Java的怀抱,还是有诸多的不适应。C++中不论多复杂的Server,只要有GDB在手,总感觉debug都不是啥大事,程序运行期间的各种状态,都可以通过GDB轻松的获取到;而到了Java中,总感觉像是被困住了手脚,有力没法使,不知道是我还掌握方法,还是事实确实如此,发现Server端的Java程序,几乎没有什么好的debug的方法。也跟一些用了几年Java的朋友聊过,大多给出的答案都是Log。以前在学校刚开始学C/C++的时候,那时候的debug就是靠printf,基本思想跟Log是一样的, 后来结识了神器GDB之后,就深深地爱上了它。现在用上了Java之后,感觉又一夜回到了解放前。我并不是说Log不重要,相反,在越复杂的系统中,Log的地位越发重要,但是对于debug而言,一点点的加Log, 然后重新编译,布署,效率实在是太低了。对于像Java这样没有GDB这样的神器的语言,Log的地位越发重要,因此像Log4j这样的组件就非常流行,前段时间在弄hadoop中异步log相关的一些事情,就顺便把log4j学习了一下,下面整理了一下log4j相关的一些内容。
1. Log4j online manual
地址:http://logging.apache.org/log4j/1.2/manual.html
本文的大部分内容是参考了这个manual,外加一些其他人的博客。
阅读全文…
近期评论