Изненадата (не се наблюдават събития на изтичане, когато времето за живот за ключ достигне нула) не е свързано с Python, а по-скоро с начина, по който Redis изтича ключовете.
Redis doc относно Времето на събития с изтекъл срок
Време на изтекли събития
Ключовете със свързано време за живот са изтекли от Redis по два начина:
- Когато ключът е достъпен чрез команда и се установи, че е изтекъл.
- Чрез фонова система, която търси ключове с изтекъл срок във фонов режим, постепенно, за да може да събира и ключове, които никога не са достъпни.
Събитията с изтекъл срок се генерират при достъп до ключ и се установи, че е изтекъл от една от горните системи, в резултат на което няма гаранции, че сървърът Redis ще може да генерира изтеклото събитие в момента, в който ключът е жив достига стойността на нула.
Ако нито една команда не е насочена към ключа постоянно и има много ключове със свързан TTL, може да има значително забавяне между времето, когато времето за живот на ключа спадне до нула, и времето, когато се генерира изтеклото събитие.
По принцип събития с изтекъл срок се генерират, когато Redis сървърът изтрие ключа а не когато времето за живот теоретично достигне стойността на нула.
Малък тест на конзолата
когато Redis работи ($ sudo service redis-server start
)
Стартирах една конзола и се абонирах:
$ redis-cli
PSUBSCRIBE "__key*__:*"
След това в друга конзола:
$ redis-cli
> config set notify-keyspace-events AKE
какво трябва да се абонира за всякакви събития
След това продължих с експериментите в тази втора конзола:
> set aaa aaa
> del aaa
> set aaa ex 5
> get aaa
Всички дейности се виждаха в абонираната конзола. Само изтичането на ключа понякога се забавяше с няколко секунди, понякога идваше точно навреме.
Имайте предвид също, че има фини разлики в съобщенията, едно съобщение [email protected]__:expire
друг [email protected]__:expired
.
Примерен слушател spy.py
import redis
import time
r = redis.StrictRedis()
pubsub = r.pubsub()
pubsub.psubscribe("*")
for msg in pubsub.listen():
print time.time(), msg
Този код се регистрира във всички съществуващи канали в redis по подразбиране и отпечатва всичко, което бъде публикувано.
Стартирайте го:
$ python spy.py
и в друга конзола опитайте да зададете ключ с изтичане. Ще видите всички събития.
За следното въвеждане на redis-cli.
$ redis-cli
127.0.0.1:6379> set a aha
OK
127.0.0.1:6379> set b bebe ex 3
OK
127.0.0.1:6379> set b bebe ex 3
OK
получаваме шпионски изход:
1401548400.27 {'pattern': None, 'type': 'psubscribe', 'channel': '*', 'data': 1L}
1401548428.36 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:a', 'data': 'set'}
1401548428.36 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:set', 'data': 'a'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'set'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:set', 'data': 'b'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expire'}
1401548436.8 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expire', 'data': 'b'}
1401548439.82 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expired'}
1401548439.82 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expired', 'data': 'b'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'set'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:set', 'data': 'b'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expire'}
1401548484.46 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expire', 'data': 'b'}
1401548487.51 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:b', 'data': 'expired'}
1401548487.51 {'pattern': '*', 'type': 'pmessage', 'channel': '[email protected]__:expired', 'data': 'b'}