Một số tính năng của các DBMS quan hệ không cần thiết đối với các dữ liệu kể trên như yêu cầu về dạng chuẩn, transactional, cách truy vấn theo kiểu join, .v.v… Nhu cầu về hệ cơ sở dữ liệ
Trang 1ĐẠI HỌC QUỐC GIA TPHCM
TRƯỜNG ĐẠI HỌC BÁCH KHOA
-oOo -
ĐÀO VÂN HẰNG
NGHIÊN CỨU VÀ XÂY DỰNG MÔ HÌNH XỬ LÝ
DỮ LIỆU LỚN TRÊN NỀN HADOOP-HBASE
Chuyên ngành: Khoa học máy tính
Mã số: 604801
LUẬN VĂN THẠC SĨ
Trang 2
CÔNG TRÌNH ĐƯỢC HOÀN THÀNH TẠI TRƯỜNG ĐẠI HỌC BÁCH KHOA ĐẠI HỌC QUỐC GIA TPHCM
Cán bộ hướng dẫn khoa học : PGS TS THOẠI NAM
(Ghi rõ họ, tên, học hàm, học vị và chữ ký) Cán bộ chấm nhận xét 1 :TS Trần Vũ Bình
(Ghi rõ họ, tên, học hàm, học vị và chữ ký) Cán bộ chấm nhận xét 2 : TS Trần Ngọc Minh
(Ghi rõ họ, tên, học hàm, học vị và chữ ký) Luận văn thạc sĩ được bảo vệ tại HỘI ĐỒNG CHẤM BẢO VỆ LUẬN VĂN THẠC SĨ
TRƯỜNG ĐẠI HỌC BÁCH KHOA, ngày 19 tháng 7 năm 2012
Thành phần Hội đồng đánh giá luận văn thạc sĩ gồm:
(Ghi rõ họ, tên, học hàm, học vị của Hội đồng chấm bảo vệ luận văn thạc sĩ)
Trang 3TRƯỜNG ĐH BÁCH KHOA TP HCM CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
NHIỆM VỤ LUẬN VĂN THẠC SĨ
Họ tên học viên: ĐÀO VÂN HẰNG Phái: Nữ Ngày, tháng, năm sinh: 20-02-1967 Nơi sinh: Hà Nội Chuyên ngành: Khoa học máy tính MSHV: 10070478
I TÊN ĐỀ TÀI:
Nghiên cứu và xây dựng mô hình xử lý dữ liệu lớn trên nền Hadoop-HBase
II NHIỆM VỤ VÀ NỘI DUNG:
- Tìm hiểu xu hướng xử lý dữ liệu lớn trong môi trường phân tán NoSQL
- Tìm hiểu Hadoop, HBase
- Xây dựng ứng dụng dữ liệu lớn dùng hệ thống Hadoop-HBase
- So sánh với cơ sở dữ liệu quan hệ MySQL
III NGÀY GIAO NHIỆM VỤ: 2/2012
IV NGÀY HOÀN THÀNH NHIỆM VỤ: 30/06/2012
V CÁN BỘ HƯỚNG DẪN : TS THOẠI NAM
TP HỒ CHÍ MINH, ngày 17 tháng 8 năm 2012
(Họ tên và chữ ký) (Họ tên và chữ ký)
TRƯỞNG KHOA
(Họ tên và chữ ký)
Trang 4LỜI CẢM ƠN
Báo cáo trình bày tóm lược những kiến thức mà tôi đã học được về NoSQL nói chung và hệ thống Hadoop, Hbase nói riêng NoSQL là một xu hướng xử lý dữ liệu lớn phát triển trong khoảng bốn năm trở lại đây chủ yếu trong cộng đồng mã nguồn
mở nhưng đã có nhiều ứng dụng trong các trang web thương mại và các viện nghiên cứu khoa học Từ môi trường thử nghiệm đến ứng dụng thật sự là một khoảng cách xa và còn tốn nhiều công sức Tôi hy vọng thời gian tới sẽ được hiện thực hệ thống Hadoop-Hbase trong một dự án cụ thể Trong suốt quá trình học tập
và làm việc cho luận văn này tôi luôn nhận được sự giúp đỡ nhiệt tình của thầy Thoại Nam Tôi muốn gửi lời cảm ơn đến thầy, người đã luôn định hướng hỗ trợ cho tôi khi giải quyết vấn đề Tôi muốn gửi lời cảm ơn đến cộng đồng mailing list của hadoop, hbase Dù không quen biết nhưng cộng đồng đã giúp đỡ nhau giải quyết các vấn đề rất hiệu quả Tôi cũng gửi lời cảm ơn đến gia đình, người thân và bạn bè đã động viên giúp đỡ tôi hoàn thành công việc
Trang 5TÓM TẮT
Trong thời gian gần đây nhu cầu xử lý dữ liệu lớn ngày tăng cao do sự phát triển của các mạng xã hội và việc nghiên cứu khoa học Hệ thống NoSQL được phát triển để làm việc với khối lượng dữ liệu lớn và không cần có lược đồ cố định Trong cộng đồng nguồn mở NoSQL có rất nhiều sản phẩm phục vụ cho từng mục đích khác nhau Báo cáo trình bày tổng quan về NoSQL sau đó chọn lựa hệ thống Hadoop-Hbase để hiện thực một ứng dụng xử lý dữ liệu lớn trên trang web âm nhạc Báo cáo cũng so sánh việc xử lý dữ liệu trên nền Hadoop-Hbase với MySQL server và đưa ra ý kiến về độ lớn dữ liệu đến đâu thì nên sử dụng sản phẩm nào Cuối cùng báo cáo xem xét hướng phát triển của mô hình Hadoop-Hbase
Trang 6an implementation of a data application in Hadoop-Hbase system used on a music website I also compared two system in my thesis : Hadoop-HBase and MySQL, giving opinion about when to use which system Finally my thesis examined the
development trend of Hadoop-HBase model
Trang 7LỜI CAM ĐOAN
Kết quả đạt được của đề tài thể hiện quá trình học tập và làm việc của tôi trên nhiều nguồn tài liệu khác nhau Các tài liệu được sử dụng trong đề tài được trình bày trong phần tham khảo của báo cáo Tôi xin cam đoan các kết quả trình bày trong báo cáo là do tôi thực hiện, không sao chép từ luận văn hay báo cáo khoa học của các tác giả khác và kết quả của luận văn này cũng chưa được trình bày để lấy bằng cấp tại bất kỳ trường nào
Trang 8MỤC LỤC
DANH MỤC HÌNH 3
Chương 1: Mở đầu 4
1.1 Nhu cầu xử lý dữ liệu lớn trong môi trường phân tán 4
1.2 Mô tả bài toán dữ liệu lớn trong đề tài 4
1.3 Đề xuất cách giải quyết 5
Chương 2: Mô hình Hadoop-HBase 7
2.1 Giới thiệu các loại NoSQL 7
2.1.1 Khái niệm về NoSQL 7
2.1.2 Phân loại NoSQL 8
2.2 Hadoop 9
2.2.1 Map/Reduce Application Framework 9
2.2.1.1 Nền tảng lý thuyết từ mô hình MapReduce của Google [2] 9
2.2.1.2 Hiện thực của MapReduce trong Hadoop 10
2.2.2 Hệ thống file phân bố HDFS 17
2.2.2.1 Hệ thống file phân bố của Google 17
2.2.2.2 Cấu trúc và đặc điểm của HDFS 19
2.3 HBase 24
2.3.1 Nền tảng lý thuyết từ Big Table của Google [3] 24
2.3.2 Cấu trúc của HBase 24
2.4 HBase tích hợp trong MapReduce 32
Chương 3: Hiện thực cách giải bài toán lưu trữ, tìm kiếm và phân tích dữ liệu từ việc tương tác với người dùng trên Internet 37
3.1 Phân tích lớp bài toán tổng quát 37
3.2 Cách giải cho bài toán cụ thể 38
3.2.1 Mô tả vấn đề 38
3.2.2 Thiết kế dữ liệu cho HBase 39
3.2.3 Thiết lập hệ thống 41
3.2.4 Xử lý dữ liệu trên Hadoop-HBase 44
3.2.5 Phân tích dữ liệu từ HBase với MapReduce 50
Trang 9Chương 4: Đánh giá kết quả, so sánh với MySQL 53
4.1 Mô hình thử nghiệm 53
4.2 Dữ liệu trang web âm nhạc xử lý trên MySQL 53
4.3 Dữ liệu trang web âm nhạc xử lý trên hệ thống Hadoop-HBase 54
4.4 So sánh hai hệ thống MySQL và Hadoop-HBase 57
4.4.1 Dữ liệu thử 57
4.4.2 Các tiêu chí so sánh hệ thống Hadoop-HBase và MySQL 58
4.4.3 Kết quả so sánh 58
4.4.4 Kết luận 62
Chương 5: Kết luận và hướng phát triển 63
5.1 Kết luận 63
5.2 Hướng phát triển 64
TÀI LIỆU THAM KHẢO 66
Trang 10DANH MỤC HÌNH
Hình 2-1 Dòng chảy dữ liệu MapReduce với một reduce task duy nhất…… 12
Hình 2-2 Dòng chảy dữ liệu MapReduce với nhiều reduce task……… 13
Hình 2-3 Dòng chảy dữ liệu MapReduce không có reduce task……… 13
Hình 2-4 Hadoop thực thi một job của MapReduce……… 14
Hình 2-5 Phân cấp của lớp InputFormat……… 16
Hình 2-6 Phân cấp của lớp OutputFormat……… 17
Hình 2-7 Kiến trúc của Google File System……… 19
Hình 2-8 Hệ thống file Hadoop……… 21
Hình 2-9 Một client đọc data từ HDFS……… 22
Hình 2-10 Một client ghi data đến HDFS……… 23
Hình 2-11 Rows và columns giống như các thẻ (tags)……… 26
Hình 2-12 Một góc nhìn theo thời gian của các thành phần của một row…… 27
Hình 2-13 Row được biểu diễn dưới dạng bảng tính……….27
Hình 2-14 Rows được nhóm lại thành các group……… 28
Hình 2-15 Các thành phần của một HBase cluster……… 31
Hình 2-16 HBase dùng các thành phần của riêng mình ………31
Hình 2-17 Quá trình MapReduce……… 33
Hình 2-18 Phân cấp của InputFormat……… 33
Hình 2-19 Sự phân cấp của Mapper……… 34
Hình 2-20 Sự phân cấp của Reducer……… 34
Hình 2-21 Thứ tự của OutputFormat……… 34
Hình 3-1 Mô hình bài toán trong Hadoop-HBase……… 40
Hình 3-2 Kiến trúc của hệ thống ……… 40
Hình 3-3 Các daemons trên master……… 44
Hình 3-4 Các daemons trên slave……… 44
Hình 4-1 Import dữ liệu từ file data.tsv 2.4GB……… 55
Hình 4-2 delete, get trên HBase shell……… 55
Hình 4-3 Trạng thái của job Analyze data khi job đang thực thi……… 56
Hình 4-4 Thư mục kết quả sau khi Analyze……… 56
Hình 5-1 Kết hợp LAM(M)P và Hadoop……… 65
Hình 5.2 Kết hợp LAM(M)P-Hadoop-HBase……… 65
Trang 11Chương 1: Mở đầu
1.1 Nhu cầu xử lý dữ liệu lớn trong môi trường phân tán
Trong khoảng thời gian gần đây nhu cầu làm việc với dữ liệu lớn ngày càng tăng cao Sự ra đời và phát triển của các mạng xã hội như Facebook, Lastfm, Twitter v.v…đòi hỏi xử lý lượng dữ liệu cực lớn Ví dụ Facebook cần phải xử lý hơn 135
tỉ thông điệp mỗi tháng do đó kho dữ liệu của họ phải vào khoảng nhiều petabyte , Yahoo cũng đạt đến hơn một terabyte/ngày Trong lãnh vực khoa học thì ngành sinh học phân tử đòi hỏi xử lý một lượng rất lớn kết quả từ các phòng thí nghiệm khác nhau, hay các dữ liệu về thời tiết, địa chấn ở các trạm quan trắc khác nhau trên khắp thế giới
Các cơ sở dữ liệu quan hệ tỏ ra không hiệu quả khi làm việc với lượng dữ liệu lớn và nhanh chóng phình to như thế này Chi phí bỏ ra để nâng cấp phần cứng và trả tiền bản quyền trở nên quá đắt đối với các mạng xã hội hay với nhu cầu tổng hợp
và phân tích dữ liệu của khoa học Hơn nữa các DBMS quan hệ vẫn không đáp ứng được yêu cầu về tính phân bố và khả năng mở rộng dữ liệu Một số tính năng của các DBMS quan hệ không cần thiết đối với các dữ liệu kể trên như yêu cầu về dạng chuẩn, transactional, cách truy vấn theo kiểu join, v.v…
Nhu cầu về hệ cơ sở dữ liệu mới là cấp thiết để đáp ứng nhu cầu xuất phát từ thực tế Có rất nhiều nghiên cứu và thử nghiệm theo hướng này gọi chung là NoSQL như Hadoop, MapReduce, Cassandra, Hbase, MongoDB v.v…Đây là một nhánh mới mở rộng của DBMS dành cho dữ liệu lớn và phân bố Trong tình hình hiện nay khi điện toán đám mây đang phát triển mạnh thì NoSQL hứa hẹn là phần nền dữ liệu cho xu hướng này
NoSQL hiện vẫn còn phát triển ở giai đoạn đầu, có rất nhiều sản phẩm khác nhau chủ yếu trong cộng đồng mã nguồn mở nhưng chưa có sản phẩm thương mại Các công ty web hay các viện nghiên cứu tự lựa chọn sản phẩm thích hợp để sử dụng, điều này giúp giảm chi phí bản quyền nhưng đòi hỏi đội ngũ phần mềm phải giỏi vì không có công ty hỗ trợ Ở Việt Nam NoSQL chưa được sử dụng nhiều do chi phí nghiên cứu của các công ty thương mại và các viện khoa học rất ít, số người tích cực trong cộng đồng mã nguồn mở chưa nhiều, các mạng xã hội ở Việt Nam chưa lớn đến mức DBMS quan hệ không đáp ứng nổi Tuy vậy việc nghiên cứu NoSQL là rất quan trọng để nắm bắt các xu hướng công nghệ của thế giới và áp dụng vào thực tế Việt Nam trong thời gian tới khi dịch vụ web và khoa học phát triển hơn
1.2 Mô tả bài toán dữ liệu lớn trong đề tài
Trên môi trường Internet khi các trang web ngày càng lớn mạnh, lượng dữ liệu sinh ra từ việc tương tác với người dùng trở nên rất lớn Việc lưu trữ, cập nhật, phân
Trang 12tích lượng dữ liệu này là bài toán cần giải quyết Dữ liệu lưu trữ có thể ở nhiều dạng như text, graph, v.v…Đề tài chọn dạng lưu trữ cơ bản là text để nghiên cứu Dữ liệu lưu có thể coi như các record trong các database thông thường Trong số rất nhiều sản phẩm thử nghiệm NoSQL hiện nay, đề tài chọn hệ thống Hadoop-HBase
là môi trường để giải quyết vấn đề vì các lý do sau:
- Hadoop có framework MapReduce rất hữu hiệu để giải quyết nhiều vấn đề trong môi trường phân bố trong đó có việc viết các chương trình phân tích dữ liệu Nhiều sản phẩm NoSQL khác cố gắng tích hợp với Hadoop để tận dụng MapReduce
- Hadoop có hệ thống file phân bố đơn giản và hiệu quả thích hợp cho dữ liệu lớn
- Hadoop làm việc với các file mà không phải với các record nên không giải quyết được các tác vụ transaction của một database thông thường như tạo, thêm, xóa, sửa record Các vấn đề này sẽ do HBase đảm nhận HBase được phát triển trên nền Hadoop nên kế thừa rất tốt các tính chất của file phân bố và có các lớp riêng tích hợp với MapReduce
- Hadoop-HBase có một cộng đồng rất tích cực nơi mọi người có thể trao đổi kinh nghiệm và giúp đỡ nhau Đây là vấn đề rất quan trọng vì trong các dự án mã nguồn mở chỉ có thể tìm trợ giúp từ cộng đồng chứ không có công ty chịu trách nhiệm
Lớp các bài toán này khác nhau về chi tiết nhưng có chung mô hình lời giải Ví
dụ về các bài toán của lớp này như thu thập dữ liệu thường xuyên từ các file log của hệ thống máy tính ở những nơi khác nhau để phân tích theo một số tiêu chí,
dữ liệu từ trang web nghe nhạc online được cập nhật, thêm, xóa và xếp hạng theo bài hát, album, nghệ sĩ v.v
1.3 Đề xuất cách giải quyết
Hướng giải quyết chung là dữ liệu được lưu trữ trong HBase để dễ thêm, bớt, xóa, sửa Dữ liệu cũ import vào HBase qua file text dùng MapReduce MapReduce cũng được dùng để viết công cụ phân tích dữ liệu
Bài toán cụ thể đề tài thực hiện như sau:
Người dùng Internet truy cập vào các trang web về âm nhạc để nghe nhạc online hoặc tải bài hát Mỗi lần user chọn bài hát hệ thống sẽ ghi lại tên user, bài hát, ca sĩ trình bày, tên album User cũng có thể đăng nhập để ghi nhận xét về bài hát, album,
nghệ sĩ Các comment sẽ được hiển thị lại cho người dùng xem trước khi đăng tiếp
comment khác Dữ liệu được tổng hợp lại để phân tích ra những kết quả như xếp hạng bài hát, album, nghệ sĩ trong khoảng thời gian cho trước
Dữ liệu sẽ được thiết kế theo table của HBase và lưu trữ phân bố trên một cluster gồm 3 máy tính Các truy cập thời gian thực như insert, delete, create, tìm
Trang 13kiếm sẽ do HBase đảm nhiệm Các tác vụ phân tích data (số lượng lượt chọn một bài hát, ca sĩ được nghe nhiều nhất, v.v…) sẽ dùng MapReduce để hiện thực
Dữ liệu khoảng 4GB lấy từ trang web âm nhạc last.fm dùng để test chương trình (dữ liệu này là hợp pháp vì last.fm cho phép lấy data qua một số hàm API của trang cho mục đích nghiên cứu)
Do giải pháp Hadoop, HBase dành cho dữ liệu lớn mới có hiệu quả nên dữ liệu
sẽ được thực thi trên MySQL để so sánh và rút ra kết luận với kích thước data từ mức nào thì Hadoop-HBase là hiệu quả và không thay thế được
Ngôn ngữ sử dụng để lập trình là Java
Nội dung báo cáo chia làm 5 phần Phần 1 giới thiệu đề tài Phần 2 tóm tắt nền tảng Hadoop-HBase Phần 3 là chi tiết cách tiếp cận để giải quyết vấn đề Phần 4 là đánh giá kết quả và so sánh với MySQL Phần 5 là kết luận và đưa ra hướng phát triển
Trang 14Chương 2: Mô hình Hadoop-HBase
2.1 Giới thiệu các loại NoSQL
2.1.1 Khái niệm về NoSQL
Cùng với sự phát triển của Internet là một loạt các ứng dụng web mới được xây dựng trên nền Internet như mạng xã hội, thương mại điện tử Các ứng dụng này có một số đặc điểm sau:
- Khối lượng dữ liệu phải lưu trữ và xử lý khổng lồ Ví dụ trong một ngày có hàng tỉrecord được tạo mới trên Facebook hay lượng dữliệu to lớn của Google cần lưu trữ để phục vụ nhu cầu tìm kiếm hiện nay trên thếgiới
- Độ co giãn lớn Ví dụ một website bán hàng có lượng giao dịch tăng nhanh cần phải mở rộng Cơ sở dữ liệu trong thời gian ngắn nhất và với chi phí rẻ
nhất Với các CSDL như Oracle, SQL Server, v.v… việc nâng cấp tốn kém tiền bản quyền cho phiên bản cao hơn và chi phí nâng cấp phần cứng
- Tính sẵn sàng cao: Nguy cơ hỏng hóc phần cứng là thường xuyên nhưng dịch
vụ cung cấp không thể ngưng trong bất cứ thời gian nào Ví dụ các đơn đặt
hàng online của Amazon không được để mất bất cứ đơn nào
- Vấn đề nhất quán dữ liệu:không cần thỏa mãn ngay tức khắc mà có thể thỏa mãn sau một thời gian dài, ngắn tùy theo tính chất của bài toán Ví dụ các đơn đặt hàng online sẽ được đáp ứng 3 giờ sau khi gửi đi thành công
Các hệ cơ sở dữ liệu quan hệ truyền thống tỏ ra không hiệu quả khi thực hiện các yêu cầu này Với các hệ CSDL quen thuộc như Oracle, MS SQL Server, DB2,… tính nhất quán được đặt lên hàng đầu vì chúng áp dụng cho các trường hợp cần độ chính xác và tính tức thời cao như ngân hàng, các dữ liệu về nhân thân, an ninh v.v…Trong khi đó tính nhất quán yêu cầu trong các ứng dụng web thế hệ mới như mạng xã hội và thương mại điện tử mang tính chất “nhất quán cuối cùng” (eventually consistency) tức là sau một thời gian nào đó tùy theo yêu cầu của từng ứng dụng tính nhất quán sẽ đạt được Ngoài ra chi phí để mở rộng và bảo trì dữ liệu của các hệ cơ sở dữ liệu truyền thống quá đắt đỏ do dữ liệu được lưu tập trung
Từ các tính chất trên, nảy sinh các vấn đề cần giải quyết để các ứng dụng web thế hệ mới có thể phát triển:
- Dữ liệu cần được lưu trữ phân tán trên các máy tính thông thường tại các nơi khác nhau về mặt địa lý để giải quyết được bài toán về lượng dữ liệu rất lớn và giá thành rẻ
- Cấu trúc của hệ cơ sở dữ liệu phải thay đổi theo hướng đơn giản và uyển
chuyển hơn để thuận tiện cho việc truy vấn, tránh các câu hỏi dạng join làm
Trang 15- Khả năng đánh chỉ số một lượng dữ liệu lớn và phục vụ các trang web nhanh chóng là một yêu cầu bắt buộc
Nhiều hướng nghiên cứu đồng thời của cộng đồng nguồn mở, các trường đại học và các hãng thương mại lớn như Google, Amazon, v.v… để phục vụ cho
việc xử lý dữ liệu trên các ứng dụng web 2.0 đã đưa đến một mô hình lưu trữ
dữ liệu mới là NoSQL với các đặc điểm:
- NoSQL không phải là anti-RDBMS nhưng nó nhấn mạnh đến các ưu thế
của mô hình lưu trữ Key-Value, mô hình cơ sở dữ liệu văn bản hay mô hình
cơ sở dữ liệu graph
- Kiến trúc của NoSQL đưa ra mô hình nhất quán yếu, transaction chỉ giới
hạn với dữ liệu đơn
2.1.2 Phân loại NoSQL
Hiện nay có khoảng hơn 122 sản phẩm NoSQL theo các 4 hướng chính sau:
1. Key-value Stores
Ý tưởng chính là dùng một bảng băm, mỗi khóa duy nhất sẽ chỉ đến một khối dữ liệu Mô hình Key/Value đơn giản và dễ hiện thực nhất Nó không hiệu quả khi truy vấn và cập nhật một phần của Value
Ví dụ: Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB, Amazon SimpleDB, Riak
2 Column Family Store
Loại này dùng để lưu trữ và xử lý một lượng dữ liệu lớn phân bố trên nhiều máy tính Vẫn có các khóa như loại 1 nhưng chúng chỉ đến nhiều column Các column này được sắp xếp theo column family
Ví dụ: Cassandra, HBase
3 Document Database
Loại này lấy cảm hứng từ Lotus Domino và giống với Key/Value Store Mô hình cơ bản là những document được đánh số theo phiên bản, những document này là tập hợp của các bộ Key/Value Store khác Các document kiểu bán cấu trúc (semi-structure) lưu trữ theo định dạng giống như JSON Loại này về cơ bản là mức tiếp theo của Key/Value Store, cho phép các value lồng nhau kết hợp với một key Document database hỗ trợ truy vấn hiệu quả hơn hai loại trên
Ví dụ: CouchDB, MongoDB
Trang 164 Cơ sở dữ liệu kiểu đồ thị
Thay vào việc dùng bảng bao gồm các hàng, cột và cấu trúc cứng nhắc của SQL, mô hình mềm dẻo graph co giãn tốt trên hệ thống nhiều máy tính Loại này không đưa ra các truy vấn mô tả cấp cao như SQL để tránh mất nhiều thời gian xử lý Thay vào đó truy vấn sẽ phụ thuộc vào từng mô hình database Một số cho phép giao tiếp RESTfull đến database, số khác đưa ra các hàm API truy vấn
Ví dụ: Neo4J, InfoGrid, Infinite Graph
2.2 Hadoop
Hadoop được Doug Cutting tạo ra, Doug Cutting cũng là người đã tạo ra Apache Lucene là một thư viện tìm kiếm văn bản được nhiều người biết đến Hadoop lúc đầu nằm trong một engine tìm kiếm mã nguồn mở trên web là Apache Nutch, Nutch cũng là một phần của Lucene Nutch bắt đầu từ năm 2002 nhưng chưa giải quyết được vấn đề tìm kiếm những dữ liệu rất lớn Từ những ý tưởng của Google phổ biến
ra công luận về Google File System (GFS) và MapReduce các tác giả của Nutch đã hiện thực được hệ thống file phân bố gọi là Nutch Distributed File System (NDFS)
và MapReduce trong Nutch NDFS và Mapreduce trong Nutch trở thành dự án con Hadoop trong Lucene vào năm 2006 Năm 2008 Hadoop trở thành một trong những
dự án hàng đầu của Apache Hadoop ngày càng phát triển, có một cộng đồng mạnh, được các công ty lớn như New York Times, Yahoo, Last.fm, Facebook…sử dụng Hiện nay Hadoop đã có version ổn định là 1.0.3 (tính đến 16/5/2012) Hai thành phần quan trọng nhất của Hadoop là Map/Reduce Application Framework và hệ thống file phân bố (Hadoop Distributed File System – HDFS) Sau đây ta sẽ xem xét chi tiết hơn về hai thành phần này
2.2.1 Map/Reduce Application Framework
2.2.1.1 Nền tảng lý thuyết từ mô hình MapReduce của Google [2]
MapReduce là mô hình lập trình kèm theo các chức năng có sẵn dùng để xử lý
và sinh ra các tập hợp dữ liệu lớn Người dùng xác định hàm map để xử lý cặp
key/value tạo ra một tập các cặp key/value trung gian, hàm reduce sẽ trộn các giá trị trung gian tương ứng với một key trung gian
Các chương trình viết theo kiểu này sẽ tự động chạy song song và thực thi trên một cụm nhiều máy tính thông thường Hệ thống khi chạy sẽ chịu trách nhiệm xử lý các vấn đề như phân hoạch dữ liệu đầu vào, định thời việc chạy chương trình trên tập hợp máy tính, giải quyết các máy tính bị lỗi và quản lý giao tiếp giữa các máy tính Điều này làm cho các lập trình viên không có kinh nghiệm về lập trình song song và hệ phân bố có thể dễ dàng sử dụng các nguồn lực của một hệ phân bố lớn
Trang 17Việc tính toán nhận một tập hợp các cặp đầu vào key/value và sản sinh ra một tập hợp cặp key/value đầu ra Người sử dụng thư viện MapReduce diễn tả việc tính toán thông qua hai hàm: Map và Reduce
Map do người dùng viết lấy một cặp đầu vào và sản sinh ra một tập hợp các cặp key/value trung gian Thư viện MapReduce nhóm các giá trị trung gian cùng kết hợp với một key I và chuyển chúng cho hàm Reduce
Hàm Reduce cũng do người dùng viết sẽ nhận key trung gian I và một tập hợp các value của key này Nó sẽ trộn các giá trị này lại tạo thành một tập value có nhiều khả năng sẽ nhỏ hơn Thường là 0 hoặc một giá trị đầu ra ứng với một Reduce Các giá trị trị trung gian cung cấp cho hàm reduce của người dùng thông qua việc lặp Điều này cho phép ta xử lý một lượng giá trị rất lớn so với bộ nhớ map (k1,v1) -> list(k2,v2)
reduce (k2, list(v2)) -> list(v2)
2.2.1.2 Hiện thực của MapReduce trong Hadoop
a) Dòng chảy dữ liệu (Data Flow) [5]
Một MapReduce job là một đơn vị công việc mà client muốn thực thi: bao gồm
dữ liệu đầu vào, chương trình MapReduce, và các thông tin cấu hình Hadoop thực hiện job bằng cách phân chia nó thành các task Có hai loại task là map tasks và reduce tasks
Có hai loại node điều khiển quá trình xử lý job: một jobtracker và một số
tasktrackers. Jobtracker điều phối tất cả các jobs chạy trên hệ thống bằng cách định thời các tasks chạy trên các tasktrackers Tasktracker chạy các task và gửi các báo cáo đến jobtracker, jobtracker giữ một hồ sơ về toàn bộ quá trình của mỗi job Nếu một task bị hỏng, jobtracker sẽ phân công nó chạy lại trên một tasktracker khác Hadoop chia input của một MapReduce job thành các phần bằng nhau gọi là input splits hay splits Hadoop tạo một maptask cho mỗi split, nó sẽ chạy hàm map
do người dùng định nghĩa cho mỗi record trong split Với phần lớn job, một split mặc định bằng một HDFS block mặc dù có thể thay đổi được tùy theo input
Hadoop làm tốt nhất khi chạy map task trên node có dữ liệu đầu vào ở trong
HDFS (data-local) Điều này gọi là tối ưu dữ liệu cục bộ (data locality optimization)
bởi vì không cần dùng đến lưu lượng quí giá của cluster Tuy vậy thỉnh thoảng cả
ba node chứa các block nhân bản HDFS của một split của maptask đều đang bận chạy maptask khác cho nên job scheduler sẽ tìm một slot còn tự do trên cùng rack (rack-local) Rất hãn hữu xảy ra trường hợp phải tìm một slot nằm ngoài rack (off-rack)
Kích thước của block là kích thước lớn nhất của input có thể đảm bảo nằm trên một node Nếu split trải dài trên hai block thì không chắc chắn rằng mọi HDFS chứa cùng hai block đó, do đó có khả năng là split sẽ phải di chuyển qua network để đến
Trang 18node đang chạy map task Điều này rõ ràng là kém hiệu quả so với chạy toàn bộ map task dùng dữ liệu cục bộ
Map tasks ghi output ra đĩa cục bộ chứ không phải ra HDFS Ouput của map là output trung gian Reduce tasks xử lý output này để cho ra kết quả cuối cùng Khi job hoàn thành thì map ouput sẽ được bỏ đi Do đó việc lưu trữ map output trên HDFS với các bản sao là không cần thiết, chỉ làm quá tải hệ thống Nếu node chạy map task bị lỗi trước khi reduce task lấy được kết quả thì Hadoop tự động chạy lại map task đó trên một node khác để tạo lại map output
Reduce task không có được những lợi thế của data cục bộ, các đầu vào cho một reducer thường là đầu ra từ tất cả các mapper Do đó các map ouput đã được sắp xếp sẽ phải di chuyển qua network đến node có reduce task đang chạy, ở đó chúng
sẽ được trộn rồi chuyển cho hàm reduce do người dùng định nghĩa Đầu ra của reduce thường chứa trong HDFS cho đảm bảo Như vậy việc ghi output của reduce
sẽ tốn băng thông nhưng cũng chỉ bằng với các thao tác ghi pipeline thông thường khác trên HDFS
Hình 2-1 là dòng chảy dữ liệu với một reduce task Các hình chữ nhật chấm chấm biểu diễn các node, mũi tên không liên tục diễn tả luồng dữ liệu trên một node
và mũi tên liền biểu diễn luồng dữ liệu giữa các nodes
Số reduce task không xác định bằng kích thước của input mà được xác định độc lập Khi có nhiều reducers, map tasks sẽ phân hoạch đầu ra của chúng, tạo thành một phân hoạch cho mỗi reduce task Có thể có nhiều khóa trong mỗi phân hoạch nhưng các records cho bất kỳ khóa cho trước nào sẽ ở trong cùng một phân hoạch Việc phân hoạch có thể được điều khiển bằng hàm phân hoạch do người dùng định nghĩa nhưng thường là dùng phân hoạch mặc định, cách này sẽ nhóm các khóa dùng hàm băm rất hiệu quả
Trang 19Hình 2-1 Dòng chảy dữ liệu MapReduce với một reduce task duy nhất
Dòng chảy dữ liệu cho trường hợp tổng quát có nhiều reduce task thể hiện trong hình 2-2 Ta có thể thấy dòng chảy dữ liệu giữa map và reduce tasks được xáo qua lại, input cho mỗi reduce task được cung cấp bởi nhiều map tasks Quá trình xáo dữ liệu qua lại trong thực tế có thể phức tạp hơn nhiều
Cũng có khả năng có zero reduce task Trường hợp này xảy ra khi ta không cần xáo các output của map task, quá trình xử lý hoàn toàn song song từ đầu đến cuối (xem hình 2-3)
b) Các hàm phối hợp (Combiner functions)
Nhiều MapReduce jobs bị hạn chế bởi băng thông của cluster, do đó cần phải tối thiểu hóa lượng dữ liệu luân chuyển giữa map và reduce tasks Hadoop cho phép người dùng xác định một combiner function chạy trên map output Output của combiner function tạo thành input cho reduce function Do combiner function là một quá trình tối ưu hóa nên việc gọi combiner function bao nhiêu lần tùy người dùng Gọi combiner function zero lần, một lần hay nhiều lần cũng cho ra cùng một output từ reducer
c) Quá trình chạy của một MapReduce Job
Ta có thể chạy một MapReduce job bằng cách gọi submit() trên đối tượng Job hay waitForCompletion(), hàm này sẽ gửi job nếu job chưa được gửi và chờ cho đến khi job được thực thi xong
Trang 20Hình 2-2 Dòng chảy dữ liệu MapReduce với nhiều reduce task
Hình 2-3 Dòng chảy dữ liệu MapReduce không có reduce task
Khi hệ thống rất lớn khoảng trên 4000 nodes thì vấn đề tắc nghẽn xảy ra Hiện thực mới của MapReduce gọi là MapReduce 2 được xây dựng trên một hệ thống gọi
là YARN sẽ giải quyết vấn đề này Luận văn chỉ trình bày các vấn đề liên quan đến MapReduce cổ điển hay MapReduce 1 (trong báo cáo gọi tắt là MapReduce)
Hình 2-4 biểu diễn một job chạy trên MapReduce Tại mức cao nhất có 4 thực thể độc lập là:
Trang 21Hình 2-4 Hadoop thực thi một job của MapReduce
• Client: đưa yêu cầu MapReduce job
• Jobtracker: điều phối quá trình chạy của job Jobtracker là một ứng dụng Java có lớp chính là JobTracker
• Các tasktracker: thực thi các task mà job phân chia Tasktracker là một ứng dụng Java có lớp chính là TaskTracker
• Hệ thống file phân bố (thường là HDFS) dùng để chia sẻ các file của job giữa các thực thể
Quá trình thực thi một MapReduce job diễn ra như sau:
- Bước 1: submit() method của Job tạo một đối tượng JobSubmitter và gọi submitJobInternal() trên đó
- Bước 2: Yêu cầu ID cho job mới từ jobtracker
- Bước 3: Sao chép các tài nguyên cần thiết để thực thi job đến hệ thống file của jobtracker trong thư mục có tên là ID của job (các tài nguyên là file JAR của job, file cấu hình, các split đầu vào )
- Bước 4: Thông báo với jobtracker rằng job đã sẵn sàng cho việc thực thi
- Bước 5: Jobtracker đặt job vào hàng đợi, ở đó job scheduler sẽ lấy ra và khởi tạo nó Công việc khởi tạo bao gồm tạo một đối tượng biểu diễn job đang
Trang 22chạy, đối tượng sẽ bao gồm các task, các thông tin để theo dõi trạng thái và quá trình của task
- Bước 6: Để tạo một danh sách các task cần thực thi đầu tiên job scheduler lấy các splits đầu vào từ hệ thống file dùng chung rồi tạo một map task cho mỗi split
- Bước 7: Tasktracker thực thi một vòng lặp đơn giản định kỳ gửi heartbeat (nhịp tim) về cho jobtracker Heartbeat thông báo với jotracker rằng tasktracker còn chạy, ngoài ra tasktracker còn thông báo khi sẵn sàng thực thi task mới Khi đó jobtracker sẽ chọn một task mới và giao tiếp với tasktracker qua giá trị trả về của heartbeat
- Bước 8: Tasktracker sao chép JAR của job từ hệ thống file dùng chung về hệ thống file của tasktracker Ngoài ra tasktracker còn chép các file cần thiết từ cache phân bố về đĩa cục bộ Sau đó tasktracker tạo một thư mục làm việc cục bộ cho task và giải nén JAR của job vào thư mục này Tasktracker tạo một đối tượng TaskRunner để thực thi task
- Bước 9: TaskRunner khởi tạo một máy ảo Java (Java Virtual Machine)
- Bước 10: Thực thi task
Quá trình con trao đổi với quá trình cha mẹ qua giao tiếp như dây rốn giữa mẹ
và con (umbilical) Bằng cách này quá trình con thông báo với quá trình cha mẹ từng giây cho đến khi task hoàn thành
Mỗi task có thể tự khởi tạo và dọn rác sau khi chạy
d) Định dạng đầu vào (Input format)
Hadoop có thể xử lý nhiều định dạng dữ liệu từ file văn bản đến cơ sở dữ liệu Một input split là một khúc input được xử lý bởi một map đơn lẻ Mỗi map xử lý một split Mỗi split được chia thành các records và map xử lý lần lượt từng record (một cặp key-value)
Hadoop làm việc hiệu quả hơn với một số lượng nhỏ các file lớn hơn là một số lượng lớn các file nhỏ Điều này một phần là do FileInputFormat (lớp cơ sở của tất
cả các lớp xử lý định dạng đầu vào) tạo ra các splits sao cho mỗi split là một phần hay toàn bộ một file Nếu file rất nhỏ (nhỏ hơn nhiều so với một HDFS block) và có rất nhiều file nhỏ đó thì mỗi map sẽ xử lý được rất ít input Sẽ có rất nhiều split do
đó việc theo vết (bookkeeping) sẽ trở nên quá tải So sánh 1GB chia thành mười sáu block 64MB hay 10,000 file 100KB 10,000 file dùng mỗi map cho một file thì thời gian để hoàn thành job sẽ chậm hàng trăm lần so với một file đầu vào duy nhất và
16 map task
Hadoop xử lý xuất sắc văn bản không có cấu trúc TextInputFormat là InputFormat mặc định Mỗi record là một hàng của input Khóa kiểu LongWritable
Trang 23là độ dời theo byte tính từ đầu file đến đầu hàng đang xét Value là nội dung của hàng bỏ đi các ký tự điều khiển
Khóa của TextInputFormat không có nhiều thông tin Thường ta dùng mỗi line trong file là một cặp key-value được phân chia bằng ký tự tab, khi đó loại input sẽ là KeyValueTextInputFormat sẽ thích hợp hơn
Ví dụ: line1 \t On the top of the Crumpetty
line2 \t The Quangle Wangle sat,
Nếu ta muốn mapper nhận một số dòng cố định từ input thì sẽ dùng NlineInputFormat Khóa của trường hợp này giống TextInputFormat
Hình 2-5 Phân cấp của lớp InputFormat
e) Định dạng đầu ra
Format mặc định của output là TextOutputFormat ghi records thành các hàng của văn bản Các loại output gồm có Text Output, Binary Output, Multiple Output, Lazy output (một loại output đặc biệt dùng để hạn chế file rỗng), Database Output Hình 2-6 mô tả sự phân cấp của lớp OutputFormat
Trang 24Hình 2-6 Phân cấp của lớp OutputFormat
2.2.2 Hệ thống file phân bố HDFS
2.2.2.1 Hệ thống file phân bố của Google
GFS (Google File System) là hệ thống file phân bố có độ co giãn lớn dùng cho những ứng dụng có rất nhiều dữ liệu Nó có khả năng kháng lỗi khi chạy trên các hệ thống máy tính thông thường và phục vụ được một số lớn clients
Các đặc điểm của GFS
• Hệ thống được xây dựng từ những thành phần thông thường không đắt tiền nên thường lỗi Phải thường xuyên theo dõi và phát hiện, cho phép lỗi và khôi phục hệ thống ngay lập tức từ các thành phần lỗi Đây là các hoạt động thường quy của hệ thống
• Hệ thống chứa nhiều file lớn Các file có dung lượng nhiều GB là bình thường và phải được xử lý hiệu quả Các file nhỏ cũng được hỗ trợ nhưng không cần tối ưu hóa
• Tải của hệ thống đầu tiên gồm hai loại đọc: đọc theo luồng lớn và đọc ngẫu nhiên nhỏ Thường hệ thống đọc cả một vùng liên tục của file hay đọc vài
KB tại một độ dời nào đó Các ứng dụng quan tâm đến hiệu suất thường đọc theo lô và sắp xếp các thao tác đọc hợp lý trên toàn file hơn là di chuyển liên tục về trước hoặc sau trên file
• Tải của hệ thống cũng gồm việc ghi tuần tự các file lớn để nối dữ liệu vào file Kích thước ghi cũng như kích thước đọc Một khi đã ghi xong file sẽ rất
Trang 25hiếm khi được sửa đổi lần nữa Ghi ít data tại vị trí bất kỳ trong file được hỗ trợ nhưng không hiệu quả
• Hệ thống phải hiện thực hiệu quả ngữ nghĩa trong trường hợp nhiều người dùng đồng thời nối dữ liệu vào cùng một file
• Băng thông duy trì cao thì quan trọng hơn là độ trễ thấp Phần lớn các ứng dụng của Google dùng xử lý data theo khối có tốc độ cao trong khi có ít yêu cầu về thời gian đáp ứng nghiêm ngặt của từng thao tác đọc ghi riêng
Kiến trúc của Google File System [1]
Một GFS cluster gồm duy nhất một master và một số chunkserver được truy cập bởi nhiều client Mỗi máy tính này là một máy tính Linux thông thường Có thể chạy cả chunkserver và client trên cùng một máy tính nếu tài nguyên cho phép File được chia thành những chunk có kích thước cố định Mỗi chunk được xác định bằng một số 64 bit toàn cục không thay đổi gọi là chunk handle do master cung cấp khi chunk được tạo thành Chunkserver chứa các chunks tại các đĩa local như là các file Linux và việc đọc, ghi chunk data được xác định bằng một chunk handle và dãy các byte Mỗi chunk được nhân bản trên nhiều chunkserver để tăng độ tin cậy Mặc định có ba nhân bản nhưng người dùng có thể định nghĩa khác tùy theo yêu cầu
Master duy trì mọi metadata của hệ thống file Metadata bao gồm namespace, các thông tin quản lý truy cập, ánh xạ từ files đến chunks và vị trí hiện tại của chunk Master cũng quản lý các tác vụ trên toàn hệ thống như nhân bản chunk, thu thập rác của những chunk mồ côi, di chuyển chunk giữa các chunkservers Master theo định kỳ giao tiếp với từng chunkserver theo thông điệp HeartBeat để đưa ra các chỉ thị và thu thập trạng thái
Mã của GFS client kết nối với mỗi ứng dụng hiện thực API của hệ thống file, giao tiếp với master và các chunkserver để đọc hay ghi data Client giao tiếp với master để thực hiện các tác vụ liên quan đến metadata nhưng các giao tiếp liên quan đến dữ liệu đi thẳng đến các chunkservers
Cả client lẫn chunkserver đều không cache data vì phần lớn các ứng dụng dùng GFS duyệt qua luồng dữ liệu rất lớn hoặc tập hợp dữ liệu quá lớn để cache Chunkserver không cần cache file data vì các chunks được lưu trữ như file cục bộ cho nên các buffer cache của Linux sẽ làm việc này
GFS chỉ có một master làm cho việc thiết kế hệ thống đơn giản và cho phép master thực hiện được việc sắp xếp và nhân bản chunk phức tạp dựa trên các thông tin toàn cục Tuy vậy ta phải làm cho master ít liên quan đến việc đọc, ghi nhất để tránh tắc nghẽn cổ chai Client không bao giờ đọc hay ghi data thông qua master Thay vào đó client chỉ hỏi master về các chunkserver nào client sẽ phải liên lạc
Trang 26Client sẽ giữ các thông tin này trong một thời gian hữu hạn và sẽ giao dịch trực tiếp với các chunkservers cho các thao tác kế tiếp
Hình 2-7 Kiến trúc của Google File System
Một thao tác đọc đơn giản sẽ diễn ra như sau theo hình 2-7:
Đầu tiên, dùng kích thước chunk cố định, client dịch tên file và độ dời tính bằng byte trong ứng dụng thành chỉ số của chunk trong file Sau đó nó sẽ gửi đến master một yêu cầu chứa tên file và chỉ số của chunk Master trả lời với thẻ của chunk và vị trí của các bản sao Client giữ lại (cache) thông tin này dùng tên file và index của chunk như là khóa
Sau đó client sẽ gửi yêu cầu đến một bản sao thường là gần nhất Yêu cầu xác định thẻ của chunk và dãy byte trong chunk Các thao tác đọc trên cùng chunk này không cần liên lạc client-master nữa cho đến khi các thông tin lưu lại (cache) hết hạn hay file mở lại Trong thực tế client thường hỏi nhiều chunk trong một yêu cầu
và master trả lời thông tin về chunk ngay lập tức sau khi yêu cầu
2.2.2.2 Cấu trúc và đặc điểm của HDFS
Hadoop được thiết kế dựa trên các đặc điểm của Google File System, ngoài ra Hadoop còn có một số tính năng ưu việt khác
cả tập dữ liệu cho nên thời gian để đọc toàn bộ tập dữ liệu đó quan trọng hơn độ
Trang 27- Phần cứng bình thường: Hadoop không yêu cầu phần cứng đắt tiền có độ tin cậy cao Nó chạy trên các phần cứng thông thường từ nhiều nhà cung cấp do đó khả năng hư hỏng của node trong cluster là cao HDFS được thiết kế để tiếp tục chạy bình thường không thông báo lỗi với người dùng khi có lỗi phần cứng xảy ra
- Truy cập data với độ trễ thấp: Các ứng dụng yêu cầu truy xuất data với độ trễ thấp (khoảng hàng chục millisecond) không làm việc tốt với HDFS Ghi nhớ rằng HDFS được tối ưu hóa cho năng suất xử lý data với sự trả giá của độ trễ HBase hiện nay là ứng viên tốt hơn cho các truy cập có độ trễ thấp
- Nhiều files nhỏ: nhiều file nhỏ không hiệu quả giống trường hợp GFS
- Giống GFS, việc ghi chỉ tiến hành ở cuối file và chỉ có một bộ phận ghi, HDFS không hỗ trợ nhiều bộ phận ghi hay sửa đổi tại một nơi bất kỳ trong file
Các khái niệm của HDFS:
- Blocks: giống chunk của GFS, độ lớn mặc định của block là 64MB
- Namenodes và Datanodes: Namenode được hiện thực giống như GFS server, Datanodes có vai trò như GFS chunkserver HDFS cluster có hai loại node hoạt động theo kiểu master-worker: một namenode (master) và một số datanodes (workers) Namenode quản lý namespace của hệ thống file Nó duy trì cây hệ thống file và metadata của tất cả các file và thư mục trong cây Những thông tin này được lưu trữ ổn định trên local disk dưới dạng của hai file: namespace image và edit log Namenode cũng biết các datanode trên đó mọi block của file
đã cho trú ngụ, tuy vậy nó không lưu trữ các vị trí của block một cách bền vững bởi vì các thông tin này được tạo lại khi hệ thống khởi động
- Một client truy cập hệ thống file bên phía người dùng bằng cách giao tiếp với namenode và datanode Client trình diễn một interface giống như hệ thống file POSIX, do vậy người dùng không cần biết namenode và datanode hoạt động như thế nào
- Các datanode là sức kéo của hệ thống file Chúng lưu trữ và lấy ra các block khi được yêu cầu (từ client hay namenode), chúng thông báo cho namenode theo định kỳ danh sách các block mà chúng lưu giữ
- Hệ thống file không thể sử dụng được nếu không có namenode Thật sự, nếu máy tính chạy namenode bị hỏng thì tất cả các file của hệ thống file bị mất bởi
vì không có cách nào khôi phục lại các file từ các block chứa trên các datanode
Vì lý do này nên làm cho namenode kháng lỗi là rất quan trọng Hadoop đưa ra hai cơ chế làm điều này Cách thứ nhất là sao lưu các file làm nên trạng thái ổn định của metadata của filesystem Hadoop có thể cấu hình để namenode ghi lại trạng thái ổn định lên nhiều filesystem Việc ghi này đồng bộ và dễ dàng Thường người ta cấu hình việc ghi này lên cả đĩa local và remote NFS mount Cách thứ hai là chạy secondary namenode Secondary namenode không chạy như một namenode mà chỉ chạy dự phòng Nhiệm vụ chính của nó là định kỳ
Trang 28trộn namespace image với edit log để ngăn ngừa edit log trở nên quá lớn Secondary namenode thường chạy trên một máy vật lý riêng vì nó yêu cầu nhiều CPU và nhiều memory như namenode để thực hiện việc trộn Nó giữ một bản sao của namespace image đã được trộn để dùng trong trường hợp namenode bị lỗi Tuy vậy trạng thái của secondary namenode bị chậm so với primary do đó khi primary bị lỗi hoàn toàn thì việc bị mất một phần data là không tránh khỏi Cách xử lý trong trường hợp này là chép các metadata file của namenode trên NFS lên secondary namenode và chạy nó như một primary mới
- Hadoop viết bằng Java, các giao dịch thông qua Java API Hadoop có một khái niệm filesystem trừu tượng mà HDFS chỉ là một hiện thực Lớp Java abstract
org.apache.hadoop.fs.FileSystem biểu diễn một hệ thống filesystem trên Hadoop Hình 2.8 mô tả vài hiện thực cụ thể của lớp này
- Giao diện: Hadoop được viết bằng Java, cả hệ thống Hadoop tương tác với nhau thông qua Java API Có nhiều interface với HDFS nhưng command-line là interface đơn giản và được ưa chuộng nhất Ngoài ra còn có Thrift cho các ứng dụng không phải Java, thư viện cho C là libhdfs, FUSE, WebDAV
Hình 2-8 Hệ thống file Hadoop
Trang 29a) Cấu trúc của File Read
Client mở file để đọc bằng cách gọi open() của đối tượng FileSystem, đối với HDFS thì đây là một instance của DistributedFileSystem (bước 1 trong hình 2.7)
DistributedFileSystem gọi namenode dùng RPC để xác định vị trí các block của một
số block đầu tiên của file (bước 2)
Sau đó client gọi read() (bước 3) Data chảy từ datanode về client trong khi
client lặp lại việc gọi này trên luồng dữ liệu (bước 4) Khi đạt đến điểm cuối của
block, DFSInputStream sẽ đóng kết nối đến datanode, rồi tiếp tục tìm datanode tốt nhất để đọc block kế tiếp (bước 5) Khi client kết thúc việc đọc sẽ gọi close() của
FSDataInputStream (bước 6)
b) Cấu trúc của File Write
Ta xét trường hợp tạo mới một file, ghi data vào rồi đóng file
Client tạo file bằng cách gọi create() trên DistributedFileSystem (bước 1 hình 2.8)
DistributedFileSystem gọi RPC đến namenode để tạo một file mới trong namespace của filesystem, không có block nào liên kết với nó (bước 2) Namenode thực hiện nhiều kiểm tra để chắc chắn là file chưa tồn tại, sau đó client được phép tạo file Nếu qua được kiểm tra namenode tạo một record cho file mới, ngược lại
IOException sẽ gửi lại DistributedFileSystem trả lại một FSDataOutputStream cho
Trang 30client để bắt đầu ghi data vào file Giống như trường hợp đọc, FSDataOutputStream bao một DFSOutputStream để điều khiển giao tiếp với các datanode và namenode
Hình 2-10 Một client ghi data đến HDFS
Khi client ghi data (bước 3) DFSOutputStream tách chúng thành các packet và ghi vào một hàng đợi bên trong gọi là data queue Data queue được dùng bởi
DataStreamer, nó có nhiệm vụ yêu cầu namenode phân phát chỗ cho các block mới bằng cách chọn ra một list các datanode thích hợp dùng chứa các bản sao List của các datanode tạo thành một pipeline-giả sử mức của bản sao là ba thì sẽ có ba node
trong pipeline DataStreamer dẫn luồng packet đến datanode đầu tiên trong
pipeline, nó lưu các packet và chuyển tiếp các packet đến datanode thứ hai, tương tự
với datanode thứ ba (bước 4) DFSOutputStream cũng duy trì một hàng đợi trong của packet đợi được datanode xác nhận gọi là ack queue Một packet sẽ bị loại bỏ
khỏi ack queue nếu nó được xác nhận bởi mọi datanode trong pipeline (bước 5) Nếu một datanode lỗi khi data đang được ghi vào nó thì các hành động sau sẽ được thực thi mà người dùng không hề hay biết Đầu tiên pipeline được đóng lại,
mọi datapacket trong ack queue được xếp lên đầu của data queue để các datanode
sau datanode lỗi không bị mất packet nào.Block hiện thời trên các datanode hoạt động sẽ được cho một định danh mới, nó sẽ giao tiếp với namenode để cho phần block trên datanode lỗi sẽ được xóa đi nếu datanode lỗi sau này được khôi phục lại Datanode lỗi sẽ bị loại bỏ khỏi pipeline và phần còn lại của block sẽ được ghi lên hai datanode còn tốt trong pipeline Namenode cảnh báo rằng số bản sao của block chưa đủ và sẽ sắp xếp để một bản sao nữa được tạo thành trên datanode khác
Khi client kết thúc ghi data sẽ gọi close() trên luồng (bước 6) Hành động này sẽ
đẩy các packet còn lại vào pipeline và đợi thông báo trước khi thông báo cho
Trang 312.3 HBase
2.3.1 Nền tảng lý thuyết từ Big Table của Google [3]
MapReduce cộng với GFS tạo thành xương sống cho việc xử lý dữ liệu lớn bao gồm toàn bộ search index của Google
Tuy vậy khả năng truy cập data ngẫu nhiên, gần với thời gian thực (ví dụ để sử dụng cho web service) vẫn còn thiếu Một hạn chế khác của GFS là khả năng xử lý file lớn rất tốt nhưng xử lý hàng triệu file nhỏ lại không tốt (đã nói đến trong phần Google File System) Google cố gắng tìm ra giải pháp để dùng trong những ứng dụng tương tác như Mail hoặc Analytics trong khi vẫn dùng hạ tầng cũ và dựa vào GFS cho việc sao lặp cũng như sự sẵn sàng của dữ liệu Data bao gồm nhiều thực thể nhỏ, hệ thống có nhiệm vụ gộp những thực thể nhỏ thành các file lớn và cung cấp một số loại chỉ mục cho phép người dùng truy cập data với việc tìm kiếm trên đĩa là ít nhất Cuối cùng hệ thống phải chứa được toàn bộ web crawl và làm việc với MapReduce để xây dựng search index kịp thời
Nhận thức được cơ sở dữ liệu quan hệ (RDBMS) không cung cấp được tính co giãn, các kỹ sư đã có cách tiếp cận khác: hy sinh một số tính chất quan hệ và dùng
một API đơn giản có các thao tác cơ bản create, read, update, delete (or CRUD) cộng với hàm scan duyệt qua các vùng khóa hay toàn bộ các bảng Google đã thiết
kế cơ sở dữ liệu cho riêng mình theo tinh thần trên và đến năm 2006 xuất bản bài
báo ra công luận có tên Bigtable: A Distributed Storage System for Structure Data
“ Bigtable là một hệ thống lưu trữ phân bố để quản trị data có cấu trúc được thiết
kế để co giãn đến kích thước rất lớn : dữ liệu đến mức petabytes phân bố trên hàng ngàn server thông thường có trên thị trường.”
“…một ánh xạ thưa, phân bố, nhiều chiều bền vững được sắp thứ tự.”
Bigtable đã được dùng tại Google ít nhất từ năm 2005 cho rất nhiều công việc khác nhau như xử lý theo lô (batch) hay ứng dụng data thời gian thực Data cũng rất
đa dạng từ nhỏ như các địa chỉ URL đến lớn như toàn bộ một trang web hay ảnh vệ tinh Bigtable đã rất thành công khi cung cấp một giải pháp hiệu quả cao, mềm dẻo cho nhiều sản phẩm của Google như Google Earth, Google Reader, Google Finance
và Google Analytics
2.3.2 Cấu trúc của HBase
HBase được hiện thực khá chính xác theo kiến trúc Bigtable Phiên bản đầu tiên của HBase là một phần của Hadoop 0.15.0 vào tháng 10 năm 2007 Tháng 5 năm
2010 HBase trở thành một trong những dự án độc lập hàng đầu của Apache Software Foundation Hiện nay Adobe, Facebook, StumbleUpon, Twitter, các nhóm của Yahoo, v.v… đang dùng Hbase cho việc lưu trữ và truy cập dữ liệu
Trang 32a) Tables, Rows, Columns, Cells
Đơn vị cơ bản nhất của HBase là column, một hay nhiều column tạo thành một row được xác định duy nhất bằng row key Nhiều row tạo thành một table, có thể có nhiều table Mỗi column có thể có nhiều version chứa trong các cell riêng biệt Các row luôn được xếp theo thứ tự từ điển của row key Điều này có gì đó giống như primary key index trong RDBMS Row key luôn là duy nhất Trong khi Bigtable chỉ xét đến một index thì HBase hỗ trợ cả secondary index Row key là một dãy byte bất kỳ và không cần thiết phải có thể đọc được đối với con người Rows được tạo thành từ các column, các column này nhóm thành các column family Điều này giúp xây dựng các biên đề tài hay ngữ nghĩa giữa data và áp dụng một số đặc tính như compression hay xác định rõ chúng sẽ ở trong memory Mọi column trong một column family được lưu trữ trong cùng một file lưu trữ cấp thấp gọi là HFile
Column families cần được định nghĩa khi tạo table và không thể thay đổi thường xuyên cũng như không thể có quá nhiều Số columm families tối đa khoảng 10-12 nhưng trong thực tế thì con số đó nhỏ hơn rất nhiều Tên của column family phải là những ký tự in được, không được trùng với tên hoặc các giá trị khác
Column thường được biểu diễn là family:qualifier với qualifier là một chuỗi
byte bất kỳ Ngược với số lượng hạn chế của column families, không có hạn chế nào cho số lượng column : bạn có thể có hàng triệu column trong một column families Cũng không có giới hạn nào về kiểu hay độ dài cho giá trị của column Hình 2.11 mô tả trực quan sự khác nhau giữa rows trong một database thông thường và rows trong thiết kế hướng column của HBase
Trong một database với lược đồ cố định giá trị NULL lưu trữ tại nơi không có
dữ liệu, còn trong HBase ta có thể bỏ toàn bộ column Hay nói cách khác không có giá trị NULL, nó không xuất hiện trong không gian lưu trữ
Một số khái niệm mới như sau:
Mỗi giá trị của column hay cell được gán nhãn thời gian (timestamp) ngầm bởi hệ thống hay tường minh bởi người dùng Điều này được dùng trong việc lưu nhiều version của một giá trị khi nó thay đổi theo thời gian
Các version khác nhau của một cell được lưu trữ theo thứ tự ngược của timestamp cho phép ta đọc giá trị mới nhất đầu tiên Người dùng có thể xác định
lưu bao nhiêu version của một giá trị Ngoài ra có hỗ trợ cho predicate deletion cho
phép ta chọn ví dụ chỉ lưu lại những giá trị ghi trong tuần trước Giá trị của cell là những array của bytes
Mô hình Bigtable mà Hbase hiện thực là một ánh xạ nhiều chiều, bền vững, thưa, phân bố Ta có thể biểu diễn việc truy cập data như sau:
Trang 33Hình 2-11 Rows và columns giống như các thẻ (tags)
Theo phong cách lập trình ta có thể viết như sau:
SortedMap<RowKey, List<SortedMap<Column, List<Value, Timestamp>>>>
SortedMap đầu tiên là bảng chứa một List của column families Các column families này chứa SortedMap khác biểu diễn các column và các giá trị của chúng Các giá trị này ở trong List cuối cùng chứa giá trị và timestamp gán vào
Một tính chất lý thú của mô hình này là các cells có thể tồn tại trong nhiều version và các column có thể được ghi vào những thời điểm khác nhau Bằng cách ngầm định, API cung cấp cho chúng ta một mô hình kết dính các column trong khi
tự động lấy các giá trị mới nhất Hình 2.12 “Một góc nhìn theo thời gian của một row” biểu diễn một phần của một row trong table
Sơ đồ 2.12 hiển thị thành phần thời gian dùng timestamp tn khi ghi vào cell Chỉ
số tăng dần diễn tả các giá trị được thêm vào những thời điểm khác nhau Hình 2.13
“Row được biểu diễn dưới dạng bảng tính” là một cách nhìn dữ liệu khác
Trang 34Hình 2-12 Một góc nhìn theo thời gian của các thành phần của một row
Hình 2-13 Row được biểu diễn dưới dạng bảng tính
Mặc dù các cell được thêm vào các thời điểm khác nhau và nằm trong nhiều version ta vẫn nhìn thấy row là sự kết hợp của các column và các giá trị version mới nhất hay nói cách khác là giá trị tn cao nhất API cung cấp cách truy vấn giá trị tại một timestamp nhất định
b) Cơ chế phân chia tự động
Đơn vị cơ bản của tính co giãn và cân bằng tải của HBase gọi là region Các dãy liên tục của row lưu trữ cùng với nhau Hệ thống sẽ tự động tách chúng ra khi chúng trở nên quá lớn Ngoài ra chúng cũng tự động kết hợp lại để giảm số lượng và các file lưu trữ
Region của Hbase tương đương với range partition thường dùng trong việc phân
chia database Các region trải rộng qua nhiều server vật lý, nghĩa là phân bố tải và
do đó cung cấp tính co giãn
Lúc đầu chỉ có một region cho một table, ta bắt đầu thêm dữ liệu vào table Hệ thống sẽ giám sát để đảm bảo rằng data không vượt quá kích thước đã cấu hình từ lúc đầu Nếu ta vượt quá giá trị tới hạn thì region sẽ tách ra làm đôi tại middle key –
là row key tại điểm giữa của region – tạo thành hai nửa bằng nhau
Mỗi region được phục vụ bởi chính xác một region server, và mỗi server có thể
phục vụ nhiều region tại bất cứ thời điểm nào Hình 2.14 biểu diễn góc nhìn luận lý của một table là một tập hợp các region từ nhiều region server
Trang 35Nguyên tắc cơ bản là số region trên một server và kích thước của region phụ thuộc vào mức độ hiệu quả một server đơn lẻ phục vụ được
Hình 2-14 Rows được nhóm lại thành các group và được phục vụ bởi các server khác nhau
Các region chia tách này giống cơ chế auto sharding của các hệ thống khác Các region cho phép khôi phục nhanh khi một server bị lỗi và cân bằng tải tốt bởi vì chúng có thể di chuyển giữa các server khi một server bị quá tải hay không hoạt động do lỗi hoặc rút khỏi hệ thống
Quá trình chia tách diễn ra rất nhanh – gần như ngay lập tức – bởi vì các region
bị split đơn giản tiếp tục đọc từ các file lưu trữ ban đầu cho đến khi dữ liệu được nén lại và ghi vào các region mới
c) API
API cung cấp các các tác vụ để tạo, xóa bảng và column families Thêm vào đó API còn có các tính năng để thay đổi metadata của table và column families như độ nén hay kích thước của block Ngoài ra còn có các tác vụ thông thường cho client
để tạo hay xóa giá trị cũng như truy xuất giá trị với row key cho trước
Tác vụ scan của API cho phép duyệt qua các dãy của row một cách hiệu quả và
giới hạn các column hay bao nhiêu version của mỗi cell được truy xuất Các column được so trùng dùng filters và chọn version dùng khoảng thời gian bằng cách chọn thời điểm bắt đầu và thời điểm kết thúc
Hệ thống còn hỗ trợ các giao tác cho từng row, hiện thực chuỗi
read-modify-write cho từng row Client có thể các tác vụ theo lô ( batch ) để tăng hiệu quả Code do client viết có thể thực thi trong vùng địa chỉ của server Framework của
server-side hỗ trợ tính năng này gọi là Coprocessor Code này truy cập dữ liệu cục
bộ của server để thực hiện các công việc light-weight batch hay dùng công thức để phân tích và tổng hợp số liệu
Trang 36Cuối cùng hệ thống HBase có thể tích hợp với MapReduce framework bằng cách tạo ra một lớp bao (wrapper) biến đổi các table thành nguồn đầu vào hay đích đầu ra cho MapReduce job
Không có ngôn ngữ dùng cho HBase như SQL đối với các RDBMS khác để query dữ liệu Truy cập data không thể thực hiện bằng cách mô tả mà chỉ thực hiện được bằng lệnh thông qua API của client Điều này làm cho việc sử dụng HBase trở nên khó khăn do đó chỉ phổ biến trong giới kỹ sư phần mềm Đối với HBase phần lớn code viết bằng Java nhưng cũng có thể truy cập data từ một số ngôn ngữ lập trình khác như Python, Rubby, v.v…
d) Hiện thực
Dữ liệu chứa trong các file gọi là HFile là những ánh xạ (map) không thay đổi
có thứ tự và bền vững từ keys đến values Về cấu tạo bên trong, các file này là những khối nối tiếp nhau với khối index nằm ở cuối Index được tải lên khi HFile được mở và nằm trong memory Khối mặc định là 64KB nhưng có thể thay đổi khi cần thiết Các file lưu trữ này cung cấp API cho phép truy xuất các giá trị đặc biệt
và scan các dãy giá trị khi biết key đầu và key cuối
Bởi vì mỗi HFile có một khối index, việc tìm kiếm chỉ cần một lần trên đĩa Đầu tiên block có thể chứa key cần tìm được xác định bằng cách tìm kiếm nhị phân trên block index trên memory, sau đó một block sẽ được đọc từ đĩa để tìm ra key cần thiết
Các file lưu trữ được lưu trên hệ thống file Hadoop (Hadoop Distributed File System –HDFS), HDFS cung cấp một tầng lưu trữ co giãn, bền vững, nhân bản được (HDFS sẽ được nói rõ ở phần sau) HDFS đảm bảo rằng data sẽ không bị mất bằng cách ghi các thay đổi trên nhiều server vật lý
Khi data được cập nhật, nó sẽ được ghi vào một commit-log gọi là write-ahead
log (WAL) trên HBase đầu tiên rồi chứa trong in-memory memstore Một khi data
trong memory vượt quá giá trị maximum cho trước, chúng sẽ được đẩy ra đĩa thành một HFile Sau khi đẩy ra đĩa commit log sẽ được xóa đến giá trị cuối cùng chưa được flush Trong khi hệ thống đẩy memstore ra đĩa nó vẫn tiếp tục phục vụ đọc, ghi Điều này được thực hiện bằng cách tra cứu trong memstore trong memory, ở đó vẫn có cập nhật, insert cho data mới trong khi data cũ được chuyển đổi thành file
Ta để ý rằng data trong memstore được sắp xếp theo key giống như HFile trên đĩa
do đó không cần thêm các thao tác sắp xếp hay tác vụ đặc biệt khác
Bởi vì các file lưu trữ không thay đổi, ta không thể xóa các giá trị một cách đơn
giản bằng cách loại bỏ cặp key/value Thay vào đó một delete marker sẽ được ghi
vào để đánh dấu key đã cho bị xóa Trong quá trình đọc dữ liệu các delete marker sẽ che phủ các giá trị và che dấu chúng đối với người dùng
Trang 37Đọc dữ liệu là quá trình trộn data chứa trong memstore (hay data chưa được ghi lên đĩa ) với data trên file lưu trữ Chú ý rằng WAL không bao giờ được dùng trong quá trình đọc file, chúng chỉ được dùng cho mục đích khôi phục dữ liệu khi một server bị lỗi trước khi quá trình ghi file hoàn thành
Bởi vì việc đẩy memstore ra đĩa làm cho số HFile tạo ra ngày càng nhiều, HBase
có một cơ chế quản lý việc này bằng cách trộn các file thành một file lớn hơn dùng
nén file Có hai cách nén: minor compaction và major compaction Cách thứ nhất
giảm số lượng file lưu trữ bằng cách ghi lại các file nhỏ vào các file lớn hơn, dùng phương pháp trộn n-way Bởi vì tất cả dữ liệu đã được sắp có thứ tự trên mỗi HFile nên việc trộn này rất nhanh và chỉ phụ thuộc vào IO của đĩa
Major compaction ghi lại các file trong phạm vi một column family của một
region thành một file Phương pháp này có một số tính năng khác so với minor
compaction: do nó có thể scan các cặp key/value nên nó sẽ bỏ đi các thực thể chứa
delete marker Xóa có điều kiện ( predicate delete) được dùng ở đây rất tốt – ví dụ loại bỏ các giá trị hết hạn do ta đã cấu hình time-to-live từ đầu hay bởi vì các thực thể đó có quá nhiều version
HBase có ba thành phần chính: client library, một master server và nhiều region server Các region server có thể thêm vào hoặc lấy đi trong khi hệ thống đang hoạt động để cân bằng tải Master server chịu trách nhiệm gán region cho region server
và dùng Apache ZooKeeper (một dịch vụ điều phối phân bố đáng tin cậy, ổn định,
có tính sẵn sàng cao) để thực hiện các nhiệm vụ của mình
Apache ZooKeeper: là một dự án mã nguồn mở và nằm trong Apache Software
Foundation ZooKeeper giống như Chubby của Google dùng với Bigtable ZooKeeper cung cấp cách truy xuất hệ thống với directories và files (gọi là znode) dùng trong hệ thống phân bố để theo dõi ownership, register services, updates Mỗi region server tạo một node tạm trong ZooKeeper, nhờ đó master server phát hiện các server trong hệ thống Chúng cũng được dùng theo dõi lỗi của server của network
Các node tạm tương ứng với session giữa ZooKeeper và client tạo ra chúng Các session có một cơ chế tạo nhịp tim để khi ZooKeeper không nhận được nhịp tim này nữa thì ZooKeeper sẽ xóa các node tạm thời tương ứng
HBase dùng ZooKeeper để đảm bảo rằng chỉ có một master server chạy, chứa vùng khởi động cho region cũng như registry cho các region server và nhiều mục đích khác ZooKeeper là một thành phần quan trọng, thiếu nó HBase không thể hoạt động
Hình 2-14 mô tả một hệ thống HBase cluster gồm các máy tính liên kết với nhau Hình 2-15 mô tả các thành phần của HBase phối hợp với nhau để tạo thành một
hệ thống, sử dụng các thành phần có sẵn như HDFS và ZooKeeper nhưng đồng thời cũng thêm vào đó các lớp của riêng mình