Apache Pig UDF: Phần 1 - Chức năng Đánh giá, Tổng hợp & Lọc



Bài đăng này mô tả về Apache Pig UDF - Chức năng Đánh giá, Tổng hợp & Lọc. Hãy xem các Chức năng Đánh giá, Tổng hợp & Lọc.

Apache Pig cung cấp hỗ trợ rộng rãi cho các chức năng do người dùng xác định (UDF) như một cách để chỉ định xử lý tùy chỉnh. Các UDF lợn hiện có thể được thực thi bằng ba ngôn ngữ: Java, Python, JavaScript và Ruby. Hỗ trợ rộng rãi nhất được cung cấp cho các hàm Java.





Các UDF của Java có thể được gọi thông qua nhiều cách. UDF đơn giản nhất chỉ có thể mở rộng EvalFunc, điều này chỉ yêu cầu thực hiện hàm thực thi. Mỗi UDF Eval phải thực hiện điều này. Ngoài ra, nếu một hàm là đại số, nó có thể triển khai giao diện Algebraic để cải thiện đáng kể hiệu suất truy vấn.

Tầm quan trọng của UDF trong Pig:

Pig cho phép người dùng kết hợp các toán tử hiện có với mã của riêng họ hoặc của người khác thông qua UDF. Ưu điểm của Pig là khả năng cho phép người dùng kết hợp các toán tử của nó với mã của riêng họ hoặc của người khác thông qua UDF. Cho đến hết phiên bản 0.7, tất cả các UDF phải được viết bằng Java và được triển khai dưới dạng các lớp Java. Điều này giúp dễ dàng thêm các UDF mới vào Pig bằng cách viết một lớp Java và thông báo cho Pig về tệp JAR.



Bản thân Pig đi kèm với một số UDF. Trước phiên bản 0.8, nó là một bộ rất hạn chế chỉ có các hàm tổng hợp SQL tiêu chuẩn và một số hàm khác. Trong 0.8, một số lượng lớn các UDF xử lý chuỗi, toán học và kiểu phức tạp tiêu chuẩn đã được thêm vào.

Piggybank là gì?

Piggybank là một tập hợp các UDF do người dùng đóng góp được phát hành cùng với Pig. Piggybank UDF không được bao gồm trong Pig JAR, vì vậy bạn phải đăng ký chúng theo cách thủ công trong tập lệnh của mình. Bạn cũng có thể viết UDF của riêng mình hoặc sử dụng những UDF do người dùng khác viết.

Đánh giá chức năng

Lớp UDF mở rộng lớp EvalFunc là cơ sở cho tất cả các chức năng Eval. Tất cả các hàm Đánh giá mở rộng lớp Java ‘org.apache.pig.EvalFunc. ‘Nó được tham số hóa với kiểu trả về của UDF là Chuỗi Java trong trường hợp này. Phương thức cốt lõi trong lớp này là ‘execute.’ Dòng đầu tiên của mã chỉ ra rằng hàm là một phần của gói myudfs.



Nó nhận một bản ghi và trả về một kết quả, kết quả này sẽ được gọi cho mọi bản ghi đi qua đường ống thực thi. Nó cần một bộ tuple, chứa tất cả các trường mà tập lệnh chuyển đến UDF của bạn làm đầu vào. Sau đó, nó trả về kiểu mà bạn có EvalFunc được tham số hóa.

Hàm này được gọi trên mọi bộ dữ liệu đầu vào. Đầu vào của hàm là một bộ dữ liệu với các tham số đầu vào theo thứ tự chúng được truyền cho hàm trong tập lệnh Pig. Trong ví dụ minh họa bên dưới, hàm lấy chuỗi làm đầu vào. Hàm sau chuyển đổi chuỗi từ chữ thường sang chữ hoa. Bây giờ hàm đã được thực hiện, nó cần được biên dịch và đưa vào một JAR.

làm thế nào để so sánh hai chuỗi
package myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data.Tuple public class UPPER mở rộng EvalFunc {public String thực thi (Tuple input) ném IOException {if (input == null || input.size () == 0) return null try {String str = (String) input.get (0) return str.toUpperCase ()} catch (Exception e) {throw new IOException ('Hàng đầu vào xử lý ngoại lệ bắt buộc', e)}}}

Chức năng tổng hợp:

