消除服务端长尾的一种方法

我们都知道, 在大规模分布式系统中, 网络调度层的设计非常重要, 网络调度层需要承担故障容忍, 慢后端检测, 高吞吐和低延迟的功能, 特别是面临百度大搜索的大扇出模型的情况下. 上周去美国参加NSDI'15, 正好会议里有一篇消除长尾的论文, 拿出来和大家分享.

论文地址: https://www.usenix.org/system/files/conference/nsdi15/nsdi15-paper-suresh.pdf

 

NSDI’15 读书笔记

 

随着大规模分布式系统的普及以及应用, 一个服务或者数据往往存在多个副本, 在这样的系统架构下, 网络调度一直是分布式系统中非常重要的研究课题, 特别是在大搜索这样规模如此庞大的系统架构下, 同时既要面临大扇出的网络模型的挑战, 又对延迟非常敏感的情况, 如何降低延迟, 避免长尾对大搜索在线架构有着非常重要的意义. 本次NSDI’15会议, C3: Cutting Tail Latency in Cloud Data Stores Via Adaptive Replica Selection, 这篇论文对如果解决长尾请求的问题提出了新的思路和方法.

 

面临的挑战

  1. 性能波动是家常便饭. 在大规模数据中心中, 引起服务性能波动的原因是多方面的. 根据google和我们自己的经验来看, 引起服务性能波动的原因包括共享资源竞争, 周期性的垃圾回收, 运维活动(比如日志备份), 硬件或者软件故障, 请求的复杂长度不同等等. 面对如此多的可能性, 势必要求网络调度系统能够对性能波动进行自适应, 高效的选择不同的服务副本, 减少长尾服务的影响.
  2. 基于负载的副本选择策略是非常困难的. 最常用的副本选择策略是LOR(Lease-outstanding-request), 对于client端, 选择一个请求队列中包含最少的请求数的服务. 这种方法非常容易实现, 并且不需要依赖任何系统全局的知识, 特别是当系统全局知识不容易获取的情况下. 但是这种方法对于减少长尾的影响是非常有限的, 特别是存在负载倾斜以及不同的服务处理速度不相同的情况下. 下图说明了这种情况. 设计分布式的, 自适应的并且稳定的负载均衡策略是非常有挑战的, 如果设计不好, 就会出现比较严重的惊群效应.

 

  1. Dynamic Snitching的缺点. Cassandra服务实现了一种叫做Dynamic Snitching的负载均衡策略. Dynamic Snitching策略根据读延迟和服务的IO负载信息来决策, 选择最快的服务. 每个服务的读延迟和IO负载信息, 通过gossip协议共享. 然而实验发现, Dynamic Snitching策略无法很好的解决长尾问题, 主要原因是每一个client都采用一个固定的周期来重新计算每个server的打分情况, 这种做法产生2个问题. 首先, client端无法在小于计算周期的时间间隔内, 自动调整负载; 其次在这个时间间隔内, 系统可能在同步信息. 可能有人会建议缩短计算的时间间隔, 但是计算是非常耗时的, 算法需要计算服务在一段历史时间内的负载情况. 另外, Dynamic Snitching策略依赖服务分享iowait的平均值, 这样如果一个外部的或者内部的io密集型活动就会影响client端对server端的打分情况. 而且仅仅考虑了iowait因素也不具有通用性.

C3的设计思路

C3是一个自适应的副本选择机制, 目标是减少服务长尾对整体响应时间的影响. C3的设计坚持2个原则, 一是自适应, 副本选择必须能够快速的处理服务性能波动; 二是行为良好, 避免惊群效应. C3的主要设计思路包括2个组件:

  1. 副本排序. 使用最少的和相似的server端反馈来指导client端对所有server进行打分和排序. 打分算法还必须考虑多个client的因素以及避免惊群效应.
  2. 分布式速度和压力控制. 每个client需要控制对server端请求发送速度, 采用一种分布式的拥塞控制技术. 当所有的服务端超出请求发送速度时, client端不再继续向server发送请求了.

副本排序

client端独立的采用一个打分函数来对所有server进行打分. 为了减少长尾, 我们的目标是选择队列长度最小(qs)和处理请求最快(1/us)的server.

  1. 延迟的和近似的反馈. 对每一个server s, Servers需要反馈请求排队时间qs和请求处理时间1/us. Client端维护qs和us的指数加权平均.
  2. 考虑不确定性和并发. Server端反馈的qs和us仅仅是server端负载的一种视图, 并且对其他client端是完全透明的, 同时也没有考虑到还在网络中传输的那些请求. 所以考虑多个client端同时发送请求是非常必要的. 对于每一个server s来说, client端维护一个瞬时的未完成的请求数os, 然后client端定义server s的队列长度是: qs’ = 1 + os * w + qs. 这里w是一个并发度系数, qs是server端反馈的队列长度.
  3. 对长队列进行惩罚. 通过qs’的定义, client端可以计算每个server的qs’/us来定义server端的排序, 然而考虑到多个client端的因素以及不同的请求, 请求的处理时间不同, 这样的线性打分函数是不够的. 下图说明了这一点. 所以C3使用了一个非递减的凸函数来估算qs’以达到惩罚长等待队列的目的. 优化后的公式为: .

 

速度和压力控制

副本选择策略可以使client端选择最快的server来发送请求. 但是单纯的副本选择策略无法让所有的client保证server端的容量不会被超过阈值, 导致server端压死. 所以C3设计了速度控制机制, 当所有server的容量已经满的情况下, 所有client都hold请求在自己的内存队列中.

  1. 去中心化的速度控制机制. 考虑到server端性能波动, client端需要预估server端的容量并且调整发送速率. 每个client对每个server维护了一个基于令牌桶的速率限制器, 限制在一个时间窗口内发送给server的请求数量. 我们定义发送速率为srate. 为了根据感知到的server性能变化来控制速率, client端追踪在这个时间窗口内接收到的请求数量, 也就是接收速率rrate. 速度控制算法的目标是根据rrate及时调整srate.
  2. 速度控制函数. 如果client端的srate小于rrate, 则根据如下公式增加srate: .
  3. 把副本选择策略和速度控制速度结合起来, 整个C3的关键算法如下:

 

效果评估

我们把C3应用到了cassandra中, 在Amazon EC2中我们部署了15个cassandra节点, 采用了Yahoo Cloud Service Benchmark作为workload. 我们重点关心下面3个问题:

  1. C3是否在没有牺牲均值和中值的情况下降低了长尾延迟
  2. C3是否提升了读吞吐
  3. C3能否很好的适应server端的性能波动

 

 

转载于:https://www.cnblogs.com/zhengran/p/4511074.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值