"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Tôi khuyên bạn nên đọc bản ghi của bài giảng "Hadoop. ZooKeeper" từ loạt bài "Các phương pháp xử lý phân tán khối lượng lớn dữ liệu trong Hadoop"

ZooKeeper là gì, vị trí của nó trong hệ sinh thái Hadoop. Sự thật về điện toán phân tán Sơ đồ hệ thống phân tán chuẩn. Khó khăn trong việc phối hợp các hệ thống phân tán. Vấn đề phối hợp điển hình. Các nguyên tắc đằng sau thiết kế của ZooKeeper. Mô hình dữ liệu ZooKeeper. cờ znode. Phiên. API khách hàng. Nguyên thủy (cấu hình, thành viên nhóm, khóa đơn giản, bầu cử lãnh đạo, khóa không có hiệu ứng bầy đàn). Kiến trúc ZooKeeper. Cơ sở dữ liệu của ZooKeeper. ZAB. Yêu cầu xử lý.

Chơi video

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Hôm nay chúng ta sẽ nói về ZooKeeper. Điều này rất hữu ích. Nó, giống như bất kỳ sản phẩm Apache Hadoop nào, đều có logo. Nó mô tả một người đàn ông.

Trước đó, chúng ta chủ yếu nói về cách dữ liệu có thể được xử lý ở đó, cách lưu trữ dữ liệu, tức là cách sử dụng và làm việc với nó bằng cách nào đó. Và hôm nay tôi muốn nói một chút về việc xây dựng các ứng dụng phân tán. Và ZooKeeper là một trong những thứ cho phép bạn đơn giản hóa vấn đề này. Đây là một loại dịch vụ nhằm mục đích phối hợp tương tác giữa các quy trình trong hệ thống phân tán, trong các ứng dụng phân tán.

Nhu cầu về những ứng dụng như vậy ngày càng trở nên nhiều hơn, đó chính là nội dung khóa học của chúng tôi. Một mặt, MapReduce và khung làm sẵn này cho phép bạn giảm mức độ phức tạp này và giải phóng lập trình viên khỏi việc viết những thứ nguyên thủy như tương tác và phối hợp các quy trình. Nhưng mặt khác, không ai đảm bảo rằng điều này sẽ không phải được thực hiện. MapReduce hoặc các khung làm sẵn khác không phải lúc nào cũng thay thế hoàn toàn một số trường hợp không thể triển khai bằng cách sử dụng khung này. Bao gồm cả MapReduce và một loạt các dự án Apache khác; trên thực tế, chúng cũng là các ứng dụng phân tán. Và để viết dễ dàng hơn, họ đã viết ZooKeeper.

Giống như tất cả các ứng dụng liên quan đến Hadoop, nó được phát triển bởi Yahoo! Bây giờ nó cũng là một ứng dụng Apache chính thức. Nó không được phát triển tích cực như HBase. Nếu bạn vào JIRA HBase, thì hàng ngày sẽ có hàng loạt báo cáo lỗi, hàng loạt đề xuất để tối ưu hóa thứ gì đó, tức là cuộc sống trong dự án liên tục diễn ra. Và ZooKeeper một mặt là một sản phẩm tương đối đơn giản, mặt khác, điều này đảm bảo độ tin cậy của nó. Và nó khá dễ sử dụng, đó là lý do tại sao nó đã trở thành một tiêu chuẩn trong các ứng dụng trong hệ sinh thái Hadoop. Vì vậy, tôi nghĩ sẽ rất hữu ích nếu xem lại nó để hiểu cách thức hoạt động và cách sử dụng nó.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Đây là hình ảnh từ một bài giảng nào đó của chúng tôi. Chúng ta có thể nói rằng nó trực giao với mọi thứ mà chúng ta đã xem xét cho đến nay. Và mọi thứ được chỉ ra ở đây, ở mức độ này hay mức độ khác, đều hoạt động với ZooKeeper, tức là đây là một dịch vụ sử dụng tất cả các sản phẩm này. Cả HDFS và MapReduce đều không viết các dịch vụ tương tự của riêng họ để hoạt động cụ thể cho họ. Theo đó, ZooKeeper được sử dụng. Và điều này giúp đơn giản hóa việc phát triển và một số thứ liên quan đến lỗi.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Tất cả những điều này đến từ đâu? Có vẻ như chúng tôi đã khởi chạy song song hai ứng dụng trên các máy tính khác nhau, kết nối chúng bằng một chuỗi hoặc dạng lưới và mọi thứ đều hoạt động. Nhưng vấn đề là Mạng không đáng tin cậy và nếu bạn đánh hơi được lưu lượng truy cập hoặc xem xét những gì đang xảy ra ở đó ở mức độ thấp, cách khách hàng tương tác trên Mạng, bạn thường có thể thấy rằng một số gói bị mất hoặc được gửi lại. Không phải vô cớ mà các giao thức TCP đã được phát minh, cho phép bạn thiết lập một phiên nhất định và đảm bảo việc gửi tin nhắn. Nhưng trong mọi trường hợp, ngay cả TCP cũng không phải lúc nào cũng có thể cứu được bạn. Mọi thứ đều có thời gian chờ. Mạng có thể bị ngắt trong một thời gian. Nó có thể chỉ nhấp nháy. Và tất cả điều này dẫn đến thực tế là bạn không thể tin tưởng vào Mạng là đáng tin cậy. Đây là điểm khác biệt chính so với việc viết các ứng dụng song song chạy trên một máy tính hoặc trên một siêu máy tính, nơi không có Mạng, nơi có bus trao đổi dữ liệu đáng tin cậy hơn trong bộ nhớ. Và đây là sự khác biệt cơ bản.

