1.概述
在操作系统中调度算法是指根据系统的资源分配策略所规定的资源分配算法。对于
不同的的系统和系统目标,通常采用不同的调度算法。在glusterfs中,调度算法用于调度哪一个存储节点来存储数据。大致表示如下:
调度算法示意图
目前在3.2.5中,实现了5种调度算法,分别是alu,random,nufa,rr,switch。
在每个算法中,他们均会实现这样几个操作:
1. 初始化函数(init),该函数在unify初始化的时候会被调用,完成调度器的初始化;
2. 析构函数(fini),该函数会在unify析构时候调用,完成调度器的销毁;
3. 更新函数(update),主要用于更新它收集到的子卷的相关信息;
4. 调度函数(schedule),通过相应的算法完成对子卷的调度工作;
5. 通知函数(notify),对相应的子卷进行通知。
在接下来下面我们将一一分析:
2.rr
rr调度算法全程为Round Robin。是让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。
2.1函数rr_init分析
1) 调度器选型验证;
2) 在相应的unify对象中查看是否有只读类型子卷,如果没有,出错返回;
3) 在相应的unify对象中查看是否有可写类型子卷,如果没有,出错返回;
4) 为调度器的一些参数赋初值;
2.2.函数rr_schedule分析
1)通过函数获得调度分界线的索引值:
next_schedule_index = ROUND_ROBIN (rr->schedule_index, rr->subvolume_count); 而函数: #define ROUND_ROBIN(index, count) ((index + 1) % count) |
2)调用rr_update,更新相应的xlator的子卷在该调度器中的状态信息。在rr_update中首先会检查是否到一个更新时间周期,如果到,则首先更新下一次状态更新的时间,再通过一个循环,收集每个子卷信息,关键代码如下:
for (i = 0; i < rr->subvolume_count; i++) { xlator_t *subvolume_xl = NULL; call_frame_t *frame = NULL; call_pool_t *pool = NULL;
subvolume_xl = rr->subvolume_list[i].xl;
pool = this_xl->ctx->pool;
frame = create_frame (this_xl, pool);
STACK_WIND_COOKIE (frame, rr_update_cbk, subvolume_xl->name, subvolume_xl, subvolume_xl->mops->stats, 0); } |
3)根据卷的状态决定选择子卷:
for (i = next_schedule_index; i < rr->subvolume_count; i++) { if (rr->subvolume_list[i].status == RR_SUBVOLUME_ONLINE && rr->subvolume_list[i].status == RR_MIN_FREE_DISK_NOT_REACHED) { pthread_mutex_lock (&rr->mutex); rr->schedule_index = i; pthread_mutex_unlock (&rr->mutex); return rr->subvolume_list[i].xl; } } |
如果该种方式下没有找到相应子卷,则通过如下方式:
for (i = 0; i < next_schedule_index; i++) { if (rr->subvolume_list[i].status == RR_SUBVOLUME_ONLINE && rr->subvolume_list[i].status == RR_MIN_FREE_DISK_NOT_REACHED) { pthread_mutex_lock (&rr->mutex); rr->schedule_index = i; pthread_mutex_unlock (&rr->mutex); return rr->subvolume_list[i].xl; } } |
如果该种方式下仍没有找到相应子卷,则还有2种方式,其实就是检查相应子卷的状态,然后确定选择一个子卷。
3.可配置选型
键名 | 类型 | 默认值 | 描述 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|