#165 - Ứng dụng của ZooKeeper trong hệ thống phân tán
Những bài viết hay
GraalVM — Make Java Great Again — batnamv.medium.com
Java Virtual Machine (JVM) hiện tại vẫn là một trong những máy ảo mặc định và phổ biến trong cộng đồng Java, Scala, Kotlin, ... JVM có hỗ trợ trình biên dịch JIT (just-in-time) để giúp chương trình của chúng ta chạy nhanh hơn bằng việc compile Java bytecode xuống mã máy (native code) cho những đoạn code hay được sử dụng. Có thể nói, JIT compilation là một phối hợp hoàn hảo giữa trình thông dịch (interpreter) và trình biên dịch (compiler).
Tuy nhiên, do xu thế triển khai các ứng dụng micro-services ở trên các containers như Docker khá là phổ biến gần đây, việc dùng JVM để chạy các ứng dụng thường sẽ tốn nhiều tài nguyên hơn so với việc chạy ứng dụng được biên dịch xuống mã máy. Đặc biệt là khi các containers này thường có ít tài nguyên hơn. Do đó, cộng đồng Java dạo gần đây đang chú ý tới máy ảo GraalVM khi mà các ứng dụng JVM có thể được biên dịch hẳn xuống mã máy thay vì phải dùng JVM để chạy ứng dụng. Bài viết sau đây của Nam Vu giới thiệu cụ thể về GraalVM và những ưu/nhược điểm của GraalVM
Airflow 2.0 Providers — medium.com
Airflow 2.0 ra mắt với rất nhiều tính năng, cải tiến nhưng cũng là một sự thay đổi lớn trong hệ sinh thái quản lý các workflow. Có rất nhiều thứ mới trong Airflow 2.0, khiến chúng ta thật khó để theo kịp và cập nhật. Tuy nhiên, có một vấn đề rất quan trọng mà chúng ta không thể bỏ qua, ảnh hưởng lớn trong việc phát triển cài đặt, quản lý, duy trì cũng như nâng cấp Airflow và các workflow chạy trong nó, đó là Airflow Providers.
Airflow 1.10 có cách tiếp cận monolithic. Nó chứa hệ thống scheduler core và tất cả các tích hợp với các dịch vụ bên ngoài - hooks, operator, sensor. Tất cả mọi thứ được đưa vào 1 gói "apache-airflow" duy nhất, bất kể bạn có muốn sử dụng nó hay không.
Airflow Provider là ý tưởng đã được đưa ra trong cộng đồng từ lâu và mất hơn 2 năm để hoàn thành. Airflow 2.0 chứa đựng một cấu trúc xây dựng mới bên trong. Airflow 2.0 main core đã trở nên đơn giản và gọn nhẹ hơn nhiều, và có thể tích hợp theo tùy chỉnh cài đặt lên tới 60 packages khác nhau để có thể hoạt động với cái rất nhiều dịch vụ như Google, AWS, Postgres, HTTP, .. . Mỗi package được phân tách trong gói phụ “airflow.providers” của riêng nó, với các dependecies được kiểm soát và ghi lại đầy đủ giữa chúng. Có một điều đặc biệt, là kể cả khi chúng ta cài đặt tất cả các providers, Airflow vẫn chạy một cách ổn định mà không có dependency conflict.
Một số lợi ích của Airflow provider được tác giả bài viết đề cập và phân tích:
Cài đặt đơn giản, gọn nhẹ
Khả năng truy cập sớm hơn vào các tích hợp mới nhất
Nâng cấp các providers nhanh hơn, dễ dàng hơn
Backport providers cho Airflow 1.10 trở đi
Khả năng migration sang Airflow 2.0 an toàn
Khả năng phát triển các Providers cho bên thứ 3
Improving large monorepo performance on GitHub — github.blog
Github hiện tại đang được sử dụng bởi hơn 56 triệu developers và có tới hơn 200 triệu repositories. Mặc dù hệ thống Github đã được thành lập khá lâu và được cải thiện khá là nhiều để đáp ứng được lưu lượng truy cập lớn như thế này. Tuy nhiên, các developers cho những mono-repositories lớn vẫn thường gặp trục trặc khi phải đẩy commits của họ lên Github. Do đó, các đội ngũ kỹ sư ở Github đã bắt đầu tìm cách để cải thiện hệ thống cho những trường hợp ngoại lệ như thế này, đặc biệt là cho những repositories có dữ liệu lớn hoặc là có nhiều developers commit thường xuyên. Một trong những cách cải thiện họ đã làm như là:
Cải thiện việc duy trì repositories bằng việc cải thiện tốc độ của lệnh git repack và tăng cường độ thử lại cho lỗi hệ thống trong off-peak hours của các repositories đó
Xóa chức năng làm hạn chế việc dùng tài nguyên trên một máy chủ
Tính toán các checksums trước khi giữ locks cho việc nhân rộng dữ liệu ở các máy khác
Để hiểu rõ hơn cách mà các đội ngũ kỹ sư ở Github đã cải thiện hệ thống của họ cho những mono-repositories lớn, các bạn có thể tham khảo thêm qua bài viết sau
Góc Distributed System
Ứng dụng của ZooKeeper trong việc xây dựng hệ thống phân tán
Nhắc tới ZooKeeper, lập trình viên sẽ nhớ ngay tới các thư viện hoặc framework nổi tiếng sử dụng như Kafka; Hadoop. Zookeeper thường được nghĩ tới như là một hierarchical key-value database và có thể dùng cho mục đích leader election / configuration management / … Vậy thật sự Zookeeper cung cấp những chức năng gì?
ZooKeeper là một service cung cấp một tập interface API cơ bản, từ đó lập trình viên có thể dựa vào đó viết tiếp những ứng dụng nâng cao hơn như configuration management; leader election; distributed locking; distributed queue; …. Cụ thể một vài API cơ bản:
Tạo/xóa node: lập trình viên có thể tạo ra một node khởi nguyên hoặc con của một node khác (ví dụ: A/B/C), đây cũng là lí do tại sao ta gọi ZooKeeper là “hierarchical” key-value database. Node lá có thể kèm theo bất cứ giá trị nào (value trong key-value). Mỗi node có thể phụ trợ thêm một vài thuộc tính như ephemeral (tự xóa khi session kết thúc) / sequential (tự cấp ID tăng dần và duy nhất cho các node con) / …
Listen trên một node: khi có bất cứ sự thay đổi nào trên node đó, client sẽ nhận được event thông báo. Tuy rằng đây là một sự kiện bất đồng bộ (ta không thể biết khi nào thay đổi được tạo ra), nhưng có một đặc tính rất đặc biệt là serializability write nhưng là FIFO read: dù thế nào thì các read event nhận được phải tuân theo quy luật nguyên nhân-hệ quả.
Ví dụ với kịch bản C1 và C2 làm tuần tự như sau:
C1 gán A = 3
C2 listen vào key A
Sau đó C1 và C2 cùng thực hiện song song các thao tác:
C1 xóa key A
C1 gán B = 4
C2 đọc key B
Như vậy, ở C2 sẽ có 2 events: đọc key B và nhận thay đổi từ key A. Thứ tự này có thể là tuần tự so với C1:
C1 xóa key A
C1 gán B = 4
C2 nhận được event A bị xóa
C2 đọc key B = 4
Hoặc đan xen với C1:
C1 xóa key A
C2 nhận được event A bị xóa
C1 gán B = 4
C2 đọc key B = 4
Không bao giờ thứ tự nhận event bị đảo ngược (không tuân theo quy luật nguyên nhân-hệ quả) ví dụ như
C1 xóa key A
C1 gán B = 4
C2 đọc được B = 4
C2 nhận được event key A bị xóa (vô lí, vì sự kiện key A bị xóa phải xuất hiện trước event gán B = 4)
Với 2 bộ API này, lập trình viên có thể tạo ra ứng dụng Group Membership Protocol bằng cách như sau:
Tạo ra một node G để biểu diễn group
Khi mỗi node join vào group, sẽ tạo ra một ephemeral node với id định danh duy nhất được gửi từ client hoặc tự generate bằng cách áp dụng thuộc tính sequential.
Lắng nghe các events trên node G
Khi có một node leave -> event trigger -> nhận ra một thành viên thoát group
ZooKeeper cung cấp nhiều API hơn vậy. Ta có thể tham khảo tiếp cách xây dựng các ứng dụng nâng cao hơn bằng ZooKeeper thông qua bài viết sau
Code & Tools
This Week Sponsors
Là một trong các sàn giao dịch P2P năng động tại nhiều quốc gia, Remitano cung cấp thị trường uy tín, an toàn tối đa và đơn giản cho hoạt động mua bán tiền mã hóa của hàng triệu khách hàng, với sản phẩm đầu tư đa dạng, giao dịch tức thời và đội ngũ hỗ trợ 24/7 bao gồm các chuyên gia ngân hàng có nhiều kinh nghiệm trong các sản phẩm tài chính, tiền điện tử, và hệ thống thanh toán, đảm bảo mang đến trải nghiệm tốt với mức phí thấp nhất cho người dùng.
Quotes
“Some of the best programming is done on paper, really. Putting it into the computer is just a minor detail.”
― Max Kanat-Alexander