Apache HBase là cơ sở dữ liệu Hadoop và dựa trên Hệ thống tệp phân tán Hadoop ( HDFS ). HBase giúp bạn có thể truy cập ngẫu nhiên và cập nhật dữ liệu được lưu trữ trong HDFS, nhưng các tệp trong HDFS chỉ có thể được nối vào và không thể thay đổi sau khi chúng được tạo. Vì vậy, bạn có thể hỏi, làm thế nào để HBase cung cấp khả năng đọc và ghi với độ trễ thấp? Trong bài đăng trên blog này, chúng tôi giải thích điều này bằng cách mô tả đường dẫn ghi của HBase - cách dữ liệu được cập nhật trong HBase.
Đường dẫn ghi là cách một HBase hoàn thành các hoạt động đặt hoặc xóa. Đường dẫn này bắt đầu từ máy khách, di chuyển đến máy chủ khu vực và kết thúc khi dữ liệu cuối cùng được ghi vào tệp dữ liệu HBase được gọi là HFile . Bao gồm trong thiết kế đường dẫn ghi là các tính năng mà HBase sử dụng để ngăn mất dữ liệu trong trường hợp máy chủ khu vực bị lỗi. Do đó, hiểu đường dẫn ghi có thể cung cấp thông tin chi tiết về cơ chế ngăn chặn mất dữ liệu gốc của HBase.
Mỗi bảng HBase được lưu trữ và quản lý bởi các nhóm máy chủ chia thành ba loại:
- Một máy chủ chính đang hoạt động
- Một hoặc nhiều máy chủ chính dự phòng
- Nhiều máy chủ khu vực
Máy chủ vùng góp phần xử lý các bảng HBase. Bởi vì bảng HBase có thể lớn, chúng được chia thành các phân vùng được gọi là vùng. Mỗi máy chủ vùng xử lý một hoặc nhiều vùng này. Lưu ý rằng vì máy chủ khu vực là máy chủ duy nhất cung cấp dữ liệu bảng HBase, sự cố máy chủ chính không thể gây mất dữ liệu.
Dữ liệu HBase được tổ chức tương tự như một bản đồ được sắp xếp, với không gian chính đã được sắp xếp được phân chia thành các phân đoạn hoặc vùng khác nhau. Ứng dụng khách HBase cập nhật bảng bằng cách gọi lệnh đặt hoặc xóa. Khi khách hàng yêu cầu thay đổi, yêu cầu đó được chuyển đến máy chủ khu vực ngay lập tức theo mặc định. Tuy nhiên, theo chương trình, máy khách có thể lưu vào bộ nhớ cache các thay đổi ở phía máy khách và chuyển những thay đổi này sang máy chủ khu vực trong một đợt, bằng cách tắt chế độ tự động. Nếu tắt chế độ autoflush, các thay đổi sẽ được lưu vào bộ nhớ đệm cho đến khi kích hoạt flush-commits hoặc bộ đệm đầy tùy thuộc vào kích thước bộ đệm được đặt theo chương trình hoặc được định cấu hình với tham số “hbase.client.write.buffer”.
Vì khóa hàng được sắp xếp, nên dễ dàng xác định máy chủ khu vực quản lý khóa nào. Yêu cầu thay đổi dành cho một hàng cụ thể. Mỗi khóa hàng thuộc về một khu vực cụ thể được cung cấp bởi một máy chủ khu vực. Vì vậy, dựa trên key của put hoặc delete, ứng dụng khách HBase có thể định vị một máy chủ khu vực thích hợp. Lúc đầu, nó định vị địa chỉ của máy chủ vùng lưu trữ vùng -ROOT- từ nhóm túc số ZooKeeper. Từ máy chủ vùng gốc, máy khách tìm ra vị trí của máy chủ vùng lưu trữ vùng -META-. Từ máy chủ khu vực meta, sau đó chúng tôi cuối cùng xác định vị trí máy chủ khu vực thực tế phục vụ khu vực được yêu cầu. Đây là một quy trình gồm ba bước, do đó, vị trí khu vực được lưu vào bộ nhớ đệm để tránh chuỗi hoạt động tốn kém này. Nếu vị trí được lưu trong bộ nhớ cache không hợp lệ (ví dụ:chúng tôi nhận được một số ngoại lệ vùng không xác định), đã đến lúc định vị lại vùng và cập nhật bộ nhớ cache.
Sau khi máy chủ vùng bên phải nhận được yêu cầu, thay đổi không thể được ghi vào HFile ngay lập tức vì dữ liệu trong HFile phải được sắp xếp theo khóa hàng. Điều này cho phép tìm kiếm các hàng ngẫu nhiên một cách hiệu quả khi đọc dữ liệu. Dữ liệu không thể được chèn ngẫu nhiên vào HFile. Thay vào đó, thay đổi phải được ghi vào một tệp mới. Nếu mỗi bản cập nhật được ghi vào một tệp, nhiều tệp nhỏ sẽ được tạo. Một giải pháp như vậy sẽ không thể mở rộng cũng như không hiệu quả để hợp nhất hoặc đọc sau này. Do đó, các thay đổi không được ghi ngay vào HFile mới.
Thay vào đó, mỗi thay đổi được lưu trữ ở một nơi trong bộ nhớ được gọi là kho lưu trữ , hỗ trợ ghi ngẫu nhiên một cách rẻ và hiệu quả. Dữ liệu trong kho lưu trữ được sắp xếp giống như dữ liệu trong HFile. Khi memstore tích lũy đủ dữ liệu, toàn bộ tập hợp đã sắp xếp sẽ được ghi vào HFile mới trong HDFS. Hoàn thành một tác vụ ghi lớn sẽ hiệu quả và tận dụng được thế mạnh của HDFS.
Mặc dù việc ghi dữ liệu vào memstore là hiệu quả, nhưng nó cũng dẫn đến một yếu tố rủi ro:Thông tin lưu trong memstore được lưu trong bộ nhớ dễ bay hơi, vì vậy nếu hệ thống bị lỗi, tất cả thông tin trong memstore sẽ bị mất. Để giúp giảm thiểu rủi ro này, HBase lưu các bản cập nhật trong nhật ký ghi trước ( WAL ) trước khi ghi thông tin vào memstore. Bằng cách này, nếu máy chủ khu vực bị lỗi, thông tin được lưu trữ trong kho lưu trữ của máy chủ đó có thể được khôi phục từ WAL của nó.
Lưu ý:Theo mặc định, WAL được bật, nhưng quá trình ghi tệp WAL vào đĩa sẽ tiêu tốn một số tài nguyên. WAL có thể bị vô hiệu hóa, nhưng điều này chỉ nên được thực hiện nếu nguy cơ mất dữ liệu không phải là mối quan tâm. Nếu bạn chọn tắt WAL, hãy xem xét triển khai giải pháp khôi phục thảm họa của riêng bạn hoặc chuẩn bị cho khả năng mất dữ liệu.
Dữ liệu trong tệp WAL được tổ chức khác với HFile. Các tệp WAL chứa danh sách các chỉnh sửa, với một chỉnh sửa đại diện cho một lần đặt hoặc xóa. Nội dung chỉnh sửa bao gồm thông tin về thay đổi và khu vực áp dụng thay đổi. Các chỉnh sửa được viết theo thứ tự thời gian, do đó, để tồn tại lâu dài, các bổ sung được thêm vào cuối tệp WAL được lưu trữ trên đĩa. Vì các tệp WAL được sắp xếp theo thứ tự thời gian, nên không bao giờ cần ghi vào một vị trí ngẫu nhiên trong tệp.
Khi WAL phát triển, chúng cuối cùng bị đóng và một tệp WAL mới, đang hoạt động được tạo để chấp nhận các chỉnh sửa bổ sung. Điều này được gọi là "cuộn" tệp WAL. Khi tệp WAL được cuộn, không có thay đổi bổ sung nào được thực hiện đối với tệp cũ.
Theo mặc định, tệp WAL được cuộn khi kích thước của nó bằng khoảng 95% kích thước khối HDFS. Bạn có thể định cấu hình hệ số bằng tham số:“hbase.regionserver.logroll.multiplier” và kích thước khối bằng tham số:“hbase.regionserver.hlog.blocksize”. Tệp WAL cũng được cuộn định kỳ dựa trên khoảng thời gian được định cấu hình “hbase.regionserver.logroll.period”, một giờ theo mặc định, ngay cả khi kích thước tệp WAL nhỏ hơn giới hạn đã định cấu hình.
Hạn chế kích thước tệp WAL tạo điều kiện phát lại tệp hiệu quả nếu cần khôi phục. Điều này đặc biệt quan trọng trong quá trình phát lại tệp WAL của một vùng vì trong khi một tệp đang được phát lại, vùng tương ứng không khả dụng. Mục đích cuối cùng là ghi tất cả các thay đổi từ mỗi tệp WAL vào đĩa và duy trì nội dung đó trong một HFile. Sau khi thực hiện xong, tệp WAL có thể được lưu trữ và cuối cùng nó sẽ bị xóa bởi chuỗi daemon LogCleaner. Lưu ý rằng các tệp WAL đóng vai trò như một biện pháp bảo vệ. Các tệp WAL chỉ cần được phát lại để khôi phục các bản cập nhật nếu không sẽ bị mất sau sự cố máy chủ khu vực.
Máy chủ vùng phục vụ nhiều vùng, nhưng không có tệp WAL cho từng vùng. Thay vào đó, một tệp WAL đang hoạt động được chia sẻ giữa tất cả các khu vực do máy chủ khu vực phục vụ. Vì tệp WAL được cuộn theo định kỳ, một máy chủ khu vực có thể có nhiều tệp WAL. Lưu ý rằng chỉ có một WAL hoạt động trên mỗi máy chủ khu vực tại một thời điểm nhất định.
Giả sử gốc HBase mặc định là “/ hbase”, tất cả các tệp WAL cho phiên bản máy chủ khu vực được lưu trữ trong cùng một thư mục gốc, như sau:
/hbase/.logs/<host>, <port>,<startcode>
Ví dụ:
/hbase/.logs/srv.example.com,60020,1254173957298
Tệp nhật ký WAL được đặt tên như sau:
/hbase/.logs/<host>, <port>,<startcode>/<host>%2C <port>%2C<startcode>.<timestamp>
Ví dụ:
/hbase/.logs/srv.example.com,60020,1254173957298/srv.example.com%2C60020%2C1254173957298.1254173957495
Mỗi chỉnh sửa trong tệp WAL có một id trình tự duy nhất. Id này tăng lên để bảo toàn thứ tự của các chỉnh sửa. Bất cứ khi nào tệp nhật ký được cuộn, id trình tự tiếp theo và tên tệp cũ sẽ được đưa vào bản đồ trong bộ nhớ. Thông tin này được sử dụng để theo dõi id trình tự tối đa của mỗi tệp WAL để chúng tôi có thể dễ dàng tìm ra liệu tệp có thể được lưu trữ sau này khi một số kho lưu trữ được chuyển vào đĩa hay không.
Các chỉnh sửa và id trình tự của chúng là duy nhất trong một khu vực. Bất kỳ khi nào một chỉnh sửa được thêm vào nhật ký WAL, id trình tự của chỉnh sửa cũng được ghi lại là id trình tự cuối cùng được ghi. Khi kho lưu trữ được chuyển vào đĩa, id trình tự cuối cùng được viết cho vùng này sẽ bị xóa. Nếu id trình tự cuối cùng được ghi vào đĩa giống với id trình tự tối đa của tệp WAL, thì có thể kết luận rằng tất cả các chỉnh sửa trong tệp WAL cho vùng này đã được ghi vào đĩa. Nếu tất cả các chỉnh sửa cho tất cả các vùng trong tệp WAL đã được ghi vào đĩa, thì rõ ràng là không cần chia nhỏ hoặc phát lại và tệp WAL có thể được lưu trữ.
Cuộn tệp WAL và xóa vào kho lưu trữ ghi nhớ là hai hành động riêng biệt và không nhất thiết phải xảy ra cùng nhau. Tuy nhiên, chúng tôi không muốn giữ quá nhiều tệp WAL cho mỗi máy chủ khu vực để tránh mất thời gian khôi phục trong trường hợp máy chủ khu vực bị lỗi. Do đó, khi cuộn tệp WAL, HBase sẽ kiểm tra xem có quá nhiều tệp WAL hay không và quyết định vùng nào nên được xóa để có thể lưu trữ một số tệp WAL.
Trong bài đăng này, chúng tôi giải thích đường dẫn ghi HBase, đó là cách dữ liệu trong HBase được tạo và / hoặc cập nhật. Một số phần quan trọng của nó là:
- Cách máy khách định vị máy chủ khu vực,
- Memstore hỗ trợ ghi ngẫu nhiên nhanh,
- Tệp WAL là cách để tránh mất dữ liệu trong trường hợp máy chủ khu vực bị lỗi.
Chúng ta sẽ nói về các định dạng HFile, tách tệp WAL, v.v. trong các bài viết tiếp theo.