13/08/2019, 09:43

Best practice trong xử lý Error Retries

Xin chào tất cả mọi người. Mình tên là nooptr đang làm việc tại 1 công ty startup Nhật Bản, có tên là Artrigger. 1 công ty chuyên cung cấp các giải pháp về Blockchain và License Business. Hôm nay mình chia sẻ đến mọi người 1 giải pháp khá hay trong vấn đề giải quyết các bài toán liên quan đến xử ...

Xin chào tất cả mọi người. Mình tên là nooptr đang làm việc tại 1 công ty startup Nhật Bản, có tên là Artrigger. 1 công ty chuyên cung cấp các giải pháp về Blockchain và License Business.

Hôm nay mình chia sẻ đến mọi người 1 giải pháp khá hay trong vấn đề giải quyết các bài toán liên quan đến xử lí error retries, có tên gọi là Exponential Backoff.

Vấn đề đặt ra

Khi làm việc với API thì việc gửi request đến API để lấy dữ liệu về là việc làm không thể thiếu. Thế nhưng không phải lúc nào API cũng hoạt động bình thường. Thi thoảng server có vấn đề và nó không thể xử lí request và sẽ trả về lỗi. Vậy để giải quyết vấn đề này thì chúng ta sẽ làm thế nào? Đa số chúng ta sẽ retries lại mấy lần, kiểu như sau:

retries = 0

DO
    wait 1 second

    status = Get the result of response

    IF status = SUCCESS
        retry = false
    ELSE
        retry = true
    END IF

    retries = retries + 1

WHILE (retry AND (retries < MAX_RETRIES))

Đoạn code này dường như hoàn hảo nhưng mà nếu suy nghĩ kĩ thì nó thật sự không hiệu quả trong 1 số trường hợp. Vậy cùng nhau xem nó đang gặp vấn đề nào nhé.

Exponential Backoff là gì?

Exponential Backoff là 1 thuật toán tính toán thời gian đợi giữa mỗi lần retries theo hàm luỹ kế để việc thực hiện gửi lại request được hiệu quả nhất.

Ví dụ như lần retries thứ 1 sẽ đợi 1s, lần retries thứ 2 sẽ đợi 2s, lần thứ 3 sẽ đợi 4s .... Tức là thời gian đợi sau mỗi lần retries sẽ không cố định mà sẽ tăng theo hàm luỹ kế. Và theo như thống kê, nếu làm theo cách này thì sẽ mang lại những hiệu quả sau:

  • Giảm tải của server
  • Loại bỏ đi những request lãng phí
  • Trước khi retries lại thì có thể ở phía server đã giải quyết xong lỗi

Vấn đề gì xảy khi không dùng Exponential Backoff

Bây giờ chúng ta quay lại ví dụ lúc trước.

retries = 0

DO
    wait 1 second

    status = Get the result of response

    IF status = SUCCESS
        retry = false
    ELSE
        retry = true
    END IF

    retries = retries + 1

WHILE (retry AND (retries < MAX_RETRIES))

Giả sử như web server của chúng ta có 2 con (con thứ 1, con thứ 2). Request gửi từ client, thông qua Load Balancer sẽ gửi lần lượt đến con thứ 1 và con thứ 2.

Giả sử như request gửi từ client thông qua Load balancer sẽ đến con thứ 1. Và lúc này con thứ 1 đang bị lỗi. Khi đó chúng ta sẽ thực hiện retries lại. Và những request tiếp theo chắc chắn sẽ gửi đến con thứ 2.

Nếu như bây giờ thời gian retries của chúng ta fix cứng là 1 giây chẳng hạn. Khi đó toàn bộ request từ client sẽ được gửi liên tiếp đến con thứ 2. Điều này đồng nghĩa với việc server thứ 2 sẽ nhận 1 số lượng request lớn, liên tục từ các client. Nó cũng giống như việc tấn công DDos vậy. Và hậu quả là con thứ 2 này cũng có khả năng bị down.

Ví dụ về thuật toán Exponential Backoff

Vậy chúng ta nên retries lại như nào cho hợp lý? Câu trả lời khá đơn giản. Chúng ta chỉ cần cài đặt thời gian retries là hàm luỹ kế là xong.

retries = 0

DO
    wait for random from 0 to (2^retries * 100) milliseconds

    status = Get the result of response

    IF status = SUCCESS
        retry = false
    ELSE
        retry = true
    END IF

    retries = retries + 1

WHILE (retry AND (retries < MAX_RETRIES))

Như trong ví dụ trên ta có thể thấy được:

  • Nếu request bị thất bại thì chúng ta sẽ đợi (1 + random_number_milliseconds) giây và thực hiện retries
  • Nếu request bị thất bại thì chúng ta sẽ đợi (2 + random_number_milliseconds) giây và thực hiện retries
  • Nếu request bị thất bại thì chúng ta sẽ đợi (4 + random_number_milliseconds) giây và thực hiện retries

