Presto là một công cụ truy vấn SQL mã nguồn mở miễn phí. Trong suốt 10 năm sử dụng công cụ này tại Meta, chúng tôi đã rút ra được rất nhiều bài học kinh nghiệm. Nếu muốn vận hành công cụ, quy trình, dịch vụ trên quy mô lớn, bạn phải giải quyết vấn đề thì mới vượt qua được những thách thức không lường trước. Sau đây là 4 bài học kinh nghiệm chúng tôi đúc rút được trong quá trình mở rộng Presto theo quy mô của Meta, cùng một số lời khuyên nếu bạn muốn chạy các truy vấn của riêng mình trên quy mô lớn!
Hình 1: Quy trình xử lý để đẩy các phiên bản mới của Presto (Sơ đồ của Philip S. Bell)
Meta chạy một lượng lớn cụm Presto tại trung tâm dữ liệu ở khắp các địa điểm trên toàn cầu. Ít nhất một lần và đôi khi là hai lần mỗi tháng, Meta sẽ xây dựng và sẵn sàng triển khai một phiên bản Presto mới. Một trong những thách thức đầu tiên chúng tôi gặp phải khi mức sử dụng Presto tại Meta tăng lên nhanh chóng, đó là làm cách nào để triển khai công cụ truy vấn này cho một lượng lớn cụm mà vẫn đảm bảo khả năng sử dụng và độ tin cậy nhất quán. Thách thức này vẫn đặc biệt đúng đối với trường hợp sử dụng Presto mang tính tương tác, tức là khi một người dùng khởi chạy truy vấn và đang tích cực chờ kết quả. Vấn đề lỗi truy vấn bớt lo ngại hơn đối với trường hợp sử dụng "hàng loạt" tự động, vì hệ thống sẽ tự động thử lại để đảm bảo rằng cuối cùng truy vấn vẫn thành công.
Giải pháp cho thách thức này rất đơn giản. Mọi cụm Presto đều nằm sau một trình cân bằng tải gọi là Cổng. Cổng này chịu trách nhiệm (kết hợp với những hệ thống khác tại Meta) định tuyến các truy vấn Presto đến cụm thích hợp. Khi một cụm Presto cần được cập nhật, trước tiên, cụm đó sẽ được đánh dấu là đã rút khỏi Cổng (tức là Cổng dừng định tuyến mọi truy vấn mới đến cụm đó). Tiếp đến, hệ thống tự động hóa sẽ chờ một khoảng thời gian định sẵn cho đến khi kết thúc các truy vấn hiện đang chạy trên cụm đó. Sau đấy, cụm sẽ được cập nhật. Khi cụm đó online, Cổng sẽ nhìn thấy và có thể bắt đầu định tuyến các truy vấn mới đến cụm đó.
Khía cạnh khác để triển khai các bản mới phát hành của Presto là khả năng sử dụng. Chúng tôi cần đảm bảo rằng người dùng vẫn có thể sử dụng Presto trong khi các cụm đang được cập nhật. Một lần nữa, hệ thống tự động hóa sẽ đảm bảo rằng tất cả trung tâm dữ liệu ở mọi khu vực thực tế luôn có sẵn số lượng cụm Presto cần thiết. Tất nhiên, cần phải cân bằng giữa việc gỡ bỏ quá nhiều cụm cùng lúc (vấn đề về khả năng sử dụng) và gỡ bỏ quá ít cụm mỗi lần (hoạt động triển khai mất quá nhiều thời gian).
Hình 2: Quy trình tự động để thêm phần cứng vào các cụm (Sơ đồ của Philip S. Bell)
Hoạt động phân phối kho dữ liệu tại Meta ở các khu vực khác nhau liên tục thay đổi. Tức là hệ thống phải duy trì các cụm Presto mới trong khi ngừng sử dụng những cụm hiện tại theo định kỳ. Đây từng là một quy trình thủ công khi chỉ có ít cụm Presto. Khi Meta bắt đầu mở rộng quy mô, việc theo dõi thủ công tất cả thay đổi đã nhanh chóng trở nên khó khăn. Để giải quyết vấn đề này, chúng tôi đã triển khai hệ thống tự động hóa nhằm xử lý việc duy trì và ngừng sử dụng các cụm.
Trước tiên, chúng tôi phải chuẩn hóa cấu hình cụm, tức là phải xây dựng cấu hình cơ sở cho các trường hợp sử dụng Presto khác nhau tại Meta. Sau đó, mỗi cụm sẽ có một số lượng tối thiểu các quy cách bổ sung hoặc bị ghi đè so với cấu hình cơ sở. Khi quá trình đó hoàn tất, hệ thống có thể bật bất kỳ cụm mới nào lên bằng cách tự động tạo cấu hình dựa trên mẫu cơ sở. Để bật cụm lên, chúng tôi cũng phải tích hợp với hook tự động hóa thì mới tích hợp được với các dịch vụ cơ sở hạ tầng khác nhau trong toàn công ty, chẳng hạn như Tupperware và những dịch vụ dành riêng cho kho dữ liệu. Sau khi một cụm online, một số truy vấn thử nghiệm sẽ được gửi đến cụm này và hệ thống tự động hóa sẽ xác minh rằng cụm đã thực hiện thành công các truy vấn đó. Tiếp đến, cụm nêu trên sẽ được đăng ký với Cổng và bắt đầu phân phối truy vấn.
Quy trình ngừng sử dụng một cụm sẽ diễn ra theo hướng ngược lại. Cụm này được hủy đăng ký khỏi Cổng và mọi truy vấn đang chạy đều được phép kết thúc. Các quy trình Presto ngừng hoạt động và cấu hình cụm bị xóa.
Hệ thống tự động hóa này được tích hợp vào quy trình duy trì và ngừng sử dụng phần cứng đối với kho dữ liệu. Kết quả cuối cùng là toàn bộ quy trình - từ bước phần cứng mới hiển thị tại trung tâm dữ liệu đến bước các cụm Presto online và phân phối truy vấn, rồi ngừng hoạt động khi ngừng sử dụng phần cứng - được tự động hóa hoàn toàn. Nhờ triển khai quy trình này, chúng tôi đã tiết kiệm được thời gian làm việc quý giá của con người, giảm thời gian phần cứng không hoạt động và giảm thiểu lỗi do con người gây ra.
Hình 3: Phát hiện máy chủ không hợp lệ (Sơ đồ của Philip S. Bell)
Khi triển khai rộng rãi Presto tại Meta, chúng tôi bắt buộc phải có sẵn công cụ và hệ thống tự động hóa để giúp công việc của nhân viên trực tổng đài (đầu mối liên hệ của Presto) trở nên dễ dàng.
Trong những năm qua, chúng tôi đã xây dựng một số "trình phân tích" để hỗ trợ nhân viên trực tổng đài gỡ lỗi và đánh giá nguyên nhân gốc rễ gây ra sự cố một cách hiệu quả. Hệ thống giám sát sẽ đưa ra cảnh báo khi có hành vi vi phạm SLA hiển thị với khách hàng. Sau đó, các trình phân tích sẽ được kích hoạt. Những trình phân tích này lấy thông tin từ nhiều hệ thống giám sát (Kho dữ liệu vận hành hay ODS), sự kiện được đăng lên Scuba và thậm chí cả nhật ký ở cấp độ máy chủ. Tiếp đến, logic tùy chỉnh trong trình phân tích sẽ liên kết tất cả thông tin này lại với nhau để suy ra nguyên nhân gốc rễ có thể gây ra sự cố. Việc này cực kỳ hữu ích với nhân viên trực tổng đài bằng cách trình bày dữ liệu phân tích nguyên nhân gốc rễ và cho phép họ chuyển thẳng đến các phương án giảm thiểu khả thi. Trong một số trường hợp, chúng tôi đã tự động hóa hoàn toàn cả quy trình gỡ lỗi lẫn quy trình khắc phục để nhân viên trực tổng đài thậm chí không cần can thiệp. Dưới đây là một vài ví dụ:
Khi chạy Presto ở quy mô lớn trên nhiều máy, chúng tôi nhận thấy rằng một số máy chủ "không hợp lệ" có thể gây ra lỗi truy vấn quá mức. Sau khi điều tra, chúng tôi xác định được một số nguyên nhân gốc rễ dẫn đến việc máy chủ "không hợp lệ", bao gồm:
Để khắc phục vấn đề này, chúng tôi hiện giám sát lỗi truy vấn trong các cụm Presto. Cụ thể là chúng tôi quy từng lỗi truy vấn cho máy chủ gây ra lỗi đó, nếu có thể. Chúng tôi cũng thiết lập cảnh báo để kích hoạt khi số lượng lỗi truy vấn cao bất thường được quy cho các máy chủ cụ thể. Sau đó, hệ thống tự động hóa sẽ khởi động để rút máy chủ đó khỏi nhóm Presto nên ngăn chặn được lỗi.
Mỗi cụm Presto đều hỗ trợ xếp hàng đợi các truy vấn trên cụm đó khi đạt đến số lượng truy vấn chạy đồng thời tối đa, tùy theo trường hợp sử dụng, cấu hình phần cứng và kích thước truy vấn. Meta áp dụng một cơ chế định tuyến phức tạp để truy vấn Presto được gửi đến "đúng" cụm, nhờ vậy mà có thể thực hiện truy vấn trong khi vẫn tận dụng tối đa các tài nguyên. Ngoài Presto, một số hệ thống có tham gia vào quá trình ra quyết định định tuyến và xem xét nhiều yếu tố:
Vì phức tạp như vậy nên nhân viên trực tổng đài có thể gặp rất nhiều khó khăn khi tìm nguyên nhân gốc rễ gây ra bất kỳ sự cố xếp hàng đợi nào gặp phải trong quá trình sản xuất. Đây là một trường hợp khác mà các trình phân tích lại trở nên quan trọng khi lấy thông tin từ nhiều nguồn và đưa ra kết luận.
Hình 4: Độ ổn định của trình cân bằng tải (Sơ đồ của Philip S. Bell)
Như đã nói ở trên, các cụm Presto của chúng tôi đều nằm sau trình cân bằng tải giúp định tuyến từng truy vấn Presto tại Meta. Ban đầu, khi Presto chưa mở rộng quy mô sử dụng trong nội bộ như hiện nay, Cổng rất đơn giản. Tuy nhiên, khi mức sử dụng Presto tại Meta tăng lên, chúng tôi đã gặp phải các vấn đề về khả năng mở rộng trong một số trường hợp. Một trong số đó là trường hợp Cổng bị lỗi khi tải nặng, dẫn đến việc tất cả người dùng đều không sử dụng được Presto. Nguyên nhân gốc rễ gây ra một số vấn đề về độ ổn định là do một dịch vụ đã vô tình tấn công Cổng bằng hàng triệu truy vấn trong khoảng thời gian ngắn, dẫn đến các quy trình của Cổng bị lỗi và không thể định tuyến bất kỳ truy vấn nào.
Để ngăn chặn trường hợp tương tự, chúng tôi bắt đầu củng cố Cổng để trở nên mạnh mẽ hơn và chịu được lưu lượng truy cập kiểu DDoS không lường trước như vậy. Chúng tôi đã triển khai tính năng giới hạn để từ chối truy vấn khi tải nặng. Tính năng giới hạn có thể được kích hoạt dựa trên số lượng truy vấn mỗi giây trên các thứ nguyên khác nhau (chẳng hạn như mỗi người dùng, mỗi nguồn, mỗi IP), đồng thời được kích hoạt ở cấp độ toàn cầu đối với mọi truy vấn. Một điểm cải thiện khác mà chúng tôi đã triển khai là tự động thay đổi quy mô. Dựa vào một dịch vụ trên toàn Meta hỗ trợ tăng và giảm quy mô công việc, số lượng phiên bản Cổng hiện rất linh động. Tức là trong trường hợp tải nặng, Cổng hiện có thể tăng quy mô để xử lý lưu lượng truy cập bổ sung và không bị sử dụng hết CPU/bộ nhớ, do đó ngăn chặn được trường hợp xảy ra sự cố như mô tả ở trên. Khi kết hợp với tính năng giới hạn, chúng tôi đảm bảo rằng Cổng hoạt động mạnh mẽ và có thể chịu được các kiểu lưu lượng truy cập bất lợi không thể lường trước.
Hình 5: Mở rộng quy mô kiến trúc Presto (Sơ đồ của Philip S. Bell)
Sau đây là một số khía cạnh quan trọng cần lưu ý khi mở rộng quy mô Presto:
Bài viết này do Neerad Somanchi - Kỹ sư sản xuất tại Meta và Philip Bell - Chuyên gia về quan hệ lập trình viên tại Meta cùng hợp tác soạn thảo.
Để tìm hiểu thêm về Presto, hãy truy cập vào prestodb.io, xem nội dung giải thích nhanh về Presto mà Philip Bell đăng trên YouTube hoặc theo dõi Presto trên Twitter, Facebook và LinkedIn.
Để tìm hiểu thêm về Meta Open Source, hãy truy cập vào trang web nguồn mở của chúng tôi, đăng ký theo dõi kênh YouTube của chúng tôi hoặc theo dõi chúng tôi trên Twitter, Facebook và LinkedIn.