Redis python đường ống dẫn

Hướng dẫn này cung cấp hướng dẫn cơ bản về hệ thống điều phối cụm Kubernetes. Mỗi mô-đun chứa một số thông tin cơ bản về các tính năng và khái niệm chính của Kubernetes và bao gồm một hướng dẫn trực tuyến tương tác. Các hướng dẫn tương tác này cho phép bạn tự quản lý một cụm đơn giản và các ứng dụng được chứa trong đó

Sử dụng các hướng dẫn tương tác, bạn có thể học cách

  • Triển khai một ứng dụng được đóng gói trên một cụm
  • Mở rộng quy mô triển khai
  • Cập nhật ứng dụng được chứa bằng phiên bản phần mềm mới
  • Gỡ lỗi ứng dụng được chứa

Các hướng dẫn sử dụng Katacoda để chạy một thiết bị đầu cuối ảo trong trình duyệt web của bạn chạy Minikube, một triển khai Kubernetes cục bộ quy mô nhỏ có thể chạy ở mọi nơi. Không cần cài đặt bất kỳ phần mềm nào hoặc định cấu hình bất kỳ thứ gì;


Kubernetes có thể làm gì cho bạn?

Với các dịch vụ web hiện đại, người dùng mong đợi các ứng dụng có sẵn 24/7 và các nhà phát triển mong muốn triển khai các phiên bản mới của các ứng dụng đó nhiều lần trong ngày. Containerization giúp đóng gói phần mềm để phục vụ các mục tiêu này, cho phép các ứng dụng được phát hành và cập nhật mà không có thời gian chết. Kubernetes giúp bạn đảm bảo các ứng dụng được chứa trong bộ chứa đó chạy ở đâu và khi nào bạn muốn, đồng thời giúp chúng tìm thấy các tài nguyên và công cụ cần thiết để hoạt động. Kubernetes là một nền tảng mã nguồn mở, sẵn sàng sản xuất được thiết kế với kinh nghiệm tích lũy của Google về điều phối vùng chứa, kết hợp với các ý tưởng hay nhất từ ​​cộng đồng

Redis là một gói phần mềm mã nguồn mở với nhiều ưu điểm tốt về tốc độ và dễ sử dụng nó đã có và đang trở nên phổ biến, biến được sử dụng nhiều trong quá trình phát triển phần mềm. Với điểm vượt trội của mình về tốc độ đối đầu Redis là sự lựa chọn rất tốt cho các ứng dụng có yêu cầu về thời gian thực. Hơn nữa, mặc dù Redis lưu trữ dữ liệu trên RAM nhưng vẫn có cơ chế ghi lại dữ liệu ra bộ nhớ ngoài đề phòng trường hợp rủi ro. Nếu bạn chưa thử Redis, tôi nghĩ bạn nên thử ngay hôm nay sẽ rất thú vị, hiệu ứng ứng dụng của bạn sẽ tăng lên một cách đáng kinh ngạc

Redis pipelining là một kỹ thuật để cải thiện hiệu suất bằng cách đưa ra nhiều lệnh cùng một lúc mà không cần chờ phản hồi cho từng lệnh riêng lẻ. Pipelining được hỗ trợ bởi hầu hết các máy khách Redis. Tài liệu này mô tả vấn đề mà đường ống được thiết kế để giải quyết và cách đường ống hoạt động trong Redis

Giao thức yêu cầu/phản hồi và thời gian khứ hồi [RTT]

Redis là một máy chủ TCP sử dụng mô hình máy khách-máy chủ và được gọi là giao thức Yêu cầu/Phản hồi

Điều này có nghĩa là thông thường một yêu cầu được thực hiện theo các bước sau

  • Máy khách gửi một truy vấn đến máy chủ và đọc từ ổ cắm, thường là theo cách chặn, để biết phản hồi của máy chủ
  • Máy chủ xử lý lệnh và gửi phản hồi lại cho máy khách

Vì vậy, chẳng hạn, một chuỗi bốn lệnh giống như thế này

  • Khách hàng. TĂNG X
  • Người phục vụ. 1
  • Khách hàng. TĂNG X
  • Người phục vụ. 2
  • Khách hàng. TĂNG X
  • Người phục vụ. 3
  • Khách hàng. TĂNG X
  • Người phục vụ. 4

Máy khách và Máy chủ được kết nối thông qua liên kết mạng. Một liên kết như vậy có thể rất nhanh [giao diện loopback] hoặc rất chậm [kết nối được thiết lập qua Internet với nhiều bước nhảy giữa hai máy chủ]. Dù độ trễ của mạng là bao nhiêu, thì các gói dữ liệu cần có thời gian để di chuyển từ máy khách đến máy chủ và ngược lại từ máy chủ đến máy khách để mang phản hồi