Ngoài ra, khi sử dụng Mạng luôn có độ trễ nhất định. Đĩa cũng có, nhưng Mạng có nhiều hơn. Độ trễ là một khoảng thời gian trễ, có thể nhỏ hoặc khá đáng kể.

Cấu trúc liên kết mạng đang thay đổi. Cấu trúc liên kết là gì - đây là vị trí đặt thiết bị mạng của chúng tôi. Có trung tâm dữ liệu, có giá đỡ đứng đó, có nến. Tất cả điều này có thể được kết nối lại, di chuyển, v.v. Tất cả điều này cũng cần phải được tính đến. Tên IP thay đổi, định tuyến mà lưu lượng truy cập của chúng tôi di chuyển cũng thay đổi. Điều này cũng cần phải được tính đến.

Mạng cũng có thể thay đổi về mặt thiết bị. Từ thực tế, tôi có thể nói rằng các kỹ sư mạng của chúng tôi thực sự muốn cập nhật định kỳ nội dung nào đó về nến. Đột nhiên một chương trình cơ sở mới xuất hiện và họ không đặc biệt quan tâm đến cụm Hadoop nào đó. Họ có công việc riêng của họ. Đối với họ, điều chính là Mạng hoạt động. Theo đó, họ muốn tải lại nội dung nào đó lên đó, flash trên phần cứng của họ và phần cứng cũng thay đổi định kỳ. Tất cả điều này bằng cách nào đó cần phải được tính đến. Tất cả điều này ảnh hưởng đến ứng dụng phân tán của chúng tôi.

Thông thường những người bắt đầu làm việc với lượng lớn dữ liệu vì lý do nào đó đều tin rằng Internet là vô hạn. Nếu có một tệp có dung lượng vài terabyte ở đó, thì bạn có thể đưa nó đến máy chủ hoặc máy tính của mình và mở nó bằng cách sử dụng làm sao và xem. Một lỗi khác là ở Khí lực nhìn vào nhật ký. Đừng bao giờ làm điều này vì nó xấu. Bởi vì Vim cố gắng đệm mọi thứ, tải mọi thứ vào bộ nhớ, đặc biệt là khi chúng ta bắt đầu di chuyển qua nhật ký này và tìm kiếm thứ gì đó. Đây là những điều bị lãng quên nhưng đáng để xem xét.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Việc viết một chương trình chạy trên một máy tính với một bộ xử lý sẽ dễ dàng hơn.

Khi hệ thống của chúng tôi phát triển, chúng tôi muốn song song hóa tất cả và song song hóa nó không chỉ trên máy tính mà còn trên một cụm. Câu hỏi được đặt ra: phối hợp vấn đề này như thế nào? Các ứng dụng của chúng tôi thậm chí có thể không tương tác với nhau nhưng chúng tôi đã chạy song song một số quy trình trên một số máy chủ. Và làm thế nào để theo dõi rằng mọi thứ đang diễn ra tốt đẹp với họ? Ví dụ, họ gửi thứ gì đó qua Internet. Họ phải viết về trạng thái của mình ở đâu đó, chẳng hạn như trong một loại cơ sở dữ liệu hoặc nhật ký nào đó, sau đó tổng hợp nhật ký này và sau đó phân tích nó ở đâu đó. Ngoài ra, chúng ta cần tính đến việc quá trình đang hoạt động và đang hoạt động thì đột nhiên xuất hiện một số lỗi hoặc bị lỗi, vậy chúng ta sẽ phát hiện ra nó nhanh chóng như thế nào?

Rõ ràng là tất cả điều này có thể được theo dõi nhanh chóng. Điều này cũng tốt, nhưng việc giám sát là một điều hạn chế cho phép bạn giám sát một số thứ ở mức cao nhất.

Khi chúng ta muốn các quy trình của mình bắt đầu tương tác với nhau, chẳng hạn như gửi cho nhau một số dữ liệu, thì câu hỏi cũng được đặt ra - điều này sẽ xảy ra như thế nào? Liệu sẽ có một số loại điều kiện chủng tộc nào đó, chúng có ghi đè lên nhau không, dữ liệu có đến chính xác không, có điều gì bị mất trong quá trình thực hiện không? Chúng ta cần phát triển một số loại giao thức, v.v.

Việc phối hợp tất cả các quá trình này không phải là chuyện tầm thường. Và nó buộc nhà phát triển phải xuống cấp độ thấp hơn nữa và viết hệ thống từ đầu hoặc không hoàn toàn từ đầu, nhưng điều này không đơn giản như vậy.

Nếu bạn nghĩ ra một thuật toán mã hóa hoặc thậm chí triển khai nó thì hãy vứt nó đi ngay lập tức, vì rất có thể nó sẽ không hiệu quả với bạn. Rất có thể nó sẽ chứa một loạt lỗi mà bạn đã quên cung cấp. Không bao giờ sử dụng nó cho bất cứ điều gì nghiêm trọng vì rất có thể nó sẽ không ổn định. Bởi vì tất cả các thuật toán tồn tại đều đã được thời gian thử nghiệm trong một thời gian rất dài. Nó bị cộng đồng làm phiền. Đây là một chủ đề riêng biệt. Và ở đây cũng vậy. Nếu không thể tự mình thực hiện một số loại đồng bộ hóa quy trình thì tốt hơn là không nên làm điều này, vì nó khá phức tạp và dẫn bạn đến con đường không ổn định là liên tục tìm kiếm lỗi.

