• 沒有找到結果。

Decentralized FCFS Fair Scheduling

As mentioned in the previous chapter, our goal is to design efficient scheduling methods over P2P network that also have low FFI. In summary, a desirable virtual queue implementation should be:

1. Decentralized, where resource scheduling involving multiple collaborative peers, 2. Low FFI, so that queue jumpers are minimized,

3. Low response time, so that improving FFI does not incur too much overhead, 4. Non-starving, such that requests or resources, once enter the virtual queue,

eventually get processed against skewed request patterns

5. Proximity-aware, so that resource scheduling should respect the underlying network topology when possible.

6. Adaptive, so that when mid-to-long term patterns of request or resource supply change, the virtual queue can adjust itself to minimize FFI and response time.

To meet the requirements, we propose a general approach based on spanning trees. As shown in Figure 4.1, the virtual queue is implemented as collaborating managers that are connected as a spanning tree. In particular, each manager serves both a resource queue and a request queue. Furthermore, we assume a many-one mapping from resource providers and requestors to these managers, so that every provider or requestor belongs to exactly one manager. Although this assumption seems unnecessary, as will become clear shortly, the reason behind it is to give the virtual queue the ability to adjust the mapping gradually when the network evolves. This is important when, for example, the patterns of resources and requests supply changes over time, or knowledge about proximity is learned. Note that in our

implementation model, a peer can be a resource provider, a requestor, or both. The virtual queue implementation is outlined in Algorithm 4.1.

Algorithm 4.1: Spanning Tree

resources: Resource queue for current round resourcesN: Resource queue for next round

init():

Figure 4.1. Virtual FCFS queue implemented as a tree of managers Manager

registerResource(Resource res):

enqueue res to resourcesN

requestFromLocal(Request r):

match(r, resources.dequeue()) and updateStatus() or, for each child in order given by order(children):

child.requestFromParent(r, m), or, requestFromChildren(parent), or, fail

requestFromChildren(Request r, Manager ch):

similar to requestFromLocal, but skip children ch

requestFromParent(Request r, Manager p):

similar to requestFromLocal, but only

downward (not calling requestFromChildren())

match(Request r, Resource res):

inform provider of res to process r;

when the provider finishes, it will inform the requestor of r and then call registerResource() to its own manager

updateStatus():

if resources is empty and all children have reported roundCompleted roundCompleted = true,

for all children ch: ch.nextRound();

In short, the implementation assumes that initially, the managers form a spanning tree in a distributed environment, which can be done in a decentralized and fault-tolerant manner (e.g.

self-stabilizing trees) and is not exploited further in this thesis. When a requester issues a request, it calls requestFromLocal() to the manager it belongs to. The manager searches for an available resource locally first, then its children recursively. If no resource is found, the parent of the manager is searched lastly.

The implementation is round-based in that resources in a given round are consumed before next round begin. A provider can issue at most one resource by calling registerResource(). New coming resources (created when a provider becomes available,

possibly after processing a request several rounds ago) will be placed in the queue for the next round.

Generally speaking, the search order is essentially hierarchical (i.e. bottom-up, children-first). However, for each manager, the order that its children are searched can still vary (via the order() function). Different strategies can be conceived to adjust the search order in order to help exploiting the network dynamism, that is, the change of patterns of both requests and resource supply over time. In addition, the network topology can evolve by reassigning peer membership as well as restructuring the spanning tree in a decentralized manner, for example, by taking into account proximity information accumulated when the network evolves. The spanning tree has great advantage in this regard because different kinds of information can be gathered and computed to aid heuristic search. We have investigated several self-adaptation heuristics to help improving the scheduling performance. They are described below:

Random Search among Children When a manager runs out of resource and attempts to

forward a request to its children, it picks a child randomly from the set of children that have not reported to the manager that they have finished for the round. Note that such status updating is realized by updateStatus() in the base algorithm 4.1. Because it is still possible that the manager may not have the most up-to-date information at the time it is forwarding

requests, a child may still receive requests after it has reported round completion status to its parent. In this case the child simply replies as if it has run out of resources. This randomized strategy is outlined in Algorithm 4.2 with common part similar to the base algorithm 4.1 skipped.

Algorithm 4.2: Spanning Tree - Random Manager m

order():

collect children with !roundCompleted into childList shuffle childList randomly

return the childList

Excessive-Resource Child First The idea is to start from the child who “seems” to have

most excessive resources, including the available resources in all of its sub-trees, hoping to guess the right path earlier. This approach also has to potential to prevent contention of resources among “busy” managers. For example, suppose a given child (including its sub-trees) generates requests more than the resources it provides for a given round. If the child is searched first (e.g. using the randomized strategy described previously) and an available resource is indeed found, this may make the requests generated from that sub-tree later unable to find a resource close-by, hence incur additional search steps. The expected

“excessiveness” for a child can be accumulated and averaged round by round easily through the spanning tree (when nextRound() is called).

Algorithm 4.3: Spanning Tree – Excessive Resources First Manager m

requestCount : int;

resourceCount: int;

requestCountAvg : float;

resourceCountAvg: float;

totalRequestCountAvg : float;

totalResourceCountAvg: float;

registerResource(Resource res):

resourceCount++

same as registerResource(res) in 4.1

requestFromLocal(Request r):

requestCount++

same as requestFromLocal (r) in 4.1

averageCounts():

compute requestCountAvg based on requestCount and old requestCountAvg

compute totalRequestCountAvg based on requestCount, requestCountAvg, and childrens’ totalRequestCountAvg compute resourceCountAvg and totalResourceCountAvg similarly

nextRound():

(root only) perform averageCounts() bottom-up same as nextRound () in 4.1

order():

order children according to their (totalResourceCountAvg – totalRequestCountAvg)

Note that how averages are obtained is not explicitly given in Algorithm 4.3. With a spanning tree, the averages can be computed easily in a bottom-up manner. Also, we do not give specific formula in averageCounts() for computing the averages for each manager because there may be alternatives. An extreme case is to compute the averages based solely on resourceCount and requestCount recorded in the current round disregarding the past

records. A more typical approach is to account for the averages from previous rounds using some weighting factors.

Member Reassignment. The idea behind this strategy is to distribute requests and

resources evenly among managers by gradually reassigning producers and requesters to new managers in a decentralized manner. Intuitively, we would like to reassign the membership between a parent and a child if they have large difference in terms of net resource supply (i.e.

average resources count minus average request count). Like the accumulation of request/resource counts in Algorithm 4.3, the net resource supply can be derived by considering both current and past resource/request statistics. With this reassignment step, it is hoped that the whole P2P network can evolve according to the patterns of resource supply and requests over time. The algorithm is depicted below:

Algorithm 4.4: Member adjustment Manager m

exchangePeers(parent, child) parentRequests = 0;

parentResources = 0;

halfRequests = (parent.requestAvg + child.requestAvg) / 2 halfResources = (parent.resourceAvg + child.resourceAvg) / 2 collect all peers belong to parent and child in l

Note algorithm 4.4 does not stated when and how a given parent-child pair is chosen to perform the member reassignment. Although it can be determined using a threshold, in our experiments in the next chapter we pick the pair that exhibit maximum difference in net resource supply, with the goal to examine the effectiveness of such member reassignment approach.

相關文件