Có một hướng không cần mở rộng server, đó là tối ưu các thành phần có sẵn để hoạt động hiệu quả hơn. Thực ra ngày nay dev dùng quá nhiều công nghệ, nhiều lớp abstract nên hiệu năng theo đó cũng bị tụt đi, giải quyết thì toàn bằng cách đắp thêm phần cứng nhưng thực ra nhiều khi một server là quá đủ.
Ví dụ: một trong các hướng tối ưu mà không thấy mấy bác ở trên nói là tối ưu network stack. Network stack của linux mặc định đang chỉ gọi là tạm ổn, tốt cho đa mục đích chứ không phải hiệu năng cao. Đây là bài viết khá chi tiết về đường đi của một packet từ lúc đến card mạng cho đến khi đến tầng application:
https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/. Có thể thấy là qua rất nhiều bước và không phải bước nào cũng đã tinh chỉnh sẵn.
Có hai hướng giải quyết, một cách tay to là bypass hết tất cả network stack của kernel, sử dụng một framework như DPDK để xử lý raw packet từ queue của NIC, implement hết các protocol từ thấp đến cao.
Cách đơn giản hơn là tunning một số bước để nó hoạt động phù hợp hơn với nhu cầu của mình. Ví dụ như hiện này nhiều NIC là multi queue, nên có thể config lại để ví dụ như packet từ địa chỉ IP A - B sẽ đi vào queue #0 (do NIC cho phép cấu hình hàm hash), rồi cũng có thể config để packet đi đến queue #1 sẽ vào CPU #2, #3, ... chứ không phải copy qua lại giữa các CPU như mặc định.
Cloudflare có vài bài hướng dẫn khá hay về chủ đề này:
Tối ưu theo throughput: 1 triệu packet/s với 1 server 6 core:
https://blog.cloudflare.com/how-to-receive-a-million-packets/
Tối ưu theo latency: trung bình 15 microsecond / request:
https://blog.cloudflare.com/how-to-achieve-low-latency/
Còn về container network thì càng nhiều thứ hay ho khác để tối ưu nữa. Mặc định khi chạy docker là chấp nhận hi sinh hiệu năng network, nhất là tăng latency, tốn CPU vì phải giả lập một con switch với đầy đủ tính năng như MAC learning, Spanning tree protocol (bridge network). Docker cũng có sẵn vài giải pháp khác như macvlan, ipvlan đỡ tốn tài nguyên hơn nhưng không phải mặc định và vẫn cần phải tìm hiểu để cấu hình thêm.
Sang bên K8S thì lại hay nữa, vì lúc này cần phải có cơ chế để routing giữ các pod một cách trong suốt, trong khi mỗi pod có thể ở cùng hoặc khác node. Cái này gọi là CNI (Container Network Interface). K8S mặc định không có CNI nào mà phải tự cài thêm khi setup. CNI phổ biến nhất là Flannel, sử dụng VXLAN. Dùng VXLAN có nghĩa là hiệu năng lại tụt đi đôi chút vì bản chất của nó là encapsulate packet layer bằng một packet UDP layer 4 để trao đổi giữa các node, tức là mất thêm CPU để xử lý cho 3 layer nữa. Cũng tương tự như docker, có các giải pháp CNI khác hiệu năng tốt hơn. Đây là một bài so sánh, lấy base là --host=network:
https://machinezone.github.io/research/networking-solutions-for-kubernetes/