Redis медленный запрос с конвейерным hgetall - PullRequest
1 голос
/ 01 ноября 2019

Итак, у меня есть небольшая и простая база данных Redis. Он содержит 136689 ключей, значениями которых являются хеш-карты, содержащие 27 полей. Я получаю доступ к таблице через интерфейс Python на узле сервера, и мне нужно загружать около 1000-1500 значений за вызов (в конце концов я увижу около 10 запросов в секунду). Простой вызов выглядит примерно так:

# below keys is a list of approximately 1000 integers, 
# not all of which are in the table

import redis
db = redis.StrictRedis(
  host='127.0.0.1',
  port=6379,
  db=0,
  socket_timeout=1,
  socket_connection_timeout=1,
  decode_responses=True
)

with db.pipeline() as pipe:
  for key in keys: 
    pipe.hgetall(key)
  results = zip(keys,pipe.execute())

Общее время для этого составляет ~ 328 мс при среднем времени на запрос ~ 0,25 мс.

Вопрос: Это очень медленно для небольшой базы данных и относительно небольшого числа запросов в секунду. Что-то не так с моей конфигурацией или тем, как я вызываю сервер? Можно ли что-то сделать, чтобы сделать это быстрее? Я не ожидаю, что таблица станет намного больше, поэтому я совершенно счастлив, жертвуя дисковым пространством для скорости.


Дополнительная информация

Вызов hget для каждой клавиши(без конвейера) медленнее (как и ожидалось) и показывает, что распределение времени является бимодальным. Меньший пик соответствует ключам, которых нет в таблице, а больший соответствует ключам, которые находятся.

Redis response time distribution

Мой файл conf выглядит следующим образом:

port 6379
daemonize yes 
save ""
bind 127.0.0.1
tcp-keepalive 300 
dbfilename mytable.rdb
dir .
rdbcompression yes 

appendfsync no
no-appendfsync-on-rewrite yes 
loglevel notice

Я запускаю сервер с:

> echo never > /sys/kernel/mm/transparent_hugepage/enabled
> redis-server myconf.conf

Я также измерил внутреннюю задержку с помощью redis-cli --intrinsic-latency 100, что дает:

Max latency so far: 1 microseconds.
Max latency so far: 10 microseconds.
Max latency so far: 11 microseconds.
Max latency so far: 12 microseconds.
Max latency so far: 18 microseconds.
Max latency so far: 32 microseconds.
Max latency so far: 34 microseconds.
Max latency so far: 38 microseconds.
Max latency so far: 48 microseconds.
Max latency so far: 52 microseconds.
Max latency so far: 60 microseconds.
Max latency so far: 75 microseconds.
Max latency so far: 94 microseconds.
Max latency so far: 120 microseconds.
Max latency so far: 281 microseconds.
Max latency so far: 413 microseconds.
Max latency so far: 618 microseconds.

1719069639 total runs (avg latency: 0.0582 microseconds / 58.17 nanoseconds per run).
Worst run took 10624x longer than the average latency.

Это предполагаетчто у меня должно получиться намного лучшее время ожидания. Тем не менее, когда я проверяю задержку сервера с помощью: > redis-cli --latency -h 127.0.0.1 -p 6379, я получаю min: 0, max: 2, avg: 0.26 (2475 samples)

Похоже, это означает, что ~ 0,25 мс - это задержка для моего сервера, но кажется, что задержка на запрос I 'Я вижу из Python то же самое, что CLI, но все это кажется очень медленным.

Хэш-карта, связанная с каждым ключом (после декодирования), имеет размер ~ 1200 байтов. Поэтому я выполнил следующий тест

redis-benchmark -h 127.0.0.1 -p 6379 -d 1500 hmset hgetall myhash rand_int rand_string
====== hmset hgetall myhash rand_int rand_string ======
  100000 requests completed in 1.45 seconds
  50 parallel clients
  1500 bytes payload
  keep alive: 1

100.00% <= 1 milliseconds
100.00% <= 1 milliseconds
69060.77 requests per second

Это, кажется, подтверждает, что моя задержка очень высока, но на самом деле не говорит мне, почему.

...