2011-03-27

百度文库的对错

  上次Google Book没觉得有什么问题.
  这次,百度文库的事,才开始想其中有什么问题.
  果然,有时候还是不够中立.

  其实,百度也许在法律上并没有什么过错.
  毕竟,它不是图书的提供者,谈不上是publish的行为.
  而对于图书上传造成的影响,大体跟P2P的合法性与否差不多.

  即,对于UGC的内容,平台本身有没有责任.
  
  对于音像制品,软件产品等相对成熟的东西来说,平台的责任很难划分清楚.
  因为这些产品本身有比较明确的适用/版权说明.
  提到涉及的范围权利等.

  而图书,至少对自己身边的几本来说,并没有明确的权利划分.

  也就是说,购买图书这个行为,其实是一个并不明确的行为.
  购买的到底是什么?

  诚然,对于图书内容的引用,涉及到著作权,但是,购买之后呢?

  买到的是什么,适用于什么范围.

  以其他产品来说,可能限制了copy的数量,和copy适用的范围.
  但是,图书呢?

  没有copy.
  那阅读这个行为呢?

  比如,某人买了这本书,是只能自己看呢?还是可以借给别人看?
  想Amazon的kindle,貌似是有提供互借的.

  而日常里,相互交换阅读也是很正常的一件事情.

  对于百度文库的这种行为,其实可以理解为一个租借场所也不为过.

  于是,从法律上来说,似乎并不违法.

  但是直觉上,这又是一个不合理的事实.
  
  它的不合理在于,适用范围上.
  购买行为,所导致的所有权问题等等.
  都是并不明朗的.

  这在网络还不发达的时代可能并不严重.
  因为交流成本的问题,一本图书的流传/借阅范围并不会产生很大影响.
  于是,图书行业也并不关心这个早已存在的漏洞.
  或者说,其实有关心过,但只是对于出版行业.

  所以,才有了对图书馆博物馆之类的,能够产生大范围影响的案例进行豁免.

  但是,互联网的发展,把这个漏洞放大了.
  
  它不仅仅是个人与个人之间的交换,不仅仅是熟人与熟人之间的交换,甚至交换的增长速度可能是非线性/级数增长的.
  在这样一个环境,出版商,或者说图书版权所有者们,对于图书的流传的把握能力就失控了.

  因为这本是原本的契约里的由于含糊不清带来的漏洞.
  在对于错之间的一种存在.

  现在,百度文库的出现把这个问题彻彻底底地暴露了.
  如果说之前Google还算是一种双赢的解决方案的话,那么百度的则是完全的利用漏洞玩的一场游戏.
  
  合法但并不合理.

  其实,本质上来说,百度文库这件事情也许算是为出版业的转型提供了一个契机.
  因为只有这种血淋淋才能让那些不能接受新事物的人,不得不为寻找盈利模式而努力.

  即便百度妥协了,但是这个漏洞已经暴露出来了.
  而且,即使没有百度,事实上,盗版/网络传播的问题已经存在已久.
  出版业也不是不知道.
  
  说到底,百度也不过是把一群掩耳盗铃的家伙的遮羞布给彻底拉下来了罢了.

  作家们遇到的问题其实是寻找新的盈利模式的问题.
  在承认互联网的游戏规则下寻找新的契机的问题.

  本来,Google其实已经为他们寻找到了一种途径.
  一种算是双赢的,互联网味道十足的模式.
  可是他们拒绝了.

  在音乐行业都开始考虑转换模式,采用在线/流量等盈利的探索方式的时候,只有出版业还在坚持游离在互联网之外,似乎这样能够独善其身.

  而百度很好地出来证明他们错了.

  所以,即便这次百度低头了.
  但如果作家们依然悠然自得,希望以古老的方式,维持古老的生计.
  就很难说,作家这个行业还能存在多久.

  至少是传统出版意义上的作家.

  像起点的模式其实解决了一部分问题. 
  当然,它不能解决所有人的问题.
  毕竟,它是一个非常商业化的东西.
  
  而有些作家,可能是没那么商业化.
  或者说,需要十年磨一剑.

  说到底,好作家的定义在于,书有人看.
  而好作家如何赚钱,则可以从如何从看书的人身上赚钱出发.

  买书是一种,阅读也是一种.
  Google能把搜索编程一种商业行为.
  自然也就有人能把阅读变成一种商业行为.

  虽然,百度这次是很没下限,如有些人所说的,这是在毁灭整个行业.
  毕竟,就很多人的思维来说,在中国,能做大,而且独大,是最快最长久的盈利方式.
  因为这里从来没有垄断审查.
  从来是纯粹的"资本说话".

  但,至少百度把这一现实的问题提前摆在了世人的面前.
  怎么想,怎么做.
  
  总该会对作家们,和出版行业有所反思. 

