GeminiDB 新特性:让 Redis 广告频控爱不释手的 exHASH

宙斯科技 后端 2024-03-27


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 接口。

团队往期技术分享目录:

https://bbs.huaweicloud.com/blogs/248875,也可加入我们的交流群哦!

开年采购季云数据库特惠
活动时间:3月1日-31日
云数据库新用户1年19元
不限新老1年6.5折

Apipost 私有化火热进行中

评论