Hành Trình Uber Chuyển Đổi Từ Hive Sang Spark SQL Cho Các Workload ETL

Cách Uber di chuyển hơn 18,000 workflow ETL, xử lý 5 triệu truy vấn mỗi tháng từ Hive sang Spark SQL để đạt hiệu suất tăng gấp 4 lần.

Khau Van Nam 5 phút đọc
Mục lục

Tạm biệt Hive: Hành trình tiến tới Spark SQL của Uber

Tại Uber, Apache Hive™ chạy trên Spark từng là “trái tim” của các hệ thống ETL cho Compliance (tuân thủ), báo cáo tài chính, dự báo rủi ro và phân tích gian lận. Với quy mô 18,000 workflow5 triệu truy vấn mỗi tháng, việc tối ưu hóa hạ tầng này là một bài toán sống còn.

1. Động lực: Tại sao phải di cư?

Chúng tôi quyết định chuyển sang Spark SQL vì hai lý do chính: Hiệu quả tính toánSự hiện đại hóa.

  • Spark 3 với các tính năng như Adaptive Query Execution (AQE)Dynamic Partition Pruning mang lại hiệu năng vượt trội.
  • Kết quả thử nghiệm ban đầu cho thấy Spark SQL giúp tăng tốc độ xử lý lên tới 4 lần so với Hive trên cùng một khối lượng công việc.
  • Cộng đồng mã nguồn mở của Hive đang dần trở nên lỗi thời, trong khi Spark phát triển cực kỳ mạnh mẽ.

2. Chiến lược di chuyển tự động (AMS)

Việc yêu cầu hơn 440 team tại Uber tự chuyển đổi workflow của họ là điều không khả thi. Do đó, chúng tôi xây dựng Automated Migration Service (AMS) để thực hiện việc này một cách âm thầm và an toàn.

Quy trình Shadow Testing:

  1. Dịch truy vấn: Tự động chuyển đổi cú pháp HiveQL sang Spark SQL.
  2. Chạy song song (Shadow Run): Chạy thử truy vấn Spark SQL mà không làm ảnh hưởng đến dữ liệu Production.
  3. Kiểm tra dữ liệu (Data Validation): So sánh kết quả đầu ra của Hive và Spark.
  4. Cập nhật mã nguồn: Sau khi vượt qua các bước kiểm tra, workflow sẽ chính thức được chuyển sang Spark SQL.

3. Thách thức kỹ thuật: Dịch truy vấn (Query Translation)

Cú pháp giữa Hive và Spark SQL có những khác biệt đáng kể, đặc biệt với các cấu trúc phức tạp như LATERAL VIEW hay EXPLODE.

Ví dụ về sự khác biệt cú pháp:

Trong Hive:

SELECT
    id,
    items.name
FROM
    orders
LATERAL VIEW EXPLODE(order_items) itemsTable AS items;

Trong Spark SQL:

SELECT
    id,
    item.name
FROM
    orders
LATERAL VIEW EXPLODE(order_items) AS item;

Chúng tôi đã xây dựng một Query Translation Service dựa trên dự án Coral của LinkedIn để tự động hóa việc này, hỗ trợ từ các câu lệnh SELECT đơn giản đến cả các lệnh DDL/DML phức tạp.

4. Đảm bảo tính nhất quán dữ liệu

Để đảm bảo Spark SQL không làm sai lệch logic kinh doanh, chúng tôi thực hiện so sánh dữ liệu ở mức độ hàng (row-level) bằng Checksum.

Ví dụ mô phỏng logic Validation (Golang):

Đây là cách chúng tôi so sánh nhanh hai tập dữ liệu bằng hashing:

package main

import (
	"crypto/md5"
	"fmt"
	"sort"
	"strings"
)

// ComputeChecksum mô phỏng việc tạo vân tay cho một dòng dữ liệu
func ComputeChecksum(row map[string]string) string {
	var keys []string
	for k := range row {
		keys = append(keys, k)
	}
	sort.Strings(keys) // Đảm bảo thứ tự cột không ảnh hưởng kết quả

	var sb strings.Builder
	for _, k := range keys {
		sb.WriteString(fmt.Sprintf("%s:%s|", k, row[k]))
	}

	hash := md5.Sum([]byte(sb.String()))
	return fmt.Sprintf("%x", hash)
}

func main() {
	hiveRow := map[string]string{"id": "1", "val": "100.0"}
	sparkRow := map[string]string{"id": "1", "val": "100.0"}

	if ComputeChecksum(hiveRow) == ComputeChecksum(sparkRow) {
		fmt.Println("Dữ liệu khớp hoàn toàn!")
	} else {
		fmt.Println("Cảnh báo: Dữ liệu sai lệch!")
	}
}

5. Những “hố đen” cần tránh khi di chuyển

Trong quá trình thực hiện, chúng tôi gặp phải một số khác biệt về hành vi hệ thống:

  1. Số thực dấu phẩy động (Floating point): Các hàm SUM hoặc AVG thường có sai số nhỏ giữa Hive và Spark. Giải quyết bằng cách sử dụng hàm ROUND trước khi so sánh.
  2. Chuyển đổi Boolean sang String: - Hive: true => "TRUE"
  • Spark: true => "true"
  • Giải pháp: Cấu hình Spark để trả về kết quả tương thích với Hive.
  1. Số lượng file nhỏ (Small Files Problem): Spark tạo ra quá nhiều file nhỏ làm quá tải HDFS. Chúng tôi đã can thiệp vào bộ máy AQE của Spark để tự động gom nhóm (rebalance) dữ liệu trước khi ghi xuống đĩa.

Kết luận

Việc chuyển đổi thành công 5 triệu truy vấn mỗi tháng không chỉ giúp Uber giảm 50% thời gian chạy và tài nguyên sử dụng, mà còn hiện đại hóa toàn bộ kho dữ liệu.

Hành trình này cho thấy: Với các hệ thống quy mô lớn, việc di chuyển không chỉ là thay đổi công nghệ, mà là xây dựng các công cụ tự động hóa đủ thông minh để giảm thiểu rủi ro cho con người.


Tham khảo chi tiết tại: Uber Engineering Blog

Nhắn qua Telegram