【最后203篇系列】003 - 填坑DogPile

devtools/2024/12/26 15:04:56/

也不知道咋回事,怎么坑这么多。

问题现象:一个程序获取拎一个服务的缓存时,数据格式报错。

找了很久,发现是Dogpile的问题:数据还在,但是结构变了。如原来缓存的是{'a': 111, 'b_list':[1,2,3]},再次获取缓存时结果是[1,2,3]

我已经懒得再去找为什么了,反正用的是set和get,我不知道为什么这样。哪怕是报错也好呀…

其实这样的工具我早就自己做了…

import pandas as pd 
from redis import Redis, ConnectionPool
import json 
import pickleclass LittleRQ:algo_ver='1000.004'def __init__(self, host = None, port = 24008, decode_responses=True,password=None, db=1, smethod = 'json'):"""初始化LittleRQ对象。Args:host (str): Redis服务器主机名或IP地址。port (int): Redis服务器端口号。decode_responses (bool, optional): 是否解码存储在Redis中的数据。默认为True。password (str, optional): 连接Redis服务器的密码。默认为None。db (int, optional): Redis数据库索引。默认为0。"""self.host = host self.port = portself.db = db self.decode_responses = decode_responsesself.password= passwordself.smethod = smethodself.pool = ConnectionPool(host=self.host, port=int(self.port), decode_responses=self.decode_responses, password=self.password, db=self.db)self.conn = Redis(connection_pool=self.pool)def info(self, is_full_info=False):"""获取Redis服务器的一些重要信息。Args:is_full_info (bool, optional): 是否返回完整的服务器信息。默认为False。Returns:dict: 包含服务器信息的字典。"""info_dict = self.conn.info()if is_full_info:return info_dictres_dict = {}the_db_name = 'db'+str(self.db)need_keys = [the_db_name,'cluster_enabled','role','total_system_memory_human','used_memory_peak_human','used_memory_human','connected_clients']for k in need_keys:res_dict[k] = info_dict[k]return  res_dictdef dbsize(self):"""返回当前数据库中键的数量。Returns:int: 键的数量。"""return self.conn.dbsize()def list_keys(self, is_force=False):"""返回当前数据库中的键列表。Args:is_force (bool, optional): 是否强制返回键列表。默认为False。Returns:list: 键列表。"""cur_len = self.dbsize()if cur_len >=1000 and is_force is False:print('键值列表长度 %s 超过一千,请用is_force允许查询' % cur_len )return Falsereturn self.conn.keys()def set_value(self, key=None, value=None, set_type=None, ex_seconds=None, ex_miliseconds=None):"""设置键值对。Args:key (str): 键名。value (str): 键值。set_type (str, optional): 设置类型,可以是'ex'(已存在)或'nx'(不存在)。默认为None,表示覆盖。ex_seconds (int, optional): 键的过期时间(秒)。默认为None。ex_miliseconds (int, optional): 键的过期时间(毫秒)。默认为None。is_json (bool, optional): 是否将值转换为JSON格式。默认为True。Returns:bool: 设置成功返回True,否则返回False。"""if self.smethod == 'json':value = json.dumps(value)else:value = pickle.dumps(value)assert set_type in ['ex','nx',None], 'set操作允许对ex已存在或者nx不存在操作。默认None覆盖。'if set_type:if set_type =='ex':res = self.conn.set(key, value, ex=ex_seconds, px=ex_miliseconds, xx=True)else:res = self.conn.set(key, value, ex=ex_seconds, px=ex_miliseconds, nx=True)else:res = self.conn.set(key, value, ex=ex_seconds, px=ex_miliseconds)return res def get_value(self, key=None):"""获取键的值。Args:key (str): 键名。Returns:str: 键的值。"""value = self.conn.get(key)if value:try:if self.smethod == 'json':return json.loads(value)else:return pickle.loads(value)except:return value else:return value def increment(self, key=None, num=1):"""对键的值进行自增操作。Args:key (str): 键名。num (int, optional): 自增数。默认为1。Returns:int: 自增后的值。"""return self.conn.incr(key, num)def decrement(self, key=None, num=1):"""对键的值进行自减操作。Args:key (str): 键名。num (int, optional): 自减数。默认为1。Returns:int: 自减后的值。"""return self.conn.decr(key, num)def delete_key(self, key=None):"""删除键。Args:key (str): 键名或键列表。Returns:int: 被删除键的数量。"""assert isinstance(key, str) or isinstance(key, list),'字符或者列表'if isinstance(key, str):key = [key]return self.conn.delete(*key)def expire_key(self, key=None, ex_seconds=1):"""设置键的过期时间。Args:key (str): 键名。ex_seconds (int): 过期时间(秒)。Returns:bool: 设置成功返回True,否则返回False。"""return self.conn.expire(key, ex_seconds)

