Bảng băm phân tán (Distributed hash tables) là một giải thuật cung cấp dịch vụ tìm kiếm tương tự cấu trúc dữ liệu bảng băm (Hash table): Một cặp {khóa, giá trị} được lưu trữ vào trong bảng băm phân tán, và bất kỳ node tham gia nào cũng có thể đưa ra một khóa và dễ dàng truy vấn lấy giá trị tương ứng. Việc hình thành khóa và gắn các khóa đó với giá trị tương ứng được thực hiện trực tiếp tại các node trong mạng, nên khi thay đổi số node tham gia không ảnh hưởng đáng kể đến hoạt động của hệ thống. Điều này cho phép bảng băm phân tán có khả năng mở rộng ra một số lượng rất lớn các node tham gia mà vẫn quản lý được sự ra vào liên tục của các node, cũng như sự gián đoạn của một số node.
Mỗi bảng băm phân tán đều cần có một không gian địa chỉ. Mỗi khóa sẽ lấy một giá trị từ không gian này. Kích thước không gian địa chỉ thường gặp nhất là 2160 (mỗi khóa là một số nhị phân 160 bit).
Các node và dữ liệu sẽ được ánh xạ vào cùng một không gian địa chỉ sử dụng hàm băm SHA-1. Với mỗi node, hàm băm sẽ băm địa chỉ IP của node đó để thu được một khóa 160 bit, gọi là định danh node (node identifier hay nodeID). Định danh node được sử dụng để xác định vị trí của node trong bảng băm. Như vậy mỗi node sẽ có một địa chỉ duy nhất, và do không gian khóa là rất lớn nên cũng có thể xem là mỗi địa chỉ tương ứng với một node duy nhất. Đối với dữ liệu, mỗi file dữ liệu cũng được gắn với một định danh. Định danh của dữ liệu được băm từ tên file dữ liệu hoặc băm từ nội dung của file, là giá trị duy nhất trong không gian địa chỉ.
Mỗi node sẽ quản lý một khoảng giá trị nhất định trong không gian địa chỉ. Dữ liệu được lưu ở node và được quản lý thông qua định danh. Khi một node muốn tìm kiếm một dữ liệu trong bảng băm phân tán, nó sẽ gửi truy vấn lần lượt qua các node khác. Nội dung truy vấn chính là định danh của dữ liệu. Khi một node lưu trữ dữ liệu có định danh trên nhận được truy vấn thì nó sẽ trả về dữ liệu yêu cầu.
Như vậy, việc tìm kiếm dữ liệu trong bảng băm phân tán sẽ luôn thực hiện được. Tuy nhiên vấn đề đặt ra là khi số lượng node tham gia lớn thì việc tìm kiếm sẽ diễn ra như thế nào để đảm bảo tính hiệu quả về mặt thời gian và tính ổn định khi liên tục có các node gia nhập và rời khỏi bảng băm.
Các tính chất của mạng DHT
DHT nhấn mạnh vào các thuộc tính sau:
- Phân tán (Decentralization): các node tham gia cấu thành hệ thống không có thành phần trung tâm làm điều phối mạng.
- Khả năng mở rộng: hệ thống vẫn có thể hoạt động hiệu quả với hàng nghìn hoặc hàng triệu node.
- Khả năng chịu lỗi: hệ thống vẫn có thể làm việc ổn định ngay cả khi có các sự kiện node tham gia, rời bỏ mạng hay lỗi diễn ra.
Kỹ thuật khóa được sử dụng để đạt được mục đích là mỗi node chỉ cần liên kết với một số ít các node khác trong hệ thống, thường là O(logn) với n là số node tham gia. Vì vậy sự thay đổi trong các thành viên chỉ ảnh hưởng đến một phần nhỏ của hệ thống.
Cuối cùng, DHT phải giải quyết những vấn đề cơ bản của các hệ thống phân tán đó là cân bằng tải, tính toàn vẹn dữ liệu, hiệu năng (cụ thể là đảm bảo các hoạt động như định tuyến, lưu trữ, truy vấn phải được thực thi nhanh chóng).
Mạng Overlay
Mỗi node duy trì một tập các liên kết với các node khác (hàng xóm của nó hoặc có thể gọi là bảng định tuyến). Các liên kết này sẽ tạo ra một mạng overlay. Một node kết nạp các node khác vào làm hàng xóm của nó dựa trên một cấu trúc nào đó, gọi là network topology.
Tất cả DHT topology đều có chung một thuộc tính quan trọng là: với một khóa k bất kỳ, node có chứa khóa k hoặc có liên kết tới node khác gần hơn với khóa k theo khoảng cách trong không gian khóa được định nghĩa ở trên, thì đều có thể định tuyến được thông điệp tới node quản lý khóa k sử dụng thuật toán tham lam: ở mỗi bước, chuyển thông điệp tới hàng xóm mà ID của nó gần nhất với khóa k. Khi không có hàng xóm nào như thế, thì chúng ta đã đến đúng node là node quản lý khóa k. Kiểu định tuyến này đôi khi được gọi là định tuyến dựa trên khóa (key based routing).
Ngoài tính chính xác trong định tuyến, có hai yếu tố quan trọng trong một topology là số lượng hops tối đa trên đường đi thấp để các yêu cầu kết thúc nhanh; và số lượng hàng xóm tối đa thấp để việc duy trì không quá khó khăn. Lựa chọn thứ ba là lựa chọn phổ biến. Nhiều DHT sử dụng tính linh hoạt trong cách chọn hàng xóm để
chọn ra những hàng xóm gần nhau về mặt độ trễ giữa các node của mạng vật lý ở phía dưới.
2.3.2.2. Mạng ngang hàng có cấu trúc Chord
Theo một đánh giá tổng hợp về các thuật toán định tuyến dựa trên DHT trong các kiến trúc mạng khác nhau như hình tròn (ring, với giao thức Chord), hình cây (tree), hình hộp (hypercube, với giao thức CAN), …xét về sự linh hoạt trong việc định tuyến, khả năng phục hồi trạng thái cũng như khả năng chịu lỗi, kiến trúc ring đều được đánh giá cáo. Vì vậy, kiến trúc Chord thường hay được sử dụng như là mạng phủ để thực hiện các cài đặt trên P2P có cấu trúc.
Giới thiệu giao thức Chord
Có thể nói Chord là đại diện tiêu biểu nhất của hệ thống mạng ngang hàng có cấu trúc DHT. Không những vậy Chord còn là nền tảng cho những nghiên cứu phát triển ứng dụng sau này. Một số nghiên cứu đã chỉ ra rằng: Chord không chỉ là một mạng DHT đơn thuần mà còn mang nhiều ưu điểm khác mà một số mạng DHT không có. Nói tới Chord ta có thể nhắc tới những đặc điểm sau đây:
- Cân bằng tải (Load Balance ): Quá trình hình thành và phân bổ khóa của Chord dựa trên thuật toán Consistent Hashing. Chính những đặc điểm của thuật toán này đã tạo cho Chord một khả năng cân bằng tải một cách tự nhiên ngay khi mạng được khởi tạo.
- Sự phân quyền: Trong giao thức Chord, không node nào quan trọng hơn node nào, quyền hạn này được thực hiện rất hiệu quả trong giao thức Chord.
- Khả năng mở rộng: Quá trình hình thành mạng, tìm kiếm dữ liệu trong Chord phụ thuộc nhiều vào sự biến thiên của hàm số logarit. Chính điều này tạo cho Chord khả năng mở rộng với số lượng rất lớn các node, cải thiện hiệu suất tìm kiếm một các tối đa.
- Tính sẵn sàng: Mỗi node trong Chord tự động điều chỉnh bảng thông tin định tuyến (Finger Table) của chính nó khi có một node tham gia hoặc dời mạng. Nói cách khác trong mạng Chord quá trình duy trì sự tồn tại của mạng diễn ra hoàn toàn tự động, chính điều này đã giảm thiểu khả năng đổ vỡ xuống mức tối thiểu khi quá trình tham gia và dời bỏ mạng của các node diễn ra.
Mô hình mạng Chord
Chord [3] được mô tả dưới dạng một vòng tròn và không gian định danh phân bố đều trên vòng tròn tăng dần theo chiều kim đồng hồ. Nếu gọi N là số bit định danh của không gian khóa thì mạng Chord có thế chứa tối đa 2N node. Mỗi node trên Chord có một định danh id và có khả năng duy trì liên kết 2 chiều với các node đứng liền trước và liền sau nó theo chiều kim đồng hồ, tạo thành 1 mạch kiên kết vòng. Node liền trước được gọi là Successor(id), và node liền sau được gọi là Predecessor(id). Thêm vào đó, mỗi node sẽ lưu một bảng định tuyến gọi là Finger Table, cho phép node đó định tuyến tới các node ở xa. Mỗi dòng trong bảng Finger Table sẽ lưu thông tin về 1 node ở xa, gọi là 1 entry. Không gian định danh có bao nhiêu bit thì Finger Table có bấy nhiêu entry.
Để hình thành được một mạng Chord hoàn chỉnh không thể không nói tới 2 yếu tố được coi như cốt lõi của mạng Chord: Consistent Hashing và Finger Table. Consitent Hasing đóng vai trò quan trong trong việc hình thành ID của các node, khóa dữ liệu và phân phối khóa vào các node tương ứng. Trong khi đó Finger Table đóng vai trò chuyển tiếp giữa các node trong mạng, phục vụ cho quá trình tìm kiếm được diễn ra một cách nhanh chóng và hiệu quả.
Consistent Hashing
Consistent Hasing là thuật toán cơ bản mà Chord sử dụng, Consistent Hashing sử dụng m bit làm độ lớn cho việc cung cấp ID và khóa của các node. ID của node được cung cấp bằng nhiều cách khác nhau( băm địa chỉ IP của node, chọn một cách tự động từ không gian ID có sẵn…). Việc tạo khóa cũng tương tự. Khóa được tạo ra bằng cách băm tên của dữ liệu, tính tần suất xuất hiện của từ trong văn bản…. Độ dài của khóa m phải đủ lớn để đảm bảo khả năng trùng giữa 2 nodes hoặc khóa là thấp.
Consistent Hashing phân phát khóa vào node như sau: Các ID được xắp xếp trên một vòng tròn module 2m. Khóa K được gắn vào node đầu tiên mà ID của nó bằng hoặc lớn hơn giá trị của K. Node đó được gọi là Successor của khóa K - Successor(k). Nếu tưởng tượng các ID hình thành lên một vòng tròn có giá trị từ 0 tới 2m - 1thì Successor(k) là node đầu tiên quay theo chiều kim đồng hồ tính từ K. Ta gọi vòng tròn ID của các node là vòng Chord.
Consistent Hashing được xây dựng với mục đích giảm thiểu tác động tới cấu trúc mạng khi các node tham gia hoặc dời bỏ mạng. Để duy trì sự sắp xếp giữa các node và
khóa, khi node N dời khỏi mạng thì toàn bộ khóa của N sẽ được chuyển lên cho Successor. Khi node N tham gia vào mạng N sẽ lấy key từ Successor của nó mà key đó có giá trị nhỏ hơn N(theo không gian khóa). Ngoài ra không có sự thay đổi nào khác xảy ra trong sự sắp xếp giữa các node và khóa của chúng.
Finger Table
Để đảm bảo quá trình tìm kiếm diễn ra hiệu quả, Chord lưu trữ thông tin định tuyến giữa các node trong một bảng được gọi là Finger Table. Gọi m là số bit của độ dài khóa, ID của node, mỗi node cần lưu trữ thông tin tối đa m node khác trong bảng Finger Table của mình, giá trị tương ứng của mỗi node trong bảng Finger Table bao gồm: ID, IP, số hiệu cổng.... Gọi i là đối tượng thứ i trong bảng Finger Table của node N, i được thể hiện bằng: N.Finger[i]. Node đầu tiên trong bảng Finger Table của N chính là Successor của N, hay còn được gọi là Immediate Successor.
Ký hiệu Định Nghĩa
Finger[k] Node đầu tiên trên vòng Chord tiếp nối (n+ 2k-1)mode 2m, 1≤ k ≤ m .interval (finger[k].start, finger[k+1].start)
.node First node>= n.finger[k].start
Successor Node tiếp theo trên vòng tròn Chord; Finger[1].Node Predecessor Node ở trước trên vòng tròn Chord.
Bảng 10: Bảng định nghĩa các trường trong Finger Table
Trong đó giá trị của trường node tại dòng i của bảng được coi như là finger thứ i của node n. Thông tin lưu trong bảng cũng bao gồm cả IP và Port của các node tương ứng. Node đầu tiên trong bảng Finger Table của n chính là Successor của n, hay còn được gọi là Immediate Successor.
Từ bảng Finger Table ở trên ta có thể thấy rằng:
- Mỗi node chỉ cần lưu trữ thông tin của một số node nhất định trong bảng định tuyến của mình.
- Node biết thông tin về các node gần nó nhiều hơn là các node ở xa.
- Bằng cách định tuyến thông qua bảng Finger Table, một node n có thể xác định được vị trí của bất kỳ khóa nào trên mạng.
Ánh xạ khóa vào một node trong Chord
Chord ánh xạ các khóa vào các node, thường theo cặp (key, value). Một value có thể là 1 address, 1 văn bản, hoặc 1 mục dữ liệu. Chord có thể thực hiện chức năng này bằng cách lưu các cặp (key, value) ở các node mà key được ánh xạ. Một node sẽ chịu
trách nhiệm lưu giữ một khóa k nếu node đó là node có định danh id nhỏ nhất thỏa mãn điều kiện id >= k. Một node khi lưu giữ khóa k cũng sẽ được gọi là Successor (k)
Hình 11: Lưu giữ key trong mạng Chord
Tìm kiếm trong mạng Chord
Trong vòng Chord, mỗi node chỉ cần liên hệ được với Successor hiện tại của nó. Quá trình tìm kiếm khóa diễn ra khá đơn giản. Tại node xác định, nơi truy vấn tìm kiếm bắt đầu, node đó sẽ chuyển truy vấn đó tới Successor của nó. Successor này sẽ xử lý, tìm kiếm từ khóa trong thư viện khóa của nó, nếu khóa đó tồn tại thì Successor sẽ trả lại kết quả cho node yêu cầu truy vấn. Ngược lại nó sẽ chuyển tiếp truy vấn tới Successor tiếp theo. Cứ như vậy, sau một số bước nhất định truy vấn sẽ có thể tìm được dữ liệu mong muốn.
Thuật toán như đã nêu ở phần trên thực chất chỉ là quá trình chuyển tiếp truy vấn giữa các node và Successor của nó. Như vậy để có thể tìm được vị trí chính xác của khóa đôi khi sẽ phải mất rất nhiều bước. Nếu khóa truy vấn càng ở xa thì số truy vấn càng lớn, nếu thực hiện nhiều truy vấn một lúc sẽ gây ra quá tải trong mạng. Để giải quyết vấn đề trên, Chord đưa ra khái niệm Finger Table, mỗi node khi thực hiện quá trình tìm kiếm sẽ thực hiện so sánh giá trị của khóa với giá trị ID của các node.
Hình 12: Tìm kiếm khóa sử dụng bảng FingerTable
Ví dụ: Tại hình trên, khi node số 8 khởi tạo tìm kiếm khóa 54, nó sẽ tìm trong bảng Finger Table và thấy giá trị của node số 42 gần với giá trị 54 nhất. Vì vậy truy vấn sẽ được chuyển trực tiếp tới node 42, node 42 sẽ so sánh trong finger table của mình và chuyển tiếp truy vấn tới node 51, node 51 sẽ chuyển truy vấn tới node 56 nơi chứa khóa 54.
Tham gia và ổn định mạng
Để đảm bảo quá trình tìm kiếm đạt hiệu quả trong khi các node tham gia và dời khởi mạng thì mỗi node trong Chord phải cập nhật được thông tin trong bảng định tuyến của mình, mỗi node sau một khoảng thời gian nhất định sẽ thực hiện quá trình ping tới successor của nó để biết là successor đó tồn tại hay đã dời khỏi mạng. Để có thể xác định được vị trí của các khóa trong mạng, Chord cần thỏa mãn 2 điểm sau:
- Mỗi successor của 1 node phải được duy trì.
- Với mỗi khóa k, node successor(k) có trách nhiệm quản lý k.
Khi tham gia vào một mạng Chord, một node n cần chọn cho nó một định danh id và báo cho các node bên cạnh biết sự tham gia của nó. Các node Successor và Predecessor sẽ cần phải cập nhật thông tin về node mới tham gia vào mạng. Node n cũng khởi tạo bảng định tuyến Finger Table. Để mạng vẫn định tuyến đúng sau khi có sự tham gia của node n, các node cần thường xuyên chạy thuật toán ổn định mạng để
cập nhật thông tin về node bên cạnh (hay node láng giềng). Một số node có lưu thông tin về n trong bảng Finger Table thì cần cập nhật các entry liên quan trong Finger Table. Cuối cùng, node Successor của n sẽ chuyển một phần khóa k mà bây giờ n là Successor(k) cho n lưu giữ. Việc chuyển khóa sẽ do tầng trên của ứng dụng thực hiện.
Khi một node chuẩn bị rời khỏi mạng, nó cần thông báo cho các node bên cạnh biết để ổn định lại mạng. Node đó cũng sẽ chuyển các khóa nó lưu giữ cho node Successor của nó.