221 - Tối ưu hoá thời gian đọc S3 giúp tăng hiệu suất tác vụ xử lý dữ liệu lớn
Trong số này, chúng ta cùng tìm hiểu về:
Cách đội ngũ Wix xây dựng quy trình phát triển để release nhanh và liên tục.
Cải thiện hiệu suất các tác vụ xử lý dữ liệu lớn nhờ tối ưu hoá thời gian đọc trên S3.
Git hoạt động như thế nào
Góc Lập Trình: Lời giải cho bài toán tìm số trùng trong mảng
Ngoài ra các bạn vẫn có thể tiếp tục đặt mua ấn phẩm Dijkstra tập 2 tại đây nhé.
Những bài viết hay
Fearless Responsible Development: How to Move Quickly without Compromising on Quality
(by nghialuu)
Đội ngũ kĩ sư ở Wix tin rằng có thể vừa phát triển tính năng mới nhanh chóng, vừa giảm số lượng bug cũng như ảnh hưởng của chúng trên môi trường production. Mặc dù Wix deploy code lên production nhiều lần trong ngày, và mỗi thay đổi có thể ảnh hưởng đến hàng triệu cửa hàng trực tuyến với hàng nghìn lượng truy cập mỗi phút, nhưng Wix không có môi trường pre-production hoặc thậm chí môi trường testing, mà kiểm thử chúng trực tiếp trên môi trường production.
Khi một kĩ sư push code, nó có thể được triển khai ngay ở production chỉ trong vài giờ hoặc thậm chí vài phút mà không có manual QA. Vậy bí quyết của Wix là gì? Bài viết đề cập các ý chính như sau:
- Trong quá trình phát triển: áp dụng rất nhiều feature toggle, viết unit test với độ bao phủ cao (high-coverage), và E2E production test.
- Khi triển khai: sử dụng gradual deployment. Tăng dần số lượng người dùng được tiếp cận phiên bản mới hoặc tính năng mới, kiểm soát bởi cơ sở hạ tầng và feature toggle.
- Theo dõi các chỉ số và KPI cụ thể một cách tường minh, kèm cơ chế alert tự động. Khi có sự cố, các kỹ sư sẽ ưu tiên bật tắt feature toggle hoặc rollback về version cũ nếu cấp thiết.
Mời các bạn tham khảo thêm chi tiết các đề xuất của Wix tại link bên dưới.
Improving efficiency and reducing runtime using S3 read optimization
(by hungngph)
Tại Pinterest, với việc xử lý hàng petabyte dữ liệu được lưu trữ trên Amazon S3 mỗi ngày, việc giám sát những chỉ số liên quan đến tốc độ đọc/ghi dữ liệu cần được ưu tiên hơn kể. Khi các kỹ sư tại đây tiến hàng kiểm tra các chỉ số liên quan của MapReduce/Cascading/Scalding jobs, một điều bất ngờ là tốc độ mapper chậm hơn dự kiến. Vấn đề này làm ảnh hưởng tới tốc độ đọc dữ liệu của các jobs liên quan. Vì vậy, nếu giảm được độ trễ này sẽ giúp đội ngũ kỹ sư tại đây tiết kiệm đáng kể thời gian, công sức trong quá trình xây dựng và vận hành hệ thống. Về lâu dài, những chi phí kỹ thuật như thế có thể tăng lên và gây tiêu tốn ngân sách của công ty.
Để cải thiện việc này, các kỹ sư tại đây đã có một cách tiếp cận mới nhằm cải thiện read throughput của S3, từ đó có thể cải thiện hiệu quả production jobs của họ. Kết quả rất đáng khích lệ với tốc độ read throughput tăng tốc lên 12 lần so với trước đó. Hơn nữa, những chỉ số liên quan tới resources saving, vcores, memory,… cũng có dấu hiệu tích cực hơn.
Trong bài viết, tác giả làm rõ điểm bottleneck khiến cho tốc độ đọc vào S3 bị hạn chế. Gồm 2 mấu chốt là Single threaded reads và Multiple unnecessary reopens. Để giải quyết những vấn đề trên, tác giả đưa ra cách triển khai hệ thống và một số kỹ thuật mà đội ngũ kỹ sư ở đây áp dụng nhằm tăng tốc tốc độ đọc vào S3. Để biết thêm chi tiết về bài viết, mời các bạn đón đọc tại đây:
(by steven.do)
Không thể không thừa nhận được rằng ngày nay git đóng vai trò nền tảng trong các dự án phát triển phần mềm và là một công cụ bắt buộc phải có đối với các đội phát triển cùng làm việc với nhau và là một engine nền tảng cho sự chuyển biến của cộng đồng open-source trong những năm qua.
Hầu như các developer làm việc với git mỗi ngày, trong bài viết này tác giả Alberto Prospero sẽ giới thiệu sâu vào đặc tính bên trong và khám phá các thành phần cơ bản của Git. Cấu trúc dữ liệu Git dựa trên 03 thành phần chính là Blobs, Trees, và Commits, 03 cấu trúc này là nền tảng của Git.
Mỗi khi ta tạo một file mới và tiến hành track file vào repository bằng lệnh `git add <file-name>`, Git sẽ tạo ra 1 blob, là 1 file được lưu tại sub-folder `.git/objects` đây là nơi sẽ lưu trữ nội dung của file ta vừa tạo, tên của blob sẽ là mã hash của nội dung file được tạo.
Giả sử ta lại tạo ra thêm một sub-folder trên repository đặt tên là `subfolder` sau đó tạo ra một file `yourfile.text` trong sub-folder vừa tạo, khi ta tiến hành commit cả 02 file bằng lệnh `git commit`, Git sẽ tiến hành hai bước:
Bước 1 tạo ra một root tree của repository. Root tree là nơi lưu trữ tổ chức cấu trúc của các file và các folder trong toàn bộ repository, đây là một file chứa tham chiếu đến mỗi blob hoặc sub-folder trong repository, và được xây dựng theo tính chất đệ quy, mỗi dòng trong root tree tham chiếu đến một blob hoặc các sub-tree khác,và từ các blob hoặc sub-tree đó lại tiếp tục tham chiếu đến các blob hoặc sub-tree tiếp theo.
Bước 2 tạo ra commit. Nội dung của Commit được lưu trữ trong 1 file chứa thông tin có liên quan đến root tree, hay parent commit ( nếu có), và một vài thông tin metadata (vd: name, hoặc email của người commit và nội dung của commit). Một khi commit file được tạo, Git sẽ hash nội dung của nó và sử dụng hash đó đặt tên cho file mới
Tiếp theo tác giả giới thiệu về Git Branch. Các branch là các tên tham chiếu (named references) đến một Commit. Khi tạo mới một branch bằng câu lệnh `git checkout -b mybranch`, Git sẽ tạo ra một file mới theo đường dẫn `.git/refs/heads`, nội dung của file là mã hash của commit từ branch được tạo ra.
Thông tin chi tiết hơn về cách thức git branch hoạt động, giải thích ý nghĩa của HEAD và ý nghĩa của việc Merge Branch, có thể tham khảo tại bài viết gốc.
Góc Lập Trình
(by phucnh)
Đề ra tuần này: Linked List Cycle II
Lời giải đề bài tuần trước: Find the Duplicate Number
Bài toán yêu cầu tìm số bị lặp nhưng không được sửa đổi mảng đầu vào, và chỉ được sử dụng độ phức tạp không gian là hằng số (constrant extra space). Ta cần chú ý tới những dữ kiện sau:
1. Mảng chỉ chứa n + 1 phần tử, và các phần tử trong khoảng [1, n]
2. Mảng chỉ chứa duy nhất 1 số bị lặp
Nhằm giới hạn độ dài của bài viết, xin chỉ giới thiệu những phương pháp đáp ứng yêu cầu "không được sửa đổi mảng đầu vào" và "độ phức tạp không gian là hằng số".
Cách tiếp cận đơn giản nhất ta có thể nghĩ tới là sử dụng 2 vòng lặp lồng nhau. Với mỗi số "curr" trong khoảng [1, n], ta duyệt mảng đầu vào và đếm phần tử "nums[i] == curr". Nếu biến đếm là 2, ta trả lại kết quả. Giải thuật được thực hiện như sau:
Độ phức tạp về thời gian time complexity của giải thuật trên là O(n^2).
Tuy nhiên, theo điều kiện của đề bài, mảng đầu vào chỉ chứa n + 1 phần tử, và các phần tử trong khoảng [1, n]. Với mỗi số "curr" trong khoảng [1, n], ta đếm số phần tử nhỏ hơn hoặc bằng số "curr", ta gọi biến đếm là "countOfLessThanOrEqualToCurrent".
Chúng ta cùng xét ví dụ sau:
nums = [1,3,4,2,2]
Ta duyệt tất cả các số "curr" trong khoảng [1, n], ta có "countOfLessThanOrEqualToCurrent" như sau:
Số bị lặp là số "2" - số nhỏ nhất có countOfLessThanOrEqualToCurrent > curr.
Như vậy, ta hoàn toàn có thể áp dụng binary search để tìm số bị lặp như sau:
Phương pháp này có độ phức tạp về thời gian time complexity là O(nlogn).
Bài toán này còn có thể tối ưu độ phức tạp thời gian tới O(n), giải thuật tối ưu có liên quan tới bài https://leetcode.com/problems/linked-list-cycle-ii/, vì vậy xin được dành sang số sau.
Code & Tools
Quotes
“Remember that code is really the language in which we ultimately express the requirements. We may create languages that are closer to the requirements. We may create tools that help us parse and assemble those requirements into formal structures. But we will never eliminate necessary precision—so there will always be code.”
--- Robert C. Martin
Feedback
Bạn đánh giá nội dung số newsletter này thế nào?
(1 = Rất tệ / 5 = Rất tốt)
(Việc đánh giá của các bạn là rất quan trọng, sẽ giúp chúng tôi liên tục cải thiện nội dung newsletter tốt hơn)