Hôm nay chúng ta đang nói về ZooKeeper. Một mặt, nó là một khuôn khổ, mặt khác, nó là một dịch vụ giúp cuộc sống của nhà phát triển trở nên dễ dàng hơn và đơn giản hóa việc triển khai logic cũng như điều phối các quy trình của chúng tôi nhiều nhất có thể.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Hãy nhớ lại một hệ thống phân tán tiêu chuẩn trông như thế nào. Đây là những gì chúng ta đã nói đến - HDFS, HBase. Có một quy trình Master quản lý các quy trình công nhân và nô lệ. Anh ta chịu trách nhiệm điều phối và phân phối nhiệm vụ, khởi động lại công nhân, khởi chạy nhiệm vụ mới và phân phối tải.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Một thứ cao cấp hơn là Dịch vụ Điều phối, tức là chuyển bản thân nhiệm vụ điều phối sang một quy trình riêng biệt, đồng thời chạy song song một số loại Master dự phòng hoặc stanby, vì Master có thể bị lỗi. Và nếu Master ngã xuống, thì hệ thống của chúng tôi sẽ không hoạt động. Chúng tôi đang chạy sao lưu. Một số trạng thái cho rằng Master cần được sao chép để sao lưu. Việc này cũng có thể được giao cho Cơ quan Điều phối. Nhưng trong sơ đồ này, chính Master chịu trách nhiệm điều phối các công nhân, ở đây dịch vụ là điều phối các hoạt động sao chép dữ liệu.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Một tùy chọn nâng cao hơn là khi mọi hoạt động phối hợp đều do dịch vụ của chúng tôi xử lý, như thường lệ. Anh ấy chịu trách nhiệm đảm bảo mọi thứ hoạt động. Và nếu điều gì đó không ổn, chúng tôi sẽ tìm hiểu về nó và cố gắng giải quyết tình huống này. Trong mọi trường hợp, chúng ta chỉ còn lại một Master, người bằng cách nào đó tương tác với nô lệ và có thể gửi dữ liệu, thông tin, tin nhắn, v.v. thông qua một số dịch vụ.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Có một sơ đồ thậm chí còn tiên tiến hơn, khi chúng ta không có Master, tất cả các nút đều là nô lệ chính, khác nhau về hành vi. Nhưng chúng vẫn cần tương tác với nhau nên vẫn còn một số dịch vụ để điều phối các hành động này. Có lẽ Cassandra, hoạt động theo nguyên tắc này, phù hợp với sơ đồ này.

Thật khó để nói kế hoạch nào trong số này hoạt động tốt hơn. Mỗi cái đều có ưu và nhược điểm riêng.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Và không cần phải sợ một số điều với Master, bởi vì, như thực tế cho thấy, anh ta không dễ bị phục vụ liên tục. Điều chính ở đây là chọn giải pháp phù hợp để lưu trữ dịch vụ này trên một nút mạnh mẽ riêng biệt, sao cho nó có đủ tài nguyên, để nếu có thể, người dùng không có quyền truy cập vào đó để họ không vô tình giết chết quá trình này. Nhưng đồng thời, trong sơ đồ như vậy, việc quản lý công nhân từ quy trình Chính sẽ dễ dàng hơn nhiều, tức là sơ đồ này đơn giản hơn về mặt thực hiện.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Và sơ đồ này (ở trên) có lẽ phức tạp hơn nhưng đáng tin cậy hơn.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Vấn đề chính là lỗi một phần. Ví dụ: khi chúng tôi gửi tin nhắn qua Mạng, một số loại tai nạn đã xảy ra và người gửi tin nhắn sẽ không biết liệu tin nhắn của mình đã được nhận hay chưa và điều gì đã xảy ra từ phía người nhận, sẽ không biết liệu tin nhắn có được xử lý chính xác hay không. , tức là anh ta sẽ không nhận được bất kỳ xác nhận nào.

Theo đó, chúng ta phải xử lý tình huống này. Và việc đơn giản nhất là gửi lại tin nhắn này và đợi cho đến khi chúng ta nhận được phản hồi. Trong trường hợp này, trạng thái của máy thu có thay đổi hay không không được tính đến. Chúng tôi có thể gửi tin nhắn và thêm cùng một dữ liệu hai lần.

ZooKeeper đưa ra các cách để giải quyết những lời từ chối như vậy, điều này cũng giúp cuộc sống của chúng ta dễ dàng hơn.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Như đã đề cập trước đó một chút, điều này tương tự như việc viết các chương trình đa luồng, nhưng điểm khác biệt chính là trong các ứng dụng phân tán mà chúng ta xây dựng trên các máy khác nhau, cách duy nhất để giao tiếp là Mạng. Về cơ bản, đây là một kiến ​​trúc không chia sẻ gì cả. Mỗi quy trình hoặc dịch vụ chạy trên một máy đều có bộ nhớ riêng, đĩa riêng, bộ xử lý riêng và không chia sẻ với bất kỳ ai.

