2013-05-30 27 views
15

Chúng tôi đang chạy một ứng dụng web và chuyển từ memcached sang redis (2.4) để lưu vào bộ nhớ đệm. Bây giờ chúng tôi hơi thất vọng về hiệu suất redis. Redis đang chạy trên cùng một máy chủ và chúng tôi chỉ sử dụng các thao tác GET và SET rất đơn giản. Trên một số yêu cầu sử dụng nhiều giá trị được lưu trong bộ nhớ cache, chúng tôi có tối đa 300 yêu cầu GET để thực hiện lại, nhưng các yêu cầu đó mất tới 150ms. Chúng tôi có khoảng 200.000 phím hoạt động và khoảng 1.000 yêu cầu redis mỗi giây. Không có vấn đề với đĩa io, ram hoặc cpu. Do mã hiện tại của chúng tôi, chúng tôi không thể nhóm các yêu cầu lại với nhau một cách đơn giản. Memcached nhanh gấp 4 lần. Những gì chúng tôi thích về redis, là chúng tôi không cần bất kỳ bộ nhớ cache nào, và có thể sử dụng các tính năng kho dữ liệu nâng cao hơn trong tương lai. Chúng tôi mong đợi redis để thực hiện tương tự như memcached. Vì vậy, có lẽ chúng ta đã bỏ lỡ một cái gì đó trong cấu hình của chúng tôi, về cơ bản là cấu hình mặc định.Điều chỉnh hiệu suất Redis

Bạn có biết cách thực hành nào tốt nhất để điều chỉnh hiệu suất lại không?

+0

Redis đang chạy trên cùng một máy chủ như thế nào? Các khách hàng, hoặc một trong đó đã được chạy memcached? 150ms cho một yêu cầu Redis âm thanh như bạn đang nhấn hoán đổi/đĩa, không phải bộ nhớ, hoặc bạn có nghĩa là 150ms cho tất cả 300 yêu cầu? –

+0

Đó là một ứng dụng web với khoảng 100 yêu cầu apache mỗi giây. Redis đang chạy trên cùng một máy chủ như chính ứng dụng web và máy chủ cơ sở dữ liệu mysql, nhưng chúng tôi dự định chuyển apache sang 3 máy chủ tải cân bằng sớm. Máy chủ hiện tại có khoảng 64GB RAM, redis mất khoảng 100MB. Có đủ ram miễn phí và không có vấn đề với cpu hoặc io. Máy chủ không chuyển sang đĩa. Và có, tôi có nghĩa là 150ms cho 300 yêu cầu, nhưng memcached chỉ mất 40ms trong cùng điều kiện. – ak2

+1

Điều duy nhất tôi có thể nghĩ là nếu bạn đang sử dụng kết nối chia sẻ với Redis cho tất cả các yêu cầu thay vì một yêu cầu trên web, bạn có thể gặp vấn đề về độ trễ với Redis, nhưng với 1000 yêu cầu mỗi giây, bạn sẽ không thấy độ trễ đó. Xin lỗi, không có gì thực sự hữu ích từ hướng của tôi ngày hôm nay :) –

Trả lời

21

Trước tiên, bạn có thể muốn đọc the Redis benchmark page. Nó cung cấp một bản tóm tắt tốt về các điểm chính để kiểm tra để điều chỉnh Redis.

Thậm chí giả sử bạn không sử dụng pipelining, 300 GET trong 150 ms không hiệu quả. Nó có nghĩa là độ trễ trung bình là 500 chúng tôi. Tuy nhiên, nó thực sự phụ thuộc vào kích thước của các đối tượng của bạn. Các đối tượng lớn hơn, có độ trễ cao hơn. Trên hộp 2 GHz AMD rất cũ của tôi, tôi có thể đo 150 độ trễ của chúng tôi cho các đối tượng nhỏ (một vài byte).

Để nhanh chóng kiểm tra độ trễ trung bình của instance Redis, bạn có thể sử dụng:

$ redis-cli --latency 

Hãy chắc chắn để sử dụng một phiên bản gần đây Redis (không 2.4) để có được tùy chọn này. Lưu ý: 2.4 là khá cũ, sử dụng Redis 2.6 - biên dịch phiên bản Redis của riêng bạn nếu cần thiết, nó thực sự đơn giản.

