2016-09-22 17 views
9

Tôi đang sử dụng gRPC với Python là máy khách/máy chủ bên trong kubernetes pods ... Tôi muốn có thể khởi chạy nhiều nhóm cùng loại (máy chủ gRPC) và để khách hàng kết nối với chúng (ngẫu nhiên).cân bằng tải phía khách hàng gRPC

Tôi đã gửi 10 nhóm máy chủ và thiết lập 'dịch vụ' để nhắm mục tiêu chúng. Sau đó, trong máy khách, tôi kết nối với tên DNS của dịch vụ - có nghĩa là kubernetes sẽ thực hiện việc cân bằng tải và đưa tôi đến một nhóm máy chủ ngẫu nhiên. Trong thực tế, khách hàng gọi các hàm gRPC (hoạt động tốt) nhưng khi tôi nhìn vào nhật ký, tôi thấy rằng tất cả các cuộc gọi đến cùng một máy chủ.

Tôi giả định máy khách đang thực hiện một số loại bộ nhớ đệm DNS dẫn đến tất cả các cuộc gọi được gửi đến cùng một máy chủ. Đây có phải là trường hợp không? Có anyway để vô hiệu hóa nó và thiết lập các khách hàng stub cùng để thực hiện một cuộc gọi "mới" và lấy một ip mới bằng DNS với mỗi cuộc gọi?

Tôi biết mức phí mà tôi có thể gây ra nếu nó sẽ truy vấn máy chủ DNS mỗi lần nhưng phân phối tải là quan trọng hơn nhiều đối với tôi vào lúc này.

EDIT

lẽ không phải là một vấn đề bộ nhớ đệm ... Có thể chỉ là cách gRPC hoạt động. HTTP/2 và kết nối có thể tái sử dụng liên tục. Bất kỳ cách nào để "ngắt kết nối" sau mỗi cuộc gọi?

Trả lời

10

Hãy để tôi tận dụng cơ hội để trả lời bằng cách mô tả cách mọi thứ được cho là hoạt động.

Cách client-side LB hoạt động trong lõi gRPC C (nền tảng cho tất cả nhưng Java và Go hương vị hoặc gRPC) là như sau (doc có thẩm quyền có thể được tìm thấy here):

Client-side LB được giữ đơn giản và "câm" với mục đích. Cách chúng tôi đã chọn để thực hiện các chính sách LB phức tạp là thông qua một máy chủ LB bên ngoài (như được mô tả trong tài liệu nói trên). Bạn không quan tâm đến kịch bản này. Thay vào đó, bạn chỉ cần tạo kênh, sử dụng chính sách LB chính sách (mặc định) .

Đầu vào cho chính sách LB là danh sách các địa chỉ được giải quyết. Khi sử dụng DNS, nếu foo.com giải quyết thành [10.0.0.1, 10.0.0.2, 10.0.0.3, 10.0.0.4], chính sách sẽ cố gắng thiết lập kết nối với tất cả chúng. Người đầu tiên kết nối thành công sẽ trở thành người được chọn cho đến khi ngắt kết nối. Vì vậy, tên "pick-first". Một tên dài hơn có thể đã được "chọn đầu tiên và gắn bó với nó càng lâu càng tốt", nhưng điều đó được tạo cho một tên tệp rất dài :). Nếu/khi người được chọn bị ngắt kết nối, chính sách chọn đầu tiên sẽ chuyển sang trả lại địa chỉ được kết nối thành công tiếp theo (được gọi nội bộ là "kênh con được kết nối"), nếu có. Một lần nữa, nó sẽ tiếp tục chọn subchannel được kết nối này miễn là nó vẫn kết nối.Nếu tất cả chúng thất bại, cuộc gọi sẽ thất bại.

Vấn đề ở đây là độ phân giải DNS, được kéo theo nội tại, chỉ được kích hoạt 1) khi tạo kênh và 2) khi ngắt kết nối kênh con được kết nối đã chọn.

Hiện tại, giải pháp hacky sẽ là tạo kênh mới cho mọi yêu cầu (rất không hiệu quả, nhưng nó sẽ thực hiện thủ thuật cho thiết lập của bạn).

Khi có thay đổi trong quý 1 năm 2017 (xem https://github.com/grpc/grpc/issues/7818) sẽ cho phép khách hàng chọn một chính sách LB khác, cụ thể là Round Robin. Ngoài ra, chúng tôi có thể xem xét giới thiệu một bit "ngẫu nhiên" cho cấu hình ứng dụng khách, điều này sẽ làm xáo trộn các địa chỉ trước khi thực hiện Round-Robin qua chúng, đạt được hiệu quả những gì bạn dự định.

+0

Cảm ơn bạn đã trả lời chi tiết. Trên thực tế, tôi đã làm những gì bạn đề xuất và tạo kênh mới cho mỗi yêu cầu (không hiệu quả, tôi biết). Từ câu trả lời của bạn tôi hiểu rằng chỉ có ip đầu tiên trong dns sẽ nhận được yêu cầu cho đến khi nó dừng lại (không có kết nối/giết chết/bị hỏng) và chỉ sau đó khách hàng sẽ nhận được ip thứ hai và vv ... là đúng? – Idan

+0

Có. Cho đến khi thay đổi, bạn có thể chọn vòng xoay thay cho lựa chọn đầu tiên làm chính sách LB, như đã đề cập. –

+0

Có giải pháp thông thường nào để mở rộng quy mô lên nhiều máy chủ gRPC không? hoặc cân bằng tải phía máy khách? –

1

Nếu bạn đã tạo dịch vụ vanilla Kubernetes, dịch vụ phải có IP ảo cân bằng tải riêng của mình (kiểm tra xem kubectl get svc your-service có hiển thị số CLUSTER-IP cho dịch vụ của bạn không). Nếu trường hợp này xảy ra, bộ nhớ đệm DNS không phải là một vấn đề, bởi vì một IP ảo duy nhất nên tách lưu lượng giữa các phần phụ trợ thực tế.

Hãy thử kubectl get endpoints your-service để xác nhận rằng dịch vụ của bạn thực sự biết về tất cả các chương trình phụ trợ của bạn.

Nếu bạn có số headless service, tra cứu DNS sẽ trả về bản ghi A có 10 IP (một cho mỗi Pod của bạn). Nếu khách hàng của bạn luôn chọn IP đầu tiên trong bản ghi A, điều đó cũng sẽ giải thích hành vi bạn đang thấy.

+0

Có một CLUSTER_IP cho máy chủ và tôi có thể thấy rằng tôi có tất cả các điểm cuối khi tôi 'nhận điểm cuối'. vẫn đi đến cùng một máy chủ. Tôi nghĩ rằng nó có thể là cách gRPC hoạt động và kết nối tái sử dụng của nó là HTTP/2 ... – Idan

Các vấn đề liên quan