Thời gian này được gọi là RTT [Round Trip Time]. Thật dễ dàng để thấy điều này có thể ảnh hưởng đến hiệu suất như thế nào khi máy khách cần thực hiện nhiều yêu cầu liên tiếp [ví dụ: thêm nhiều thành phần vào cùng một danh sách hoặc điền vào cơ sở dữ liệu có nhiều khóa]. Ví dụ: nếu thời gian RTT là 250 mili giây [trong trường hợp liên kết rất chậm qua Internet], ngay cả khi máy chủ có thể xử lý 100 nghìn yêu cầu mỗi giây, chúng tôi sẽ có thể xử lý tối đa bốn yêu cầu mỗi giây

Nếu giao diện được sử dụng là giao diện vòng lặp, RTT sẽ ngắn hơn nhiều, thường là dưới một phần nghìn giây, nhưng ngay cả điều này cũng sẽ tăng lên rất nhiều nếu bạn cần thực hiện nhiều thao tác ghi liên tiếp

May mắn thay, có một cách để cải thiện trường hợp sử dụng này

Đường ống Redis

Máy chủ Yêu cầu/Phản hồi có thể được triển khai để có thể xử lý các yêu cầu mới ngay cả khi máy khách chưa đọc các phản hồi cũ. Bằng cách này, có thể gửi nhiều lệnh đến máy chủ mà không cần chờ phản hồi và cuối cùng đọc các phản hồi trong một bước

Điều này được gọi là pipelining, và là một kỹ thuật được sử dụng rộng rãi trong nhiều thập kỷ. Chẳng hạn, nhiều triển khai giao thức POP3 đã hỗ trợ tính năng này, tăng tốc đáng kể quá trình tải xuống email mới từ máy chủ

Redis đã hỗ trợ pipelining từ những ngày đầu tiên, vì vậy dù bạn đang chạy phiên bản nào, bạn đều có thể sử dụng pipelining với Redis. Đây là một ví dụ sử dụng tiện ích netcat thô

$ [printf "PING\r\nPING\r\nPING\r\n"; sleep 1] | nc localhost 6379
+PONG
+PONG
+PONG

Lần này, chúng tôi không trả chi phí RTT cho mọi cuộc gọi mà chỉ trả một lần cho ba lệnh

Rõ ràng, với đường ống, thứ tự các hoạt động của ví dụ đầu tiên của chúng tôi sẽ như sau

  • Khách hàng. TĂNG X
  • Khách hàng. TĂNG X
  • Khách hàng. TĂNG X
  • Khách hàng. TĂNG X
  • Người phục vụ. 1
  • Người phục vụ. 2
  • Người phục vụ. 3
  • Người phục vụ. 4

LƯU Ý QUAN TRỌNG. Trong khi máy khách gửi lệnh bằng cách sử dụng đường ống, máy chủ sẽ buộc phải xếp hàng các câu trả lời, sử dụng bộ nhớ. Vì vậy, nếu bạn cần gửi nhiều lệnh bằng đường ống, tốt hơn là gửi chúng thành các đợt, mỗi đợt chứa một số lượng hợp lý, chẳng hạn như 10 nghìn lệnh, đọc các câu trả lời, sau đó gửi lại 10 nghìn lệnh khác, v.v. Tốc độ sẽ gần như nhau, nhưng bộ nhớ bổ sung được sử dụng sẽ tối đa là dung lượng cần thiết để xếp hàng các câu trả lời cho các lệnh 10k này

Đó không chỉ là vấn đề của RTT

Pipelining không chỉ là một cách để giảm chi phí độ trễ liên quan đến thời gian khứ hồi, nó thực sự cải thiện đáng kể số lượng thao tác bạn có thể thực hiện mỗi giây trong một máy chủ Redis nhất định. Điều này là do không sử dụng đường ống dẫn, việc phục vụ mỗi lệnh rất rẻ từ quan điểm truy cập cấu trúc dữ liệu và tạo ra câu trả lời, nhưng lại rất tốn kém từ quan điểm thực hiện I/O ổ cắm. Điều này liên quan đến việc gọi tòa nhà tổng hợp read[]write[], có nghĩa là đi từ vùng đất của người dùng đến vùng hạt nhân. Chuyển đổi ngữ cảnh là một hình phạt tốc độ rất lớn