Để nhanh chóng chạy một chuẩn mực để nghiên cứu độ trễ, bạn có thể khởi động:

$ redis-benchmark -q -n 10000 -c 1 -d average_size_of_your_objects_in_bytes 

Nó chạy với một kết nối duy nhất và không pipelining, vì vậy độ trễ có thể được rút ra từ thông. Hãy thử so sánh kết quả của các điểm chuẩn này với các số liệu được đo bằng ứng dụng của bạn.

Có một số điểm bạn có thể muốn kiểm tra:

  • nào Redis thư viện khách hàng để bạn sử dụng? Với ngôn ngữ phát triển nào? Đối với một số ngôn ngữ kịch bản, bạn cần phải cài đặt mô-đun thuê để có được một khách hàng hiệu quả.
  • Máy của bạn có phải là máy ảo không? Trên hệ điều hành nào?
  • Các kết nối với Redis có ổn định không? (nghĩa là bạn không được phép kết nối/ngắt kết nối tại mỗi yêu cầu HTTP của máy chủ ứng dụng của bạn).

Tại sao nó tốt hơn với memcached? Vâng, một cá thể được ghi nhớ duy nhất chắc chắn có khả năng mở rộng hơn và có thể đáp ứng nhanh hơn một cá thể Redis duy nhất, vì nó có thể chạy trên nhiều luồng. Redis là nhanh, nhưng đơn luồng - việc thực hiện tất cả các lệnh được tuần tự hóa. Vì vậy, khi một lệnh đang diễn ra cho một kết nối, tất cả các máy khách khác phải chờ đợi - độ trễ xấu trên một lệnh đã cho cũng sẽ tác động đến tất cả các lệnh đang chờ xử lý. Nói chung, ở mức thông lượng thấp, hiệu suất có thể so sánh được.

Với 1000 q/s (thông lượng thấp của Redis hoặc tiêu chuẩn ghi nhớ), tôi có thể nói rằng vấn đề của bạn có thể xảy ra hơn ở phía khách hàng (tức làlựa chọn thư viện máy khách, kết nối/ngắt kết nối, vv ...), so với chính máy chủ Redis.

Cuối cùng tôi nên đề cập rằng nếu bạn tạo một số truy vấn Redis cho mỗi yêu cầu HTTP, hãy xem xét pipelining các lệnh bạn gửi tới Redis càng nhiều càng tốt. Nó thực sự là một điểm then chốt để phát triển các ứng dụng Redis hiệu quả.

Nếu máy chủ ứng dụng của bạn nằm trên cùng một hộp với Redis, bạn cũng có thể sử dụng ổ cắm miền unix thay cho vòng lặp TCP để kết nối với Redis. Nó cải thiện hiệu suất một chút (lên tới 50% thông lượng khi không sử dụng pipelining).

+0

"việc thực hiện tất cả các lệnh được serialized": bạn sẽ cho biết thêm chi tiết về tuyên bố này? với tôi nó có vẻ như bạn đang nói rằng trong khi một lệnh đang chạy không có lệnh khác, ngay cả trên các kết nối khác có thể chạy. là làm thế nào redis đạt được nguyên tử lệnh? – akonsu

+0

Có chính xác. Xem http://stackoverflow.com/questions/10489298/redis-is-single-threaded-then-how-does-it-do-concurrent-io/10495458#10495458 –

+0

Xem thêm http://redis.io/topics/độ trễ –

0

Kiểm tra xem redis có đang sử dụng bộ nhớ hoán đổi hệ điều hành hay không. Nếu đó là sau đó sẽ thêm độ trễ. Để tìm hiểu, tìm kiếm "Độ trễ được tạo ra bằng cách hoán đổi" tại đây: http://redis.io/topics/latency

Nếu phần cứng máy chủ của bạn có khả năng NUMA, hãy khởi động lại máy chủ đỏ với numactl tốt hơn. Đừng quên tắt chế độ khôi phục vùng (vm.zone_reclaim_mode = 0) trong sysctl nếu bạn đang bắt đầu với redis-server với NUMA.

0

Cố gắng viết mã 300 yêu cầu GET bên trong tập lệnh Lua. Nó sẽ hoạt động nhanh hơn vì bạn tiết kiệm thời gian khi chạm vào ngăn xếp TCP/IP mặc dù mã máy khách của bạn đang chạy cục bộ với Redis.