分布式散记

 

         对分布式系统有一些粗浅理解,记录下一些要点,以备记忆。


         1 EC纠删码 & Reed-Solomon 算法


        分布式存储要讲究效益。正常情况下系统对一个数据会通过备份数据以保证数据安全,例如把数据存储为两份或者三份,这个方法的优点是简单,CPU没有计算量,但是存储成本高。


         一些公司未来节约成本会使用EC纠删码算法,如七牛公司,其具体的算法我不清楚,其大概就是把数据氛围28分,计算出4份冗余数据,即以1.1倍的数据量以达到存储三倍的等同效果。百度网盘也用了EC方法来节约存储,如Reed Solomn算法,它把数据划分为8份,通过这个算法计算出4份冗余数据,通过1.5倍数据来达到3倍数据的效果。EC纠删码的缺点当然是CPU的计算量比较高。


       2 多粒度存储


       SATA盘存储数据时候,以4k为一个物理单位作为一个page给文件分配空间,其粒度就是4k。类似的,分布式存储中也要区分数据的粒度。一般地,分布式系统为了在系统存储利用率和io效率之间取得一些平衡,会采取多级粒度,如大文件存储系统如HDFS之类可以8M为最小粒度,以256M为最大粒度,中间有16M、32M、64M和128M四种粒度,共6种粒度。分布式系统可以把集群中每台机器按照某种粒度均匀划分,当外部有文件写申请的时候,metaserver可以根据文件的大小来把文件写在不同的机器上。


       有些内存数据库(如鹅厂的CMEM)可以认为是一个object文件系统,它的object大小默认为84B,当然这个object大小是可以由client决定的。CMEM及其继承者CKV中的datanode(即集群中的数据存储者)每个数据的桶的大小为1G,所以如果你去搜索CKV时候,它自称数据伸缩范围为1G至1P。


       3 串行写以及多次读取


       如上面已经叙述过的,一般大型的分布式系统中如HDFS为了保证数据的CAP中的P一般会把数据存储三份。那么,第一个问题就是选取集群中的那三台机器呢?分布式系统一般写速度要比读速度快,这是其与单机系统有所区别的一个显著特点,因为大部分分布式系统读的次数要远多于写的次数。metaserver可以先选取四台机器,分别进行网络测速,从中选择三台网速最快的系统,其中一台为master,其他两台为slave。


        当FS中的metaserver收到client通过写请求发来的数据包时候,它为了保证CAP中的C即严格数据一致性,会通知三台机器进行串行写。metaserver先把请求包发给master,master收到包的时候,把要写的文件内容放在内存中,不待写成功就会立即把请求包再转发给一个slave,第一个slave写成功后再把数据转给第二个slave,待第二个slave写成功后再把给master一个ack包,以通知master两个slave都已经写成功。master再检测自己的数据是否写成功了,只有自身也写成功才会给metaserver返回ok包。master不待自己写成功就把数据包转给slave有两层意义,第一是保证串行速度,第二也是最终的一条就是当master-slave-slave三份数据还没有写成功时,如果master收到了metaserver转发的外部其他client的对这个文件的读请求,此时它从磁盘上就读不到数据,其他client就得不到这个文件,这就保证了数据的严格一致性。


         4 命令取消


         在HDFS这种保证数据严格一致性的系统中,数据存储采用了master-slave-slave结构,只有master对外提供读服务。有的分布式系统只用了master-slave两级结构保证数据备份,master和slave都可以对外提供数据读服务。如果client规定读超时为10ms,它可能先把读请求发送给master,当10ms超时后后还没有收到master的返回包,它就可以再向slave发送读请求。


        如果发出去2ms后,client收到了master的返回包,它就可以再向slave发送一个cancel读命令,当slave收到这个命令后就不再执行先前收到的读请求。


        5 单线程与多线程


        分布式系统的开发者,有人喜好多线程如memcached,有人喜好单线程如redis。依照现在的趋势看来,redis的用户貌似比memcache多一些。但是redis因为采用了单线程模式开发,它就有可能发生一些莫名其妙的问题。


        我知道的一个场景就是,如果用户采用了aof方式在sata中备份内存的数据,当sata盘写满的时候,redis就会把磁盘清空,把内存中的所有数据写入sata盘。这个时候如果有外部写请求,它会在处理写请求和把内存中的数据写入磁盘两个任务之间倒腾,此时就有可能把写请求的数据丢掉。如果此时还有外部读请求,它就会疯掉。


      6 主从数据同步
      很多通过log进行主从同步的系统如mysql,都有一个checkpoint的概念。每隔一段时间,就检查上一次checkpoint到目前为止数据的checksum是否一致,如果不一致只用从checkpoint到目前为止之间的数据进行同步就可以了。
      详细步骤可以参考[《腾讯游戏数据自愈服务方案简介》][1]。


      7 消息队列
      kafka消息队列一个巧妙的地方,就是一个写者直接把数据写进一个磁盘,多个写者分别写进多个磁盘,这样消费者读的时候直接去相应的磁盘去读。所以队列的瓶颈反而是在cpu。
  
      8 数据一致性
      cache一般缓存了db的热点数据。一般的系统都存在着多读多写的问题,如何保证写的时候,前端的数据表现一致并且保证后端的最终数据一致性?
      写的时候,发送冰冻命令,如果冰冻失败,就写失败,这就意味着先前有一个写请求已经发送了冰冻命令;冰冻成功后,向mysql执行写操作,然后就完了。cache冰冻其间只能被读,写以及其他冰冻都会失败,冰冻超时后,数据会被删除掉,这样当下一次读过来的时候看到cache中无数据,就到mysql读出来,然后写到cache中,然后整个读才算成功。Cache接受到冰冻命令后,如果其中没有数据,会返回给客户端说没有数据。写请求就会先发送一个读命令(读命令会先把旧数据从mysql出来写进cache中),然后再次发送冰冻命令。


      此记。后面如果我的知识储备库有了新货,就会更新在这里。文章有错误是在所难免的,也请各位朋友指正。
    


  [1]: http://blog.csdn.net/dba_waterbin/article/details/43608587

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值