Khi sử dụng đường ống, nhiều lệnh thường được đọc bằng một lệnh gọi hệ thống read[] và nhiều phản hồi được gửi bằng một lệnh gọi hệ thống write[]. Do đó, tổng số lượng truy vấn được thực hiện mỗi giây ban đầu tăng gần như tuyến tính với các đường ống dài hơn và cuối cùng đạt gấp 10 lần so với đường cơ sở thu được mà không cần đường ống dẫn, như thể hiện trong hình này

Một ví dụ mã trong thế giới thực

Trong điểm chuẩn sau, chúng tôi sẽ sử dụng ứng dụng khách Redis Ruby, hỗ trợ đường ống, để kiểm tra sự cải thiện tốc độ do đường ống

require 'rubygems'
require 'redis'

def bench[descr]
  start = Time.now
  yield
  puts "#{descr} #{Time.now - start} seconds"
end

def without_pipelining
  r = Redis.new
  10_000.times do
    r.ping
  end
end

def with_pipelining
  r = Redis.new
  r.pipelined do
    10_000.times do
      r.ping
    end
  end
end

bench['without pipelining'] do
  without_pipelining
end
bench['with pipelining'] do
  with_pipelining
end

Chạy tập lệnh đơn giản ở trên mang lại các số liệu sau trên hệ thống Mac OS X của tôi, chạy qua giao diện loopback, trong đó đường ống dẫn sẽ mang lại sự cải thiện nhỏ nhất vì RTT đã khá thấp

without pipelining 1.185238 seconds
with pipelining 0.250783 seconds

Như bạn có thể thấy, bằng cách sử dụng đường ống dẫn, chúng tôi đã cải thiện việc chuyển tiền lên gấp năm lần

Đường ống vs Viết kịch bản

Sử dụng Redis scripting, có sẵn từ Redis 2. 6, một số trường hợp sử dụng cho pipelining có thể được giải quyết hiệu quả hơn bằng cách sử dụng các tập lệnh thực hiện nhiều công việc cần thiết ở phía máy chủ. Một lợi thế lớn của scripting là nó có thể đọc và ghi dữ liệu với độ trễ tối thiểu, giúp các thao tác như đọc, tính toán, ghi rất nhanh [pipelining không thể trợ giúp trong trường hợp này vì máy khách cần phản hồi của lệnh đọc trước đó

Đôi khi, ứng dụng cũng có thể muốn gửi các lệnh EVAL hoặc EVALSHA trong một đường dẫn. Điều này hoàn toàn có thể xảy ra và Redis hỗ trợ nó một cách rõ ràng bằng lệnh SCRIPT LOAD [nó đảm bảo rằng có thể gọi EVALSHA mà không có nguy cơ bị lỗi]

ruột thừa. Tại sao các vòng lặp bận bị chậm ngay cả trên giao diện loopback?

Ngay cả với tất cả thông tin cơ bản được trình bày trong trang này, bạn vẫn có thể thắc mắc tại sao điểm chuẩn Redis như sau [bằng mã giả], lại chậm ngay cả khi được thực thi trong giao diện vòng lặp, khi máy chủ và máy khách đang chạy trong cùng một máy vật lý

FOR-ONE-SECOND:
    Redis.SET["foo","bar"]
END

Xét cho cùng, nếu cả quy trình Redis và điểm chuẩn đều chạy trong cùng một hộp, thì không phải nó chỉ sao chép thư trong bộ nhớ từ nơi này sang nơi khác mà không có bất kỳ độ trễ thực tế hoặc liên quan đến mạng nào sao?

Lý do là các tiến trình trong một hệ thống không phải lúc nào cũng chạy, thực ra đó là bộ lập lịch hạt nhân cho phép tiến trình chạy. Vì vậy, chẳng hạn, khi điểm chuẩn được phép chạy, nó sẽ đọc câu trả lời từ máy chủ Redis [liên quan đến lệnh cuối cùng được thực thi] và viết một lệnh mới. Lệnh hiện nằm trong bộ đệm giao diện loopback, nhưng để máy chủ có thể đọc được, hạt nhân phải lên lịch cho quá trình máy chủ [hiện bị chặn trong lệnh gọi hệ thống] để chạy, v.v. Vì vậy, trong điều kiện thực tế, giao diện loopback vẫn liên quan đến độ trễ giống như mạng, do cách thức hoạt động của bộ lập lịch hạt nhân

Về cơ bản, điểm chuẩn vòng lặp bận rộn là điều ngớ ngẩn nhất có thể được thực hiện khi đo hiệu suất trên máy chủ được nối mạng. Điều khôn ngoan là chỉ cần tránh điểm chuẩn theo cách này

Chủ Đề