Nếu chúng ta viết một chương trình đa luồng trên một máy tính thì chúng ta có thể sử dụng bộ nhớ dùng chung để trao đổi dữ liệu. Chúng tôi có một chuyển đổi ngữ cảnh ở đó, các quy trình có thể chuyển đổi. Điều này ảnh hưởng đến hiệu suất. Một mặt, không có thứ đó trong chương trình trên một cụm, nhưng có vấn đề với Mạng.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Theo đó, vấn đề chính nảy sinh khi viết hệ thống phân tán là cấu hình. Chúng tôi đang viết một số loại ứng dụng. Nếu nó đơn giản thì chúng ta mã hóa cứng tất cả các loại số trong mã, nhưng điều này thật bất tiện, vì nếu chúng ta quyết định rằng thay vì thời gian chờ là nửa giây, chúng ta muốn thời gian chờ là một giây thì chúng ta cần phải biên dịch lại ứng dụng và cuộn lại mọi thứ một lần nữa. Đó là một chuyện khi nó ở trên một máy, bạn có thể khởi động lại nó, nhưng khi chúng ta có nhiều máy, chúng ta phải liên tục sao chép mọi thứ. Chúng ta phải cố gắng làm cho ứng dụng có thể cấu hình được.

Ở đây chúng ta đang nói về cấu hình tĩnh cho các tiến trình hệ thống. Điều này không hoàn toàn, có thể theo quan điểm của hệ điều hành, nó có thể là một cấu hình tĩnh cho các quy trình của chúng tôi, tức là đây là một cấu hình không thể đơn giản lấy và cập nhật.

Ngoài ra còn có một cấu hình động. Đây là những thông số mà chúng tôi muốn thay đổi nhanh chóng để chúng được chọn ở đó.

Vấn đề ở đây là gì? Chúng tôi đã cập nhật cấu hình, triển khai nó, vậy thì sao? Vấn đề có thể là một mặt chúng ta tung ra config nhưng quên mất cái mới, config vẫn ở đó. Thứ hai, trong khi chúng tôi triển khai, cấu hình đã được cập nhật ở một số nơi nhưng không được cập nhật ở những nơi khác. Và một số quy trình ứng dụng của chúng tôi chạy trên một máy đã được khởi động lại bằng cấu hình mới và ở đâu đó có cấu hình cũ. Điều này có thể dẫn đến ứng dụng phân tán của chúng tôi không nhất quán từ góc độ cấu hình. Vấn đề này là phổ biến. Đối với cấu hình động, nó phù hợp hơn vì nó ngụ ý rằng nó có thể được thay đổi nhanh chóng.

Một vấn đề khác là thành viên nhóm. Chúng tôi luôn có một số nhóm công nhân, chúng tôi luôn muốn biết ai còn sống, ai đã chết. Nếu có Master thì anh ta phải hiểu những công nhân nào có thể được chuyển hướng đến khách hàng để họ chạy tính toán hoặc làm việc với dữ liệu, còn công nhân nào thì không. Một vấn đề liên tục nảy sinh là chúng ta cần biết ai đang làm việc trong cụm của mình.

Một vấn đề điển hình khác là bầu cử lãnh đạo, khi chúng ta muốn biết ai là người chịu trách nhiệm. Một ví dụ là sao chép, khi chúng ta có một số quy trình nhận các thao tác ghi và sau đó sao chép chúng giữa các quy trình khác. Anh ta sẽ là người lãnh đạo, mọi người khác sẽ tuân theo anh ta, sẽ đi theo anh ta. Cần phải lựa chọn quy trình sao cho rõ ràng đối với mọi người, để không chọn được hai người lãnh đạo.

Ngoài ra còn có quyền truy cập loại trừ lẫn nhau. Vấn đề ở đây phức tạp hơn. Có một thứ gọi là mutex, khi bạn viết các chương trình đa luồng và muốn truy cập vào một số tài nguyên, chẳng hạn như ô nhớ, bị giới hạn và thực hiện chỉ bởi một luồng. Ở đây tài nguyên có thể là thứ gì đó trừu tượng hơn. Và các ứng dụng khác nhau từ các nút khác nhau trong Mạng của chúng tôi chỉ được nhận quyền truy cập độc quyền vào một tài nguyên nhất định chứ không phải để mọi người có thể thay đổi tài nguyên đó hoặc viết nội dung nào đó vào đó. Đây là cái gọi là ổ khóa.

ZooKeeper cho phép bạn giải quyết tất cả những vấn đề này ở mức độ này hay mức độ khác. Và tôi sẽ chỉ ra các ví dụ về cách nó cho phép bạn làm điều này.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Không có nguyên thủy chặn. Khi chúng ta bắt đầu sử dụng một cái gì đó, nguyên thủy này sẽ không đợi bất kỳ sự kiện nào xảy ra. Rất có thể, thứ này sẽ hoạt động không đồng bộ, do đó cho phép các tiến trình không bị treo trong khi chúng đang chờ đợi thứ gì đó. Đây là một điều rất hữu ích.

Tất cả các yêu cầu của khách hàng được xử lý theo thứ tự của hàng đợi chung.

Và khách hàng có cơ hội nhận được thông báo về những thay đổi ở một số trạng thái, về những thay đổi trong dữ liệu, trước khi khách hàng tự nhìn thấy dữ liệu đã thay đổi.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

