Timeseries¶
redis-py
supports RedisTimeSeries which is a time-series-database module for Redis.
This example shows how to handle timeseries data with redis-py
.
Health check¶
[1]:
import redis
r = redis.Redis(decode_responses=True)
ts = r.ts()
r.ping()
[1]:
True
Simple example¶
Create a timeseries¶
[2]:
ts.create("ts_key")
[2]:
True
Add samples to the timeseries¶
We can either set the timestamp with an UNIX timestamp in milliseconds or use * to set the timestamp based en server’s clock.
[3]:
ts.add("ts_key", 1657265437756, 1)
ts.add("ts_key", "1657265437757", 2)
ts.add("ts_key", "*", 3)
[3]:
1657272304448
Get the last sample¶
[4]:
ts.get("ts_key")
[4]:
(1657272304448, 3.0)
Get samples between two timestamps¶
The minimum and maximum possible timestamps can be expressed with respectfully - and +.
[5]:
ts.range("ts_key", "-", "+")
[5]:
[(1657265437756, 1.0), (1657265437757, 2.0), (1657272304448, 3.0)]
[6]:
ts.range("ts_key", 1657265437756, 1657265437757)
[6]:
[(1657265437756, 1.0), (1657265437757, 2.0)]
Delete samples between two timestamps¶
[7]:
print("Before deletion: ", ts.range("ts_key", "-", "+"))
ts.delete("ts_key", 1657265437756, 1657265437757)
print("After deletion: ", ts.range("ts_key", "-", "+"))
Before deletion: [(1657265437756, 1.0), (1657265437757, 2.0), (1657272304448, 3.0)]
After deletion: [(1657272304448, 3.0)]
Multiple timeseries with labels¶
[8]:
ts.create("ts_key1")
ts.create("ts_key2", labels={"label1": 1, "label2": 2})
[8]:
True
Add samples to multiple timeseries¶
[9]:
ts.madd([("ts_key1", "*", 1), ("ts_key2", "*", 2)])
[9]:
[1657272306147, 1657272306147]
Add samples with labels¶
[10]:
ts.add("ts_key2", "*", 2, labels={"label1": 1, "label2": 2})
ts.add("ts_key2", "*", 2, labels={"label1": 3, "label2": 4})
[10]:
1657272306457
Get the last sample matching specific label¶
Get the last sample that matches “label1=1”, see Redis documentation to see the posible filter values.
[11]:
ts.mget(["label1=1"])
[11]:
[{'ts_key2': [{}, 1657272306457, 2.0]}]
Get also the label-value pairs of the sample:
[12]:
ts.mget(["label1=1"], with_labels=True)
[12]:
[{'ts_key2': [{'label1': '1', 'label2': '2'}, 1657272306457, 2.0]}]
Retention period¶
You can specify a retention period when creating timeseries objects or when adding a sample timeseries object. Once the retention period has elapsed, the sample is removed from the timeseries.
[13]:
retention_time = 1000
ts.create("ts_key_ret", retention_msecs=retention_time)
[13]:
True
[14]:
import time
# this will be deleted in 1000 milliseconds
ts.add("ts_key_ret", "*", 1, retention_msecs=retention_time)
print("Base timeseries: ", ts.range("ts_key_ret", "-", "+"))
# sleeping for 1000 milliseconds (1 second)
time.sleep(1)
print("Timeseries after 1000 milliseconds: ", ts.range("ts_key_ret", "-", "+"))
Base timeseries: [(1657272307670, 1.0)]
Timeseries after 1000 milliseconds: [(1657272307670, 1.0)]
The two lists are the same, this is because the oldest values are deleted when a new sample is added.
[15]:
ts.add("ts_key_ret", "*", 10)
[15]:
1657272308849
[16]:
ts.range("ts_key_ret", "-", "+")
[16]:
[(1657272308849, 10.0)]
Here the first sample has been deleted.
Specify duplicate policies¶
By default, the policy for duplicates timestamp keys is set to “BLOCK”, we cannot create two samples with the same timestamp:
[17]:
ts.add("ts_key", 123456789, 1)
try:
ts.add("ts_key", 123456789, 2)
except Exception as err:
print(err)
TSDB: Error at upsert, update is not supported when DUPLICATE_POLICY is set to BLOCK mode
You can change this default behaviour using duplicate_policy
parameter, for instance:
[18]:
# using policy "LAST", we keep the last added sample
ts.add("ts_key", 123456789, 2, duplicate_policy="LAST")
ts.range("ts_key", "-", "+")
[18]:
[(123456789, 2.0), (1657272304448, 3.0)]
For more informations about duplicate policies, see Redis documentation.
Using Redis TSDB to keep track of a value¶
[19]:
ts.add("ts_key_incr", "*", 0)
[19]:
1657272310241
Increment the value:
[20]:
for _ in range(10):
ts.incrby("ts_key_incr", 1)
# sleeping a bit so the timestamp are not duplicates
time.sleep(0.01)
[21]:
ts.range("ts_key_incr", "-", "+")
[21]:
[(1657272310241, 0.0),
(1657272310533, 1.0),
(1657272310545, 2.0),
(1657272310556, 3.0),
(1657272310567, 4.0),
(1657272310578, 5.0),
(1657272310589, 6.0),
(1657272310600, 7.0),
(1657272310611, 8.0),
(1657272310622, 9.0),
(1657272310632, 10.0)]