2011-03-26

关于Hadoop

  在hadoop里写了点东西,大概也印证了有怎样的环境才有怎样的解决方案.

  确实,在hadoop里,不像在一台机器上,能比较容易的mutex操作.
  毕竟,你要mutex 的东西都不知道物理上在什么地方,甚至还存在不存在.
  所有,这个是思维要转变的地方.

  在分布式情况下,有时候create比read/write来得更浅显易懂.
  毕竟,除了delete操作,其他操作都不会影响create的行为.
  而且,当delete操作也依赖于create的某些标志性行为的时候,一切都简化到create操作上了.

  比如,要进行任何操作,先create一个标志,表明holding了这个resource.
  
  当然,这中间也还是会有些问题的.
  比如,在hadoop里,这依赖于namenode操作的正确性.
  
  某种程度上说,这种解决方法其实是利用了namenode的单点性.
  由于所有对hdfs的操作都需要汇总反馈到namenode上 ,所以,用namenode去拦截调度也是很容易想到的思路.
  毕竟,所谓的一致性,是由namenode保证的.

  但是,如果是纯粹的对等网络呢?
  比如,没有namenode的?

  其实最后还是会归结到这种有中间节点的模型上.

  比如hadoop准备改造的mapreduce模型.
  实际上就是去掉的jobtracker的这个单独的job调度节点,把它分散到开来.

  也就是实际上来所,是在tasktracker上vote一个节点作为某一个job的jobtracker罢了.

  这其实有时典型的分层思维.
  跟ip地址的掩码模式差不多.
  加一层即可虚拟出许多隔离的东西出来.

  resource manager就是这个新加的一层.

  所以,从这个程度上来说,也许并没有纯粹的对等模型.
  多少还是有一些中心节点的.
  只不过这种中心节点的特殊性不强罢了.

  就像人的选举一样.
  本质都是差不多的.
  只是由于某些原因变得有些特殊罢了.

  所以,平等这个东西,首先是建立在公平之上.
  没有公平,也就没有平等.

  话说回来,hadoop或者说map reduce这个东西,也许又是Google重新修饰了一番的东西.
  就像Bigtable的概念一样,重新包装了下,以不太直观的形式描述一个很简单的模型/思路.

  mapreduce其实就是把计算分摊到各台机器上罢了.
  即使不用hadoop,写个脚本自己分块数据自己计算汇总也是可以的.
  只不过hadoop本身解决了分块的问题.

  而所谓的map/reduce过程,则多少有些无谓?
  毕竟,redcue本身其实也是一种map过程.
  至少从hadoop的实现上来说,是这样.

  而且,hadoop本身似乎也是这么认为的.
  这个从job的combine设置以及,不显式设置reduce数目的时候,job的行为可以看出.
  
  本质上说,hadoop的reduce过程只是map的特例.
  所不同的是output出来的数量分块比较少.

  当然,从编程接口上来说,reduce跟map的区别在于,reduce是key的一个汇总.
  但其实这是map output的sort使然.
  reduce也不过是根据output结果去取罢了.

  所以,其实mapreuce本质上就是一个数据格式的转换问题.
  只不过被放到到了分布式的情况下.
  多了调度和同步的问题.

  除开这些,mapreduce也许什么都不是.  

2011-03-06

