Trên vòng Chord, các node được xác định bằng định danh id duy nhất. Mỗi node sẽ quản lý một vài server ảo. Dựa vào độ lệch giữa capacity và tải hiện thời của
27
node, ta sẽ xây dựng vòng Chord mới có số bit không gian định danh lớn gấp 2 lần số bit không gian định danh vòng Chord ban đầu.
Mỗi node vật lý trong vòng Chord ban đầu sẽ có các thông tin sau: id – định danh của node
Capacity C - tải định mức
workload W - tải hiện thời
mismatch m - độ lệch giữa tải định mức và tải hiện thời của node
m = C - W
isOverloaded – trạng thái tải của node (=1 nếu quá tải và =0 nếu ngược
lại)
Server ảo của node có các thông tin:
workPerRound – tải của VS
key – định danh của VS
originalPsId – định danh của node đang quản lý VS
Giả sử vòng Chord ban đầu có n bit định danh không gian. Như vậy vòng Chord mới sẽ có (2*n) bit không gian định danh.
Vòng Chord mới (gọi là nChord) được xây dựng dựa vào độ mismatch của node trên vòng Chord ban đầu như sau:
- Độ lệch được định nghĩa bằng phép tính:
m = C – W;
- id của node trên vòng Chord mới sẽ có giá trị như sau: if (isOverloaded = 0)
new_id = m .2n + old_id
if (isOverloaded = 1) new_id = id
Để rõ hơn, ta xét ví dụ sau:
28
Hình 3.1. Vòng Chord ban đầu
Khi đó, vòng Chord mới (nChord) có 16 bit không gian định danh được xây dựng như hình 3.2:
Hình 3.2. Vòng Chord mới
Mỗi node trên vòng Chord ban đầu đều có một bảng định tuyến. Khi sang vòng Chord mới với định danh id mới, các node sẽ phải cập nhật lại bảng định tuyến của mình.
29 3.2. Chèn
Một node nặng tải có thể phát hiện node nhẹ tải trên vòng nChord dựa vào bảng định tuyến của nó.
- Một node nặng tải h muốn chuyển server ảo v có tải w để thành node nhẹ tải, nó
sẽ tìm node có id > w *2n
- Trong tất cả các node có id thỏa mãn, chọn node có id nhỏ nhất để thực hiện việc chuyển server ảo.
Vậy tại sao khi node nặng tải muốn chuyển server ảo có tải w đi thì nó sẽ phải tìm node có id > w *2n ? Vì vòng Chord ban đầu có n bit không gian định danh và khi chuyển sang vòng Chord mới, định danh của node nặng tải được giữ nguyên nên các node nặng tải trên vòng Chord mới luôn có id < 2n. Suy ra một node mà có id > w *2n sẽ luôn là node nhẹ tải. Mà node nhẹ tải có công thức là new_id = m .2n + old_id > w *2n thì luôn chắc chắn rằng: m > w, tức là độ chênh lệch tải của node nhẹ tải thỏa mãn công thức trên luôn lớn hơn tải của server ảo mà nó sẽ nhận. Khi đó, khi nhận server ảo từ node nặng tải, node nhẹ tải có id thỏa mãn công thức trên cũng vẫn nhẹ tải.
Để tìm node có id > w*2n, ta dựa vào bảng định tuyến của node cần tìm. Nó sẽ tìm trong bảng định tuyến của nó predecessor gần nhất của id trên vòng tròn định danh và chuyển truy vấn đến predecessor này. Cứ như thế, các node sẽ chuyển tiếp truy vấn dựa vào bảng định tuyến của chính nó đến khi truy vấn đến được node h sao cho trên vòng tròn định danh h nằm giữa n và successor của n. Khi đó, ta sẽ tìm được node chịu trách nhiệm quản lý key là w*2n. Nếu node này có id đúng bằng w*2n thì kết quả truy vấn là node liền sau nó. Nếu node này có id > w*2n thì kết quả truy vấn sẽ là chính node đó.
VD:
30
Hình 3.3. Ví dụ vòng Chord
Bây giờ, node N8 thực hiện tìm node có id>54. Đầu tiên, node N8 sẽ tìm node chịu trách nhiệm quản lý id 54. Từ bảng định tuyến của mình, node N8 xác định được node lớn nhất và nhỏ hơn 54 chính là node N42. N8 chuyển truy vấn đến N42. Dựa vào bảng định tuyến của mình, N42 thấy rằng node lớn nhất và nhỏ hơn 54 chính là node N51. Nó lại chuyển tiếp truy vấn đến N51. Sau đó, node N51 thấy rằng successor của nó là N56 quản lý key 54. Khi đó, nó sẽ trả về kết quả truy vấn là node N56.
Giả sử trong vòng Chord tồn tại node N54 thì node chịu trách nhiệm quản lý key 54 chính là N54. Nhưng kết quả truy vấn cho node có id >54 chính là node N56.
Nếu tìm được node nhẹ tải l thỏa mãn điều kiện trên, thực hiện việc chuyển server ảo từ node nặng tải h sang node nhẹ tải l. Việc chuyển này sẽ được thực hiện
theo quy trình sau:
- Gửi thông tin về việc chuyển cho các node có liên quan trong vòng Chord cũ
gồm: node nặng tải h đang chứa VS v, node nhẹ tải l sẽ nhận v. Sau khi hai
node này nhận được thông tin, chúng sẽ tự liên hệ với nhau và thực hiện việc chuyển server ảo trong vòng Chord cũ.
- Xóa thông tin của VS v trong CSDL node h và thay đổi các thông tin của 2
node, cập nhật lại vòng nChord. VD:
Giả sử trong vòng Chord có 8 bit không gian định danh như hình 3.3, node N1 có các server ảo v1, v2, v3 với tải tương ứng là w1 = 5, w2 = 4, w3 = 6. Để trở thành node nhẹ tải, node N1 phải chuyển w2 = 4 đi. Node N1 sẽ tìm node có id nhỏ nhất và thỏa mãn điều kiện: id > w2 * 28, tức là id >1024. Trong số các node thỏa mãn, node tốt nhất có thể chấp nhận v2 chính là node N3850. Hai node N1 và N3850 sẽ tự liên hệ
31
với nhau và thực hiện chèn server ảo v2 của N1 vào node N3850. Sau bước này, thông tin của N1 và N3850 được thay đổi, cụ thể: N1 sẽ có C = 12, W = w1 + w3 = 11 và xóa thông tin của server ảo v2 trong CSDL. N3850 sẽ có C = 35, W = 24 và thêm thông tin của server ảo v2 trong CSDL.
Khi đó, vòng nChord sẽ cập nhật lại. Coi như N1 và N3850 rời bỏ mạng, 2 node mới gia nhập vào mạng là N257 (old_id = 1)và N2826 (old_id = 10). Cả hai node đều
có trường isOverloaded = 0.
Bước này sẽ tiếp tục cho đến khi trong vòng nChord không còn node nào có
trường isOverloaded = 1, hoặc không thể thực hiện việc chuyển server ảo nào đi nữa.
Trường hợp đầu, thuật toán kết thúc với tất cả các node nhẹ tải. Trường hợp sau, thuật toán sẽ tiếp tục với bước hoán đổi.
3.3. Hoán đổi
Nếu như node nặng tải h không tìm thấy node có id nào thỏa mãn điều kiện trên thì ta sẽ chọn server ảo nặng tải nhất v của nó và cố gắng tìm server ảo v’ của node nhẹ tải i sao cho Wi + load(v) – load(v’) ≤ Ci . Trong số các node được chọn, ta sẽ chọn
node nhẹ tải có server ảo load(v’) bé nhất thỏa mãn điều kiện trên. Sau đó hai node
này sẽ tự tiến hành hoán đổi hai server ảo trên và thay đổi các thông tin liên quan. Nếu
không thể tìm một node nhẹ tải i sao cho load(v’) < load(v), thuật toán sẽ kết thúc.
Nếu không, thuật toán sẽ quay trở lại bước chèn.
Sau khi thực hiện hoán đổi được, quay trở lại bước chèn để xem có thể chèn được các server ảo còn lại hay không. Nếu không thể chèn, thuật toán lại tiếp tục thực hiện bước hoán đổi. Cứ như vậy, sau mỗi lần hoán đổi thành công, lại quay trở về thực hiện bước chèn để cố gắng chèn các server ảo.
Hình 3. Như vậy, chương 3 đã
server ảo cải tiến cho phương pháp di chuy pool đã nói trong chương 2. Thu
thuật toán di chuyển server trung của thuật toán di chuy bình thường mà không sợ hệ
32
Hình 3.4. Sơ đồ thuật toán của giải pháp mới
ã trình bày giải pháp cân bằng tải phi tập trung s n cho phương pháp di chuyển server ảo nhiều-nhiều s
ương 2. Thuật toán này vẫn chưa cải thiện được hi n server ảo nhiều-nhiều, tuy nhiên, nó đã bước đầu phá v t toán di chuyển server ảo nhiều-nhiều, và hoàn toàn có th
ệ thống bị đổ vỡ khi bị tấn công.
p trung sử dụng các u sử dụng global c hiệu năng của u phá vỡ tính tập u, và hoàn toàn có thể hoạt động
33
Chương 4. Mô phỏng và đánh giá
Để so sánh giải pháp mới với các phương pháp đã có, chương này sẽ mô tả mô phỏng giải pháp mới. Trước đó, tác giả Jonathan Ledlie đã xây dựng một bộ mô phỏng các thuật toán cân bằng tải: k-choices, di chuyển một-một, threshold và proportion.
Khóa luận tốt nghiệp “Cân bằng tải trong các mạng ngang hàng” của tác giả Nguyễn
Thị Mi cũng đã mô phỏng được thêm phương pháp di chuyển nhiều-nhiều và phương pháp cân bằng tải phi tập trung dựa trên server ảo [3]. Chương này sẽ đi vào việc thực hiện mô phỏng, từ đó có thể đánh giá hiệu năng của các phương pháp đã có và giải pháp cân bằng tải mới.
4.1. Bộ mô phỏng của Jonathan Ledlie
Bộ mô phỏng của Jonathan Ledlie [5] thực hiện các thuật toán cân bằng tải trên kiến trúc mạng ngang hàng có cấu trúc Chord. Nó được viết bằng C++ trên hệ điều hành Linux. Sau đó, dựa trên bộ mô phỏng này, tác giả Nguyễn Thị Mi đã sửa đổi để mô phỏng chạy được trên Window.
Trong đó, các ID của node được sắp xếp trật tự trên không gian định danh của vòng Chord. Bộ mô phỏng gồm các bước được thực hiện tuần tự trong hàm main của
file lb.cc: các node tham gia và thoát khỏi mạng, update bảng định tuyến, thực hiện
truy vấn và cân bằng tải.
Các node tham gia và thoát khỏi mạng
Việc tham gia và thoát khỏi mạng của các node sẽ được mô tả thông qua
birth(myInitialVsCount) và death(). Trong mô phỏng, tác giả sử dụng phân bố Pareto để mô tả quá trình vào/ra của các node trong mạng. Ở đây, tác giả dùng hai file đầu vào:
- Một file chứa thông tin về khả năng riêng (capacity) của từng node là file
gnutelle.4096n. File này gồm hai cột: cột đầu tiên là định danh ID của node,
còn cột thứ hai là capacity của node đó. Ví dụ:
0 10 1 106 2 10 3 10 4 106 5 10 …
34
- Một file chứa thông tin vào/ra của các node ở mỗi vòng là file
pareto.4096n.3hours. File này gồm 3 cột: cột đầu tiên là số vòng (round) tính
theo giây, thời gian bắt đầu là 0, cột thứ hai mô tả hoạt động của node tại thời điểm đó (b/d/w/r/q) với b: birth, d: death, w: chuyển đổi tải, r: trạng thái ghi của node là true và q: chỉ xuất hiện ở cuối file để kết thúc chương trình. Cột thứ ba là định danh ID của node thực hiện hành động ở cột thứ hai. Ví dụ:
0 b 0 0 b 1 0 b 10 0 b 100 0 b 1000 0 b 1002 … Cập nhật bảng định tuyến
Ban đầu các server ảo có một bảng định tuyến rỗng. Sau đó, nó sẽ sử dụng cơ chế định tuyến của Chord để hoàn thiện bảng định tuyến của mình. Nếu một server ảo
có định danh là a, thì hàng i trong bảng định tuyến của nó là successor của key a+2i mod D (với D = 2160). Các server ảo dùng hàm fixFingers() trong file fingers.cc
để cập nhật bảng định tuyến của mình.
Mỗi hàng trong bảng định tuyến hay còn gọi là finger sẽ có timeout là 30s. Mỗi lần finger này được sử dụng thành công thì timeout sẽ được thiết lập lại. Khi node rời bỏ mạng, các server ảo trỏ đến node không được thông báo.
Thực hiện truy vấn
Các hàm phân bố được thực hiện trong file distribution.cc. Nếu các truy vấn gửi
tới các node giống nhau thì phân bố truy vấn được gọi là phân bố uniform. Ngược lại, các truy vấn gửi đến các node không đồng đều thì phân bố truy vấn được gọi là phân bố Zipf. Dưới đây là hàm phân bố Zipf:
( , , ) = ⁄
∑ ( ⁄ )
Trong đó, N là số lượng node được truy vấn, k là thứ hạng của node được truy
vấn (node có thứ hạng càng cao thì bị truy vấn càng nhiều) và là giá trị lũy thừa biểu thị đặc điểm của phân bố. Giá trị đại diện cho mức độ truy vấn giữa các node có các thứ hạng khác nhau. Ta sẽ sử dụng các giá trị biến thiên của để xem xét xem các thuật toán cân bằng tải sẽ cho kết quả như thế nào trong trường hợp mạng có độ skew khác nhau: = 0.8, = 1.2.
35
Truy vấn được khởi tạo từ node với đích được chọn từ phân bố đồng đều hoặc phân bố Zipf. Mỗi hop trong truy vấn sử dụng finger thích hợp để định tuyến truy vấn về đích. Nếu hop là node nặng tải thì truy vấn thất bại. Ngược lại, truy vấn thành công khi chúng đến được node đích.
Cân bằng tải
Trung bình 30s, các node kiểm tra cân bằng tải một lần. Node sẽ kiểm tra tải hiện thời của nó là trên hay dưới tải định mức target (0.99x và 0.1x capacity). Nếu bị mất cân bằng tải, node sẽ thực hiện cân bằng tải theo các thuật toán: di chuyển server ảo một-một, threshold, k-choices và proportion. Code của các thuật toán cân bằng tải nằm chủ yếu ở file server.cc. Với việc gán giá trị cho tham số
activeLBmethod, ta sẽ chạy với thuật toán tương ứng. Nếu activeLBmethod =
‘t’ thì thuật toán cân bằng tải là di chuyển server ảo một-một. Nếu
activeLBmehthod = ‘g’ thì thuật toán cân bằng tải là threshold. Nếu
activeLBmehthod = ‘p’ thì thuật toán cân bằng tải là proportion. Nếu
activeLBmehthod = ‘k’ thì thuật toán cân bằng tải là k-choices. Còn nếu
activeLBmehthod = ‘-’ thì không sử dụng thuật toán cân bằng tải nào.
4.2. Mô tả mô phỏng của giải pháp cân bằng tải mới
Các node vật lý được cài đặt là class PhysicalServer PS trong vòng
Chord bao gồm các trường sau: id – định danh node, capacity – tải định mức, work – tải hiện thời, mismatch – độ lệch tải, isOverload – trạng thái của node, newid – id của
node trên vòng Chord mới. Các server ảo được cài đặt là class VirtualServer
VS của node cũng được lưu gồm các trường: double key – định danh của server ảo, int original_PS_ID – định danh của node đang quản lý VS, workPerRound – tải của VS.
Các hàm thực hiện các bước của giải pháp cân bằng tải mới được mô tả trong file
honghien.cc.
Vòng Chord mới sẽ được tạo dựa vào độ lệch tải trên vòng Chord cũ, sử dụng
hàm NCN_create_nChord(numberOfOverloadPS). Độ lệch tải mismatch
giữa tải định mức C và tải hiện thời W của node trên vòng Chord ban đầu được tính bằng công thức:
36
Dựa vào độ lệch tải này, ID của node trên vòng Chord mới được xác định như sau:
if (ps[i].getCapacity() > ps[i].getWorkPerRound()) {
newID = ps[i].getId() + (int)(floor(ps[i].getMismatch())) * FACTOR;
ps[i].setNewID(newID); // them truong new_id cho PS } else
{
newID = ps[i].getId();
ps[i].setNewID(newID); // PS nang tai co id moi bang id cu numberOfOverloadPS = numberOfOverloadPS + 1;
}
Nếu có PS nặng tải thì thực hiện chèn NCN_insert_nChord(). Nếu đến một lúc nào đó, vẫn còn PS nặng tải mà không thể chèn được thì chuyển sang bước hoán đổi NCN_dislodge_nChord().
Hình 4.1. Mô t
Mỗi node sẽ có 1 b
server.h:
37
Mô tả quá trình hoạt động của giải pháp mới
38
class PsFinger {
private:
ChordID *psfinger; // Mang cac finger public:
PsFinger(); ~PsFinger();
void fixPsFingers(ChordID newId); ChordID getPsKey(int index)
{
return (ChordID) psfinger[index]; }
};
Tại bước chèn, ta phải thực hiện tìm được node thỏa mãn điều kiện là định danh id của nó phải lớn hơn một giá trị cụ thể nào đấy. Ở đây ta sẽ sử dụng hàm
findBestFitPs(PhysicalServer*inputPs,ChordID pivotId)với đầu
vào là node tìm kiếm inputPs và một giá trị cho trước pivotId. Hàm này nằm trong file honghien.cc và được cài đặt như sau:
PhysicalServer* findBestFitPs(PhysicalServer* inputPs, ChordID pivotId)
{
map<ChordID, PhysicalServer*>::iterator p;