У меня есть базовый веб-API, написанный на Node.js, который записывает объект как HSET в кеш Redis. Оба работают в контейнерах докеров.
У меня есть скрипт Python, работающий на той же виртуальной машине, которой нужно следить за кешем Redis, а затем запускать некоторый код, когда появляется новый HSET или изменяется поле в HSET.
Я наткнулся на Redis Pub/Sub, но я не уверен, что это действительно правильный способ его использования.
Для проверки я создал два скрипта Python. Первый подписывается на систему обмена сообщениями:
import redis
import json
print ("Redis Subscriber")
redis_conn = redis.Redis(
host='localhost',
port=6379,
password='xxx',
charset = "utf-8",
decode_responses=True)
def sub():
pubsub = redis_conn.pubsub()
pubsub.subscribe("broadcast")
for message in pubsub.listen():
if message.get("type") == "message":
data = json.loads(message.get("data"))
print(data)
if __name__ == "__main__":
sub()
Второй публикует в систему обмена сообщениями:
import redis
import json
print ("Redis Publisher")
redis_conn = redis.Redis(
host='localhost',
port=6379,
password='xxx',
charset = "utf-8",
decode_responses=True)
def pub():
data = {
"message": "id:3"
}
redis_conn.publish("broadcast", json.dumps(data))
if __name__ == "__main__":
pub()
Я перепишу издателя на Node.js, и он просто опубликует ключ HSET, например id:3. Затем подписчик запустится в Python, и когда он получит новое сообщение, он будет использовать этот ключ HSET «id: 3» для поиска фактического HSET и других действий.
Это не похоже на правильный способ сделать это, но часы Redis не поддерживают HSET. Есть ли лучший способ сделать это?
Это не похоже на правильный способ сделать это, но часы Redis не поддерживают HSET.
Redis WATCH
поддерживает хеш-ключи, но не поддерживает хэш-поля.
Есть ли лучший способ сделать это?
Хотя я полагаю, что ваш подход может быть приемлемым для определенных сценариев, сообщения pub/sub являются «выстрелил и забыл»: ваш подписчик может отключиться по любой причине сразу после того, как издатель опубликовал сообщение, но до того, как у него будет возможность прочитать его — и ваш объект Таким образом, запись будет потеряна навсегда, даже если подписчик после этого автоматически переподключится.
Вместо этого вы можете выбрать потоки Redis, которые позволяют добавлять записи в данный поток (аналогично процессу публикации вашего кода) и использовать их (аналогично сценарию вашего подписчика) посредством процесса, сохраняющего сообщения.
В качестве альтернативы, возможно, более простого подхода, вы можете просто разделить свои хэши на несколько ключей, по одному на поле, чтобы вы могли их WATCH
.
Возможно, вы захотите взглянуть на уведомления key-space. Уведомления о ключевом пространстве могут автоматически публиковать сообщения через PubSub при изменении, добавлении, удалении ключа и т. д.
Вы можете использовать события, например, вызов HSET, и указать имя ключа, по которому он был вызван. Или вы можете использовать ключи, например my:awesome:key, и получать уведомления о произошедшем событии. Или оба.
Вам нужно включить уведомления о ключевом пространстве, чтобы использовать их:
redis.cloud:6379> CONFIG SET notify-keyspace-events KEA
Вы можете подписаться на все события и ключи следующим образом:
redis.cloud:6379> PSUBSCRIBE '__key*__:*'
"pmessage","__key*__:*","__keyspace@0__:foo","set"
"pmessage","__key*__:*","__keyevent@0__:set","foo"
Надеюсь, это поможет!