HDFS的碎碎念.

  HDFS说简单也简单,说复杂,其实也不复杂.

  它解决的主要是在集群规模大了之后,distribution的问题.
  更重要的是把disk的failure视为常态.

  因为毕竟,只是单纯的distribution的话,如NFS的也可以达到目的.
  但概念是Google提出的,它面对的问题显然不是一般人会常态遇见的.

  所以HDFS/GFS的概念主要在replication.
  
  理论上的模型也很符合直觉.
  寻找一个可用的节点,然后分发之.
  
  所不同的就是这种分发的具体实现了.

  HDFS的replication其实很简单.

  比如你upload一个local的文件到HDFS的时候,DFSClient会向namenode发起一个RPC的create请求.

  顺便说下,Hadoop的RPC其实有两套.
  一套是给各种node的用的,基于interface的reflection.
  另一个套是给DFSClient之类的,基于Invocaionhandler.
  但本质都是把方法名和参数以及连接信息什么的写到流里,然后在method.invoke()

  也许可以理解为前者是给server用的.毕竟有了local的instance.
  而诸如DFSClient的是没有instance的实现的,所以要InovcationHandler去hook.

  回到create.
  
  namenode会向FSNamesystem添加一个inode信息,同时记录一个lease.
  此时的inode为INodeFileUnderConstruction,表明是未完成的.
  而lease的作用是用来保证不重复create/以及一些超时处理.
  
  然后namenode将这个RPC的请求返回给DFSClient.
  
  DFSClient会开启一个DataStreamer去做copy and write的工作.

  首先是到RPC到namenode去申请block.
  此时的namenode会去查看FSNamesystem里的inode信息.
  
  namenode会检查inode的类型是否是INodeFileUnderConstruction,即未完成.
  然后会check下lease的信息,看时候有意外的已经replication的情况.(这个估计是以前有类似bug吧.)

  当然,在此时,一般这些check都会pass掉的.
  但,这是distribution的,所以,按照状态机来变换是最简单的事情.
   
  datanode会根据block size去选择一些datanode.
  在用DFSClient.copyfromlocal的情况下,block size是由参数fs.local.block.size决定的.
  其他情况下,是由dfs.block.size决定的.

  replicator在choose datanode的时候会根据replication的数目而略有说不同.
  当数目是<2的时候,当local也是datanode的是会被选上.
  其他情况则感觉datanode上的block数目和load做一个权衡.

  然后把选择好的naenode把block和datanode的分配信息返还给DFSClient.
  DFSClient则选择第一个datanode建立连接,把读到的数据写到这个选中的datanode上.

  在DataStreamer里还有一个ResponseProcessor的东西,在处理这个datanode返回来的ack.

  但是,这里只写往了一个datanode,那么replication怎么实现的呢?

  这个在datanode的实现了.
  datanode在经历过一些列初始化之后,会有一个DataXceiverServer去处理进来的连接.
  尤其的,没一个连接会dispatch到DataXceiver去处理.
  
  DataXceiver就是HDFS的IO操作的核心吧.
  
  当地一个datanode收到DFSClient发来的OP_WRITE_BLOCK请求时候,会调用writeBlock把读到的block写到datanode的local filesystem里.
  同时会取DFSClient传过来的datanode array信息,取第一个,然后与之建立连接,然后把把block信息和剩下的datanode写到对方的stream里.
  
  即,HDFS的replication就是通过这种级联的,pipeline方式的write扩散出去的.
  同样,ack也是一级一级地往前传递.

  至于写到datanode上的block大小限制是在DFSOutputStream里限定的.
  当写到这个数的时候会表明这是最后一个package.

  至于读则差不多.
  namenode会在返回datanode的时候稍微排序下.
  将local和local rack的往前排.
  因为client在取datanode的时候总是先取前面.

  至于local rack怎么决定的.
  这个在NetworkTopology里,没仔细看.  

聊聊卡布里尼

最近看了部片叫卡布里尼,算是可能这段时间来比较有意思的一部电影. 故事也不算复杂,就是一个意大利修女去美国传教,建立慈善性质医院的故事. 某种程度上来说,也很一般的西方普世价值主旋律. 但是如果换一套叙事手法,比如共产国际的社会主义革命建立无产阶级广厦千万间的角度来看的话,也不是...