Tôi có bảng Hive chứa dữ liệu của các cuộc gọi của khách hàng. Để đơn giản xem xét nó có 2 cột, cột đầu tiên giữ ID khách hàng và cột thứ hai giữ dấu thời gian của cuộc gọi (dấu thời gian unix).Tính toán sự khác biệt giữa các bản ghi liên tiếp trong Hadoop với Truy vấn Hive
Tôi có thể truy vấn bảng này để tìm tất cả các cuộc gọi cho mỗi khách hàng:
SELECT * FROM mytable SORT BY customer_id, call_time;
Kết quả là:
Customer1 timestamp11
Customer1 timestamp12
Customer1 timestamp13
Customer2 timestamp21
Customer3 timestamp31
Customer3 timestamp32
...
Có thể tạo một truy vấn Hive trả về, đối với mỗi khách hàng , bắt đầu từ cuộc gọi thứ hai, khoảng thời gian giữa hai cuộc gọi thành công? Đối với ví dụ trên truy vấn mà nên trở lại:
Customer1 timestamp12-timestamp11
Customer1 timestamp13-timestamp12
Customer3 timestamp32-timestamp31
...
Tôi đã cố gắng để thích ứng với các giải pháp từ sql solution, nhưng tôi bị mắc kẹt với những hạn chế Hive: it accepts subqueries only in FROM và joins must contain only equalities.
Cảm ơn bạn.
EDIT1:
Tôi đã cố gắng sử dụng một hàm Hive UDF:
public class DeltaComputerUDF extends UDF {
private String previousCustomerId;
private long previousCallTime;
public String evaluate(String customerId, LongWritable callTime) {
long callTimeValue = callTime.get();
String timeDifference = null;
if (customerId.equals(previousCustomerId)) {
timeDifference = new Long(callTimeValue - previousCallTime).toString();
}
previousCustomerId = customerId;
previousCallTime = callTimeValue;
return timeDifference;
}}
và sử dụng nó với cái tên "đồng bằng".
Nhưng có vẻ như (từ nhật ký và kết quả) đang được sử dụng vào thời gian MAP. 2 vấn đề nảy sinh từ đây:
Đầu tiên: Các bảng dữ liệu phải được sắp xếp theo ID khách hàng và timestamp trước khi sử dụng chức năng này. Truy vấn:
SELECT customer_id, call_time, delta(customer_id, call_time) FROM mytable DISTRIBUTE BY customer_id SORT BY customer_id, call_time;
không hoạt động vì phần sắp xếp được thực hiện lúc REDUCE, sau khi chức năng của tôi đang được sử dụng.
Tôi có thể sắp xếp dữ liệu bảng trước khi sử dụng hàm, nhưng tôi không hài lòng với điều này vì nó là phí mà tôi hy vọng sẽ tránh.
Thứ hai: Trong trường hợp cấu hình Hadoop phân tán, dữ liệu được chia giữa các trình theo dõi công việc có sẵn. Vì vậy, tôi tin rằng sẽ có nhiều trường hợp của hàm này, một cho mỗi người lập bản đồ, do đó, có thể có cùng một dữ liệu khách hàng được chia giữa 2 người lập bản đồ. Trong trường hợp này, tôi sẽ mất các cuộc gọi của khách hàng, điều này không được chấp nhận.
Tôi không biết cách giải quyết vấn đề này. Tôi biết rằng DISTRIBUTE BY đảm bảo rằng tất cả các dữ liệu với một giá trị cụ thể được gửi đến cùng một bộ giảm (do đó đảm bảo rằng SORT hoạt động như mong đợi), không ai biết nếu có cái gì đó tương tự cho người lập bản đồ?
Tiếp theo, tôi định làm theo đề xuất của libjack để sử dụng tập lệnh giảm. Điều này "tính toán" là cần thiết giữa một số truy vấn hive khác, vì vậy tôi muốn thử tất cả mọi thứ Hive cung cấp, trước khi chuyển sang một công cụ khác, theo đề nghị của Balaswamy vaddeman.
EDIT2:
tôi bắt đầu để điều tra giải pháp kịch bản tùy chỉnh. Nhưng, trong trang đầu tiên của chương 14 trong Lập trình Hive cuốn sách (chương này trình bày các kịch bản tùy chỉnh), tôi thấy đoạn sau:
streaming thường là kém hiệu quả hơn so với mã hóa UDFs thể so sánh hoặc đối tượng InputFormat. Serialize và deserializing dữ liệu để vượt qua nó trong và ra khỏi đường ống là tương đối kém hiệu quả. Nó cũng khó khăn hơn để gỡ lỗi toàn bộ chương trình một cách thống nhất. Tuy nhiên, nó rất hữu ích cho việc tạo mẫu nhanh và để tận dụng mã hiện có không được viết bằng Java. Đối với người dùng Hive người không muốn viết mã Java, nó có thể là cách tiếp cận rất hiệu quả.
Vì vậy, rõ ràng rằng tập lệnh tùy chỉnh không phải là giải pháp tốt nhất về mặt hiệu quả.
Nhưng làm cách nào để giữ chức năng UDF của tôi, nhưng đảm bảo chức năng hoạt động như mong đợi trong cấu hình Hadoop phân tán? Tôi đã tìm thấy câu trả lời cho câu hỏi này trong phần UDF Internals của trang Wiki Ngôn ngữ UDF thủ công. Nếu tôi viết truy vấn của tôi:
SELECT customer_id, call_time, delta(customer_id, call_time) FROM (SELECT customer_id, call_time FROM mytable DISTRIBUTE BY customer_id SORT BY customer_id, call_time) t;
nó được thực hiện tại giảm thời gian và PHÂN PHỐI BỞI và Sắp xếp cấu trúc đảm bảo rằng tất cả các hồ sơ từ khách hàng cùng đang được xử lý bởi các giảm tương tự, theo thứ tự của các cuộc gọi.
Vì vậy, UDF ở trên và truy vấn này xây dựng giải quyết vấn đề của tôi.
(Xin lỗi vì đã không thêm các liên kết, nhưng tôi không được phép làm điều đó bởi vì tôi không có đủ điểm danh tiếng)
Tôi nghĩ điều này rất giống với [câu hỏi này] (http://stackoverflow.com/questions/14028796/reduce-a-set-of-rows-in-hive-to-another-set-of-rows) Tôi trả lời bằng cách sử dụng một bản đồ tùy chỉnh/giảm trong hive. Bạn sẽ phải cung cấp kịch bản giảm phù hợp. – libjack
Tôi không biết làm thế nào để làm điều này trong hive nhưng có cascading api để làm this.there là một cái gì đó được gọi là bộ đệm trong cascading.http: //docs.cascading.org/cascading/2.0/userguide/html/ch05s05.html –