只要再加一个命名工具就好

from typing import List, Optional
from pydantic import BaseModelclass TName(BaseModel):space : str tier1 : str tier2 : str @propertydef prefix(self):return '.'.join([self.space, self.tier1,self.tier2]) +  '.'

使用例子


redis_ip = 'IP'
passwd = 'YOURS'
tname = TName(space='andypile', tier1 ='tier1', tier2 = 'tier2')
varname = tname.prefix + 'varname'
lq = LittleRQ(host = redis_ip, port = 24008, decode_responses=True,password=passwd, db=1)
# 设置一个缓存
some_dict ={'a':111, 'b':[1,2,3]}
lq.set_value(key=varname, value=some_dict)lq.get_value(key=varname)In [11]: lq.get_value(key=varname)
Out[11]: {'a': 111, 'b': [1, 2, 3]}In [12]: varname
Out[12]: 'andypile.tier1.tier2.varname

可以在set_value时指定超时时间,也可以在之后设置expire时间。然后还可以进行增量计数,这些都是redis最常用的功能。再也不用dogpile了,实在很坑。


http://www.ppmy.cn/devtools/145552.html

相关文章

excel中如何筛选一列中重复的内容,相同的内容只保留一次

1. 目的 筛选excel中一列中重复出现的值,统计里面的类别有多少,即相同的内容,只保留一次。以下图为例,我想筛选出左边这些人最喜欢的水果都有哪些,即相同的水果只保留一次。 2. 步骤实现 以上面的最喜欢的水果为例&…

Day50 图论part01

图论理论基础 大家可以在看图论理论基础的时候,很多内容 看不懂,例如也不知道 看完之后 还是不知道 邻接矩阵,邻接表怎么用, 别着急。 理论基础大家先对各个概念有个印象就好,后面在刷题的过程中,每个知识…

Hive其五,使用技巧,数据查询,日志以及复杂类型的使用

目录 一、关于Hive使用的一些技巧 二、表的数据查询 三、Hive默认的日志 四、复杂数据类型 1、Array的使用 2、展开函数的使用 explode 3、Map的使用 4、Struct结构体 一、关于Hive使用的一些技巧 1、可以直接不进入hive的情况下执行sql语句 通过shell的参数 -e 可以执…

PDF在线预览实现:如何使用vue-pdf-embed实现前端PDF在线阅读

一、前言 在本篇博客中介绍的vue-pdf-embed核心逻辑是获取pdf内容并将其每一页渲染到canvas画布上,以类似图片的方式展示出来。pdf作为本地资源放在项目中。二、vue-pdf-embed是什么 vue-pdf-embed是一个基于Vue.js的插件,专门用于在Vue应用中嵌入和展示…

Maven 项目文档

如何创建 Maven 项目文档。 比如我们在 C:/MVN 目录下,创建了 consumerBanking 项目,Maven 使用下面的命令来快速创建 java 项目: mvn archetype:generate -DgroupIdcom.companyname.bank -DartifactIdconsumerBanking -DarchetypeArtifact…

重温设计模式--C++迭代器种类和用法

文章目录 定义1、 输入迭代器(Input Iterator2、输出迭代器(Output Iterator)3、前向迭代器(Forward Iterator)4、双向迭代器(Bidirectional Iterator)5、 随机访问迭代器(Random - …

基于python语音启动电脑应用程序

osk模型进行输入语音转换 txt字典导航程序路径 pyttsx3引擎进行语音打印输出 关键词程序路径 import os import json import queue import sounddevice as sd from vosk import Model, KaldiRecognizer import subprocess import time import pyttsx3 import threading# 初始…

【YashanDB知识库】XMLAGG方法的兼容

本文内容来自YashanDB官网,原文内容请见 https://www.yashandb.com/newsinfo/7802943.html?templateId1718516 【关键字】 XMLAGG方法的兼容 【问题描述】 崖山数据库不支持将XMLAGG相关的函数内容,需要替换成支持的功能函数WM_CONCAT(T.COLUMN_NAME…