不合格的程序猿
分类: 服务器与存储
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