Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

redis + gevent - Hiệu suất kém - tôi đang làm gì sai?

Điều này được mong đợi.

Bạn chạy điểm chuẩn này trên một máy ảo, trên đó chi phí của các cuộc gọi hệ thống cao hơn trên phần cứng vật lý. Khi gevent được kích hoạt, nó có xu hướng tạo ra nhiều lệnh gọi hệ thống hơn (để xử lý thiết bị epoll), do đó, bạn sẽ có hiệu suất kém hơn.

Bạn có thể dễ dàng kiểm tra điểm này bằng cách sử dụng dấu tích trên tập lệnh.

Không có gevent, vòng lặp bên trong tạo ra:

recvfrom(3, ":931\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41
recvfrom(3, ":941\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41

Với gevent, bạn sẽ có:

recvfrom(3, ":221\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41
recvfrom(3, 0x7b0f04, 4096, 0, 0, 0)    = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(5, EPOLL_CTL_ADD, 3, {EPOLLIN, {u32=3, u64=3}}) = 0
epoll_wait(5, {{EPOLLIN, {u32=3, u64=3}}}, 32, 4294967295) = 1
clock_gettime(CLOCK_MONOTONIC, {2469, 779710323}) = 0
epoll_ctl(5, EPOLL_CTL_DEL, 3, {EPOLLIN, {u32=3, u64=3}}) = 0
recvfrom(3, ":231\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41

Khi cuộc gọi recvfrom bị chặn (EAGAIN), gevent sẽ quay lại vòng lặp sự kiện, do đó, các lệnh gọi bổ sung được thực hiện để đợi các sự kiện trình mô tả tệp (epoll_wait).

Xin lưu ý rằng loại điểm chuẩn này là trường hợp xấu nhất đối với bất kỳ hệ thống vòng lặp sự kiện nào, bởi vì bạn chỉ có một bộ mô tả tệp, do đó không thể phân tích các hoạt động chờ đợi trên một số bộ mô tả. Hơn nữa, I / Os không đồng bộ không thể cải thiện bất kỳ điều gì ở đây vì mọi thứ đều đồng bộ.

Đây cũng là trường hợp xấu nhất đối với Redis vì:

  • nó tạo ra nhiều vòng tới máy chủ

  • nó kết nối / ngắt kết nối một cách có hệ thống (1000 lần) vì nhóm được khai báo trong hàm UxDomainSocket.

Trên thực tế, điểm chuẩn của bạn không kiểm tra gevent, redis hoặc redis-py:nó thực hiện khả năng của máy ảo để duy trì một trận bóng bàn giữa 2 quá trình.

Nếu bạn muốn tăng hiệu suất, bạn cần:

  • sử dụng pipelining để giảm số vòng quay

  • làm cho nhóm liên tục trên toàn bộ điểm chuẩn

Ví dụ:hãy xem xét tập lệnh sau:

#!/usr/bin/python

from gevent import monkey
monkey.patch_all()

import timeit
import redis
from redis.connection import UnixDomainSocketConnection

pool = redis.ConnectionPool(connection_class=UnixDomainSocketConnection, path = '/tmp/redis.sock')

def UxDomainSocket():
    r = redis.Redis(connection_pool = pool)
    p = r.pipeline(transaction=False)
    p.set("testsocket", 1)
    for i in range(100):
        p.incr('testsocket', 10)
    p.get('testsocket')
    p.delete('testsocket')
    p.execute()

print timeit.Timer(stmt='UxDomainSocket()', setup='from __main__ import UxDomainSocket').timeit(number=1000)

Với tập lệnh này, tôi nhận được hiệu suất tốt hơn gấp 3 lần và hầu như không tốn chi phí với gevent.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bull queue:Khi một công việc không thành công, làm thế nào để ngăn hàng đợi xử lý các công việc còn lại?

  2. 6 chỉ số giám sát Redis quan trọng bạn cần xem

  3. Bế tắc khi sử dụng Aggregator + Redis

  4. cách định cấu hình ttl khác nhau cho từng bộ đệm redis khi sử dụng @cacheable trong springboot2.0

  5. Redis là một luồng, sau đó nó thực hiện I / O đồng thời như thế nào?