Mỗi khi download xong được một segment thì receiver sẽ lưu lại segment này trong phần bộ nhớ lưu trữ chia sẻ (contribute storage) của mình. Đồng thời receiver cũng phải gửi một thông báo cho Tracker để thống kê lượng dữ liệu truy cập cũng như thời gian truy cập và đánh giá mức độ phổ biến của mỗi video (11). Tracker xác nhận bằng một thông báo ACK (12). Việc đánh giá mức độ phổ biến được thực hiện tại Tracker như sau: nếu video thứ k có tổng số truy cập là Ck và số lần truy cập của video phổ biến nhất là Cmax thì mức độ phổ biến của video thứ k là Ck/Cmax. Đối với những video phổ biến, khi càng có nhiều yêu cầu truy cập thì càng có nhiều phân đoạn của video được lưu đệm trên các peer và càng có thêm nhiều yêu cầu streaming có khả năng được đáp ứng. Trong khi đó những video ít phổ biến chỉ được một vài peer lưu đệm và có khả năng số ít các peer này không kết hợp đủ băng thông phục vụ cho yêu cầu streaming. Trong trường hợp này, Video server sẽ tham gia hỗ trợ streaming và cũng chỉ có những video ít phổ biến mới được hỗ trợ. Như vậy trong mô hình đề xuất, việc streaming các video phổ biến nhiều khả năng được thực hiện bởi các peer thông thường, trong khi các video ít phổ biến hơn sẽ được hỗ trợ bởi Video server. Bởi vì số lượng các yêu cầu truy cập đối với những video ít phổ biến cũng ít xuất hiện cho nên lưu lượng tải đối với Video server cũng thuộc mức độ vừa phải. Do đó cũng không cần phải triển khai những server mạnh và có băng thông lớn như trong mô hình Client/Server.
Dưới đây là giải thuật của hệ thống:
Ký hiệu Ý nghĩa
Send <> to Thủ tục gửi thông báo
Get <> from Thủ tục truy cập danh sách
ADD() Thủ tục thêm một phần tử vào danh sách
Scheduling() Thủ tục lập lịch 200 Kbps 200 Kbps 100 Kbps 250 Kbps 250 Kbps 200 Kbps 300 Kbps P1 (Seg#0) P2 (Seg#0) P3 (Seg#0, #1) P4 (Seg#1, #2) P5 (Seg#2) P6 (Receiver) Playback rate 500 Kbps
PeerAddr Địa chỉ của peer gửi yêu cầu
TrackerAddr Địa chỉ của Tracker
VideoServerAddr Địa chỉ của Video server
Peerlist[videoID] Danh sách các peer truy cập video tương ứng với videoID
num_segment Số lượng segment của video ứng với videoID
Standby_set[i] Tập các peer đang chia sẻ segment thứ i
Supplier_set[i] Tập các peer được chọn ra làm peer cung cấp segment thứ i
TotalAvailBandwidth() Hàm tính tổng băng thông chia sẻ của các peer
Storing to Thủ tục lưu lại segment vào bộ nhớ lưu trữ chia sẻ
BwAvail Băng thông tối đa có thể upload của mỗi peer
Seg_size Kích thước của một segment
ContributeStorage Bộ nhớ lưu trữ chia sẻ của mỗi peer
StAvail Kích thước bộ nhớ lưu trữ chia sẻ
Bảng 2-1: Các ký hiệu được sử dụng trong giải thuật
New Peer : khi kết nối vào hệ thống
1:
2:
3:
// gửi yêu cầu truy cập danh sách các video trong hệ thống
Send REQUEST_VIDLST to Web server; // nhận video list từ Web server
Get <videolist> from Web server;
// gửi yêu cầu truy cập videoID cho Web server khi chọn xem video
Send REQUEST_INF<videoID> to Web server;
Web server: khi nhận được yêu cầu truy cập video của New Peer
1:
// thông báo cho New Peer các thông tin mô tả video cũng như địa chỉ của // Tracker và Video server
Send REPLY_INF<videoID, TrackerAddr, VideoServerAddr, MetaData> to New Peer;
New Peer: khi nhận được thông báo trả lời từ Web server
// gửi yêu cầu peerlist tương ứng với videoID cho Tracker theo địa chỉ nhận được // từ Web server
Tracker: khi nhận được yêu cầu peerlist từ New Peer
1: 2:
// gửi peerlist cho New Peer
Send REPLY_PRLST<videoID, peerlist[videoID]> to New Peer;
ADD(peerlist[videoID], PeerAddr);
New Peer: khi nhận được peerlist từ Tracker 1: if peerlist = Ø then
2: for i:=1 to num_segment do
3: Send REQUEST_SEG<videoID, Segi> to Video Server;
4: else
5: for i := 1 to num_segment do
// gửi truy vấn segment thứ i cho tất cả các peer có trong peerlist
6: for jpeerlist[videoID] do
7: Send REQUEST_SEG<videoID, Segi> to peerj;
8: end for j
9: Standby_set[i] := Ø;
// chờ một khoảng thời gian TCollect để nhận các thông báo trả lời
10: while timeout ≤ Tcollect do
11: if recept RESPONSE<videoID, Segi, BwAvail> from peerjthen
// kết nạp peerj vào tập dự phòng của segment thứ i
12: Standby_set[i] := Standby_set[i] { peerj};
13: end if
14: end while
// nếu không tìm thấy peer cung cấp cho Segment thứ i
15: if Standby_set[i] = Ø then
// gửi yêu cầu truy cập Video server để download về segment thứ i
16: Send REQUEST_SEG<videoID, Segi> to Video Server;
17: else // nếu Standby_set[i] ≠ Ø
// Chọn từ Standby_set[i] M supplier tốt nhất và
// có tổng băng thông chia sẻ lớn hơn tốc độ phát hình CBR,
18: k :=1;
19: Supplier_set[i]:= Ø;
//Pot là hàm đánh giá mức độ tốt của mỗi peer (xem phần 2.4.1)
21: Supplier_set[i]:= Supplier_set[i] MaxPot{Standby_set[i]};
22: Standby_set[i]:= Standby_set[i] \ MaxPot{Standby_set[i]};
23: k:=k+1;
24: end while
// yêu cầu các peer được chọn dành riêng băng thông
25: for jSupplier_set[i] do
26: Send REQUEST_RSVBW<Reserver bandwidth> to Supplier[j];
27: end for j
// Áp dụng giải thuật lập lịch sinh ra lịch biểu gửi cho M supplier // để tải về Nsche block (xem giải thuật lập lịch trong phần 2.4.2)
28: Scheduling(Supplier_set[i], Nsche);
29: for jSupplier_set[i] do
30: Send Schedule to Supplier[j];
31: end for j
// chờ nhận các block …
32: end if
// kết thúc download segment thứ i
// lưu lại Segment thứ i vào bộ nhớ lưu trữ chia sẻ
33: if StAvail ≥ Seg_size then
34: StAvail:=StAvail – Seg_size;
35: Storing Segi to ContributeStorage;
36: else
// nếu không còn đủ bộ nhớ để lưu Segment thứ i
37: Xóa Segment cũ nhất trong ContributeStorage;
38: Storing Segi to ContributeStorage;
39: end if
// gửi thông báo cho Tracker
40: Send COMPLETE_SEG<videoID, Segi> to Tracker;
41: end for i
42: end if