Skip to content

Commit

Permalink
redis: use a Lua script to get measures
Browse files Browse the repository at this point in the history
  • Loading branch information
jd committed Feb 8, 2018
1 parent 14e8456 commit 320a487
Showing 1 changed file with 28 additions and 12 deletions.
40 changes: 28 additions & 12 deletions gnocchi/storage/redis.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2017 Red Hat
# Copyright © 2017-2018 Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
Expand All @@ -14,8 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License.

import six

from gnocchi.common import redis
from gnocchi import storage
from gnocchi import utils
Expand All @@ -26,6 +24,7 @@ class RedisStorage(storage.StorageDriver):

STORAGE_PREFIX = b"timeseries"
FIELD_SEP = '_'
FIELD_SEP_B = b'_'

_SCRIPTS = {
"list_split_keys": """
Expand All @@ -47,6 +46,21 @@ class RedisStorage(storage.StorageDriver):
return -1
end
return ids
""",
"get_measures": """
local results = redis.call("HMGET", KEYS[1], unpack(ARGV))
local final = {}
for i, result in ipairs(results) do
if result == false then
local field = ARGV[i]
if redis.call("EXISTS", KEYS[1]) == 1 then
return {-1, field}
end
return {-2, field}
end
final[#final + 1] = result
end
return {0, final}
""",
}

Expand Down Expand Up @@ -114,16 +128,18 @@ def _delete_metric(self, metric):
def _get_measures(self, metric, keys, aggregation, version=3):
if not keys:
return []
redis_key = self._metric_key(metric)
fields = [
self._aggregated_field_for_split(aggregation, key, version)
for key in keys
]
results = self._client.hmget(redis_key, fields)
for key, data in six.moves.zip(keys, results):
if data is None:
if not self._client.exists(redis_key):
raise storage.MetricDoesNotExist(metric)
raise storage.AggregationDoesNotExist(
metric, aggregation, key.sampling)
return results
code, result = self._scripts['get_measures'](
keys=[self._metric_key(metric)],
args=fields,
)
if code == -1:
sampling = utils.to_timespan(result.split(self.FIELD_SEP_B)[2])
raise storage.AggregationDoesNotExist(
metric, aggregation, sampling)
if code == -2:
raise storage.MetricDoesNotExist(metric)
return result

0 comments on commit 320a487

Please sign in to comment.