电子说
exHash 类型是一种支持 Field 过期的新型数据类型,它在原先的 Hash 类型基础上进行了扩展:在支持 Hash 类型的通用功能以外,exHash 类型还支持为 Field 设置过期时间和版本,增强了数据结构的灵活性,从而简化了很多复杂场景下的业务开发工作。
本文以两种常见的场景(频控场景 &购物车)为例,通过使用 GeminiDB Redis 接口中的 exHash 类命令来实现复杂的业务,简化开发难度。
一、exHash 命令使用简介
命令语法定义如下:
大写关键字:命令关键字。
斜体:变量。
[options]:可选参数,不在括号中的参数为必选。
A|B:该组参数互斥,请进行二选一或多选一。
...:前面的内容可重复。
二、应用场景
1. 频控场景
频控指的是对用户在一定时间内(例如一天、一周、一个月)进行某种操作的次数进行限制,可以控制特定广告或信息在一定时间内在特定平台上的展示次数,以避免过度曝光和广告疲劳,同时优化广告效果和用户体验;对于广告来说,也可以提高广告的效果和转化率。此外,频控还可以避免恶意行为,如刷流量、刷评论、刷点赞等。
频控的 3 个要素包含用户 ID、广告 ID、触发次数;以用户 ID 为 key,广告 ID 为 field,指定时间内的触发次数为 value,恰好构成频控的三要素。先配置好各个广告的指定频控策略,如下图所示即可根据如下的方式来实现频控:
最左边通过 Hash 类型来实现,通过 expire 命令设置 User_1 的过期时间为一天,每推送一次通过 hincrby 来增加指定广告的推送次数,每次推送指定广告前在一天内的推送次数则可以通过 hget 获取进行判断,一天后该用户的数据自动过期无需手动清理,这样便可以简单地实现频控。但这个方案的缺点在于对于每个用户(即每个 key)只能设置一个过期时间,无法做到例如 8 小时 3 次这样指定时间段内的灵活的频控策略。
为了做到对每个广告都配置指定时间段内的灵活频控,如中间图所示可以通过将时间戳拼接在 value 里的方式用 Hash 类型来实现,但这种方案无疑是增加了业务侧开发的工作量。
如最右图所示,支持给 field 设置过期时间的 exHash 类型可以很完美地解决 Hash 类型面对频控场景的缺点。由于 Field 支持过期时间设置,那么该场景下,平台可以给每个广告都配置不同时间段内的频次要求,假设此时给 AD_2 配置的频控策略为 8 小时内 2 次,那么如图所示在下一次再准备给 User_1 推送 AD_2 广告前,先通过 exhget User_1 AD_2 命令获取到了该值已经是 2 时,便可以判断出此时根据平台频控策略,不应该再给 User_1 推送 AD_2 广告了。而当 8 小时一过,User_1 的 AD_2 这个 field 过期后,exhget 无法再获取到这个 field 的信息,则可以继续给 User_1 推送 AD_2 广告了。
2. 购物车场景
最近双十一期间,相信很多同学购物车里都填满了各种想要清空的宝贝,这里就以购物车场景为例介绍该场景的几种不同 Redis 类型的实现,并比较这几种实现方案的优缺点。
1)基于 String 实现购物车功能
如图所示基于 String 可以轻松地实现各个用户的购物车功能,该方案需要将用户 ID 与商品 ID 进行拼接作为 key,例如 User_1#Earphones_1,key 对应的 value 为购物车中用户准备购买的数量,其中可能有部分商品为限时特购,所以有过期时间,为 key 对应的过期时间。
涉及命令如下:
该方案会存在如下问题:
额外拼接增加编、解码开发工作量
某个用户获取自己的购物车清单时还需要通过 scan 命令前缀匹配扫描所有 key,并通过 get 命令去获取对应的值。
想要直接获取清单长度时,仍然需要遍历整个前缀 key 的数目,方法复杂。
存在大量重复的用户名前缀,浪费存储空间。
2)基于 Hash 实现购物车功能
可以根据如图所示的 Hash 类型来实现购物车的管理,用户 ID 作为 key,商品 ID 作为 field,value 为购物车中对应商品的数量。其中对于部分限时特购的商品,其过期时间通过拼接的方式放到 field 对应的 value 里。
涉及命令如下:
该方案相对于 String 类型的方案有了不少优化:
获取某个用户购物车中的所有商品清单仅需要一个 hgetall 命令即可
获取某个用户的清单长度时直接 hlen 获取即可
不存在大量重复的用户名前缀问题
然而该方案仍存在一个明显的缺点,即对于部分限时特购的商品处理起来复杂:对于 User_1 的 Keyboard_1 商品,如果要再加一个数量,不能直接使用 hincrby,而是需要先 hget 获取 Keyboard_1 商品的值并解码,再加上指定的数量再编码后 hset 对应的值。
3)基于 exHash 实现购物车功能
根据如图所示的 exHash 类型来实现购物车的管理,同 Hash 类型一样,用户 ID 作为 key,商品 ID 作为 field,value 为购物车中对应商品的数量。其中对于部分限时特购的商品,由于 exHash 类型可以为 Field 设置过期时间,其过期时间可通过 hset 命令直接设置。
涉及命令如下:
该方案相对于 Hash 类型的优化主要体现在可以直接为各 field 设置过期时间,使业务侧使用起来简单又高效。可以看到 exHash 类型相关的命令和 Hash 类型是类似的,使用起来学习成本很低,业务侧改造成本相对也比较低。
图 1.1 华为商城购物车中,用户 ID、商品 ID、商品数量及 exhash 类型命令的使用。
三、总结
本文介绍了 GeminiDB Redis 接口的 exHash 类型的特性、使用方法及应用场景。为客户提供了一种语法与原生 Redis Hash 类型类似、和 Hash 类型的使用相互隔离、支持给 Field 单独设置过期时间和版本的 exHash 类型作为各种复杂场景的解决方案。未来,GeminiDB Redis 接口将持续致力于开发更多好用的企业级特性,帮助客户轻松运维,高效开发。
如果你的业务需要一款稳定可靠的 KV 数据库,可以试试 GeminiDB Redis 接口。
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !