Professional Documents
Culture Documents
GT Os8
GT Os8
Một hệ thống phân tán là một tập các bộ vi xử lý kết nối lỏng với nhau
bởi một mạng lưới thông tin liên lạc. Từ một điểm nhìn cụ thể của một bộ vi xử lý trong một
hệ thống phân tán, các bộ vi xử lý còn lại và các tài nguyên tương ứng ở xa, trong khi tài
nguyên của mình mang tính địa phương.
Các bộ vi xử lý trong một hệ thống phân tán có thể khác nhau về kích thước và chức năng.
Chúng có thể bao gồm bộ vi xử lý nhỏ, máy trạm, máy tính mini, và
hệ thống máy tính lớn. Những bộ vi xử lý này được gọi bởi một
tập các tên, chẳng hạn như các địa điểm, các nút, máy tính, máy móc, máy chủ tùy thuộc
vào bối cảnh trong đó chúng được đề cập. Chúng ta chủ yếu sử dụng thuật ngữ địa điểm để
cho biết
vị trí của một máy tính và thuật ngữ máy chủ để chỉ một hệ thống cụ thể tại một địa điểm. Nói
chung,
một máy chủ đặt tại một địa điểm có một nguồn tài nguyên mà một máy chủ đặt tại một
địa điểm khác hay khách hàng (hoặc người sử dụng) muốn sử dụng. Một cấu trúc chung của
một hệ thống phân tán được thể hiện trong Hình 16.1.
thông tin
Khi một số địa điểm được kết nối với nhau bởi một mạng lưới thông tin liên lạc,
người sử dụng tại các địa điểm khác nhau có cơ hội để trao đổi thông tin. Ở
tầng thấp, các thông điệp được truyền giữa các hệ thống, giống như tin nhắn
truyền qua lại giữa các tiến trình trong hệ thống đơn máy tính. Qua tin nhắn, tất cả các chức
năng cấp cao hơn được tìm thấy trong hệ thống độc lập có thể được mở rộng để xuất hiện
trong các hệ thống phân tán.
Các chức năng này bao gồm chuyển tập tin, đăng nhập, mail, và các cuộc gọi thủ tục từ xa
(RPCs).
Lợi thế của một hệ thống phân tán là các chức năng này có thể được thực hiện với một
khoảng cách lớn. Hai người tại các địa điểm địa lý xa xôi có thể
hợp tác trong một dự án, ví dụ. Bằng cách chuyển các tập tin của dự án,
đăng nhập vào hệ thống từ xa của nhau để chạy chương trình, và trao đổi
mail để phối hợp công việc, người sử dụng giảm thiểu những hạn chế cố hữu trong khoảng
cách
làm việc.
Những lợi thế của hệ thống phân tán đã dẫn đến một xu hướng giảm kích thước trong các
ngành công nghiệp. Nhiều công ty đang thay thế máy tính lớn của họ
với mạng lưới các máy trạm hoặc máy tính cá nhân. Các công ty nhận được các tính năng tốt
hơn với cùng một chi phí, linh hoạt hơn trong
vị trí các nguồn lực và mở rộng cơ sở vật chất, giao diện người dùng tốt hơn, và
bảo trì dễ dàng hơn.
Một hệ điều hành mạng cung cấp một môi trường mà trong đó người sử dụng có thể truy cập
tài nguyên từ xa bằng cách
đăng nhập vào máy tính từ xa hoặc chuyển dữ liệu từ các
máy tính từ xa vào máy riêng của họ.
Đăng nhập từ xa
Một chức năng quan trọng của một hệ điều hành mạng là cho phép người dùng đăng nhập
từ xa. Internet cung cấp các dịch vụ như telnet, rsh, ssh cho mục đích này.
Truyền file từ xa
Một chức năng chính của một hệ điều hành mạng là cung cấp một cơ chế để chuyển file từ xa
từ một máy tính khác.
Chuyển dữ liệu
Giả sử một người dùng tại địa điểm A muốn truy cập dữ liệu (chẳng hạn như một tập tin) cư
trú tại địa điểm B. Hệ thống có thể chuyển dữ liệu theo một trong hai phương pháp cơ bản.
Một cách là di chuyển toàn bộ tập tin về địa điểm A. Từ đó, tất cả
truy cập vào tập tin mang tính địa phương. Khi người sử dụng không còn cần truy cập vào tập
tin,
bản sao của tập tin (nếu nó đã được sửa đổi) được gửi trở lại địa điểm B. Ngay cả nếu chỉ có
một
thay đổi khiêm tốn đã được thực hiện trong một tập tin lớn, tất cả các dữ liệu phải được
chuyển giao.
Cơ chế này có thể được xem như là một hệ thống tự động FTP. Cách tiếp cận này
được sử dụng trong hệ thống tập tin Andrew, nhưng nó đã được
nhận xét là hiệu quả quá kém.
Cách tiếp cận khác là chuyển đến địa điểm A chỉ những phần của tập tin
thực sự cần thiết cho các nhiệm vụ. Nếu phần khác được yêu cầu
sau đó, một chuyển giao sẽ diễn ra. Khi người dùng không còn muốn truy cập
tập tin, bất kỳ một phần của nó đã được sửa đổi phải được gửi trở lại địa điểm B. giao thức hệ
thống tập tin mạng Sun Microsystems (NFS) sử dụng phương pháp này, cũng như các phiên
bản mới hơn của Andrew.
Rõ ràng là nếu chỉ một phần nhỏ của một tập tin lớn được truy cập, cách tiếp cận sau thích
hợp hơn. Nếu phần lớn của tập tin cần được truy cập, sẽ hiệu quả hơn khi sao chép toàn bộ tập
tin. Trong cả hai phương pháp, dữ liệu di cư bao gồm nhiều tác vụ hơn là chỉ chuyển dữ liệu
từ một địa điểm khác.
Hệ thống phải thực hiện các bản dịch dữ liệu khác nhau nếu hai địa điểm có liên quan
không trực tiếp tương thích (ví dụ, nếu họ sử dụng biểu diễn mã ký tự khác nhau
hoặc biểu diễn số nguyên khác nhau về thứ tự của các bit).
Di cư tiến trình
Một phần mở rộng hợp lý của việc di chuyển tính toán là di cư tiến trình.
Khi một tiến trình được đệ trình để thực hiện, nó không phải lúc nào cũng được thực hiện tại
nơi nó bắt đầu chạy. Toàn bộ tiến trình, hoặc các bộ phận của nó, có thể được thực hiện tại
các địa điểm khác nhau. Phương pháp này có thể được sử dụng vì nhiều lý do:
- Cân bằng tải. Các tiến trình (hoặc tiến trình con) có thể được phân phối trên
mạng để cân bằng khối lượng công việc.
- Tăng tốc tính toán. Nếu một tiến trình duy nhất có thể được chia thành một số
tiến trình con có thể chạy đồng thời trên các địa điểm khác nhau, lúc đó tổng số
thời gian thực hiện công việc có thể được giảm.
- Phần cứng đặc biệt. Tiến trình có thể có những đặc điểm làm cho nó
phù hợp hơn khi thực hiện trên một số bộ xử lý chuyên ngành (chẳng hạn như ma trận
nghịch đảo trên mảng các bộ xử lý) hơn là trên một bộ vi xử lý.
- Phần mềm đặc biệt. Tiến trình có thể yêu cầu một phần mềm chỉ có tại một địa điểm cụ thể,
và phần mềm đó không thể di chuyển được, hoặc sẽ ít tốn kém hơn khi di chuyển tiến trình.
- Truy cập dữ liệu. Cũng như trong di chuyển tính toán, nếu dữ liệu được sử dụng trong
tính toán rất nhiều, để cho tiến trình chạy từ xa có thể sẽ hiệu quả hơn là dịch chuyển tất cả
các dữ liệu.
Chúng ta sử dụng hai kỹ thuật bổ sung để di chuyển các tiến trình trong một
mạng máy tính. Trong kỹ thuật đầu tiên, hệ thống có thể cố gắng để che giấu thực tế là tiến
trình đã di cư với khách hàng. Kỹ thuật này có lợi thế rằng người sử dụng không
cần phải viết mã chương trình của mình một cách rõ ràng để thực hiện việc di chuyển.
Phương pháp này thường được sử dụng để đạt được cân bằng tải và tăng tốc tính toán
trong một số các hệ thống đồng nhất khi mà chúng không cần người dùng truy nhập vào để
giúp chúng thực hiện các chương trình từ xa.
Phương pháp khác là cho phép hoặc yêu cầu người sử dụng xác định một cách rõ ràng cách
thức di chuyển tiến trình. Phương pháp này thường được sử dụng khi
tiến trình phải được di chuyển để đáp ứng một phần cứng hay phần mềm đặc biệt.
Bạn có thể nhận ra rằng Web có rất nhiều khía cạnh của môi trường tính toán phân tán. Nó
cung cấp khả năng di chuyển dữ liệu (giữa máy chủ Web và máy khách Web). Nó cũng cung
cấp khả năng di cư tính toán. Ví dụ, một khách hàng Web có thể kích hoạt một hoạt động về
cơ sở dữ liệu trên một máy chủ Web. Cuối cùng, với Java, nó cung cấp một hình thức của quá
trình di cư: Java applet được gửi từ
máy chủ cho khách hàng, nơi nó được thực hiện. Một hệ thống điều hành mạng
cung cấp hầu hết các tính năng này, nhưng một hệ điều hành phân tán giúp cho chúng dễ dàng
được tiếp cận. Kết quả là một nền tảng mạnh mẽ và dễ sử dụng-một trong những lý do cho sự
tăng trưởng rất lớn của World Wide Web.
Để giải thích cấu trúc của một DFS, chúng ta cần phải định nghĩa các thuật ngữ dịch vụ, máy
chủ, và khách hàng. Một dịch vụ là một thực thể phần mềm chạy trên một hoặc nhiều máy
và cung cấp một loại chức năng cho khách hàng. Một máy chủ là một dịch vụ
phần mềm chạy trên một máy tính duy nhất. Khách hàng là một quá trình có thể gọi
một dịch vụ bằng cách sử dụng một tập hợp các hoạt động hình thành nên giao diện của khách
hàng. Đôi khi một giao diện cấp thấp hơn được định nghĩa cho sự tương tác giữa các máy gọi
là giao diện giữa các máy.
Sử dụng thuật ngữ này, chúng ta nói rằng một hệ thống tập tin cung cấp dịch vụ tập tin cho
khách hàng. Một giao diện khách hàng cho một dịch vụ tập tin được hình thành bởi một tập
hợp các hoạt động tập tin nguyên thủy, chẳng hạn như tạo ra một tập tin, xóa một tập tin, đọc
từ một tập tin, và viết vào một tập tin.
Thành phần phần cứng chính mà một máy chủ tập tin kiểm soát là một tập hợp các
thiết bị lưu trữ thứ cấp (thông thường, từ đĩa) địa phương nơi mà các tập tin được lưu trữ
và từ đó chúng được lấy theo yêu cầu của khách hàng.
DFS là một hệ thống tập tin mà khách hàng, máy chủ, và thiết bị lưu trữ
phân tán giữa các máy tính của một hệ thống phân tán. Theo đó,
hoạt động dịch vụ được thực hiện trên mạng. Thay vì có một
kho dữ liệu tập trung duy nhất, hệ thống thường xuyên có lưu trữ trên
nhiều thiết bị độc lập. Như bạn sẽ thấy, cấu hình cụ thể và thực hiện một
DFS có thể thay đổi từ hệ thống đển hệ thống. Trong một số cấu hình, máy chủ chạy trên
một máy dành riêng, trong cấu hình khác, một máy có thể được dùng làm cả máy chủ và máy
khách. Một DFS
có thể được thực hiện như một phần của một hệ điều hành phân tán, hoặc theo cách khác,
bởi một lớp phần mềm có nhiệm vụ quản lý thông tin liên lạc giữa
hệ điều hành thông thường và hệ thống tập tin. Các tính năng đặc biệt của một
DFS là sự đa dạng và tự chủ của khách hàng và máy chủ trong hệ thống.
Một cách lý tưởng nhất, một DFS sẽ làm cho khách hàng cảm thấy như
tập tin hệ thống thông thường tập trung. Sự đa dạng và phân tán các máy chủ và các thiết bị
lưu trữ nên được thực hiện trong suốt. Điều đó có nghĩa là giao diện khách hàng của một DFS
không nên phân biệt giữa các tập tin địa phương và từ xa. Việc của DFS là xác định vị trí
các tập tin và sắp xếp việc vận chuyển dữ liệu. Một DFS trong suốt tạo điều kiện cho
người sử dụng di động bằng cách mang lại một môi trường của người sử dụng (có nghĩa là
thư mục làm việc) ở bất cứ nơi nào người sử dụng đăng nhập.
Tiêu chí hiệu suất quan trọng nhất của một DFS là số lượng thời gian cần thiết để đáp ứng yêu
cầu dịch vụ. Trong các hệ thống thông thường, thời gian này bao gồm thời gian truy cập đĩa
và một số ít của thời gian xử lý CPU. Trong một DFS, truy cập từ xa có các chi phí bổ sung
do các cấu trúc phân tán. Chi phí này bao gồm thời gian để chuyển các yêu cầu tới một máy
chủ, cũng như thời gian để có được những phản hồi qua mạng tới cho khách hàng. Đối với
mỗi hướng, ngoài việc chuyển giao thông tin, còn có thời gian cho CPU chạy các phần mềm
giao thức truyền thông. Hiệu suất của một DFS có thể được xem như là một khía cạnh khác
của sự trong suốt của DFS. Đó là, hiệu suất một DFS lý tưởng sẽ được so sánh với một
tập tin hệ thống quy ước.
Thực tế DFS quản lý một tập hợp các thiết bị lưu trữ phân tán là một đặc diểm phân biệt quan
trọng. Các không gian lưu trữ được quản lý tổng thể bởi một DFS
bao gồm không gian lưu trữ khác nhau nhỏ hơn đặt từ xa. Thông thường,
các không gian lưu trữ cấu thành tương ứng với một bộ tập tin. Một đơn vị thành phần
là một tập nhỏ nhất các tập tin có thể được lưu trữ trên một máy tính duy nhất, độc lập
với các đơn vị khác. Tất cả các tập tin thuộc cùng một đơn vị thành phần phải cư trú
trong cùng một vị trí.
Cách đặt tên là một ánh xạ giữa các đối tượng vật lý và logic. Ví dụ,
người dùng sử dụng các đối tượng dữ liệu logic đại diện bằng tên tập tin, trong khi
hệ thống thao tác với các khối dữ liệu vật lý được lưu trữ trên các khe đĩa. Thông thường, một
người sử dụng đề cập đến một tập tin bằng một tên văn bản. Sau đó tên này được ánh xạ tới
một số định danh ở cấp thấp hơn và sau đó được ánh xạ tới các khối đĩa. Cơ chế ánh xạ đa cấp
cung cấp cho người dùng với một sự trừu tượng về tập tin và giấu đi các chi tiết về cách
làm thế nào và tập tin được lưu trữ ở đâu trên đĩa.
Trong một DFS trong suốt, một chiều hướng mới được thêm vào sự trừu tượng:
ẩn đi vị trí trong mạng nơi tập tin nằm. Trong một hệ thống tập tin thông thường,
phạm vi của các ánh xạ tên là một địa chỉ trong một đĩa. Trong một DFS, phạm vi này
được mở rộng để bao gồm máy cụ thể mà trên đĩa của nó tập tin được lưu trữ.
Đi thêm một bước xa hơn với khái niệm xử lý các tập tin trừu tượng dẫn tới
khả năng sao chép tập tin. Với một tên tập tin, ánh xạ trả về một
tập các vị trí của các bản sao của tập tin này. Trong sự trừu tượng này, sự tồn tại của
nhiều bản sao và vị trí của chúng được ẩn đi.
Có ba phương pháp tiếp cận chính để đặt tên trong một DFS. Trong phương pháp tiếp cận đơn
giản, một tập tin được xác định bởi một sự kết hợp của tên máy chủ của nó và tên địa phương,
đảm bảo một tên duy nhất trên toàn hệ thống. Ví dụ trong hệ thống Ibis,
một tập tin được xác định duy nhất bởi tên máy chủ: tên địa phương, tên địa phương là một
đường dẫn UNIX. Phương án đặt tên này không cung cấp vị trí trong suốt cũng như không
phải độc lập vị trí. Tuy nhiên, các hoạt động tập tin có thể được sử dụng cho cả tập tin địa
phương và các tập tin từ xa. DFS được cấu trúc như một tập của các thành phần bị cô lập, mỗi
trong số đó là toàn bộ một hệ thống tập tin thông thường. Trong phương pháp tiếp cận đầu
tiên này, các thành phần vẫn còn bị cô lập, mặc dù đã được cung cấp các phương tiện để chỉ
một tập tin từ xa. Chúng ta không đi sâu vào phương pháp này.
Cách tiếp cận thứ hai được phổ biến bởi hệ thống tập tin mạng của Sun, NFS.
NFS là thành phần tập tin hệ thống của ONC +, một gói phần mềm mạng được hỗ trợ bởi
nhiều nhà cung cấp UNIX. NFS cung cấp một phương tiện để gắn kết các thư mục từ xa vào
thư mục địa phương, do đó đem lại một cây thư mục mạch lạc.
Phiên bản NFS trước đây chỉ cho phép các thư mục từ xa đã được gắn kết
được truy cập một cách trong suốt. Với sự ra đời của các tính năng tự động gắn kết, gắn kết
được thực hiện theo yêu cầu, dựa trên một bảng gắn kết và cấu trúc
tên tập tin. Các thành phần được tích hợp để hỗ trợ chia sẻ trong suốt, mặc dù
việc tích hợp này là hạn chế và không đồng đều, bởi vì mỗi máy có thể gắn kết
các thư mục từ xa khác nhau vào cây thư mục của nó. Cấu trúc kết quả nhận được là rất đa
dạng.
Chúng ta có thể đạt được sự tích hợp tổng thể của các hệ thống tập tin thành phần bằng cách
sử dụng phương pháp tiếp cận thứ 3. Ở đây, một cấu trúc tên toàn cầu duy nhất được áp dụng
cho tất cả các tập tin trong hệ thống. Lý tưởng nhất, các tập tin hệ thống tích hợp có cấu trúc
giống như cấu trúc của một hệ thống tập tin thông thường. Tuy nhiên trong thực tế, rất nhiều
các tập tin đặc biệt (Chẳng hạn, đối với tập tin thiết bị và thư mục nhị phân cụ thể của máy
trên UNIX) thực hiện điều này rất khó khăn.
Để đánh giá cấu trúc đặt tên, chúng ta nhìn vào sự phức tạp quản lý.
Cấu trúc phức tạp nhất và khó duy trì nhất là cấu trúc NFS.
Bởi vì bất kỳ thư mục từu xa nào cũng có thể được gắn vào bất cứ đâu của
cây thư mục địa phương, kết quả là hệ thống phân cấp có thể sẽ khó có cấu trúc. Nếu một máy
chủ trở nên không sẵn sàng, một số gắn kết thư mục trên các máy khác nhau trở nên
vô dụng. Ngoài ra, một cơ chế kiểm soát riêng biệt công nhận máy nào được phép gắn kết thư
mục nào vào cây thư mục của nó. Do đó, một người sử dụng có thể truy cập vào một cây thư
mục từ xa trên một máy khách, nhưng bị từ chối truy cập khi ơ trên một máy khách khác.
Hãy xem xét khi một người dùng yêu cầu truy cập vào một tập tin từ xa. Các máy chủ lưu trữ
các tập tin đã được định vị thông qua hệ thống đặt tên, và bây giờ các chuyển giao dữ liệu
thực tế phải diễn ra.
Một cách để đạt được chuyển giao này là thông qua một cơ chế dịch vụ từ xa
theo đó yêu cầu cho truy cập được gửi đến máy chủ, máy chủ
thực hiện truy cập, và kết quả của nó sẽ được chuyển trở lại cho người sử dụng. Một
trong những cách phổ biến nhất của việc thực hiện dịch vụ từ xa là
mô hình gọi thủ tục từ xa (RPC). Một sự tương tự tồn tại giữa các phương pháp truy cập ổ đĩa
trong hệ thống tập tin thông thường và phương pháp dịch vụ từ xa trong một DFS: bằng cách
sử dụng phương pháp dịch vụ từ xa tương tự để thực hiện một truy cập đĩa cho mỗi yêu cầu
truy cập.
Để đảm bảo hiệu suất hợp lý của một cơ chế dịch vụ từ xa, chúng ta có thể
sử dụng bộ đệm. Trong các hệ thống tập tin thông thường, lý do dùng bộ nhớ đệm
để giảm I / 0 đĩa (do đó làm tăng hiệu suất), trong khi ở DFS, mục tiêu
là để giảm lưu lượng mạng và I / 0 đĩa. Trong các thảo luận sau đây, chúng ta
mô tả việc thực hiện của bộ nhớ đệm trong một DFS và tương phản chúng với
mô hình dịch vụ từ xa cơ bản.
Vị chí bộ đệm
Các dữ liệu lưu trữ trong bộ đệm phải được lưu trữ trên đĩa hay trong bộ nhớ chính? Đĩa
đệm có một lợi thế rõ ràng hơn bộ nhớ đệm: chúng đáng tin cậy.
dữ liệu sửa đổi lưu trữ trong bộ đệm sẽ bị mất trong một tai nạn nếu bộ nhớ đệm được lưu giữ
trong bộ nhớ. Thêm vào đó, nếu các dữ liệu lưu trữ được lưu giữ trên đĩa đệm, chúng vẫn còn
đó trong thời gian phục hồi, và không cần phải lấy chúng một lần nữa. Đệm trong bộ nhớ có
một số lợi thế của riêng mình, chúng cho phép các máy trạm không cần đĩa.
Dữ liệu có thể được truy cập nhanh hơn từ một bộ đệm trong bộ nhớ chính hơn là từ trên đĩa.
Công nghệ đang hướng tới bộ nhớ lớn hơn và ít tốn kém. Các kết quả tăng tốc hiệu suất được
dự báo sẽ lớn hơn những lợi thế bộ đệm trên đĩa cứng.
Các bộ đệm máy chủ (được sử dụng để tăng tốc độ đĩa I / 0) sẽ có trong bộ nhớ chính
không phụ thuộc vào vị trí vùng đệm của người dùng, nếu chúng ta sử dụng đệm trên bộ nhớ
chính trên máy người dùng, chúng ta có thể xây dựng một cơ chế bộ nhớ đệm duy nhất sử
dụng cho cả máy chủ và người sử dụng.
Nhiều triển khai truy cập từ xa có thể được coi là sự lai của
bộ nhớ đệm và dịch vụ từ xa. Trong NFS, ví dụ, việc thực hiện dựa trên
dịch vụ từ xa nhưng được tăng cường với vùng đệm trong bộ nhớ máy khách và máy chủ để
tăng cường hiệu suất.
Các giao thức NFS và hầu hết các thực hiện không cung cấp bộ nhớ đệm đĩa.
Thực hiện gần đây của Solaris NFS (Solaris 2,6 và vượt ra ngoài) cung cấp tùy chọn cho
người dùng bộ đệm đĩa. Một khi các khách hàng NFS đọc các khối của một tập tin từ máy
chủ, nó đệm chúng trong bộ nhớ cũng như trên đĩa.
Nếu các đệm bộ nhớ bị xóa, hoặc ngay cả khi khởi động lại hệ thống, bộ đệm đĩa
được tham chiếu. Nếu một khối cần thiết không phải trong đệm bộ nhớ cũng không phải trong
bộ đệm đĩa, 1 RPC được gửi đến máy chủ để lấy các khối, và khối được viết
vào bộ nhớ đệm đĩa cũng như lưu trữ trong đệm bộ nhớ của khách hàng.
Một cách khác là chính sách viết chậm cũng được biết đến như là viết vào bộ đệm nhưng
chúng ta trì hoãn cập nhật vào các bản sao chủ. Những sửa đổi được viết vào
bộ đệm và sau đó được viết vào máy chủ tại một thời điểm sau đó. Chính sách này có hai lợi
thế hơn viết ngay. Đầu tiên, bởi vì viết được thực hiện trên bộ nhớ đệm, truy cập viết hoàn
thành nhanh hơn rất nhiều. Thứ hai, dữ liệu có thể
được ghi đè trước khi chúng được viết trở lại, trong trường hợp này chỉ cần phải viết bản cập
nhật cuối cùng. Thật không may, phương án trì hoãn viết có các vấn đề về độ tin cậy, khi dữ
liệu chưa viết bị mất bất cứ khi nào một máy tính người dùng có vấn đề.
Biến thể của chính sách viết chậm thể hiện sự khác nhau khi các khối dữ liệu biến đổi
được đẩy tới máy chủ. Một cách thay thế là đẩy một khối khi nó sắp
bị đẩy ra khỏi bộ nhớ đệm của khách hàng. Tùy chọn này có thể dẫn đến hiệu suất tốt,
nhưng một số khối có thể cư trú trong bộ nhớ đệm của khách hàng một thời gian dài trước khi
chúng được viết lại cho máy chủ. Một thỏa hiệp giữa phương án này và
chính sách viết ngay là quét bộ đệm đều đặn và đẩy các khối đã được thay đổi kể từ lần quét
gần đây nhất
NFS sử dụng chính sách này cho các tập tin dữ liệu, nhưng một khi một thao tác viết được
ban hành tới máy chủ trong quá trình đẩy dữ liệu từ bộ đệm, việc viết phải hoàn thành tại đĩa
của máy chủ trước khi nó được coi là hoàn chỉnh.
NFS xử lý các dữ liệu meta (dữ liệu thư mục và tập tin dữ liệu thuộc tính) khác nhau. Bất kỳ
thay đổi dữ liệu meta nào được ban hành đồng bộ với máy chủ. Vì vậy, việc
thất thoát cấu trúc tập tin, sai lệch cấu trúc thư mục được tránh khi một khách hàng hoặc máy
chủ gặp vấn đề.
Đối với NFS có cachefs, viết các khu vực bộ đệm đĩa địa phương được thực hiện khi chúng
được viết đến máy chủ, để giữ cho tất cả các bản sao đồng nhất. Vì vậy, NFS
với cachefs cải thiện hiệu suất hơn NFS tiêu chuẩn với một yêu cầu đọc
khi yêu cầu đó gặp bộ đệm, nhưng làm giảm hiệu suất để đọc hoặc viết khi yêu cầu không
gặp bộ đệm. Như với tất cả các bộ đệm, rất quan trọng để có một bộ đệm có tỷ lệ gặp cao
nhằm đạt được hiệu suất. Hình 17,1 cho thấy làm thế nào cachefs sử dụng viết ngay và
viết sau tại bộ đệm.
Tuy nhiên, một biến thể viết chậm trên là ghi dữ liệu trở lại máy chủ
khi tập tin được đóng lại. Chính sách viết khi đóng này được sử dụng trong AFS. Trong
trường hợp các tập tin được mở trong thời gian ngắn hoặc ít khi được sửa đổi, chính sách này
không làm giảm đáng kể lưu lượng truy cập mạng. Ngoài ra, chính sách viết khi đóng đòi hỏi
quá trình đóng file phải bị trì hoãn trong khi tập tin được viết tới máy chủ. Điều này
làm giảm những lợi thế hiệu suất của chính sách viết chậm. Đối với các tập tin được
mở trong thời gian dài và được thay đổi thường xuyên,
lợi thế hiệu suất của chính sách này hơn chính sách viết chậm với cập nhật thường xuyên hơn
rõ ràng.
Phương pháp khách hàng khởi tạo. Khách hàng khởi tạo một kiểm tra tính hợp lệ, trong đó nó
liên lạc với máy chủ và kiểm tra xem các dữ liệu địa phương là phù hợp với
các bản sao chủ. Tần số kiểm tra tính hợp lệ là mấu chốt của
phương pháp này và xác định ngữ nghĩa nhất quán. Nó có thể trải
từ kiểm tra trước mỗi khi truy cập tới chỉ có một kiểm tra trước lần truy cập đầu tiên
một tập tin. Mỗi truy cập cùng với một kiểm tra tính hợp lệ sẽ bị chậm khi so sánh với truy
cập được phục vụ ngay lập tức bởi bộ đệm.
Theo một cách khác, kiểm tra có thể được khởi đầu ở các khoảng thời gian cố định. Tùy thuộc
vào tần số của nó, việc kiểm tra tính hợp lệ có thể tăng tải cả mạng và
máy chủ.
Phương pháp máy chủ khởi tạo. Máy chủ ghi lại cho mỗi khách hàng các tập tin
(hoặc các bộ phận của tập tin) mà nó lưu tại bộ đệm. Khi máy chủ phát hiện một khả năng
không thống nhất, nó phải phản ứng. Một khả năng cho sự mâu thuẫn xảy ra khi
hai khách hàng khác nhau trong chế độ xung đột bộ đệm một tập tin. Trên UNIX
, chúng ta có thể giải quyết khả năng không thống nhất bằng những máy chủ đóng vai trò tích
cực. Các máy chủ phải được thông báo bất cứ khi nào một tập tin được mở ra, và chế độ dự
kiến (đọc hoặc viết)
được chỉ định cho mỗi lần mở. Các máy chủ sau đó có thể hoạt động khi nó phát hiện rằng
một tập tin đã được mở đồng thời trong chế độ xung đột bằng cách vô hiệu hóa
bộ nhớ đệm cho tập tin đó cụ thể. Trên thực tế, vô hiệu hóa kết quả bộ nhớ đệm và
chuyển sang chế độ hoạt động phục vụ từ xa.
Nhân rộng các tập tin trên các máy khác nhau trong một hệ thống tập tin phân tán là một
dự phòng hữu ích cho việc cải thiện tính sẵn sàng. Sao chép trên nhiều máy có thể đem lại lợi
ích về hiệu suất: chọn một bản sao gần đó để phục vụ cho một yêu cầu truy cập sẽ có
thời gian phục vụ ngắn hơn.
Yêu cầu cơ bản của một chương trình sao chép là bản sao khác nhau của
cùng một tập tin nằm trên các máy độc lập. Tức là, sự sẵn sàng của một bản sao không bị ảnh
hưởng bởi sự sẵn sàng của phần còn lại của các bản sao.
Yêu cầu này rõ ràng ngụ ý rằng quản lý bản sao gắn liền với quản lý địa điểm.
Đó là mong muốn để ẩn các chi tiết của sao lưu với người sử dụng. Ánh xạ
tên tập tin được sao lưu tới một bản sao là nhiệm vụ đặc biệt của phương án đặt tên.
Sự tồn tại của bản sao nên trong suốt đối với tầng cao hơn. Tại tầng thấp các bản sao phải
được phân biệt với nhau bởi các tên cấp thấp khác nhau. Một yêu cầu trong suốt khác là cung
cấp điều khiển sao lưu ở tầng cao hơn. điều khiển sao lưu bao gồm xác định
mức độ nhân bản và vị trí của bản sao. Theo một số
trường hợp, chúng ta có thể muốn để lộ những chi tiết này cho người sử dụng.
Vấn đề chính liên quan tới các bản sao là vấn đề cập nhật. Từ quan điểm một người sử dụng,
bản sao của một tập tin biểu thị cùng một thực thể logic, và như vậy, một
cập nhật bản sao bất kỳ phải được phản ánh trên tất cả các bản sao khác. Chính xác hơn,
ngữ nghĩa nhất quán có liên quan phải được đảm bảo khi truy cập đến các bản sao
như là khi truy cập bản sao logic. Nếu sự thống nhất là không
quan trọng, nó có thể được hy sinh để tăng tính sẵn sàng và tăng hiệu suất. Các tên miền của
ánh xạ là một cặp <primary-replica-identifier, local-replica-identifier>. Nếu không có
bản sao địa phương tồn tại, một giá trị đặc biệt được sử dụng. Như vậy, lập bản đồ liên quan
đến một máy. Nếu các bản sao địa phương là một bản chính, cặp định danh chứa 2 ID giống
hệt nhau. Cập nhật chỉ được thực hiện trên các bản sao chính và
làm cho tất cả các bản sao khác trở nên vô hiệu thông qua việc gửi tin nhắn thích hợp. huỷ bỏ
hiệu lực Nguyên tử và tuần tự của tất cả các bản sao phụ không phải là
đảm bảo. Do đó, một bản sao cũ có thể được coi là hợp lệ. Để đáp ứng
truy cập viết từ xa, chúng ta di chuyển các bản sao chính đển máy tính yêu cầu.
Trong một hệ thống tập trung, chúng ta luôn có thể xác định thứ tự các sự kiện xảy ra, do hệ
thống có một bộ nhớ chung và đồng hồ duy nhất.
Nhiều ứng dụng có thể yêu cầu chúng ta xác định trật tự. Ví dụ, trong một
kế hoạch phân bổ tài nguyên, chúng ta xác định rằng một tài nguyên có thể được sử dụng chỉ
sau khi tài nguyên đã được cấp. Một hệ thống phân tán, tuy nhiên, không có bộ nhớ và đồng
hồ đồng nhất. Vì vậy, đôi khi không thể nói cái nào trong số hai sự kiện xảy ra trước. quan hệ
xảy ra trước chỉ là một phần của sắp xếp sự kiện trong hệ thống phân tán. Do việc xác định
một trật tự tổng quát là rất quan trọng trong nhiều ứng dụng, chúng ta trình bày
một thuật toán phân tán để mở rộng quan hệ xảy ra trước thành quan hệ trật tự tổng quát của
tất cả các sự kiện trong hệ thống.
Vì chúng ta chỉ xem xét tiến trình tuần tự, tất cả các sự kiện thực hiện trong một
tiến trình duy nhất hoàn toàn được sắp xếp. Theo luật nhân quả, một tin nhắn chỉ có thể
được nhận sau khi nó đã được gửi. Do đó, chúng ta có thể xác định Quan hệ xảy ra trước (ký
hiệu là ->) trên một tập hợp các sự kiện như sau (giả định rằng gửi và nhận tin nhắn cấu thành
một sự kiện):
1.Nếu các sự kiện A và B trong cùng một tiến trình, và A đã được thực hiện trước B,
do đó A -> B.
2. Nếu A là sự kiện gửi tin nhắn từ một tiến trình và B là sự kiện nhận được tin nhắn đó bởi
tiến trình khác, do đó A -> B.
3. Nếu A -> B và B -> C, do đó A -> C.
Nếu hai sự kiện, A và B, không liên quan đến mối quan hệ -> (có nghĩa là, A không xảy ra
trước B, và B đã không xảy ra trước A), chúng ta nói rằng hai sự kiện được thực hiện đồng
thời. Trong trường hợp này, không sự kiện nào là nguyên nhân ảnh hưởng đến sự kiện kia.
Tuy nhiên, nếu A -> B, rất có thể nó có thể sự kiện A là nguyên nhân ảnh hưởng đến sự kiện
B.
Một sơ đồ không gian-thời gian, chẳng hạn như trong hình 18,1, có thể minh họa tốt nhất
định nghĩa xảy ra trước và xảy ra đồng thời. Hướng ngang đại diện
không gian (có nghĩa là, các tiến trình khác nhau), và hướng thẳng đứng đại diện
thời gian. Các nhãn đường thẳng đứng biểu thị tiến trình (hoặc bộ vi xử lý). Các nhãn
dấu chấm biểu thị sự kiện. Một đường lượn sóng biểu thị một thông điệp được gửi từ một tiến
trình đến một tiến trình khác. Sự kiện là đồng thời nếu và chỉ nếu không có con đường tồn tại
giữa chúng.
Ví dụ, đây là một số kiện có quan hệ xảy ra trước trong hình 18,1:
P1 ->q2
ro -> q4
q3 -> r4
P1 -> q4 (do P1-> q2 và q2 -> q4)
Chúng ta không thể biết cái nào trong hai sự kiện đồng thời, chẳng hạn như qo và p2, xảy ra
đầu tiên. Tuy nhiên, vì không sự kiện nào ảnh hưởng đến sự kiện khác (không có cách nào
cho một trong các sự kiện biết liệu sự kiện khác đã xảy ra), không quan trọng sự kiện nào xảy
ra trước. Điều quan trọng là bất kỳ tiến trình nào quan tâm đến thứ tự
của hai sự kiện đồng thời đồng ý về một số trật tự.
Hình 8.3: Thời gian tương đối cho ba tiến trình đồng thời.
Thực hiện
Để xác định một sự kiện A đã xảy ra trước một sự kiện B, chúng ta cần hoặc là cùng một
đồng hồ, hoặc thiết lập các đồng hồ hoàn toàn đồng bộ. Do các cái đó không
có sẵn trong một hệ thống phân tán, chúng ta phải định nghĩa quan hệ xảy ra trước
mà không cần sử dụng đồng hồ vật lý.
Trước tiên, chúng ta gán với mỗi sự kiện hệ thống một nhãn thời gian. Chúng ta sau đó có thể
xác định yêu cầu thứ tự toàn cục: cho tất cả các cặp sự kiện A và B, nếu A -> B,
thì nhãn thời gian của A là ít hơn nhãn thời gian của B.
Làm thế nào để chúng ta đáp ứng yêu cầu thứ tự toàn cục trong môi trường phân tán? Chúng
ta định nghĩa trong mỗi tiến trình Pi một đồng hồ logic, LCi. Các đồng hồ logic có thể được
thực hiện như một thao tác tăng lên đơn giản giữa
hai sự kiện bất kỳ liên tiếp xảy ra trong một tiến trình. Do đồng hồ logic
có giá trị tăng đơn điệu, nó gán một số duy nhất cho mỗi
sự kiện, và nếu một sự kiện A xảy ra trước sự kiện B trong tiến trình Pi, thì LCi (A) <
LCi (B). Các nhãn thời gian cho một sự kiện là giá trị của đồng hồ logic cho
sự kiện đó. Cách này này đảm bảo rằng đối với bất kỳ hai sự kiện trong cùng một tiến trình
yêu cầu thứ tự toàn cục được đáp ứng.
Thật không may, cách này không đảm bảo yêu cầu thứ tự toàn cục khi có nhiều tiến trình. Để
minh họa cho vấn đề này, hãy xem xét hai tiến trình P1 và P2 giao tiếp với nhau. Giả sử P1
gửi một thông điệp tới P2 (sự kiện A) với LC1 (A) = 200, và P2 nhận được tin nhắn
(sự kiện B) với LC2 (B) = 195 (vì bộ xử lý P2 chậm hơn so với bộ vi xử lý cho P1, đồng hồ
logic của nó sẽ chậm hơn). Tình trạng này vi phạm yêu cầu của chúng ta, do A -> B nhưng
nhãn thời gian của A là lớn hơn so với nhãn thời gian của B.
Để giải quyết khó khăn này, chúng ta yêu cầu một tiến trình tăng đồng hồ logic của nó
khi nó nhận được một tin nhắn có nhãn thời gian lớn hơn giá trị hiện tại của
đồng hồ logic của nó. Cụ thể là, nếu tiến trình Pi nhận được một tin nhắn (sự kiện B)
với nhãn thời gian t và LCi (B) < t, thì nó sẽ tăng đồng hồ của nó để LCi (B) = t +
1. Như vậy, trong ví dụ của chúng tôi, khi P2 nhận được tin nhắn từ P1, nó sẽ tăng
đồng hồ logic để LC2 (B) = 201.
Cuối cùng, để hiện thực yêu cầu thứ tự toàn cục, chúng ta cần chú ý rằng, với phương pháp
nhãn thời gian, nếu các nhãn thời gian của hai sự kiện, A và B,
như nhau, chúng là các sự kiện đồng thời. Trong trường hợp này, chúng ta có thể sử dụng
danh tính của tiến trình để tạo ra một trật tự toàn cục.
Trong Chương trước, chúng ta đã biết khái niệm của một giao dịch nguyên tử, là một
đơn vị chương trình phải được thực hiện. Đó là, hoặc là tất cả các hoạt động
liên kết với nó được thực hiện hoàn thành, hoặc không được thực hiện. Khi chúng ta
làm việc với một hệ thống phân tán, đảm bảo tính nguyen tử của một giao dịch
trở nên phức tạp hơn là trong một hệ thống tập trung. Khó khăn này
xảy ra bởi vì một số máy tính khác nhau có thể được tham gia trong việc thực hiện một đơn vị
giao dịch. Sự thất bại của một trong các máy tính này, hay thất bại của mạng
kết nối các máy tính, có thể dẫn đến tính toán sai lầm.
Đảm bảo rằng việc thực hiện các giao dịch trong hệ thống phân tán vẫn giữ nguyên tính
nguyên tử là chức năng của bộ phối hợp giao dịch. Mỗi máy tính có một bộ điều phối giao
dịch địa phương, có trách nhiệm phối hợp thực hiện tất cả các giao dịch khởi xướng tại máy
tính đó. Đối với mỗi giao dịch như vậy, bộ điều phối chịu trách nhiệm cho những việc sau:
- Khởi tạo thực hiện giao dịch
- Chia giao dịch thành một số giao dịch con và phân phối những giao dịch con này đến các địa
điểm thích hợp để thực hiện.
- Phối hợp kết thúc giao dịch, có thể dẫn đến
giao dịch được hoàn thành tại tất cả các địa điểm hoặc bị hủy bỏ tại tất cả các địa điểm.
Chúng tôi giả định rằng mỗi máy tính duy trì một bản ghi cho các mục đích phục hồi.
Giai đoạn 1. Ci thêm một bản ghi <prepare T> vào nhật ký trên thiết bị lưu trữ ổn định. Sau
đó gửi tin nhắn prepare (T) tới tất cả các địa điểm tại đó T đã thực hiện. Khi nhận được tin
nhắn, bộ quản lý giao dịch tại các địa điểm này xác định liệu nó đã sẵn sàng cam kết hoàn
thành phần việc của nó trong T chưa. Nếu câu trả lời là không, nó tạo một bản ghi <no T> vào
trong nhật ký, và sau đó nó phản hồi bằng cách gửi tin nhắn abort (T) cho Ci. Nếu câu trả lời
là có, nó thêm một bản ghi <ready T> vào nhật ký. Bộ quản lý giao dịch sau đó trả lời với một
tin nhắn ready (T) đến Ci.
Giai đoạn 2. Khi Ci nhận được tin nhắn phản hồi cho prepare (T) từ
tất cả các địa điểm, hoặc khi hết thời gian nhận phản hồi, Ci có thể xác định liệu giao dịch T
có thể được hoàn tất hoặc bị hủy bỏ. Giao dịch T được hoàn tất nếu Ci nhận được thông điệp
ready (T) từ tất cả các địa điểm tham gia. Nếu không,
giao dịch T phải được hủy bỏ. Tùy thuộc vào phán quyết, hoặc là một bản ghi
<commit T> hoặc một bản ghi <abort T> được thêm vào nhật ký. Tại thời điểm này, số phận
của giao dịch đã được xác định. Bộ điều phối gửi, hoặc một
tin nhắn commit (T) hoặc abort (T) đến tất cả các địa điểm tham gia. Khi một địa điểm nhận
được tin nhắn đó, nó ghi lại tin nhắn trong nhật ký.
Do tính thống nhất được yêu cầu để hoàn tất một giao dịch, số phận của T được xác định ngay
sau khi ít nhất một đại điểm đáp ứng với abort (T). Lưu ý rằng bộ điều phối tại Si có thể quyết
định đơn phương hủy bỏ T, vì nó là một trong các địa điểm thực hiện T. Các phán quyết cuối
cùng liên quan đến T được xác định tại thời điểm bộ điều phối ghi lại quyết định (hoàn tất
hoặc hủy bỏ) vào nhật ký trong bộ lưu trữ ổn định.
Trong một số hiện thực của giao thức 2PC, một địa điểm sẽ gửi 1 tin nhắn acknowledge
(T) tới bộ điều phối ở cuối của giai đoạn thứ hai của giao thức. Khi bộ điều phối viên nhận
được tin nhắn acknowledge (T) từ tất cả các các địa điểm, nó sẽ ghi bản ghi <complete T>
vào nhật ký.
- Nếu một địa điểm đang hoạt động có chứa một bản ghi <commit T> trong nhật ký của nó, T
phải được hoàn tất.
- Nếu một địa điểm đang hoạt động có chứa một bản ghi <abort T> trong nhật ký của nó, T
phải bị hủy bỏ.
- Nếu địa điểm đang hoạt động không chứa một bản ghi <ready T> trong nhật ký của nó, bộ
điều phối Ci không thể đã quyết định hoàn tất T. Chúng ta có thể suy ra kết luận này bởi vì
một địa điểm không có một bản ghi <ready T> trong nhật ký của nó thì không thể gửi một tin
nhắn ready (T) cho Ci;. Tuy nhiên, bộ điều phối có thể đã quyết định hủy bỏ T. Thay vì chờ
đợi Ci phục hồi, tôt nhất nên hủy bỏ T trong trường hợp này.
- Nếu không có trường hợp trên nào xảy ra, tất cả các địa điểm đang hoạt động phải có một
bản ghi <ready T> trong nhật ký của chúng, nhưng không có bản ghi điều khiển bổ sung khác
(như <abort T> hoặc <commit T>). Do điều phối gặp lỗi, không thể xác định liệu một quyết
định đã được thực hiện, hoặc quyết định đó là gì cho đến khi bộ điều phối phục hồi. Vì vậy,
các địa điểm đang hoạt động phải chờ cho Ci phục hồi. Khi số phận của T vẫn chưa rõ ràng,
T có thể tiếp tục giữ tài nguyên hệ thống. Ví dụ, nếu khóa được sử dụng,
T có thể giữ khóa với các dữ liệu ở các địa điểm đang hoạt động. Một tình huống như vậy là
không mong muốn do Ci có thể phục hồi sau vài giờ hoặc vài ngày. Trong thời gian này, các
giao dịch khác có thể bị buộc phải chờ T. Kết quả là, không có dữ liệu không chỉ trên địa
điểm bị lỗi (Ci) mà còn không có trên các địa điểm đang hoạt động tốt. Số lượng dữ liệu
không có tăng lên khi thời gian chết của Ci tăng. Tình trạng này được gọi là vấn đề khóa
chặn, bởi vì T bị chặn trong khi chờ sự phục hồi của Ci
Mạng bị lỗi
Khi một liên kết bị lỗi, các tin nhắn trong quá trình được truyền thông qua
liên kết không đi đến điểm đến của nó một cách nguyên vẹn. Từ góc nhìn của các địa điểm
kết nối trong liên kết đó, các địa điểm khác đã bị lỗi. Vì vậy, các phương án trình bày trước
đây có thể áp dụng tốt ở đây.
Khi một liên kết bị hỏng, mạng có thể bị phân mảnh. Trong trường hợp này, có
hai khả năng tồn tại. Bộ điều phối và tất cả các địa điểm tham gia có thể ở lại
một phân vùng, trong trường hợp này, sự hỏng hóc không có ảnh hưởng tới giao thức hoàn tất
Khả năng khác, bộ điều phối và những địa điểm tham gia có thể thuộc về một số
phân vùng khác nhau, trong trường hợp này, tin nhắn giữa địa điểm tham gia và bộ điều phối
bị mất, quy về trường hợp liên kết bị lỗi.
Chúng ta sẽ xem xét một cách ngăn ngừa tắc nghẽn mới dựa trên đánh dấu thời gian và ngừng
tài nguyên. Mặc dù cách tiếp cận này có thể xử lý bất kỳ tình huống bế tắc nào có thể phát
sinh trong một hệ thống phân tán, chúng ta chỉ xem xét trường hợp đơn giản một thể hiện của
một loại tài nguyên.
Để kiểm soát việc ngừng, chúng ta chỉ định một số ưu tiên duy nhất cho mỗi
tiến trình. Những con số này được sử dụng để quyết định xem một tiến trình Pi phải đợi
tiến trình Pj. Ví dụ, chúng ta có thể cho Pi đợi Pj nếu Pi có số ưu tiên cao hơn
hơn so với của Pj nếu không Pi sẽ chết. Cách này ngăn chặn deadlocks
bởi vì, cho mỗi cạnh Pi -> Pj trong đồ thị đợi, Pi có ưu tiên cao hơn
hơn Pj. Như vậy, một chu trình không thể tồn tại.
Một khó khăn với chương trình này là khả năng xảy ra nạn đói. Một số
tiến trình với các ưu tiên rất thấp luôn luôn có thể bị chết. Điều này
có thể tránh được thông qua việc sử dụng các nhãn thời gian. Mỗi tiến trình trong
hệ thống được phân một dấu thời gian duy nhất khi nó được tạo ra. Có hai
đề án bổ sung nhằm ngăn ngừa bế tắc bằng cách sử dụng dấu thời gian đã được đề xuất:
- Phương pháp đợi-chết. Cách tiếp cận này dựa trên kĩ thuật không ngừng tài nguyên. Khi tiến
trình Pi yêu cầu một nguồn tài nguyên hiện đang được dùng bởi Pj, Pi được cho phép chờ đợi
chỉ khi nó có dấu thời gian nhỏ hơn so với Pj (đó là, Pi cũ hơn Pj). Nếu không, Pi được cuộn
lại (chết). Ví dụ, giả sử rằng tiến trình P1, P2 và P3 có các dấu thời gian 5, 10, và 15, tương
ứng. Nếu P1 yêu cầu một nguồn tài nguyên được sử dụng bởi P2, P1 sẽ chờ đợi. Nếu P3 yêu
cầu một nguồn tài nguyên được sử dụng bởi P2, P3 sẽ được cuộn lại.
- Phương pháp bị thương - đợi. Cách tiếp cận này được dựa trên kỹ thuật ngừng tài nguyên và
là cách tiếp cận ngược với phương pháp đợi - chết. Khi tiến trình
Pi yêu cầu một nguồn tài nguyên hiện đang được sử dụng bởi Pj, Pi được phép chờ đợi chỉ khi
nó có dấu thời gian lớn hơn so với Pj (có nghĩa là, Pi trẻ hơn
Pj). Nếu không, Pj được cuộn lại (Pj bị thương bởi Pi). Trở về với ví dụ của chúng ta
trước đây, với tiến trình P1, P2 và P3, nếu P1 yêu cầu một nguồn tài nguyên
được sử dụng bởi P2, sau đó nguồn tài nguyên sẽ được ngừng sử dụng từ P2, và P2 sẽ là
cuộn lại. Nếu P3 yêu cầu một nguồn tài nguyên được sử dụng bởi P2, P3 sẽ chờ đợi.
Cả hai phương pháp có thể tránh được nạn đói, khi một tiến trình bị cuộn lại, nó không được
phân một dấu thời gian mới. Do các dấu thời gian luôn luôn tăng,
tiến trình đó được cuộn lại cuối cùng sẽ có các dấu thời gian nhỏ nhất. Vì vậy,
nó sẽ không được cuộn lại một lần nữa. Tuy nhiên, có sự khác biệt đáng kể trong
cách hai phương pháp hoạt động.
Trong phương pháp đợi chết, một tiến trình già phải chờ đợi cho một tiến trình trẻ hơn
giải phóng tài nguyên của nó. Do đó, tiến trình càng cũ, càng có xu hướng
chờ đợi. Ngược lại, trong phương pháp thương - đợi, một tiến trình cũ không bao giờ chờ đợi
cho một tiến trình trẻ.
Trong phương pháp đợi - chết, nếu một tiến trình Pi chết và được cuộn lại bởi vì nó
đã yêu cầu một nguồn tài nguyên được sử dụng bởi tiến trình Pj, sau đó Pi có phát hành lại
chuỗi các yêu cầu giống nhau khi nó được khởi động lại. Nếu tài nguyên vẫn được sử dụng
bởi Pj, Pi sau đó sẽ chết một lần nữa. Do đó, Pi có thể chết nhiều lần trước khi nhận được
tài nguyên cần thiết. Tương phản loạt các sự kiện này với những gì xảy ra trong
phương pháp thương - đợi. Tiến trình Pi bị thương và cuộn lại vì Pj đã yêu cầu một nguồn tài
nguyên mà nó nắm giữ. Khi Pi được khởi động lại và yêu cầu các
tài nguyên hiện đang được sử dụng bởi Pj, Pi chờ đợi. Vì vậy, cuộn lại ít xảy ra hơn trong
phương pháp thương - đợi.
Hình 8.5: Đồ thị chờ đợI toàn cục cho hình 8.4
Rõ ràng, nếu bất kỳ đồ thị chờ đợi địa phương nào xuất hiện chu kỳ, bế tắc đã xảy ra.
Thực tế là khi chúng ta không thấy có chu kỳ trong bất kỳ các đồ thị chờ đợi địa phương
không có nghĩa là không có bế tắc. Để minh họa cho vấn đề này, chúng ta xem xét
hệ thống mô tả trong hình 18,3. Mỗi đồ thị chờ đợi là mạch hở, tuy nhiên,
bế tắc tồn tại trong hệ thống. Để chứng minh rằng một bế tắc đã không xảy ra, chúng ta
phải chỉ ra rằng hợp nhất của tất cả các đồ thị địa phương là mạch hở. Đồ thị hợp nhất (hình
18,4) mà chúng ta có được từ sự hợp nhất của hai đồ thị chờ đợi của hình 18,3
thực sự chứa một chu kỳ, ngụ ý rằng hệ thống này là ở trong trạng thái bế tắc.
Một số phương pháp có sẵn để tổ chức đồ thị chờ đợi trong một hệ thống phân tán. Chúng ta
mô tả một số đề án phổ biến ở đây.
Khi các thuật toán phát hiện bế tắc được gọi, bộ điều phối tìm kiếm trên
đồ thị toàn cục của nó. Nếu một chu kỳ được tìm thấy, một nạn nhân được lựa chọn để được
cuộn lại. Bộ điều phối phải thông báo cho tất cả các địa điểm quá trình cụ thể đã được lựa
chọn như là nạn nhân. Các địa điểm, đến lượt nó, cuộn lại tiến trình nạn nhân.
Tiếp theo, chúng ta xem xét việc xây dựng đồ thị từ ba tùy chọn được liệt kê
ở trên. Với tùy chọn 1, bất cứ khi nào một cạnh hoặc được lắp vào hoặc gỡ bỏ từ một
đồ thị địa phương, địa điểm đó cũng phải gửi một tin nhắn để điều phối viên để thông báo
việc sửa đổi này. Khi nhận được tin nhắn, bộ điều phối cập nhật đồ thị toàn cục của nó.
Với tùy chọn 2, 1 địa điểm có thể gửi một số thay đổi như vậy trong một
thông báo định kỳ. Trở lại ví dụ trước của chúng ta, tiến trình điều phối sẽ duy trì đồ thị chờ
đợi toàn cục như mô tả trong hình 18,4. Khi địa điểm S2 chèn cạnh P3-> P4 vào đồ thị chờ
đợi địa phương của nó, nó cũng gửi một tin nhắn đến bộ điều phối. Tương tự như vậy, khi địa
điểm S1 xóa cạnh P5 -> P1 bởi vì P1 đã giải phóng một tài nguyên được yêu cầu bởi P5, 1
một tin nhắn thích hợp được gửi đến bộ điều phối.
Lưu ý rằng, với mỗi trong hai lựa chọn này được sử dụng, sự cuộn lại không cần thiết
vẫn có thể xảy ra, như là một kết quả của hai tình huống:
1 Chu kỳ lỗi có thể tồn tại trong đồ thị chờ đợi toàn cục. Để minh họa điểm này
chúng ta xem xét một bản chụp của hệ thống như mô tả trong hình 18,5. Giả sử
P2 giải phóng các tài nguyên nó đang sử dụng tại địa điểm S1 dẫn đến việc xóa
cạnh P1 -> P2 tại địa điểm S1. Tiến trình P2 sau đó yêu cầu một tài nguyên đang được sử
dụng bởi P3 tại địa điểm S2, kết quả là việc bổ sung cạnh P2 -> P3 vào địa điểm S2. Nếu
tin nhắn chèn P2 -> P3 từ địa điểm S2 đến trước tin nhắn xóa P1-> P2 từ địa điểm S1, bộ
điều phối có thể khám phá 1 chu trình giả P1 -> P2 -> P3 -> P1 sau khi chèn (nhưng trước khi
xóa). Thủ tục phục hồi bế tắc có thể được kích hoạt mặc dù không có bế tắc xảy ra.
2. Sự cuộn lại không cần thiết cũng có thể xảy ra khi một sự bế tắc thực sự
xảy ra và nạn nhân đã được xác định, nhưng trong cùng một lúc một trong những
tiến trình bị hủy bỏ vì lý do không liên quan đến sự bế tắc (như
khi một tiến trình đã vượt quá thời gian được phân bổ). Ví dụ, giả sử
rằng địa điểm S1 trong hình 18.3 quyết định hủy bỏ P2. Đồng thời, bộ
điều phối đã phát hiện ra một chu kỳ và chọn P3 là nạn nhân. Cả hai P2 và
P3 bị cuộn lại mặc dù chỉ cần P2 bị cuộn lại
Bây giờ hãy xem xét một thuật toán phát hiện bế tắc tập trung sử dụng tùy chọn
3 phát hiện tất cả các bế tắc thật sự xảy ra và không phát hiện sai
bế tắc. Để tránh việc báo cáo của bế tắc sai, chúng ta yêu cầu rằng các yêu cầu
Hình 8.6: Các đồ thị đợI địa phương và toàn cục
từ các địa điểm khác nhau được gán với các định danh đặc trưng duy nhất (hoặc dấu thời
gian). Khi tiến trình Pi tại địa điểm S1 yêu cầu một tài nguyên từ Pj, tại địa điểm S2, một tin
nhắn yêu cầu với dấu thời gian TS được gửi đi. Cạnh Pi -> Pj với nhãn TS được chèn vào
đồ thị chờ đợi địa phương của S1. Cạnh này được lắp vào đồ thị chờ đợi địa phương của
S2 chỉ khi S2 đã nhận được tin nhắn yêu cầu và có thể không ngay lập tức
cấp các tài nguyên được yêu cầu. Một yêu cầu từ Pi tới Pj trong cùng một địa điểm được xử lý
theo cách thông thường, không có nhãn thời gian được gán với các cạnh Pi -> Pj.
Hình 8.7: Đồ thị chờ đợi địa phương đã chỉnh sửa từ hình 18.3.
Để xác định một bế tắc tồn tại, chúng ta phải gọi một thuật toán phát hiện bế tắc phân tán.
Giả sử rằng, tại địa điểm Si, đồ thị chờ đợi địa phương có chứa một chu kỳ liên quan đến
nút Pex · chu kỳ này phải có dạng
điều này chỉ ra rằng tiến trình Pkij tại địa điểm Si đang chờ đợi để có được một tài nguyên
nằm ở một địa điểm khác, Sj. Khi phát hiện chu kỳ này, Si gửi đến
Sj một tin nhắn phát hiện bế tắc có chứa thông tin về chu kỳ đó.
Khi Sj nhận được tin nhắn phát hiện bế tắc này, nó cập nhật đồ thị chờ đợi địa phương của nó
với các thông tin mới. Sau đó, nó tìm kiếm đồ thị chờ đợi địa phương mới được
xây dựng một chu kỳ không liên quan đến Pex. Nếu một chu trình tồn tại,
bế tắc được tìm thấy, và một chương trình phục hồi thích hợp được kích hoạt. Nếu một chu kỳ
liên quan đến Pex được phát hiện, Sj phát đi một thông điệp phát hiện bế tắc tới
một địa điểm thích hợp, Sk. Sk lặp lại các thủ tục như trên.
Như vậy, sau một số hữu hạn các vòng, hoặc là một sự bế tắc được phát hiện hoặc
tính toán phát hiện bế tắc tạm dừng.
Để minh họa cho thủ tục này, chúng tôi xem xét các đồ thị chờ đợi địa phương của hình
18.6. Giả sử rằng địa điểm S1 phát hiện ra chu kỳ
Do P3 đang chờ đợi để có được một tài nguyên tại địa điểm S2, một
tin nhắn phát hiện bế tắc mô tả chu kỳ đó được truyền từ S1 đến S2. Khi S2
nhận được tin nhắn này, nó cập nhật đồ thị chờ đợi, đồ thị chờ đợi địa phương biểu diễn trên
hình 18.7. Biểu đồ này có chứa chu kỳ
không bao gồm nút PEX · Vì vậy, hệ thống này ở trong trạng thái bế tắc,
và một chương trình phục hồi thích hợp phải được gọi.
Lưu ý rằng kết quả sẽ là như nhau nếu S2 phát hiện chu kỳ trước
ở đồ thị chờ đợi địa phương và gửi thông báo phát hiện bế tắc đến S1.
Trong trường hợp xấu nhất, cả hai địa điểm sẽ khám phá ra chu kỳ trong cùng khoảng thời
gian, và
hai tin nhắn phát hiện bế tắc sẽ được gửi: một từ S1 đến S2 và một từ
S2 đến S1. Tình huống này dẫn đến truyền thông tin,
cập nhật hai đồ thị chờ đợi địa phương và tìm kiếm cho chu kỳ trong cả hai đồ thị một cách
không cần thiết.
Hình 8.8: Đồ thị chờ đợi địa phương sửa đổi tạI địa điểm S2 của hình 18.6.
Để làm giảm lưu lượng tin nhắn, chúng ta gán cho mỗi tiến trình Pi một định danh duy nhất,
biểu thị ID (Pi). Khi địa điểm Sk phát hiện ra rằng đồ thị chờ đợi địa phương
có chứa một chu kỳ liên quan đến nút Pex có dạng
nó sẽ gửi một thông điệp phát hiện bế tắc đến một địa điểm khác chỉ khi
Nếu không, Sk tiếp tục thực hiện bình thường, để lại gánh nặng của
bắt đầu các thuật toán phát hiện bế tắc cho các địa điểm khác.
Để minh họa sơ đồ này, chúng ta xem xét lại các đồ thị chờ đợi duy trì
tại các địa điểm S1 và S2 như trong hình 18,6. Giả sử rằng
Giả sử cả hai địa điểm khám phá ra các chu kỳ địa phương tại cùng một thời điểm. Chu trình
của địa điểm S1 có dạng
Do ID (P3)> ID (P2), địa điểm S1 không gửi một thông báo phát hiện bế tắc tới S2.
Chu kỳ tại địa điểm S2 có dạng
Do ID (P2) <ID (P3), địa điểm S2 gửi một thông điệp phát hiện bế tắc tới địa điểm
S1, khi S1 nhận được tin nhắn, nó cập nhật đồ thị chờ đợi địa phương của nó. Địa điểm S1
sau đó tìm kiếm một chu kỳ trong đồ thị và phát hiện ra rằng hệ thống này đang trong trạng
thái bế tắc.
Như chúng ta đã chỉ ra trong mục 18,3, nhiều thuật toán phân tán sử dụng
tiến trình điều phối nhằm thực hiện các chức năng cần thiết cho các tiến trình khác trong hệ
thống. Các chức năng này bao gồm thực thi loại trừ lẫn nhau, duy trì
đồ thị chờ đợi toàn cục để phát hiện bế tắc, thay thế một mã thông báo bị mất, và
kiểm soát thiết bị đầu vào/ra trong hệ thống. Nếu tiến trình điều phối bị lỗi do lỗi của địa điểm
mà nó cư trú, hệ thống chỉ có thể tiếp tục
thực hiện bằng cách khởi động lại một bản sao mới của bộ điều phối trên một số địa điểm
khác. Các thuật toán xác định địa điểm mà một bản sao mới của bộ điều phối nên
khởi động lại được gọi là thuật toán bầu cử.
Các thuật toán bầu cử giả định rằng có một số hiệu ưu tiên duy nhất gắn
với mỗi tiến trình hoạt động trong hệ thống. Để dễ dàng theo dõi, chúng ta giả định rằng
số hiệu ưu tiên của tiến trình Pi là i. Để đơn giản hóa cuộc thảo luận, chúng ta giả định
một sự tương ứng một-một giữa các tiến trình và các địa điểm và do đó coi
cả hai như là tiến trình. Bộ điều phối luôn luôn là tiến trình có
số hiệu ưu tiên lớn nhất. Do đó, khi một bộ điều phối bị lỗi, các thuật toán phải bầu chọn
tiến trình đang hoạt động với số ưu tiên lớn nhất. Con số này phải được gửi
mỗi tiến trình hoạt động trong hệ thống. Ngoài ra, các thuật toán phải cung cấp một
cơ chế cho một tiến trình phục hồi để có thể xác định được bộ điều phối hiện tại.
1. Pj là bộ điều phối mới (j> i). Tiến trình Pi ghi lại thông tin này.
2. Pj đã bắt đầu một cuộc bầu cử (j <i). Tiến trình Pi gửi một phản ứng đển Pj
và bắt đầu thuật toán bầu cử riêng của mình, với điều kiện là Pi chưa từng bắt đầu việc bầu cử
đó.
Tiến trình hoàn thành thuật toán của nó có số ưu tiên cao nhất được bầu
là bộ điều phối. Nó gửi số ưu tiên của nó cho tất cả các tiến trình đang hoạt động với số ưu
thấp hơn. Sau một tiến trình bị lỗi phục hồi, nó ngay lập tức bắt đầu thực hiện
cùng một thuật toán. Nếu không có tiến trình đang hoạt động với số ưu tiên cao hơn,
quá trình phục hồi bắt buộc tất cả các quá trình với số ưu tiên thấp hơn để nó trở thành bộ
điều phối, thậm chí nếu có một bộ điều phối hiện đang hoạt động có số ưu tiên thấp hơn. Vì lý
do này, thuật toán được gọi là thuật toán bully.
Chúng ta có thể trình bày các hoạt động của thuật toán với một ví dụ đơn giản
một hệ thống bao gồm các tiến trình P1 tới P4. Hoạt động của thuật toán như sau:
- Tất cả các tiến trình đang hoạt động, P4 là tiến trình điều phối.
- P1 và P4 bị lỗi. P2 xác định rằng P4 đã bị lỗi bằng cách gửi một yêu cầu mà
không được trả lời trong thời gian T. P2 sau đó bắt đầu thuật toán bầu cử của mình bằng cách
gửi một yêu cầu tới P3.
- P3 nhận được yêu cầu, gửi trả lại cho P2, và bắt đầu thuật toán riêng của mình bằng cách
gửi một yêu cầu bầu cử đến P4.
- P2 nhận được trả lời của P3 và bắt đầu chờ đợi cho một khoảng thời gian T '.
- P4 không trả lời trong vòng một khoảng thời gian T, do đó, P3 tự mình là bộ
điều phối mới và gửi số 3 tới P2 và P1. (P1 không nhận được
số này, vì nó đã gặp lỗi.)
- Sau đó, khi P1 phục hồi, nó sẽ gửi một yêu cầu bầu cử tới P2, P3, P4.
- P2 và P3 gửi trả lại cho P1 và bắt đầu thuật toán bầu cử các riêng của mình. P3 sẽ
một lần nữa được bầu, thông qua các sự kiện tương tự như trước.
- Cuối cùng, P4 phục hồi và thông báo cho P1, P2 và P3 rằng nó là bộ điều phối hiện tại. (P4
gửi thông điệp không yêu cầu bầu cử, vì nó là tiến trình với số ưu tiên cao nhất trong hệ
thống.)
- Nếu tiến trình P, phát hiện bộ điều phối gặp lỗi, nó tạo ra một danh sách hoạt động mới
trống rỗng. Sau đó nó sẽ gửi một tin nhắn elect (i) tới hàng xóm của mình bên phải và cho
thêm số i vào danh sách hoạt động của nó.
- Nếu Pi nhận được một tin nhắn elect (j) từ tiến trình bên trái, nó đáp ứng bằng một trong ba
cách:
a. Nếu đây là thông điệp elect đầu tiên nó nhìn thấy hoặc gửi, Pi tạo ra một
danh sách hoạt động mới với số i và j. Nó sau đó gửi tin nhắn elect (i),
sau đó là tin nhắn elect (j).
b. Nếu i <> j, tức là tin nhắn nhận được không chứa số của Pi, sau đó Pi thêm j vào danh sách
hoạt động của nó và chuyển tiếp tin nhắn cho hàng xóm bên phải của nó.
c. Nếu i = j-có nghĩa là, nếu Pi nhận được tin nhắn elect (i), danh sách hoạt động của Pi giờ
chứa các con số của tất cả các tiến trình hoạt động trong hệ thống. Tiến trình Pi bây giờ có thể
xác định số lớn nhất trong danh sách hoạt động để xác định Tiến trình điều phối mới.
Thuật toán này không xác định làm thế nào một tiến trình đang phục hồi xác định
số của tiến trình điều phối hiện tại. Một giải pháp đòi hỏi tiến trình đang phục hồi
để gửi một thông điệp yêu cầu. Thông điệp này được chuyển quanh vòng tới
điều phối viên hiện tại, và được gửi trả lại thông điệp có chứa số hiệu của nó.