#155 - uReplicator: Uber Engineering’s Robust Apache Kafka Replicator
Grokking Newsletter là email newsletter hàng tuần từ Grokking, chia sẻ cho các bạn những bài viết, phân tích kỹ thuật về Software Engineering hay kèm theo bình luận từ team Grokking. Trong số này: quy trình khai thác dữ liệu trong doanh nghiệp, bài toán Thundering Herd Problem, và Paxos vs Raft (distributed systems).
Nếu bạn đọc thấy hay, mong các bạn ủng hộ Grokking bằng cách forward email cho những bạn bè làm software engineering!
Những bài viết hay
Tìm hiểu về quy trình khai thác dữ liệu trong doanh nghiệp — pandaml.com
Khi còn ngồi trên ghế nhà trường, khoa học dữ liệu thường chỉ gói gọn trong việc lấy dữ liệu có sẵn, áp dụng thuật toán và đánh giá độ chính xác của mô hình. Liệu đi làm có khác biệt với đi học nhiều không? Để trả lời cho câu hỏi này, hãy cùng tác giả tìm hiểu về quy trình khai thác dữ liệu trong doanh nghiệp thông qua một ví dụ cụ thể về CRISP - DM
CRISP – DM là viết tắt cho Cross Industry Standard Process for Data Mining, tạm dịch là “quy trình tiêu chuẩn cho khai thác dữ liệu trong nhiều lĩnh vực”. Quy trình này được hình thành từ năm 1996, nhưng cho đến nay có lẽ vẫn là một trong những tiêu chuẩn được sử dụng rộng rãi nhất.
6 bước cơ bản của CRISP – DM:
Hiểu về nhu cầu của doanh nghiệp (Business Understanding)
Hiểu về dữ liệu (Data Understanding)
Chuẩn bị dữ liệu (Data Preparation)
Xây dựng mô hình (Modeling)
Đánh giá chất lượng mô hình (Evaluation)
Triển khai giải pháp (Deployment)
Bài viết sẽ đi phân tích chi tiết tưng bước của CRISP - DM, qua đó giúp mọi người, đặc biệt là các bạn mới ra trường hay mới bắt đầu làm việc trong lĩnh vực khoa học dữ liệu hiểu hơn về quy trình khai thác dữ liệu trong thực tế tại các doanh nghiệp.
Từ học thuật cho đến áp dụng thực tế luôn là một khoảng cách lớn. Việc hiểu được nhu cầu của doanh nghiệp để áp dụng một giải pháp phù hợp rất là quan trọng cho quyết định đến sự thành công của một dự án và mang lại giá trị lâu dài cho doanh nghiệp.
Thundering Herds & Promises. Story of a Service — instagram-engineering.com
Cache là một phần không thể thiếu của nhiều services để giảm độ latency và giảm lưu lượng requests tới các hệ thống backend. Mỗi lần cache bị xóa hoặc một request hoàn toàn mới được đưa tới hệ thống thì thông thường sẽ có vài cách xử lý như sau:
Nếu cache bị xóa hoặc máy chủ bị khởi động lại thì chúng ta có thể truy vấn dữ liệu cache từ đĩa (nếu có) thay vì gửi request tới backend (có hỗ trợ trong memcached hoặc redis)
Nếu một request hoàn toàn mới được gửi tới thì chúng ta có thể xử lý dần dần bằng cách giả lập các fake requests để làm ấm cache trước hoặc là phát hành client mới từ từ để requests mới không tới quá nhiều một lần
Tuy nhiên trên thực tế thì vấn đề cache bị trống rắc rối hơn rất là nhiều khi mà sản phẩm của bạn có rất là nhiều người dùng. Một ví dụ đơn giản như là nếu có 100 requests xảy ra đồng thời và cache đều không có cho những requests này thì chúng ta sẽ phải gửi 100 requests cùng lúc tới hệ thống backend để lấy dữ liệu. Tuy nhiên, nếu hệ thống backend của chúng ta bị quá tải hoặc không thể xử lý hết kịp thời do vấn đề tài nguyên thì sẽ có thêm rất nhiều vấn đề khác có thể nảy sinh ra với hệ thống. Đây có thể là một ví dụ điển hình cho “Thundering Herd Problem”
Để cải thiện hệ thống và tránh việc thundering herd problem xảy ra thường xuyên thì các đội ngũ kỹ sư ở Instagram đã tận dụng Promise. Thay vì chứa dữ liệu chính trong cache thì họ bọc dữ liệu này trong Promise rồi lưu trữ Promise trên cache. Nếu một request tới mà không xuất hiện trong cache thì hệ thống sẽ kiểm tra thử nếu Promise của dữ liệu cần được truy xuất có trong cache hay không và tạo ra một Promise mới nếu không có. Do đó, khi các requests khác được gửi tới thì chúng có thể chia sẽ cái Promise này cho cùng một dữ liệu trong lúc chờ đợi hệ thống backend truyền dữ liệu về. Việc tận dụng Promise đã giúp Instagram hạn chế việc thundering herd problem xảy ra nhiều và giúp họ triển khai hoặc restart một cluster dễ dàng hơn
uReplicator: Uber Engineering’s Robust Apache Kafka Replicator — eng.uber.com
Tại Uber, Kafka được dùng cho nhiều hệ thống khác nhau. Do dữ liệu ở Uber rất là lớn, Kafka được phân ra ở nhiều clusters trong các data center khác nhau. Tuy nhiên, có vài trường hợp cần phải gom dữ liệu ở nhiều Kafka clusters khác nhau về cùng một chỗ để xử lý và phân tích những dữ liệu này. Vào thời điểm khi các đội ngũ kỹ sư ở Uber cần hỗ trợ trường hợp này thì Kafka 0.8.2 có ứng dụng MirrorMaker giúp việc vận chuyển dữ liệu Kafka một cách dễ dàng hơn.
Mặc dù MirrorMaker vận hành khá là hiệu quả lúc đầu, các kỹ sư ở Uber dần nhận ra những vấn đề về MirrorMaker khi dữ liệu ở Uber chứa trong Kafka ngày càng gia tăng. Một số hạn chế của MirrorMaker như là:
Expensive Rebalancing: Mỗi MirrorMaker worker dùng Kafka consumers để tiếp nhận dữ liệu. Các consumers này thường phải đi qua một quá trình tái cân bằng để đàm phán xem consumer nào nhận Kafka topic hoặc partition nào (thường được diễn ra nhờ vào Apache Zookeeper). Do dữ liệu ở Uber khá lớn, quá trình này diễn ra khá là lâu và có thể bị mắc kẹt dẫn tới việc vi phạm end-to-end latency của hệ thống
Difficult Adding Kafka Topics: Tại Uber, họ có một danh sách các Kafka topics được tiếp nhận ở MirrorMaker để kiểm soát nguồn dữ liệu được truyền tải qua WAN link. Do đó, mỗi lần họ cần thêm một Kafka topic mới thì họ phải restart MirrorMaker để cập nhật danh sách mới. Tuy nhiên, MirrorMaker sẽ tự rebalance các consumers để tiếp nhận nguồn dữ liệu mới này. Như đã được đề cập ở trên, quá trình này là một nổi sợ hãi ở Uber khi vận hành MirrorMaker
Do đó, các đội ngũ kỹ sư ở Uber đã quyết định xây dựng hệ thống uReplicator để thay thế và khắc phục những hạn chế mà Kafka MirrorMaker gây ra lúc bấy giờ. uReplicator chứa 4 thành phần chính:
Helix uReplicator Controller: Bộ phận này được dựa trên Apache Helix và ZooKeeper giúp kiểm soát và vận hành toàn bộ hệ thống. Một số ví dụ về trách nhiệm của bộ phần này là: phân tán và phân công Kafka partitions cho worker; quản lý việc thêm/xóa Kafka topics/partitions hoặc uReplicator workers; phát hiện những nodes bị lỗi và tái phân tán Kafka partitions của những node này qua các node khác.
uReplicator Worker: Bộ phận này có nhiệm vụ chính là replicate dữ liệu từ một Kafka cluster này tới một cluster khác. Các workers này khác với MirrorMaker ở chỗ là chúng không tự tái cân bằng lẫn nhau mà nhờ vào uReplicator controller cho việc tái cân bằng
Helix Agent: Bộ phận này xuất hiện ở mỗi worker và nhận thông báo khi mà có một sự thay đổi cho Kafka partitions của worker này. Đồng thời, helix agent sẽ truyền tải thông báo này cho Dynamic Kafka Consumer
Dynamic Kafka Consumer = bộ phận này cũng xuất hiện ở mỗi worker và thay thế cho cơ cấu tái cân bằng ở MirrorMaker để thêm/xóa Kafka partitions một cách nhanh chóng
Góc Distributed System
Paxos vs Raft: Have we reached consensus on distributed consensus?
Nghiên cứu về đồng thuận (consensus) là trọng tâm của lĩnh vực hệ thống phân tán. Thuật toán đồng thuận Paxos xuất bản năm 1989 trở thành thuật toán chính trong nhiều hệ thống (Google Spanner; Google Chubby; Apache ZooKeeper). Tuy nhiên, Paxos nổi tiếng vì sự khó hiểu ngay cả trong cộng đồng học thuật. Paper về thuật toán Raft xuất bản năm 2012 là một bước đột phá bởi tính dễ hiểu, và tập trung hơn về khía cạnh engineering trong việc trình bày hướng giải quyết. Các hệ thống phân tán lớn ra đời sau này (etcd; CockroachDB; TiDB; ...) sử dụng Raft để giải quyết bài toán đồng thuận hoặc replicate data giữa các máy tính trong mạng. Tuy nhiên nếu ta nhìn lại thuật toán Paxos (cụ thể hơn là multi-decree Paxos) dưới lăng kính của Raft, ta sẽ thấy hai thuật toán đều có nhiều đặc điểm chung: sử dụng State Machine Replication; single leader; ... Cụ thể hơn, khác biệt lớn nhất là điều kiện leader election:
- Raft: điều kiện leader rất chặt, buộc các node muốn trở thành leader phải chứa thông tin về log đầy đủ nhất. Do vậy, sau khi trở thành leader, node đấy chỉ cần replicate log ra toàn bộ các node follower trong mạng.
- Multi-decree Paxos: điều kiện để trở thành leader lỏng hơn, không yêu cầu một node muốn trở thành leader phải chứa thông tin đầy đủ nhất về log. Do vậy, sau khi một node trở thành leader, thuật toán phải giải quyết việc đồng bộ log giữa leader và follower, để hệ thống đạt được trạng thái consistency. Bài báo sau đây (xuất bản năm 2020) trình bày cách đồng nhất các thuật ngữ giữa 2 thuật toán Paxos và Raft. Từ đó, bài báo phân tích kĩ các điểm giống và khác giữa 2 thuật toán, đồng thời cũng đưa ra lưu đồ để implement multi-decree Paxos dựa trên Raft.
Code & Tools
This Week Sponsors
POPS is a creative, innovative & hyper-growth working environment where storytelling meets technology.
POPS is the leading digital entertainment company in Southeast Asia. With over 12 years in entertainment, we provide thousands of exclusive, high-quality, carefully curated local and international contents and bring a unique entertainment experience through POPS Original series, concerts, movies, comics, esports and more.
We are on a journey to find talents who are passionate about technology and love to develop POPS APP_the digital entertainment product with the latest technologies such as: OTT, Video On Demand, Microservices, etc. to give end users in the region great experiences with an all-inclusive digital entertainment platform.
Góc Tuyển Dụng
Visit https://popsww.com/en/careers for current job openings.
Quotes
Sometimes the problem is to discover what the problem is.
- Gordon Glegg