
Airbnb tiết lộ hệ thống đo lường Prometheus hàng tỷ chuỗi
Airbnb discloses a billion-series Prometheus metrics pipeline
Một phương pháp đã được thử nghiệm trong sản xuất để chuyển quy trình số liệu quy mô lớn từ StatsD sang OpenTelemetry và Prometheus. Nhấn enter hoặc nhấp để xem hình ảnh ở kích thước đầy đủ
A phương pháp đã được thử nghiệm trong sản xuất để di chuyển quy mô lớn quy trình số liệu từ StatsD đến OpenTelemetry và Prometheus.
Nhấn enter hoặc nhấp để xem hình ảnh đầy đủ kích thước
By: Eugene Ma, Natasha Aleksandrova
Khi di chuyển sang một hệ thống giám sát mới, bạn sẽ muốn tải trước công việc để thu thập tất cả các số liệu của mình. Điều này bộc lộ các tắc nghẽn ở quy mô ghi đầy đủ và bỏ chặn quá trình di chuyển các nội dung yêu cầu dữ liệu thực để xác thực, chẳng hạn như trang tổng quan và cảnh báo. Trước tiên, việc thu thập tất cả số liệu của bạn có nghĩa là bạn có thể tập trung vào những thách thức kỹ thuật chính — quy mô, độ chính xác và hiệu suất — mà không phải lo lắng về cách người dùng sẽ áp dụng các công cụ mới của bạn.
Nhưng đối với dự án của chúng tôi, cách tiếp cận này không hề đơn giản: hầu hết các số liệu của chúng tôi đều được trang bị bằng thư viện StatsD, OpenTelemetry đang thu hút được sự chú ý và hệ thống lưu trữ mới của chúng tôi dựa trên Prometheus. Chúng tôi còn lại rất nhiều câu hỏi mở. Chúng ta phân nhánh các số liệu ở đâu? Chúng ta có nên áp dụng OpenTelemetry không? Các số liệu của chúng tôi có hoạt động tốt với Prometheus không? Nhiệm vụ thu thập số liệu yêu cầu chúng tôi phải trả lời những câu hỏi này và suy nghĩ lại cơ sở hạ tầng số liệu của mình.
Thiết bị đo lường và thu thập
Các dịch vụ của chúng tôi ban đầu sử dụng giao thức StatsD, với Veneur thu thập và thu thập xe sidecar chuyển tiếp số liệu đến nhà cung cấp của chúng tôi.
Nhấn enter hoặc nhấp để xem hình ảnh ở kích thước đầy đủ
Để di chuyển khỏi kiến trúc này, chúng tôi đã xác định một tập hợp rõ ràng các giao thức thiết bị đo được ưu tiên và hỗ trợ. Giao thức đo từ xa OpenTelemetry (OTLP) hiện được khuyến nghị cho các dịch vụ nội bộ, trong khi Prometheus được ưu tiên cho khối lượng công việc OSS. StatsD (định dạng DogStatsD) vẫn là phương án dự phòng cho các đường dẫn hoặc ứng dụng cũ khó cập nhật/công cụ.
Điều này khiến chúng tôi phải áp dụng OpenTelemetry Collector (OTel Collector) trung lập với nhà cung cấp.
Di chuyển ghi kép cách tiếp cận
Khoảng 40% dịch vụ của chúng tôi sử dụng thư viện số liệu được duy trì trên nền tảng chung, đây là điểm khởi đầu hợp lý cho việc áp dụng OTLP và cho phép triển khai rộng rãi phát xạ OTLP trên các dịch vụ đó. Bằng cách cho phép thư viện này phát ra các số liệu kép, StatsD cho quy trình hiện tại và OTLP cho OTel Collector mới, chúng tôi đã đạt được tiến trình di chuyển rộng rãi với ít trở ngại.
Quy trình thu thập trong quá trình di chuyển:
Nhấn enter hoặc nhấp để xem hình ảnh đầy đủ kích thước
Lợi ích được thực hiện bằng cách chuyển sang OTLP
Việc chuyển sang OTLP mang lại lợi ích đáng kể so với việc duy trì trên StatsD:
- Dữ liệu lược tả JVM cho thấy rằng thời gian CPU dành cho việc xử lý số liệu đã giảm từ 10% xuống dưới 1% tổng số mẫu CPU trong quá trình sản xuất sau khi di chuyển từ StatsD sang OTLP.
- OTLP cung cấp độ tin cậy cao hơn StatsD, dựa trên UDP và dễ bị mất gói hơn trong điều kiện thông lượng cao.
- Việc phát ra OTLP vốn đã loại bỏ nhu cầu về bước dịch StatsD-sang-OTLP trung gian bên trong OTel Collector.
- Vì chương trình phụ trợ của chúng tôi dựa trên Prometheus nên việc duy trì trên StatsD sẽ hạn chế người dùng ở các biểu đồ cổ điển. OTLP cho phép chúng tôi áp dụng các khả năng gốc của Prometheus chẳng hạn như biểu đồ hàm mũ với độ chính xác hoàn toàn.
- OTLP là một giao thức trung lập với nhà cung cấp, được CNCF tài trợ và là tiêu chuẩn ngành trên thực tế cho phép đo từ xa. Việc chuyển sang OTLP giúp chúng tôi hỗ trợ các trường hợp sử dụng khả năng quan sát trong tương lai mà không gặp rào cản về giao thức.
Một thách thức gặp phải với OTLP
Mặc dù hầu hết các dịch vụ đều xử lý chế độ OTLP + StatsD ghi kép mà không gặp sự cố, các bộ phát số liệu có khối lượng cao nhất của chúng tôi (nhiều trong số đó cũng nằm trong số các dịch vụ quan trọng nhất của chúng tôi) đã gặp phải sự suy giảm đáng kể về hiệu suất sau khi bật OTLP. Đặc biệt, các dịch vụ này bắt đầu chịu áp lực bộ nhớ, hoạt động thu gom rác tăng lên và tăng trưởng vùng nhớ khối xếp.
Qua điều tra, chúng tôi đã kết nối các vấn đề về hiệu suất với thực tế là các dịch vụ đó phát ra số liệu lượng số rất cao (ở mức hơn 10K mẫu mỗi giây cho mỗi phiên bản). Để giảm thiểu hiện tượng hồi quy này, chúng tôi đã cập nhật cấu hình thư viện số liệu chung để sử dụng tính tạm thời delta (AggregationTemporalitySelector.deltaPreferred()) cho một nhóm dịch vụ chọn lọc. Thay đổi đó giúp giảm gánh nặng bộ nhớ trong quá trình vì thời gian delta tránh giữ lại trạng thái đầy đủ cho tất cả các kết hợp nhãn số liệu giữa các lần xuất.
Dựa trên quan sát của chúng tôi, chúng tôi nhận thấy rằng việc chuyển sang thời gian delta chỉ cần thiết đối với các dịch vụ phát ra khối lượng số liệu cực cao nên chúng tôi đã để phần còn lại của dịch vụ sử dụng chế độ tích lũy mặc định. Điều đó có nghĩa là, với các chỉ số delta, những lỗi không mong muốn sẽ dẫn đến những khoảng trống rõ ràng trong dữ liệu, một sự đánh đổi mà chúng tôi chấp nhận để đổi lấy việc giảm mức sử dụng bộ nhớ và cải thiện độ ổn định. Với số liệu tích lũy, những lỗi tương tự đó thường xuất hiện dưới dạng bước nhảy lớn hơn giữa các điểm dữ liệu chứ không phải là khoảng cách.
Hình ảnh bộ sưu tập cuối cùng
Với OTLP hiện đóng vai trò là luồng dữ liệu chính và đường dẫn StatsD dự phòng chỉ được duy trì khi cần thiết, chúng tôi đã đạt được một kiến trúc bộ sưu tập nhất quán và sẵn sàng cho tương lai. OTel Collector cố định quy trình, cấp dữ liệu trực tiếp vào chương trình phụ trợ lưu trữ dựa trên Prometheus của chúng tôi, với đường dẫn cũ có sẵn để tương thích.
Nền tảng này rất cần thiết trước khi giải quyết các thách thức phức tạp hơn như tổng hợp.
Sơ đồ minh họa thiết kế cuối cùng này và luồng số liệu hoàn chỉnh thông qua hệ thống.
Nhấn enter hoặc nhấp vào để xem hình ảnh ở kích thước đầy đủ
Tổng hợp phát trực tuyến
Để kiểm soát chi phí, quy trình trước đây của chúng tôi đã sử dụng một nhánh nội bộ của Veneur để tổng hợp các nhãn cấp phiên bản (ví dụ: pod, tên máy chủ) thay vì gửi số liệu thô trực tiếp cho nhà cung cấp của chúng tôi. Trong thế giới Prometheus, chúng tôi cần một bước tổng hợp tương tự.
Các tùy chọn bị từ chối
Có một số tùy chọn mà chúng tôi đã cân nhắc sử dụng nhưng đã loại bỏ:
- Tiếp tục sử dụng Veneur: Tiếp tục với Veneur yêu cầu viết lại đáng kể để hỗ trợ mô hình dữ liệu và giao thức của Prometheus, đồng thời đợt phân nhánh này đang được bảo trì liên tục gánh nặng.
- Quy tắc ghi âm: Mặc dù quy tắc ghi âm rất hữu ích trong việc cải thiện hiệu suất truy vấn nhưng trước tiên, chúng yêu cầu lưu trữ dữ liệu thô trong TSDB, điều này làm giảm mục tiêu tiết kiệm chi phí của chúng tôi.
- m3aggregator: Mặc dù đã được thử nghiệm trong chiến đấu tại các công ty khác, kiến trúc có vẻ phức tạp hơn chúng tôi mong muốn.
- OpenTelemetry Collector: Thiếu hỗ trợ tổng hợp số liệu, mặc dù đề xuất.
- Vector: không có khả năng chia tỷ lệ tích hợp sẵn. Được viết bằng Rust, phương pháp này không được áp dụng rộng rãi tại Airbnb.
Chọn vmagent
Cuối cùng, chúng tôi đã xem xét vmagent từ VictoriaMetrics.
Ưu điểm:
- Hỗ trợ tổng hợp phát trực tuyến cho các chỉ số Prometheus
- Hỗ trợ phân chia, cung cấp cách mở rộng quy mô theo chiều ngang
- Tài liệu cực kỳ thân thiện với người dùng và dễ thiết lập
- Nó có một cơ sở mã nhỏ (~10K LOC), nên rất dễ hiểu và sửa đổi nếu cần.
Nhấn enter hoặc nhấp để xem hình ảnh đầy đủ kích thước
Kiến trúc của chúng tôi có hai lớp vmagent: bộ định tuyến và bộ tổng hợp. Bộ định tuyến là các số liệu không trạng thái và phân đoạn bằng cách băm liên tục tất cả các nhãn ngoại trừ những nhãn mà bạn muốn tổng hợp lại (ví dụ: “pod”, “host”). Bộ tổng hợp thực hiện việc tổng hợp (tức là tổng hợp các bộ đếm) và duy trì trạng thái đầu ra trong bộ nhớ (tức là tổng số đang chạy hiện tại). Trên dòng lệnh, mỗi bộ định tuyến được chuyển một danh sách tĩnh gồm tên máy chủ tổng hợp (Kubernetes cung cấp nhận dạng mạng ổn định cho nhóm StatefulSet). Cách tiếp cận đơn giản này tránh sự phụ thuộc bổ sung vào việc khám phá dịch vụ và giữ cho việc phân chia số liệu nhất quán giữa các nhóm.
Sau khi tìm ra cách mở rộng quy mô vmagent, chúng tôi đã thực hiện một số tùy chỉnh nội bộ để hỗ trợ môi trường số liệu của mình (bao gồm hỗ trợ biểu đồ gốc và đa thuê kiểu Mimir). Các thay đổi chung khác đã được đóng góp ngược dòng (5931, 5938, 5990).
Kết quả
Chúng tôi đã đạt được mục tiêu của mình mục tiêu tổng hợp số liệu: cụm sản xuất duy nhất của chúng tôi đã mở rộng quy mô tới hàng trăm công cụ tổng hợp, sử dụng hơn 100 triệu mẫu mỗi giây.
Ngoài việc giảm tổng chi phí xuống một mức độ lớn, công nghệ mới của chúng tôi đường ống tổng hợp cung cấp một lợi ích khác. Vì nó được tập trung hóa và xử lý TẤT CẢ số liệu của chúng tôi nên đây là một công cụ tiện lợi và mạnh mẽ cho các loại chuyển đổi khác. Khi người dùng triển khai một thay đổi không tốt về công cụ đo lường, việc loại bỏ các chỉ số có vấn đề sẽ rất hữu ích. Khi người dùng tạm thời cần số liệu thô, chúng tôi sử dụng nó để phát ra kép số liệu thô một cách nhanh chóng.
Bộ đếm thưa thớt
Sau khi di chuyển sang quy trình chỉ số dựa trên Prometheus mới, chúng tôi nhận thấy các truy vấn PromQL của chúng tôi trên một số bộ đếm nhất định liên tục bị tính dưới mức so với nhà cung cấp trước đây của chúng tôi.
Vấn đề với rate()
Nguyên nhân cốt lõi nằm ở cách Prometheus tính toán tỷ lệ thay đổi từ các bộ đếm tích lũy. Trong hệ thống giám sát StatsD, điểm dữ liệu đo delta được quan sát trong cửa sổ xả (thường là 10 giây). Trong Prometheus, điểm dữ liệu đo số lượng tích lũy bắt đầu từ 0. Trong thực tế, bạn sẽ sử dụng những thứ như rate() hoặc tăng() để rút ra các delta, điều này có ý nghĩa hơn đối với biểu đồ.
Tuy nhiên, có một trường hợp đặc biệt: khi bộ đếm được tạo, nó cũng có thể được tăng lên cùng lúc.
Hãy xem xét một bộ đếm tăng một lần và đặt lại (do khởi động lại nhóm) trước khi nó có thể tăng lại:
1 1 1 1 1 - - - 1
↑ resetMỗi lần bộ đếm đặt lại, số gia sẽ bị mất trước khi hàm rate() của PromQL có cơ hội tạo ra một delta.
Ban đầu, chúng tôi dự đoán rằng trường hợp biên sẽ có tác động tối thiểu do Prometheus được áp dụng rộng rãi và độ tin cậy đã được chứng minh trong nhiều môi trường khác nhau. Tuy nhiên, khi chúng tôi di chuyển nhiều người dùng hơn, chúng tôi bắt đầu thấy vấn đề này thường xuyên hơn và nó khiến quá trình di chuyển bị đình trệ. Hệ thống Airbnb có xu hướng tạo ra nhiều bộ đếm giá thấp với kích thước cao. Yêu cầu theo dõi bộ đếm cho mỗi đơn vị tiền tệ cho mỗi người dùng trên mỗi khu vực có thể thấy bất kỳ chuỗi dữ liệu cụ thể nào chỉ tăng lên một vài lần trong ngày và những cập nhật này có thể bị mất do sự cố với rate(). Tuy nhiên, đây thường là những số liệu quan trọng mà nhóm sản phẩm cần theo dõi một cách chính xác.
Các giải pháp bị từ chối
Trước khi đi đến phương pháp cuối cùng, chúng tôi đã xem xét một số giải pháp thay thế — mỗi giải pháp đều có những hạn chế đáng kể.
- Khởi tạo trước tất cả các bộ đếm để zero: Không thực tế với số lượng callite, ngoài việc không thể dự đoán tất cả nhãn kết hợp trước.
- Yêu cầu các nhóm sử dụng nhật ký để biết số lượng chính xác: Nhật ký và số liệu là các hệ thống riêng biệt và phục vụ các trường hợp sử dụng khác nhau. We needed real-time dashboards and alerting on metrics. Việc yêu cầu các nhóm cơ cấu lại khả năng quan sát của họ xung quanh các giới hạn của chúng tôi là không thể chấp nhận được.
- Phát ra đồng hồ đo thay vì bộ đếm: Trong nội bộ, Prometheus không phân biệt giữa đồng hồ đo và bộ đếm. Tuy nhiên, bằng cách này, chúng tôi sẽ đi ngược dòng với các quy ước của Prometheus.
- Thêm các điều chỉnh PromQL hacky: Chúng tôi có thể yêu cầu người dùng bổ sung các truy vấn của họ bằng nhiều thủ thuật hack. Nhưng điều này sẽ đẩy sự phức tạp lên mỗi nhóm khi viết bảng thông tin và cảnh báo.
Giải pháp: không tiêm
Rõ ràng, giải pháp này phải minh bạch và có hệ thống. Quá trình di chuyển vốn đã đòi hỏi rất nhiều từ người dùng của chúng tôi và thật không hợp lý khi mong đợi nhóm của chúng tôi tự sửa đổi mọi trang web cuộc gọi.
Ý tưởng rất đơn giản: chúng tôi cần chèn các số 0 vào luồng số liệu của mình một cách liền mạch. Cấp tổng hợp của chúng tôi đã xử lý tất cả số liệu của chúng tôi ở một vị trí tập trung, vì vậy đây là nơi hoàn hảo để thực hiện thay đổi.
Chúng tôi đã triển khai một điều chỉnh về Bộ tổng hợp: khi chúng tôi xóa số tổng hợp lần đầu tiên, hãy xóa số 0 thay vì tổng số chạy thực tế.
Hãy xem xét một bộ đếm tăng thêm một đơn vị mỗi lần xóa. Trong thực tế, điều này trông như thế này:
Nhấn enter hoặc nhấp để xem hình ảnh ở kích thước đầy đủ
Bằng cách chèn số 0 tổng hợp, tất cả các bộ đếm đều được khởi tạo ngầm về 0 để khớp với ngữ nghĩa truy cập của Prometheus. The delayed flush is also important, it ensures the zero’s timestamp doesn’t conflict with any previous samples. Có một nhược điểm: mức tăng ban đầu sẽ trễ một khoảng thời gian xả, đây không phải là vấn đề lớn trong thực tế.
Phương pháp này yêu cầu những thay đổi tối thiểu đối với vmagent, giữ cho bản sửa lỗi không hiển thị với người dùng cuối và giải quyết vấn đề tại nguồn thay vì ghi đè lên nó.
Kết luận
Trong bài đăng blog này, chúng tôi đã nói về cách chúng tôi thu thập tất cả số liệu StatsD hiện có vào một chỉ số mới, Quy trình chỉ số dựa trên Prometheus.
Chúng tôi đã triển khai chiến lược thiết bị đo ghi kép, áp dụng Giao thức đo từ xa mở (OTLP) trong khi vẫn duy trì hỗ trợ cho StatsD. Việc chuyển đổi này mang lại hiệu suất tăng và mở khóa việc sử dụng các tính năng như biểu đồ gốc.
Để quản lý chi phí và quy mô, chúng tôi đã giới thiệu quy trình tổng hợp phát trực tuyến hai lớp tập trung bằng cách sử dụng thiết lập vmagent phân đoạn. Cuối cùng, chúng tôi đã giải quyết vấn đề về bộ đếm thưa thớt liên tục bị đếm thiếu bằng cách triển khai kỹ thuật "không chèn" minh bạch trong cấp tổng hợp của chúng tôi.
Công việc của chúng tôi chứng minh một kế hoạch chi tiết thực tế, đã được thử nghiệm trong sản xuất để di chuyển một quy trình số liệu lớn, khối lượng lớn sang các tiêu chuẩn nguồn mở, hiện đại như OpenTelemetry và Prometheus, trong khi vẫn duy trì độ chính xác của dữ liệu và hiệu quả chi phí.
Nếu loại công việc này bạn quan tâm, hãy xem các vai trò mở.
Lời cảm ơn
Cảm ơn nhóm Observability — Abdurrahman Allawala, Rong Hu, Callum Jones, Rishabh Kumar, Wei Song và Yann Ramin — và các đối tác của chúng tôi trong toàn công ty đã giúp thực hiện việc này thành hiện thực.
Chúng tôi đặc biệt muốn cảm ơn Helen Lee và Vlad Kostyukov vì sự hỗ trợ của họ đối với OpenTelemetry thiết bị đo đạc.
Chúng tôi cũng muốn cảm ơn Suman Karumuri và Xuân Lu vì đã hỗ trợ họ viết bài đăng này trong thời gian họ làm việc tại Airbnb.
Tất cả tên sản phẩm, biểu trưng và nhãn hiệu đều là tài sản của chủ sở hữu tương ứng. Tất cả tên công ty, sản phẩm và dịch vụ được sử dụng trong trang web này chỉ nhằm mục đích nhận dạng. Việc sử dụng những tên, biểu trưng và thương hiệu này không ngụ ý sự chứng thực.
Tác giả: jmarbach