Và sẽ loop cho đến khi số lần retries đạt MAX_RETRIES thì thôi. Nếu MAX_RETRIES = 5 thì chúng ta sẽ có 2^5 = 32 giây, MAX_RETRIES = 6 thì chúng ta sẽ có 2^6 = 64 giây. Tuỳ thuộc vào từng use case mà chúng ta sẽ chọn ra giá trị MAX_RETRIES phù hợp.

Ví dụ thực tế

Ví dụ 1: Google HTTP client

retry_interval = retry_interval * multiplier ^ (N - 1)
randomized_interval := retry_interval * 
(random value in range [1 - randomization_factor, 1 + randomization_factor])
  • Nếu status của response là 5xx thì sẽ thực hiện retries.
  • Mặc định thì retry_interval = 0.5s, randomization_factor = 0.5, multiplier= 1.5, max_interval = 1 minute, max_elapsed_time = 15s
  • Nếu retry_interval > max_elapsed_time (15s) thì sẽ stop lại quá trình loop

Kết quả:

request retry_interval randomized_interval
01      00.50          [0.25, 0.75]
02      00.75          [0.38, 1.12]
03      01.12          [0.56, 1.69]
04      01.69          [0.84, 2.53]
05      02.53          [1.27, 3.80]
06      03.80          [1.90, 5.70]
07      05.70          [2.85, 8.54]
08      08.54          [4.27, 12.81]
09      12.81          [6.41, 19.22]
10      19.22          STOP

Ví dụ 2:AWS SimpleDB

currentRetry = 0
 DO
   status = execute Amazon SimpleDB request
   IF status = success OR status = client error (4xx)
     set retry to false
     process the response or client error as appropriate
   ELSE
     set retry to true
     currentRetry = currentRetry + 1
     wait for a random delay between 0 and (4^currentRetry * 100) milliseconds
   END-IF
 WHILE (retry = true AND currentRetry < MaxNumberOfRetries) 

Kết quả:

request randomized_interval
1       [0, 400)
2       [0, 1600)
3       [0, 6400)
4       [0, 25600)
5       [0, 102400)

Tổng kết

Hi vọng qua bài này các bạn cũng hiểu rõ được Exponential Backoff là gì, làm thế nào để retries error hiệu qủa. Chúc các bạn thành công.

Bài liên quan

Đôi nét về TF-IDF trong xử lý ngôn ngữ tự nhiên

Mở đầu Xử lý ngôn ngữ là công việc vô cùng quan trọng nhằm giúp cho máy tính hiểu được ngôn ngữ con người, qua đó giúp đỡ con người các công việc như: dịch thuật, phân tích văn bản, tìm kiếm thông tin, v.v.. TF-IDF là một trong những kỹ thuật cơ bản trong xử lý ngôn ngữ giúp đánh giá mức độ ...

Bùi Văn Nam viết 21:28 ngày 14/08/2019

Best practice trong xử lý Error Retries

Xin chào tất cả mọi người. Mình tên là nooptr đang làm việc tại 1 công ty startup Nhật Bản, có tên là Artrigger. 1 công ty chuyên cung cấp các giải pháp về Blockchain và License Business. Hôm nay mình chia sẻ đến mọi người 1 giải pháp khá hay trong vấn đề giải quyết các bài toán liên quan đến xử ...

Trịnh Tiến Mạnh viết 09:43 ngày 13/08/2019

Các thuật ngữ trong Xử lý ngôn ngữ tự nhiên

Vai trò của Xử lý ngôn ngữ tự nhiên-XLNNTN (Natural Language Processing-NLP) trong khai thác Big Data là không thể phủ nhận trong bối cảnh phát triển của doanh nghiệp hiện nay. Đối với ngôn ngữ tiếng Anh, ta đã được kế thừa nhiều tri thức cũng như nhiều công cụ có sẵn để áp dụng ngay ...

Trần Trung Dũng viết 23:39 ngày 16/09/2018

Hướng Dẫn Xử Lý Lỗi 404 Error trong Laravel

Lỗi không tìm thấy trang hay 404 error thường xuất hiện khi người dùng truy cậ vào một trang sử dụng sai địa chỉ URL. Ví dụ như thay vì truy cập vào trang https://www.codehub.vn/bai-viet thì họ lại truy cập vào trang https://www.codehub.vn/bai-vietv (thừa ký tự v). Trong trường hợp này chúng ta ...

Vũ Văn Thanh viết 10:39 ngày 07/09/2018

Xử lý tiếng nói: Các thành của tiếng việt trong xử lý tiếng nói

Abstract : Tổng hợp tiếng nói trên thế giới đã phát triển từ rất lâu. Và Tiếng Việt mới phát triển được trong vòng 20 năm gầy đầy. Để tổng hợp tiếng nói chuẩn xác, ta cần phải tìm được các đặc điểm về ngữ điệu của ngôn ngữ đó. Và mục đích của bài viết này để giới thiệu về các đặc điểm của Tiếng ...

Bùi Văn Nam viết 13:28 ngày 12/08/2018
0