十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

redis-py 的 Redis 模块命令使用指南:Bloom、JSON、Search 与 TimeSeries 一站式实践

redis-py 的 Redis 模块命令使用指南:Bloom、JSON、Search 与 TimeSeries 一站式实践 redis-py 的 Redis 模块命令使用指南Bloom、JSON、Search 与 TimeSeries 一站式实践【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-pyredis-py 除了封装 Redis 核心命令外还通过RedisModuleCommands将 RedisBloom、RedisJSON、RediSearch、RedisTimeSeries 等官方模块的命令统一挂载到客户端命名空间下。本文以 docs/redismodules.rst 为骨架结合 redis/commands/redismodules.py 及redis/commands/下各模块的实现源码系统讲解如何通过r.bf()、r.cf()、r.cms()、r.topk()、r.json()、r.ft()、r.ts()等命名空间调用模块能力并深入剖析其底层响应回调与 RESP2/RESP3 适配机制。读完本文你将掌握模块化数据结构过滤器、草图、JSON 文档、全文索引、时序数据在 redis-py 中的完整用法。一、前置条件先安装 Redis 模块模块命令与核心命令不同它们由 Redis 模块提供因此使用任何模块命令前必须先确保目标 Redis 服务器已加载对应模块。文档明确强调Accessing redis module commands requires the installation of the supported Redis module.快速体验全部模块能力最简单的方式是使用官方提供的 Redismod Docker 镜像一条命令即可拉起内置 RedisBloom、RedisJSON、RediSearch、RedisTimeSeries 等模块的 Redis 实例。生产环境则需要在启动 Redis 时通过配置文件或命令行显式加载模块如loadmodule /path/to/redisbloom.so可参考仓库根目录的 docker-compose.yml 了解本仓库测试环境的模块编排方式。二、模块命名空间总览一切从r.bf()/r.json()开始所有模块命令都通过redis.commands.redismodules中的RedisModuleCommands混入类暴露。该类被注入到同步与异步客户端中其 docstring 写道This class contains the wrapper functions to bring supported redis modules into the command namespace.从 redis/commands/redismodules.py 可以看到每个命名空间的入口方法及其对应的包装类命名空间方法返回对象对应模块核心命令前缀r.json()JSONRedisJSONJSON.*r.ft(index_nameidx)SearchRediSearchFT.*r.ts()TimeSeriesRedisTimeSeriesTS.*r.bf()BFBloomRedisBloomBF.*r.cf()CFBloomRedisBloomCF.*r.cms()CMSBloomRedisBloomCMS.*r.topk()TOPKBloomRedisBloomTOPK.*r.tdigest()TDigestBloomRedisBloomTDIGEST.*r.vset()VectorSetVector SetVSIM.*注意两个细节ft()的默认索引名r.ft()不带参数时返回绑定索引名idx的Search对象见 redis/commands/redismodules.py这与文档中 When an index name is not specified, an index namedidxis created 的描述一致。因此多个不同索引必须显式传名如r.ft(my_index)。json()的自定义编解码器r.json()可传入encoder/decoder默认JSONEncoder()/JSONDecoder()JSON 对象在客户端本地完成序列化/反序列化。每个包装类都持有self.client并复用客户端的execute_command这意味着模块命令与核心命令共享连接池、Pipeline 与集群路由能力——例如 TimeSeries 与 JSON 均提供了专属的pipeline()方法。此外AsyncRedisModuleCommands为每个命名空间提供了对应的异步版本AsyncJSON、AsyncSearch、AsyncTimeSeries、AsyncBFBloom等通过redis.asyncio客户端同样可以调用全部模块命令。三、RedisBloom 命令概率型数据结构家族RedisBloom 是 redis-py 支持模块中覆盖面最广的涵盖布隆过滤器BF、布谷鸟过滤器CF、Count-Min SketchCMS与 Top-KTOPK四种概率型数据结构其完整命令定义位于 redis/commands/bf/commands.py。3.1 Bloom FilterBF文档给出的核心示例创建过滤器并写入元素import redis r redis.Redis() r.bf().create(bloom, 0.01, 1000) r.bf().add(bloom, foo)结合 redis/commands/bf/commands.pycreate(key, errorRate, capacity, expansionNone, noScaleNone)直接映射到BF.RESERVE命令参数含义如下errorRate期望的误判率false positive probability示例中的0.01表示 1%capacity期望插入的元素数量用于估算位数组大小expansion过滤器扩容系数默认值为 2不传时过滤器默认支持自动扩容auto-scalingnoScale置位后过滤器不允许扩容追加NONSCALING标签见 redis/commands/bf/init.py。create同时被别名为reserve二者等价。Bloom Filter 的常用命令还有add(key, item)/madd(key, *items)写入单个或多个元素insert(key, items, capacityNone, errorNone, noCreateNone, expansionNone, noScaleNone)批量插入且允许在 key 不存在时按参数自动创建过滤器NOCREATE可禁止自动创建exists(key, item)/mexists(key, *items)判断元素是否可能存在返回 1/0scandump(key, iter)/loadchunk(key, iter, data)增量保存与恢复大过滤器首次调用时iter传 0迭代返回(iter, data)对直到(0, NULL)表示完成用于绕过 SAVE/RESTORE 对超大过滤器的限制info(key)返回容量、大小、子过滤器数、已插入元素数与扩容率card(key)返回过滤器的基数即添加且被检测为唯一的元素数量至少使一个子过滤器中的一个位被置位。3.2 Cuckoo FilterCF文档示例import redis r redis.Redis() r.cf().create(cuckoo, 1000) r.cf().add(cuckoo, filter)布谷鸟过滤器支持删除操作这是它与布隆过滤器的关键区别。create(key, capacity, expansionNone, bucket_sizeNone, max_iterationsNone)对应CF.RESERVE其中bucket_size控制桶大小、max_iterations控制插入时的最大踢出迭代次数分别追加BUCKETSIZE与MAXITERATIONS参数见 redis/commands/bf/init.py。CF 命令族定义于 redis/commands/bf/commands.py还包括addnx(key, item)仅当元素不存在时才添加比add略慢insert(key, items, capacityNone, nocreateNone)/insertnx(...)批量插入去重版本exists/mexists成员判定delete(key, item)删除元素count(key, item)返回元素在过滤器中可能出现的次数scandump/loadchunk增量持久化info(key)返回大小、桶数量、过滤器数、插入/删除元素数、桶大小、扩容率与最大迭代数。3.3 Count-Min SketchCMS文档示例按维度初始化、累加计数并查看信息import redis r redis.Redis() r.cms().initbydim(dim, 1000, 5) r.cms().incrby(dim, [foo], [5]) r.cms().info(dim)CMS 是一个近似计数结构initbydim(key, width, depth)按显式维度初始化initbyprob(key, error, probability)则按误差与概率自动推导维度对应CMS.INITBYPROB。incrby(key, items, increments)要求items与increments均为等长列表源码通过append_items_and_increments将二者交错拼接成item1 inc1 item2 inc2 ...的参数序列见 redis/commands/bf/init.py。其余命令redis/commands/bf/commands.pyquery(key, *items)一次查询一个或多个元素的近似计数merge(destKey, numKeys, srcKeys, weights[])合并多个草图到目标 key要求所有草图宽度与深度一致weights用于对源草图加权默认权重 1info(key)返回宽度、深度与总计数。3.4 Top-KTOPK文档示例import redis r redis.Redis() r.topk().reserve(mytopk, 3, 50, 4, 0.9) r.topk().info(mytopk)reserve(key, k, width, depth, decay)对应TOPK.RESERVE参数k为保留的 Top-K 数量、width/depth为草图维度、decay为概率衰减因子。info(key)返回这四项配置值。Top-K 的其余能力redis/commands/bf/commands.pyadd(key, *items)添加一个或多个元素返回每个元素是否新进入 Top-K的标识列表incrby(key, items, increments)按增量增加元素计数query(key, *items)判断元素是否在 Top-K 列表内count(key, *items)返回元素计数——注意该方法自 redis-py 4.4.0 起被标记为弃用deprecated_function(version4.4.0, reasondeprecated since redisbloom 2.4.0)建议优先使用query与listlist(key, withcountFalse)列出完整 Top-K 列表withcountTrue时附带近似计数追加WITHCOUNT参数。3.5 T-DigestTDIGESTT-Digest 用于对海量数值做高精度的分位数/秩统计估计。核心用法redis/commands/bf/commands.pyr.tdigest().create(td, compression100) # 默认 compression100追加 COMPRESSION 参数 r.tdigest().add(td, [1.0, 2.0, 3.0, 100.0]) r.tdigest().quantile(td, 0.5) # 中位数估计 r.tdigest().cdf(td, 3.0) # 小于等于 3.0 的比例min/max返回最小值/最大值空草图分别返回DBL_MAX/DBL_MINmerge(destination_key, num_keys, *keys, compressionNone, overrideFalse)合并多个草图num_keys必须位于*keys之前OVERRIDE用于覆盖目标 key 的既有内容trimmed_mean(key, low_cut_quantile, high_cut_quantile)剔除低/高截断分位数之外的观测后求均值rank/revrank估计值所在秩小于该值 等于该值一半的观测数byrank/byrevrank由秩反推值reset(key)将草图清零并重新初始化。3.6 底层回调Bloom 家族如何解析返回值Bloom 各包装类在构造时通过apply_module_callbacks为不同协议注册响应回调见 redis/commands/bf/init.py 中_BFBloomBase.__init__BF.RESERVE等创建类命令统一注册bool_ok将OK解析为布尔值BF.INFO在 RESP2 下解析为BFInfo对象在 RESP3 下同样注册BFInfo回调TOPK 的TOPK.ADD/TOPK.INCRBY/TOPK.LIST使用parse_to_list将多行返回解析为 Python 列表。这套按get_protocol_version(client)与get_legacy_responses(client)分发的回调机制common / resp2 / resp3 / resp2_unified / resp3_unified / resp3_to_resp2_legacy 六套映射是整个模块命令体系在 RESP2 与 RESP3 协议下保持一致 Python 返回类型的核心。四、RedisJSON 命令原生 JSON 文档操作RedisJSON 允许以 JSON 文档为粒度进行读写。文档示例import redis r redis.Redis() r.json().set(mykey, ., {hello: world, i am: [a, json, object!]})set(name, path, obj, nxFalse, xxFalse, decode_keysFalse, fphaNone)见 redis/commands/json/commands.py的关键行为path使用 JSONPath 语法.表示根路径仓库还提供Path.root_path()便捷方法nx/xx为存在性修饰符且二者互斥——同时为 True 会直接抛出Exception源码显式检查 nx and xx are mutually exclusivedecode_keysTrue时先对obj的键做 UTF-8 解码decode_dict_keysfpha可强制 Redis 以指定浮点类型存储同构浮点数组取值来自FPHAType枚举BF16、FP16、FP32、FP64非法值抛出DataError见 redis/commands/json/commands.py。JSONCommands覆盖了完整的 JSON 操作redis/commands/json/commands.py读取get、mget、type、resp递归转为 RESP 兼容类型对象操作objkeys、objlen数组操作arrappend、arrindex支持可选的start/stop搜索区间、arrinsert、arrlen、arrpop、arrtrim数值操作numincrby、nummultby字符串操作strappend、strlen结构修改del别名delete、forget、clear、toggle、merge调试debug。在异步客户端下AsyncJSON额外提供了set_file(name, path, file_name, ...)与set_path(json_path, root_folder, ...)见 redis/commands/json/init.py前者把文件内容写入指定 key后者递归遍历目录批量写入 JSON 文件且文件读取与目录遍历都通过asyncio.to_thread放到线程池执行避免阻塞事件循环。JSON 客户端同样支持 Pipeliner.json().pipeline()且每个模块命令都注册了对应的解码回调——例如JSON.GET走self._decode将字节串反序列化为 Python 对象JSON.SET注册lambda r: r and nativestr(r) OK归一化为布尔值。五、RediSearch 命令全文索引与查询RediSearch 在 redis-py 中的入口是r.ft()。文档示例创建带权重的文本索引并查看信息import redis from redis.commands.search.field import TextField r redis.Redis() index_name my_index schema ( TextField(play, weight5.0), TextField(ball), ) r.ft(index_name).create_index(schema) print(r.ft(index_name).info())要点拆解create_index(schema)对应FT.CREATEschema是字段元组。TextField(name, weight1.0, no_stemFalse, phonetic_matcherNone, withsuffixtrieFalse)见 redis/commands/search/field.py默认追加TEXT WEIGHT weight参数示例中play字段权重 5.0在全文检索排序时权重更高。字段基类Field还支持NUMERIC、TAG、GEO、VECTOR、SORTABLE、NOINDEX等修饰其中sortable允许排序、no_index只存不索引注意非可排序且不可索引的字段会被ValueError拒绝。info()对应FT.INFO返回索引定义、字段、文档数、索引失败数等元信息解析器见 redis/commands/search/commands.py 中的_parse_info系列回调。SearchCommands是模块中命令面最广的实现redis/commands/search/commands.py还包括查询searchFT.SEARCH、aggregateFT.AGGREGATE配合AggregateRequest/AggregateResult、hybridFT.HYBRID向量 全文混合检索、profileFT.PROFILE性能剖析、spellcheck拼写纠正、explain/explaincli文档管理add_documentFT.ADD、add_document_hashFT.ADDHASH、delete/del、mget索引管理alterFT.ALTER加字段、dropindexFT.DROPINDEXdelete_documentsTrue时删除文档、aliasadd/aliasupdate/aliasdel/aliaslist辅助能力tagvals、config_get/config_set、dictadd/dictdel/dictdump、sugadd/sugdel/suglen/sugget、synupdate/syndump、游标cursor等。Search类还内置了BatchIndexer批量索引器redis/commands/search/init.py每chunk_size默认 1000篇文档自动通过 Pipeline 批量提交一次add_document/add_document_hash入队、commit()手动刷新可显著提升大批量建索引的吞吐。异步版本AsyncSearch.BatchIndexer的commit为协程。关于默认索引名Search.__init__(client, index_nameidx)的 docstring 明确 The default name isidx。因此在单索引场景可以省略参数但多索引务必显式命名。六、RedisTimeSeries 命令时序数据写入与查询文档示例创建保留 5 秒的时序对象import redis r redis.Redis() r.ts().create(2, retention_msecs5000)create(key, retention_msecsNone, uncompressedFalse, labelsNone, chunk_sizeNone, duplicate_policyNone, ignore_max_time_diffNone, ignore_max_val_diffNone)见 redis/commands/timeseries/commands.py对应TS.CREATE其中retention_msecs5000表示数据保留 5000 毫秒5 秒超期样本会被自动淘汰uncompressed默认 False即默认启用压缩存储labels传入Dict[str, str]作为序列标签供queryindex按标签过滤chunk_size控制分块字节数duplicate_policy处理时间戳重复时的策略如 BLOCK/LAST/FIRST 等。TimeSeries 常用命令族redis/commands/timeseries/commands.py写入add(key, timestamp, value, ...)追加样本key 不存在时自动创建madd(ktv_tuples)批量追加接受(key, timestamp, value)三元组列表要求序列已存在incrby(key, value, timestampNone, ...)对最新样本做增量累加key 不存在时自动创建读取get、range/revrange按时间区间查询支持聚合、mget/mrange/mrevrange跨序列、ts.range系列配合aggregation_type与bucket_size_msec实现降采样规则与标签createrule(source_key, dest_key, aggregation_type, bucket_size_msec, align_timestampNone)创建压缩compaction规则、deleterule删除规则、queryindex(filters)按标签查询序列、querylabels元信息info(key)返回TSInfo包括保留时长、标签、样本数、内存占用等、alter修改保留期与标签、del删除区间数据。TimeSeries 也提供 Pipeliner.ts().pipeline()见 redis/commands/timeseries/init.py且内部对RedisCluster客户端自动选择ClusterPipeline。七、协议适配与统一响应模块命令的解析哲学纵观各模块实现会发现一个共同模式每个包装类的__init__都调用apply_module_callbacks(...)根据客户端当前的协议版本get_protocol_version与legacy_responses配置从六套回调映射中选择合适的一套再通过client.set_response_callback(cmd, cb)注册到客户端。例如Bloom 家族的创建命令统一bool_ok、*_INFO命令解析为BFInfo/CFInfo/CMSInfo/TopKInfo/TDigestInfo对象redis/commands/bf/init.pyJSON 家族把JSON.GET等结果经JSONDecoder还原为原生 Python 对象JSON.SET归一化为布尔值redis/commands/json/init.pySearch 家族针对 RESP2、原生 RESP3 与 RESP3 线协议 RESP2 旧版 Python 形态_RESP3_TO_RESP2_LEGACY_MODULE_CALLBACKS分别注册不同解析器redis/commands/search/commands.py并专门为 Pipeline 场景准备了_RESP3_TO_RESP2_LEGACY_PIPELINE_CALLBACKS保证升级到 RESP3 后 Pipeline 返回形状与旧版本一致。对使用者而言这意味着无论底层走 RESP2 还是 RESP3模块命令的 Python 返回值形态都保持稳定你只需关注业务逻辑无需关心线协议差异。八、模块命令使用建议与限制环境校验模块命令执行前请确认 Redis 服务端已加载对应模块可用MODULE LIST或直接调用一个模块命令验证。若未安装模块命令会返回未知命令错误。异步与集群同步、异步客户端均支持全部模块命名空间TimeSeries 与 JSON 的 Pipeline 实现已适配RedisCluster集群场景下会自动走ClusterPipeline。参数形态模块命令的批量接口如cms.incrby、topk.incrby要求items与increments为等长列表ts.madd要求(key, timestamp, value)三元组列表——这是与核心命令散列传参的明显差异使用时注意按文档形态传入。弃用提示topk.count自 redis-py 4.4.0 起标记弃用对应 RedisBloom 2.4.0 起弃用新代码应改用query与list(withcountTrue)。索引名默认值ft()默认绑定idx索引多索引场景必须显式传参否则容易误操作默认索引。通过 docs/redismodules.rst 中列出的 automodule 指令读者还可以在构建后的 API 文档中查阅BFCommands、CFCommands、CMSCommands、TOPKCommands、JSONCommands、SearchCommands、TimeSeriesCommands的完整方法签名与文档字符串这些与仓库源码一一对应是深入掌握各模块命令最权威的参考资料。【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表