Cloud & KubernetesKO · Nguồn: Tiếng Hàn#kubernetes#spark#operator#blue-green#memory

Toss vận hành Spark Connect trên Kubernetes bằng hai lớp Operator

Bài kỹ thuật của Toss mô tả cách tách phục hồi từng Driver và thay thế cả nhóm máy chủ Spark Connect trên Kubernetes, kèm bài học về readiness probe và rò bộ nhớ glibc.

Vibe DevOps biên soạn ngày · khoảng 540 từ

Điểm chính từ bài gốc

  • Toss chia vai trò: Apache Spark Operator lo khởi động và phục hồi từng Driver, còn Spark Tenant Operator tự viết lo số lượng máy chủ và việc thay thế theo từng tenant.
  • Khi đổi cấu hình, nhóm dùng Blue-Green theo generation: chỉ chuyển phiên mới sang khi toàn bộ máy chủ mới sẵn sàng, máy chủ cũ được drain và mặc định bị xóa sau 90 phút.
  • Probe HTTP qua giao diện Spark từng báo Ready sai vì đường dẫn bị chuyển hướng, nên được thay bằng exec probe thử kết nối gRPC tới cổng Connect.
  • Yêu cầu readiness gây vòng chờ giữa Executor và Driver; nhóm vượt qua bằng cách cho Executor kết nối thẳng IP của Driver Pod.
  • Bộ nhớ Driver tăng dần tới OOMKilled dù Heap ổn định; giới hạn số arena của glibc giúp hiện tượng không tái diễn trong 72 giờ quan sát.

Theo bài gốc

Điểm đáng chú ý trong kiến trúc

Đây là bài kỹ thuật trong một loạt bài của nhóm Data Infra tại Toss Securities, không phải thông báo phát hành. Các máy chủ Spark Connect được gom theo mục đích thành tenant với image, tài nguyên và số replica riêng; Tenant Operator đóng vai trò giống Deployment quản lý nhiều SparkApplication.

Khi Apache Spark Operator hết lượt thử lại, Tenant Operator chỉ tạo lại ứng dụng nếu còn ít nhất một máy chủ khỏe; nếu không, hệ thống coi là sự cố và dừng thay thế tự động để tránh vòng lặp lỗi.

Theo bài gốc

Readiness và bộ nhớ dài hạn

Theo tác giả, Connect chỉ mở cổng sau khi SparkContext khởi tạo xong, trong khi Executor được tạo ngay trong quá trình đó và phải tra DNS của headless Service, vốn chỉ công bố địa chỉ sau khi Driver Ready. Nhóm đã đóng góp một thiết lập lên upstream để tách việc công bố địa chỉ khỏi việc nhận yêu cầu; tác giả ghi chú thiết lập này dành cho Spark 4.3.0, phiên bản cũ hơn cần backport.

Với bộ nhớ tăng ngoài Heap, NMT không giải thích được mức tăng nên nhóm nghi bộ nhớ đã giải phóng còn kẹt trong các arena của glibc. Khi vận hành thật, họ dùng giá trị max(4, cores) cho Driver và Executor.

Bình luận của Vibe DevOps — không phải nội dung bài gốc

Góc nhìn vận hành

Góc nhìn Vibe DevOps: bài học áp dụng cho mọi dịch vụ giữ phiên trong bộ nhớ. Hãy kiểm tra readiness probe có đo đúng khả năng phục vụ, tách bước chuẩn bị, chuyển lưu lượng và tắt máy cũ, kèm giới hạn drain rõ ràng. Với container Java bị OOMKilled khi Heap thấp, theo dõi bộ nhớ cgroup trước khi chỉ tăng memory overhead, và thử cấu hình allocator trên môi trường kiểm thử đủ lâu.

Lệnh và khoá cấu hình xuất hiện trong bài gốc

Trích nguyên văn từ nguồn để tra cứu; hãy đọc ngữ cảnh tại bài gốc trước khi áp dụng.

spark.kubernetes.executor.useDriverPodIP=true

Cho Executor kết nối bằng IP của Driver Pod thay vì DNS của Service, tránh vòng chờ readiness.

MALLOC_ARENA_MAX=2

Giới hạn số arena của glibc; nhóm dùng giá trị này khi so sánh và không thấy bộ nhớ tăng liên tục.

spark.kubernetes.driver.service.publishNotReadyAddresses

Thiết lập do nhóm đóng góp upstream, công bố địa chỉ Driver trước khi Ready và bỏ bước chờ Ready trước khi tạo Executor.

⚠️ Lưu ý và giới hạn

  • Kết quả về bộ nhớ đến từ một đợt quan sát của riêng Toss, phụ thuộc workload và phiên bản glibc, JVM.
  • Spark Tenant Operator là công cụ do nhóm tự xây; bài không cho biết công cụ này có được công bố mã nguồn hay không.

Đọc bài gốc tại 토스 기술 블로그 (Toss Tech) ↗


Thực hành tiếp trên Vibe DevOps

Bài khác trong Thế giới DevOps · Tin tức