ZooKeeper có thể hoạt động ở hai chế độ. Chế độ đầu tiên là hoạt động độc lập, trên một nút duy nhất. Điều này thuận tiện cho việc thử nghiệm. Nó cũng có thể hoạt động ở chế độ cụm, trên bất kỳ số lượng nút nào. may chủNếu chúng ta có một cụm 100 máy, nó không nhất thiết phải chạy trên 100 máy. Chỉ cần phân bổ một vài máy để ZooKeeper hoạt động là đủ. Và nó tuân thủ nguyên tắc tính khả dụng cao. ZooKeeper lưu trữ một bản sao hoàn chỉnh của dữ liệu trên mỗi phiên bản đang chạy. Tôi sẽ giải thích cách nó thực hiện điều này sau. Nó không phân mảnh hay phân vùng dữ liệu. Một mặt, đây là một nhược điểm vì chúng ta không thể lưu trữ nhiều, nhưng mặt khác, điều đó không cần thiết. Nó không được thiết kế cho mục đích đó; nó không phải là một cơ sở dữ liệu.

Dữ liệu có thể được lưu trữ ở phía máy khách. Đây là nguyên tắc tiêu chuẩn để chúng tôi không làm gián đoạn dịch vụ và không tải nó với những yêu cầu tương tự. Một khách hàng thông minh thường biết về điều này và lưu trữ nó.

Ví dụ, có điều gì đó đã thay đổi ở đây. Có một số loại ứng dụng. Một người lãnh đạo mới đã được bầu, người chịu trách nhiệm xử lý các hoạt động ghi chẳng hạn. Và chúng tôi muốn sao chép dữ liệu. Một giải pháp là đặt nó vào một vòng lặp. Và chúng tôi liên tục đặt câu hỏi về dịch vụ của mình - có điều gì thay đổi không? Tùy chọn thứ hai là tối ưu hơn. Đây là cơ chế theo dõi cho phép bạn thông báo cho khách hàng rằng có điều gì đó đã thay đổi. Đây là phương pháp ít tốn kém hơn về nguồn lực và thuận tiện hơn cho khách hàng.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Khách hàng là người dùng sử dụng ZooKeeper.

Máy chủ chính là quy trình ZooKeeper.

Znode là điều quan trọng trong ZooKeeper. Tất cả các znode được ZooKeeper lưu trữ trong bộ nhớ và được tổ chức dưới dạng sơ đồ phân cấp, dưới dạng cây.

Có hai loại hoạt động. Đầu tiên là cập nhật/ghi, khi một số thao tác thay đổi trạng thái của cây của chúng ta. Cây là phổ biến.

Và có thể máy khách không hoàn thành một yêu cầu và bị ngắt kết nối, nhưng có thể thiết lập một phiên để nó tương tác với ZooKeeper.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Mô hình dữ liệu của ZooKeeper giống với một hệ thống tệp. Có một thư mục gốc tiêu chuẩn và sau đó chúng tôi đi qua các thư mục đi từ thư mục gốc. Và sau đó là danh mục cấp một, cấp hai. Đây là tất cả các znode.

Mỗi znode có thể lưu trữ một số dữ liệu, thường không lớn lắm, chẳng hạn như 10 kilobyte. Và mỗi znode có thể có một số lượng con nhất định.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Znode có nhiều loại. Chúng có thể được tạo ra. Và khi tạo một znode, chúng tôi chỉ định loại mà nó thuộc về.

Có hai loại. Đầu tiên là lá cờ phù du. Znode tồn tại trong một phiên. Ví dụ: khách hàng đã thiết lập một phiên. Và miễn là phiên này còn tồn tại thì nó sẽ tồn tại. Điều này là cần thiết để không tạo ra thứ gì đó không cần thiết. Điều này cũng phù hợp với những thời điểm quan trọng đối với chúng ta là lưu trữ dữ liệu gốc trong một phiên.

Loại thứ hai là cờ tuần tự. Nó tăng bộ đếm trên đường tới znode. Ví dụ: chúng tôi có một thư mục chứa ứng dụng 1_5. Và khi chúng tôi tạo nút đầu tiên, nó nhận được p_1, nút thứ hai - p_2. Và khi chúng tôi gọi phương thức này mỗi lần, chúng tôi chuyển toàn bộ đường dẫn, chỉ cho biết một phần của đường dẫn và con số này sẽ tự động tăng lên vì chúng tôi chỉ ra loại nút - tuần tự.

Znode thông thường. Cô ấy sẽ luôn sống và có cái tên mà chúng tôi nói với cô ấy.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Một điều hữu ích khác là cờ canh gác. Nếu chúng tôi cài đặt nó, thì máy khách có thể đăng ký một số sự kiện cho một nút cụ thể. Sau này tôi sẽ chỉ cho bạn một ví dụ về cách thực hiện việc này. ZooKeeper tự thông báo cho khách hàng rằng dữ liệu trên nút đã thay đổi. Tuy nhiên, thông báo không đảm bảo rằng một số dữ liệu mới đã đến. Họ chỉ nói rằng có gì đó đã thay đổi nên bạn vẫn phải so sánh dữ liệu sau này với các cuộc gọi riêng biệt.

Và như tôi đã nói, thứ tự của dữ liệu được xác định theo kilobyte. Không cần phải lưu trữ dữ liệu văn bản lớn ở đó vì nó không phải là cơ sở dữ liệu, nó là một máy chủ điều phối hành động.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Tôi xin nói thêm một chút về các phiên làm việc. Nếu chúng ta có nhiều máy chủ, chúng ta có thể chuyển đổi liền mạch giữa các máy chủ. người phục vụSử dụng ID phiên. Điều này khá tiện lợi.

Mỗi phiên có một số loại thời gian chờ. Một phiên được xác định bằng việc máy khách có gửi bất cứ thứ gì đến máy chủ trong phiên đó hay không. Nếu anh ta không truyền bất cứ thứ gì trong thời gian chờ, phiên sẽ bị ngắt hoặc khách hàng có thể tự đóng phiên đó.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Nó không có nhiều tính năng nhưng bạn có thể làm những việc khác nhau với API này. Lệnh gọi mà chúng ta đã thấy tạo sẽ tạo một znode và nhận ba tham số. Đây là đường dẫn đến znode và nó phải được chỉ định đầy đủ từ gốc. Và đây cũng là một số dữ liệu mà chúng tôi muốn chuyển đến đó. Và loại cờ. Và sau khi tạo, nó trả về đường dẫn đến znode.

Thứ hai, bạn có thể xóa nó. Thủ thuật ở đây là tham số thứ hai, ngoài đường dẫn đến znode, có thể chỉ định phiên bản. Theo đó, znode đó sẽ bị xóa nếu phiên bản mà chúng tôi chuyển giao tương đương với phiên bản thực sự tồn tại.

Nếu chúng tôi không muốn kiểm tra phiên bản này thì chúng tôi chỉ cần chuyển đối số "-1".

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Thứ ba, nó kiểm tra sự tồn tại của znode. Trả về true nếu nút tồn tại, ngược lại là false.

Và sau đó đồng hồ gắn cờ xuất hiện, cho phép bạn giám sát nút này.

Bạn có thể đặt cờ này ngay cả trên nút không tồn tại và nhận được thông báo khi nó xuất hiện. Điều này cũng có thể hữu ích.

Một vài thử thách nữa là lấy dữ liệu. Rõ ràng là chúng ta có thể nhận dữ liệu qua znode. Bạn cũng có thể sử dụng đồng hồ cờ. Trong trường hợp này, nó sẽ không cài đặt nếu không có nút. Do đó, bạn cần hiểu rằng nó tồn tại và sau đó nhận dữ liệu.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Ngoài ra còn có SetData. Ở đây chúng tôi chuyển phiên bản. Và nếu chúng tôi chuyển thông tin này, dữ liệu trên znode của một phiên bản nhất định sẽ được cập nhật.

Bạn cũng có thể chỉ định "-1" để loại trừ kiểm tra này.

Một phương pháp hữu ích khác là có được trẻ em. Chúng ta cũng có thể nhận được danh sách tất cả các znode thuộc về nó. Chúng ta có thể theo dõi điều này bằng cách đặt cờ theo dõi.

Và phương pháp đồng bộ cho phép tất cả các thay đổi được gửi cùng một lúc, từ đó đảm bảo rằng chúng được lưu và tất cả dữ liệu đã được thay đổi hoàn toàn.

Nếu chúng ta so sánh với lập trình thông thường, thì khi bạn sử dụng các phương pháp như ghi, ghi nội dung nào đó vào đĩa và sau khi nó trả về phản hồi cho bạn, không có gì đảm bảo rằng bạn đã ghi dữ liệu vào đĩa. Và ngay cả khi hệ điều hành tự tin rằng mọi thứ đã được ghi, vẫn có các cơ chế trong chính đĩa nơi quá trình này đi qua các lớp bộ đệm và chỉ sau đó dữ liệu mới được đặt vào đĩa.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Hầu hết các cuộc gọi không đồng bộ được sử dụng. Điều này cho phép khách hàng làm việc song song với các yêu cầu khác nhau. Bạn có thể sử dụng phương pháp đồng bộ, nhưng nó kém hiệu quả hơn.

Hai thao tác chúng ta đã nói đến là cập nhật/ghi, thay đổi dữ liệu. Đó là tạo, setData, đồng bộ hóa, xóa. Và đọc tồn tại, getData, getChildren.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Bây giờ là một số ví dụ về cách bạn có thể tạo các nguyên mẫu để làm việc trong hệ thống phân tán. Ví dụ, liên quan đến cấu hình của một cái gì đó. Một công nhân mới đã xuất hiện. Chúng tôi đã thêm máy và bắt đầu quá trình. Và có ba câu hỏi sau đây. Nó truy vấn cấu hình ZooKeeper như thế nào? Và nếu muốn thay đổi cấu hình thì chúng ta thay đổi như thế nào? Và sau khi chúng tôi thay đổi nó, làm thế nào mà những công nhân mà chúng tôi đã có được nó?

ZooKeeper thực hiện việc này tương đối dễ dàng. Ví dụ: có cây znode của chúng tôi. Có một nút cho ứng dụng của chúng tôi ở đây, chúng tôi tạo một nút bổ sung trong đó chứa dữ liệu từ cấu hình. Đây có thể hoặc không thể là các tham số riêng biệt. Vì kích thước nhỏ nên kích thước cấu hình thường cũng nhỏ nên hoàn toàn có thể lưu trữ ở đây.

Bạn đang sử dụng phương pháp lấy dữ liệu để lấy cấu hình cho nhân viên từ nút. Đặt thành đúng. Nếu vì lý do nào đó nút này không tồn tại, chúng tôi sẽ được thông báo về nó khi nó xuất hiện hoặc khi nó thay đổi. Nếu chúng ta muốn biết điều gì đó đã thay đổi thì chúng ta đặt nó thành true. Và nếu dữ liệu trong nút này thay đổi thì chúng ta sẽ biết về nó.

SetData. Chúng tôi đặt dữ liệu, đặt “-1”, tức là chúng tôi không kiểm tra phiên bản, chúng tôi cho rằng chúng tôi luôn có một cấu hình, chúng tôi không cần lưu trữ nhiều cấu hình. Nếu bạn cần lưu trữ nhiều, bạn sẽ cần thêm một cấp độ khác. Ở đây chúng tôi cho rằng chỉ có một nên chỉ cập nhật bản mới nhất nên không kiểm tra phiên bản. Tại thời điểm này, tất cả khách hàng đã đăng ký trước đó sẽ nhận được thông báo rằng có gì đó đã thay đổi trong nút này. Và sau khi nhận được, họ cũng phải yêu cầu lại dữ liệu. Thông báo là họ không nhận được dữ liệu mà chỉ nhận được thông báo về những thay đổi. Sau đó họ phải yêu cầu dữ liệu mới.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Tùy chọn thứ hai để sử dụng nguyên thủy là thành viên nhóm. Chúng tôi có một ứng dụng phân tán, có rất nhiều công nhân và chúng tôi muốn hiểu rằng tất cả họ đều sẵn sàng. Vì vậy, họ phải tự đăng ký rằng họ làm việc trong ứng dụng của chúng tôi. Và chúng tôi cũng muốn tìm hiểu, từ quy trình Chính hoặc ở một nơi nào khác, về tất cả những người lao động đang hoạt động mà chúng tôi hiện có.

Chung ta se lam như thê nao? Đối với ứng dụng, chúng tôi tạo nút công nhân và thêm cấp độ con vào đó bằng phương thức tạo. Tôi có một lỗi trên slide. Ở đây bạn cần tuần tự chỉ định thì tất cả các công nhân sẽ được tạo lần lượt. Và ứng dụng yêu cầu tất cả dữ liệu về nút con của nút này sẽ nhận được tất cả các nhân viên đang hoạt động tồn tại.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Đây là một triển khai khủng khiếp về cách thực hiện điều này trong mã Java. Hãy bắt đầu từ cuối, với phương pháp chính. Đây là lớp của chúng ta, hãy tạo phương thức của nó. Là đối số đầu tiên, chúng tôi sử dụng máy chủ, nơi chúng tôi đang kết nối, tức là chúng tôi đặt nó làm đối số. Và đối số thứ hai là tên của nhóm.

Kết nối diễn ra như thế nào? Đây là một ví dụ đơn giản về API được sử dụng. Mọi thứ ở đây tương đối đơn giản. Có một lớp ZooKeeper tiêu chuẩn. Chúng tôi chuyển máy chủ cho nó. Và đặt thời gian chờ, ví dụ: thành 5 giây. Và chúng tôi có một thành viên tên là connectSignal. Về cơ bản, chúng tôi tạo một nhóm dọc theo đường truyền. Chúng tôi không ghi dữ liệu ở đó, mặc dù điều gì đó có thể đã được viết. Và nút ở đây thuộc loại liên tục. Về cơ bản, đây là một nút thông thường sẽ tồn tại mọi lúc. Đây là nơi phiên được tạo. Đây là việc thực hiện của chính khách hàng. Khách hàng của chúng tôi sẽ gửi tin nhắn định kỳ cho biết phiên vẫn còn hoạt động. Và khi chúng ta kết thúc session, chúng ta gọi close và thế là xong, session sẽ kết thúc. Đây là trường hợp có điều gì đó xảy ra với chúng tôi, để ZooKeeper phát hiện ra điều đó và cắt phiên.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Làm thế nào để khóa một tài nguyên? Ở đây mọi thứ phức tạp hơn một chút. Chúng tôi có một nhóm công nhân, có một số tài nguyên mà chúng tôi muốn khóa. Để làm điều này, chúng tôi tạo một nút riêng biệt, ví dụ, được gọi là lock1. Nếu chúng ta có thể tạo ra nó thì chúng ta đã có một chiếc khóa ở đây. Và nếu chúng tôi không thể tạo nó, thì nhân viên sẽ cố gắng lấy getData từ đây và vì nút đã được tạo nên chúng tôi đặt một trình theo dõi ở đây và thời điểm trạng thái của nút này thay đổi, chúng tôi sẽ biết về nó. Và chúng ta có thể cố gắng có thời gian để tạo lại nó. Nếu chúng ta lấy nút này, lấy khóa này thì sau khi không cần khóa nữa, chúng ta sẽ bỏ nó, vì nút đó chỉ tồn tại trong phiên. Theo đó, nó sẽ biến mất. Và một khách hàng khác, trong khuôn khổ một phiên khác, sẽ có thể khóa nút này, hay đúng hơn, anh ta sẽ nhận được thông báo rằng có điều gì đó đã thay đổi và anh ta có thể cố gắng thực hiện kịp thời.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Một ví dụ khác về cách bạn có thể chọn người lãnh đạo chính. Điều này phức tạp hơn một chút, nhưng cũng tương đối đơn giản. Những gì đang xảy ra ở đây? Có một nút chính tổng hợp tất cả các công nhân. Chúng tôi đang cố gắng lấy dữ liệu về người lãnh đạo. Nếu điều này xảy ra thành công, tức là chúng tôi nhận được một số dữ liệu, thì nhân viên của chúng tôi bắt đầu đi theo người lãnh đạo này. Anh ấy tin rằng đã có người lãnh đạo.

Nếu người lãnh đạo chết vì lý do nào đó, chẳng hạn như bị ngã, thì chúng tôi sẽ cố gắng tạo ra một người lãnh đạo mới. Và nếu chúng tôi thành công thì công nhân của chúng tôi sẽ trở thành người lãnh đạo. Và nếu ai đó tại thời điểm này đã tạo ra được một người lãnh đạo mới, thì chúng ta hãy cố gắng tìm hiểu xem đó là ai và sau đó đi theo anh ta.

Ở đây nảy sinh cái gọi là hiệu ứng bầy đàn, tức là hiệu ứng bầy đàn, vì khi một người lãnh đạo qua đời thì người đến trước sẽ trở thành người lãnh đạo.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Khi thu thập tài nguyên, bạn có thể thử sử dụng một cách tiếp cận hơi khác như sau. Ví dụ: chúng ta muốn có một chiếc khóa nhưng không có hiệu ứng hert. Nó sẽ bao gồm thực tế là ứng dụng của chúng tôi yêu cầu danh sách tất cả các id nút cho một nút đã tồn tại có khóa. Và nếu trước đó nút mà chúng tôi đã tạo khóa là nút nhỏ nhất trong tập hợp mà chúng tôi nhận được, thì điều này có nghĩa là chúng tôi đã chiếm được khóa. Chúng tôi kiểm tra xem chúng tôi đã nhận được khóa chưa. Để kiểm tra, sẽ có điều kiện là id mà chúng tôi nhận được khi tạo khóa mới là tối thiểu. Và nếu chúng tôi nhận được nó, thì chúng tôi sẽ làm việc xa hơn.

Nếu có một id nhất định nhỏ hơn khóa của chúng tôi thì chúng tôi sẽ đặt người theo dõi sự kiện này và đợi thông báo cho đến khi có gì đó thay đổi. Tức là chúng tôi đã nhận được khóa này. Và cho đến khi nó rơi ra, chúng tôi sẽ không trở thành id tối thiểu và sẽ không nhận được khóa tối thiểu, và do đó chúng tôi sẽ có thể đăng nhập. Và nếu điều kiện này không được đáp ứng thì chúng ta ngay lập tức đến đây và cố gắng lấy lại chiếc khóa này, vì có thể có điều gì đó đã thay đổi trong thời gian này.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

ZooKeeper bao gồm những gì? Có 4 điều chính. Đây là quá trình xử lý - Yêu cầu. Và cả chương trình phát sóng nguyên tử ZooKeeper. Có Nhật ký cam kết nơi tất cả các hoạt động được ghi lại. Và chính DB được sao chép trong bộ nhớ, tức là chính cơ sở dữ liệu nơi toàn bộ cây này được lưu trữ.

Điều đáng chú ý là tất cả các thao tác ghi đều phải thông qua Bộ xử lý yêu cầu. Và các thao tác đọc sẽ chuyển trực tiếp đến cơ sở dữ liệu trong bộ nhớ.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Bản thân cơ sở dữ liệu được sao chép hoàn toàn. Tất cả các phiên bản của ZooKeeper đều lưu trữ một bản sao dữ liệu hoàn chỉnh.

Để khôi phục cơ sở dữ liệu sau sự cố, có nhật ký Cam kết. Thông lệ tiêu chuẩn là trước khi dữ liệu vào bộ nhớ, nó sẽ được ghi vào đó để nếu gặp sự cố, nhật ký này có thể được phát lại và trạng thái hệ thống có thể được khôi phục. Và ảnh chụp nhanh định kỳ của cơ sở dữ liệu cũng được sử dụng.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

ZooKeeper Atomic Broadcast là một thứ được sử dụng để duy trì dữ liệu được sao chép.

ZAB chọn nội bộ một nhà lãnh đạo theo quan điểm của nút ZooKeeper. Các nút khác trở thành người theo dõi cô ấy và mong đợi một số hành động từ cô ấy. Nếu họ nhận được bài dự thi, họ sẽ chuyển tiếp tất cả cho người lãnh đạo. Đầu tiên anh ấy thực hiện thao tác ghi và sau đó gửi tin nhắn về những gì đã thay đổi cho những người theo dõi anh ấy. Trên thực tế, điều này phải được thực hiện một cách nguyên tử, tức là hoạt động ghi và phát sóng toàn bộ sự việc phải được thực hiện một cách nguyên tử, do đó đảm bảo tính nhất quán của dữ liệu.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop" Nó chỉ xử lý các yêu cầu ghi. Nhiệm vụ chính của nó là chuyển đổi hoạt động thành một bản cập nhật giao dịch. Đây là một yêu cầu được tạo đặc biệt.

Và điều đáng chú ý ở đây là tính bình thường của các bản cập nhật cho cùng một hoạt động được đảm bảo. Nó là gì? Điều này, nếu được thực hiện hai lần, sẽ có cùng trạng thái, tức là bản thân yêu cầu sẽ không thay đổi. Và điều này cần phải được thực hiện để trong trường hợp xảy ra sự cố, bạn có thể khởi động lại thao tác, từ đó khôi phục những thay đổi đã không còn hiệu lực vào lúc này. Trong trường hợp này, trạng thái của hệ thống sẽ trở nên giống nhau, tức là không xảy ra trường hợp một loạt các quá trình giống nhau, chẳng hạn như các quá trình cập nhật, dẫn đến các trạng thái cuối cùng khác nhau của hệ thống.

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

"Hadoop. ZooKeeper" từ loạt bài Technostream của Mail.Ru Group "Các phương pháp xử lý phân tán khối lượng dữ liệu lớn trong Hadoop"

Nguồn: www.habr.com

Thêm một lời nhận xét