查看原文
其他

图解:讲一点分布式的基础知识!

The following article is from 码农翻身 Author 码农翻身刘欣

    点击上方 "程序员小乐" ,关注公众号

8点20分,第一时间与你相约

每日英文

You never know how strong you really are until being strong is the only choice you have.不到没有退路之时,你永远不会知道自己有多强大。


每日掏心话

世界很大、风景很美、若岁月静好,那就要颐养身心;面对人生的无奈,我们能做的,就是选择时干干脆脆,不犹豫,选择之后,坦坦荡荡,不后悔。


来自公众号:码农翻身 | 责编:乐乐

图片来自网络



   正文   


故事还是得从单机开始,没有单机哪儿来的分布式?


在IT世界,二进制的数据是我们最宝贵的资产,必须要把它保存在断电也不怕的硬盘上。



但是只用一块硬盘很危险,万一坏了数据就彻底没了。于是人们就想了个办法,把两块硬盘组织了起来,互为备份。


这种方式有个专门的术语,叫RAID ,就是冗余磁盘阵列的意思。


上图中两个磁盘互为备份,是RAID 1 , 数据会被同时写到两块硬盘中,安全性大大提高。


需要提醒的是,虽然这里有两块硬盘,但是从用户角度,只能看到一个逻辑的硬盘,操作系统已经把底层的两块硬盘给隐藏了。


RAID 1 的不爽之处是浪费了一个硬盘的容量, 改进方案可以用RAID 5:


RAID5 并没有像RAID 1那样对数据做备份, 它引入了一个叫做奇偶校验的东西(上图的黄色部分),  这样当一个磁盘坏的时候,就可以利用其它磁盘的数据进行恢复。


具体的计算如下(略繁琐,可以跳过)。


奇偶校验是用异或(xor)来实现的,简单的说,相同为0,不同为1


比如, 磁盘1保存 的数值是7(二进制 0111), 磁盘2 保存的是数值是8(二进制1000), 做一个xor操作

0111 xor 1000  => 1111


那磁盘3保存的值就是二进制1111


现在假设磁盘2坏掉了,换了个新磁盘,那根据磁盘1 中的 0111 和磁盘3中的1111,就可以计算出磁盘2的值是:


0111 xor 1111 =>  1000


于是磁盘2的值就可以恢复了!


但是, 如果在恢复的时候,又有一个盘坏掉了,那就悲催了。


使用RAID 5,写入时需要做计算,性能受到一定影响。

聪明的你肯定可以想到,除了RAID 1, 5, 还有其他方式, 例如RAID 0, 2,3,6,7, 5E 等,八仙过海,各显神通。


主从备份


但是在互联网应用中,RAID用的越来越少了,更常用的是跨越机器的备份。


这种方式不会把数据分散地写到各个机器的硬盘中,而是整体地写到一个机器中,然后整体地复制到其他机器。

由于跨越了网络,这种备份通常是异步的


副本多了,还带来了一个好处,可以把读操作发到副本机器上去读,主库只负责写操作, 压力就降低了


这就是常见的MySQL主从复制,读写分离。


可是,由于时间差的关系, 副本的数据可能会落后于主库, 产生读写不一致的问题,需要程序员想办法来解决。

(注:具体的复制细节,请移步《MySQL:硬盘在24 * 7工作中罢工了,我该怎么办?》)


分区


备份问题解决了, 如果你的数据越来越多,马上就会面对另外一个问题:一个机器无论如何也放不下了,怎么办?


解决办法就是分区, 把逻辑上是整体的数据,分别存储到不同的物理机器上去。


(不同的系统称呼不同,Elasticsearch 把它称为Shard,即分片, HBase把他称为Region)


可以这么分:


每个机器保存一段数据, Redis的Cluster就采用了类似的方式,每个服务器负责一段Hash槽。


还可以这么分:


这种方式称为Round-Robin ,也是Kafka默认的分区策略


Elasticsearch 则采用了另外一种办法:余数算法


余数算法简单明了, 非常容易确定一个数据保存在哪个机器上, 存取都非常地方便。


但是弱点也非常明显:如果数据更多了,想增加分区怎么办?


对不起,增加不了! 因为一旦增加分区,余数就会发生变化,数据就找不到了。


分区+备份


仅仅把数据做了分区还不够,如果分区所在的节点如果坏了,数据就丢了。


为了可靠性,数据必须得有备份,像这样:


每个机器上都有一个分区的主副本,每个主副本都有两个从副本(保存在不同的机器上),数据安全多了。


这是个非常常见的复制方式,Kafka和Elastic search 都在使用,需要注意的是:复制的最小单位是分区,而不是节点。


比如机器1挂掉了, 分区1的主副本丢掉了, 不用怕, 分区1还有两个从副本,分别保存在机器2和机器3上, 可以从他们那里去读数据。


问题是现在有两个从副本,他们都想当主副本,承担起主副本的职责,到底谁来当?


这是个非常麻烦的问题,把问题抽象一下:这相当于在一个分布式环境下(通常有着不可靠的网络),各个节点要达成共识:同意一个节点当老大。


解决这个问题,必须要利用一些共识算法(Raft, Paxos 等),  这些算法都很复杂,可以自己去实现,但是最好还是利用现成的组件,例如Zookeeper,让这个稳定可靠的“黑盒子”来帮忙吧。


说说你对分布式的理解?


欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。


欢迎各位读者加入程序员小乐技术群,在公众号后台回复“加群”或者“学习”即可。


猜你还想看


阿里、腾讯、百度、华为、京东最新面试题汇集

面试官问我:一个 TCP 连接可以发多少个 HTTP 请求?我竟然回答不上来...

面试官问我:说一下你对MySQL索引的理解?我竟然回答上来了...

10年前被删的初恋,凌晨1点突然加我…

记一次Linux被入侵,服务器变“矿机”全过程

知乎已读服务的前生今世与未来


关注「程序员小乐」,收看更多精彩内容
: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存