分布式技术原理与算法解析 04 - 存储&高可靠
分布式存储
分布式数据复制技术
常用于数据备份
- 同步复制技术
注重一致性,用户请求更新数据库时,主数据库要同步到备数据库后才结束阻塞返回给用户 - 异步复制技术
注重可用性,用户更新数据时立即给用户响应,备数据库的更新会在之后异步执行。一般用于对用户请求响应时延要求很高的场景 - 半同步复制技术
介于前二者之间,用户发出请求后主数据库执行写,并给备数据库发送同步请求,部分备份数据库(1个或过半)回复成功后即可响应用户
分布式高可靠之负载均衡
服务请求负载均衡
大量用户请求时,请求尽量均衡地分配到多台服务器进行处理,每个节点都处理一部分而非所有用户请求。
- 轮询
- 加权轮询
- 随机
- 一致性哈希
数据负载均衡
使用一致性哈希将数据均匀分布,如Redis的哈希环
分布式高可靠之流量控制
控制每个服务器接收的请求数,保证服务器可用。主要包括漏桶策略和令牌策略
漏桶策略
有一个固定容量的水桶,底部有一个洞匀速流出水,水桶可接收任意流速的水。每个请求都会向水桶中加一滴水,溢出的水滴代表请求被丢弃,成功滴出的水滴代表请求被匀速处理。这种策略做到了流量整形,无论流量多大,输出依旧是一个稳定的流量。缺点是对于突发流量丢弃的比较多。
漏桶策略适用于间隔新突发流量且流量不用即使处理的场景,可在空闲期处理暂存的大流量时期流入的流量;不适合流量要即使处理场景。缺乏效率,始终以固定速率处理。
Sentinel中匀速排队限流策略,分布式追踪系统Jaeger中有一种速率限制类型采集策略,都是使用了漏桶算法。
令牌策略
一个固定容量的桶,固定速率向其中放令牌,桶满时丢弃多余令牌。没来一个请求要先去一个令牌才可被响应。
当有突发大流量时,只要有足够多的令牌请求就迅速被执行。通常令牌容量的设置接近服务器处理的极限,可有效利用服务器资源。适用于有突发性流量,且流量要即使处理场景。
如Google的开源工具Guava提供的RateLimiter
Sentinel 流量控制方法:监控应用的并发线程数或QPS指标,当达到设定值时采取一定策略对流量控制,避免应用被高流量击垮。
- 通过并发线程数进行流量控制
- 通过QPS进行流量控制
分布式高可用之故障隔离
保证系统高可用,在出现故障时故障模块不会影响其他模块,同时方便故障的定位。有两个分割维度:按照系统功能隔离,通过资源实现隔离。
- 线程级隔离
- 进程级隔离
- 资源隔离
分布式高可用之故障恢复
软件故障通常由开发者自行解决,主要考虑硬件故障。常见有:节点硬件故障,如硬盘、内存故障、负载过大;网络故障,如线路问题、DNS故障、路由器故障。通过心跳包检测故障,判断节点能否正常提供服务。
单点故障恢复:采用主备方式处理,使用Raft等分布式一致性算法选举出一个新Master
网络故障恢复:CAP选择
网络分区
在分布式集群中,由于节点间网络不通,导致集群中形成不同的子集群。子集群中网络相同,但子集群间网络不同。
集中式架构中主要是主节点与备节点不通,且从节点只能联系到一个主节点
非集中式架构,节点是对称的,所以是分成不同子集
判断方式就是通过心跳包,将心跳可达的节点归属到一个子集。
处理方法
一种方式是将不可达的节点剔除,选出新的主节点。但这会造成双主问题。一些其他方式如下:
通过 Static Quorum 处理网络分区
设定一个固定数值,分区中节点数大于这个数值时该分区就是活动分区。这个数要大于总节点数的一半。但有两个缺点:当分裂的子集群过多时没有满足条件的分区;这种策略中数值是固定不变的,不适用于有节点动态加入的场景。
通过 Keep Majority 处理网络分区
有过半节点的分区即为活动分区,将总数设为奇数以防止双主。可解决动态加入节点的问题,但也不适用于多分区场景。
通过设置仲裁机制处理网络分区
引入第三方组件作为仲裁者,其可与所有节点连接并获得心跳信息。该节点拥有全局心跳信息,可根据全局心跳判断分区,并决定保留和舍弃哪些子集群。
基于共享资源的方式处理网络分区
与分布式锁类似,某个子集群获得了共享资源才可以提供服务。如果其获取锁并发生故障,会导致其他子集群不可用。