Chinaunix首页 | 论坛 | 博客
  • 博客访问: 765650
  • 博文数量: 274
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 862
  • 用 户 组: 普通用户
  • 注册时间: 2015-10-24 15:31
个人简介

不合格的程序猿

文章分类

全部博文(274)

文章存档

2019年(3)

2018年(1)

2017年(4)

2016年(160)

2015年(106)

我的朋友

分类: 服务器与存储

2016-09-01 19:37:16

一.什么是pg的revovery?为什么需要它?

考虑两种最常见的场景:

1. osd暂时的故障下线然后又上线。

2.osd永久的故障下线,更换硬盘重新上线。

无论哪种情况,osd上线后通常会发现,自己承载的pg有数据落后了,需要进入恢复模式,从其它osd上获取新的数据达到同步。

这个过程就是pg的recovery过程。

recovery分为两种:

1. log-based recovery. 是说osd故障时间不长,需要恢复的数据可以通过pg log回放找回来。

2. backfill recovery. 是说无法通过pg log回放找全数据,只能通过全量回填(backfill)拷贝。


二.pg recovery三个相关的限流参数:

osd_max_backfills:默认值10

osd_recovery_max_active:默认值15

osd_recovery_max_single_start:默认值5


1.    osd_max_backfills的含义是:一个osd上承载了多个pg。可能很多pg都需要做第二种recovery,即backfill。 设定这个参数来指明在一个osd上最多能有多少个pg同时做backfill。

详细至代码:

class OSDService 两个跟backfill reservation 相关的成员:

  AsyncReserverlocal_reserver;
  AsyncReserver remote_reserver;

当一个pg在primary osd上发现自己需要backfill to a preblica, 就将自己加入 local_reserver queue(只有osd_max_backfills 个slots。从这里看到osd_max_backfills限制的是slot个数),同时还要请求replica在remote_reserver(同样只有osd_max_backfills个slot)获得slot,然后做数据回填工作。


2.    osd_recovery_max_active的含义是:一个osd上可以承载多个pg, 可能好几个pg都需要recover,这个值限定该osd最多同时有多少pg做recover。

详细至代码:

每个OSD有一个叫recovery_tp的线程池专门处理recovery操作,线程池的线程数默认是osd recovery thread = 1。

这个线程池对应操作一个叫RecoveryWQ的工作队列。OSD承载的pg发现自己需要做recvoery,就把自己queue进此队列。

osd recovery thread在干活dequeue的时候,发现当前active的pg recover数达到osd_recovery_max_active了,那就暂时不要出列,只能hold住了。

  struct RecoveryWQ : publicThreadPool::WorkQueue {
     ...
    PG *_dequeue() {
      if (osd->recovery_queue.empty())
     return NULL;
      
      if (!osd->_recover_now())
     return NULL;

      PG *pg = osd->recovery_queue.front();
      osd->recovery_queue.pop_front();
      return pg;
    }

bool OSD::_recover_now()

{

  if(recovery_ops_active >= cct->_conf->osd_recovery_max_active) {

   dout(15) << "_recover_now active " <

            << " >= max " <_conf->osd_recovery_max_active << dendl;

   return false;

  }

3.    osd_recovery_max_single_start的含义是:这个值限定了每个pg可以启动recover操作的最大数。

详细至代码:

void OSD::do_recovery(指定pg),调用pg->start_recovery_ops(指定一次启动多少个recoveryops, 参数由osd_recovery_max_single_start及osd_recovery_max_active共同决定)


三.如何调整recovery限流值?

默认值并不能很好的适应线上情况,通常导致后端osd请求过高并发过高,影响心跳和导致客户端请求挂起。结果表现为,客户端读写受影响,正常OSD因为没有心跳回应而被标记为down.

在更换SATA盘时,限流建议值如下:

osd_max_backfills:1

osd_recovery_max_active:3

osd_recovery_max_single_start:1

实验结果表明: 更换的SATA盘在做backfill时,磁盘util保持在40~70%的合理区间。

全SSD集群的更换磁盘时,参数值应该可以适当调大。但在没有实践结果支持的情况下,建议保守设置为跟SATA盘一样的限流值。

还有一个额外的参数:osd_recovery_op_priority从默认值10改到1. 将recovery优先级降到最低。也会降低对客户端读写的影响,但目前没有调整。

转自:http://blog.csdn.net/guzyguzyguzy/article/details/50439621

阅读(1734) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~