滑动窗口报告缓存

lymnna71  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(403)

我有一个api端点,它接受一些带有“date\u from”和“date\u to”字段的数据作为输入。
当发出请求时,它将启动报告的生成。这些“date\u from”和“date\u to”字段用于生成 (date_to - date_from).days 子请求的数量。根据每个子请求生成hash,hash用于通过hash从redis数据库中获取子响应,或者生成一些等式,然后将子响应保存到redis。最后,所有子响应被聚合并作为实际响应返回。
我有一个用例,其中所有的数据都已经存储在redis中,但是在从date到date和从date到date的很长的范围内仍然是 (date_to - date_from).days 对缓存数据库的请求量。因此,我决定通过生成hash以同样的方式将请求的最终响应存储在redis中。
我的问题是,这些报告是定期生成的日期从和日期到滑动窗口。例如,昨天 date_from = "2017-03-08" date_to = "2020-05-07" 但今天是 date_from = "2017-03-09" date_to = "2020-05-08" . 也就是说
大部分报表都是缓存的,但这一过程的速度却慢得令人难以置信
昨天已经准备好了非常类似的报告,可以在几秒钟内访问,但它并不完整,也没有办法知道它们是相似的。
这是我的密码

def generate_report(self, serialized_data):
    result = {
            'deviation' : []
             }
    total_hash = hashlib.sha256(str(serialized_data).encode()).hexdigest()
    total_target = self.redis.get(total_hash)
    if not total_target:
        for date_from, date_to in self.date_range:
            serialized_data['media_company']['date_from'] = \
                                                date_from.strftime("%Y-%m-%d")
            serialized_data['media_company']['date_to'] = \
                                                date_to.strftime("%Y-%m-%d")
            hash = hashlib.sha256(str(serialized_data).encode()).hexdigest()
            target = self.redis.get(hash)
            media_company, context, validator = \
                                    self.prepare_for_validation(serialized_data)
            if not target:
                target = validator.check({'media_company': media_company,**context})
                self.redis.setex(hash, timedelta(days=180), json.dumps(target))
            else:
                self.redis.expire(hash, timedelta(days=180))
                target = json.loads(target)

            result['deviation'].append(target['deviation'])
            result['date'] = [str(date_to) for date_from, date_to in self.date_range]
        total_target = result
        self.redis.setex(total_hash, timedelta(days=180), json.dumps(total_target))
    else:
        total_target = json.loads(total_target)
    return total_target

total\u hash表示初始数据的哈希,
self.date\u range表示子请求的日期范围数组,
hash表示子查询的哈希
你能推荐一种更好的缓存数据的方法吗?或者是加速这个算法的方法?

hwamh0ep

hwamh0ep1#

您可以考虑使用redis管道,而不是在循环中使用单个get命令,我不确定python代码如何做到这一点,但下面的原型可能会对您有所帮助

p1 = self.redis.pipeline()
if not total_target:
  for date_from, date_to in self.date_range:
     #use pipeline here to get target for each day.
     hash = hashlib.sha256(str(serialized_data).encode()).hexdigest()
     p1.get(hash)

# use other pipeline here to set values and expires base on result

# also compute target_toal

p2 = self.redis.pipeline()
for result in p1.execute():
   if not result:
      -- p2 set value with expiry
   else
      -- p2 set expiry

相关问题