Các hàm tổng hợp là một loại hàm Eval phổ biến khác. Hàm tổng hợp thường được áp dụng cho dữ liệu được nhóm. Hàm Aggregate nhận một túi và trả về một giá trị vô hướng. Một tính năng thú vị và có giá trị của nhiều hàm Aggregate là chúng có thể được tính toán từng bước theo cách phân tán. Trong thế giới Hadoop, điều này có nghĩa là các tính toán từng phần có thể được thực hiện bởi Bản đồ và Bộ kết hợp và kết quả cuối cùng có thể được tính toán bởi Bộ giảm.

Điều rất quan trọng là phải đảm bảo rằng các hàm Tổng hợp là đại số được thực hiện như vậy. Ví dụ về loại này bao gồm COUNT, MIN, MAX và AVERAGE được tích hợp sẵn.

ĐẾM là một ví dụ về một hàm đại số trong đó chúng ta có thể đếm số phần tử trong một tập con dữ liệu và sau đó tổng các số đếm để tạo ra kết quả cuối cùng. Hãy xem việc triển khai hàm COUNT:

public class COUNT mở rộng EvalFunc thực thi Đại số {public Long executive (Tuple input) ném IOException {return count (input)} public String getInitial () {return Initial.class.getName ()} public String getIntermed () {return Intermed.class. getName ()} public String getFinal () {return Final.class.getName ()} static public class Ban đầu mở rộng EvalFunc {public Tuple Operating (Tuple input) ném IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} static public class Intermed mở rộng EvalFunc {public Tuple execute (Tuple input) ném IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} static public class Final extension EvalFunc {public Tuple thi hành (Tuple input) ném IOException {return sum (input)}} được bảo vệ tĩnh Số lượng dài (đầu vào Tuple) ném ExecException {Object giá trị = input.get (0) if (giá trị instanceof DataBag) return ((DataBag) giá trị) .size () else if (giá trị instanceof Map) trả về các giá trị Long (((Bản đồ)) mới) .size ())} Long sum được bảo vệ tĩnh (Tuple i nput) ném ExecException, NumberFormatException {DataBag giá trị = (DataBag) input.get (0) long sum = 0 for (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) sum + = (Dài) t.get (0)} trả về tổng}}

COUNT triển khai giao diện Đại số trông giống như sau:

public interface Algebraic {public String getInitial () public String getIntermed () public String getFinal ()}

Để một hàm có thể trở thành đại số, nó cần phải triển khai giao diện Đại số bao gồm định nghĩa của ba lớp bắt nguồn từ EvalFunc. Hợp đồng là chức năng thực thi của lớp Ban đầu được gọi một lần và được chuyển tới bộ nguyên liệu đầu vào ban đầu. Đầu ra của nó là một bộ tuple chứa kết quả từng phần. Hàm thực thi của lớp Intermed có thể được gọi không hoặc nhiều lần và lấy đầu vào của nó là một bộ giá trị chứa các kết quả từng phần được tạo ra bởi lớp Ban đầu hoặc bởi các lệnh gọi trước của lớp Intermed và tạo ra một bộ giá trị với kết quả từng phần khác. Cuối cùng, hàm thực thi của lớp Final được gọi và cho kết quả cuối cùng là một kiểu vô hướng.

Chức năng Bộ lọc:

Các hàm bộ lọc là các hàm Eval trả về giá trị Boolean. Nó có thể được sử dụng ở bất cứ đâu mà một biểu thức Boolean thích hợp, bao gồm toán tử FILTER hoặc biểu thức Bincond. Apache Pig không hỗ trợ hoàn toàn Boolean, do đó, các hàm Bộ lọc không thể xuất hiện trong các câu lệnh như ‘Foreach’, nơi kết quả được xuất cho một toán tử khác. Tuy nhiên, các hàm Bộ lọc có thể được sử dụng trong các câu lệnh bộ lọc.

Ví dụ dưới đây triển khai hàm IsEmpty:

import java.io.IOException import java.util.Map import org.apache.pig.FilterFunc import org.apache.pig.PigException import org.apache.pig.backend.executionengine.ExecException import org.apache.pig.data.DataBag import org.apache.pig.data.Tuple import org.apache.pig.data.DataType / ** * Xác định xem túi hoặc bản đồ có trống không. * / public class IsEmpty mở rộng FilterFunc {@Override public Boolean thi (Tuple input) ném IOException {try {Object giá trị = input.get (0) if (values ​​instanceof DataBag) return ((DataBag) giá trị) .size () == 0 else if (các giá trị instanceof Map) trả về ((Bản đồ) các giá trị) .size () == 0 else {int errCode = 2102 String msg = 'Không thể kiểm tra a' + DataType.findTypeName (giá trị) + 'cho sự trống rỗng.' ném ExecException mới (msg, errCode, PigException.BUG)}} catch (ExecException ee) {ném ee}}}