如何使用 Tair 增强数据结构构建丰富在线实时场景
——李子昂(慨慷)
阿里云数据库技术专家
一、什么是 Redis 数据结构模块
Redis 数据结构模块是 Redis 提供的一种扩展数据结构功能的方式。Redis 提供了很多内置的数据结构,但是如何通过自己想要的方式来扩展自定义数据结构? Redis 在 4.0 引入 Redis Modules, 用户可以通过调用 Redis Modules API 来实现自定义的数据结构。
上图为 Redis 官网的 Redis Modules 列表,其中 TairHash、TairString 以及 TairZset 都由阿里云 Tair 团队贡献和开源。
Redis Modules 使 Redis 的生态得到了非常大的增强和补充,扩展性也得到了极大的增强,为 Redis 带来了非常多新的应用场景和可能。
Redis 本身提供了非结构化的数据结构,用于更好的描述复杂的数据逻辑结构,并提供对应的算法。以描述煮茶的步骤为例,煮一壶茶可以分为三个步骤:洗茶叶、煮开、凉茶。如果使用传统的关系性数据结构去描述煮茶过程,需要有这样一张表:
第一个字段为步骤,描述了每一个步骤的先后关系,比如第一步是洗茶叶,第二步是将茶煮开,第三步是将茶凉好,需要依赖步骤的字段去实现它们之间的顺序管理。
第二个字段为操作,需要记录前一字段每步骤所对应的动作,分别为洗茶叶、将茶煮开、将茶凉好三个步骤。
第三个字段为时间,记录每步骤所需要的时间。
有了这样一张表后,即可将煮茶的逻辑行为变为可以被存储到数据库中的步骤,通过操作即可找到具体要做什么,而且可以通过步骤字段排序得到操作之间的顺序。
然而,通过以上过程抽象可见,传统的关系型数据结构描述煮茶过程十分复杂,我们需要将一切信息存入表中,这就需要构建者有非常强的抽象能力。设计者应能够做到将复杂的业务模型抽象出具体的逻辑步骤,并且设计好每一个字段。如果在业务构建之初没有对字段进行良好的设计,或是在业务快速发展和迭代中没有对数据库表字段做好维护,则很容易出现字段暴增带来数据库维护上的灾难,这也是传统数据库使用过程中常见的问题。
而采用非关系型数据库来描述这个过程就会变得非常轻松。上面的例子可以我们改为使用 Redis 的 list 数据结构来描述煮茶过程。可以将煮茶的三个步骤作为三个 node 存到 list 的数据结构中:比如第一个节点为洗茶叶,下一个节点为将茶煮好,再下一个节点为将茶放凉。很轻松地即可将自然的行为转换成在 Redis 中存储的数据,且此数据可以还原行为顺序。
用 Redis 来存储数据,带来的优势就是对于数据的应用和数据的抽象非常自然,不需要再拘泥于字段的抽象方案,能够更加专注于业务逻辑本身。
同样,企业级的服务往往非常复杂,有时一些特定的场景下,依然难以通过Redis 基本的数据结构来进行抽象。阿里云的 Tair 团队从数据库实践的角度出发,经过多年的积累,总结了大量业务的最佳实践。通过将这些宝贵的经验抽象、归纳、总结,最终形成了 Tair 增强型数据结构系列。
上图右侧列出了目前已经支持的增强数据结构,包括 TairGIS、TairJson、TairTS, 分别可以处理地理位置数据、 JSON 以及时序数据。有了这些增强型的数据结构,Tair 用户能够非常轻松地利用已有的宝贵经验,去搭建自己的企业级在线实时服务。
二、Tair 增强数据结构简介
TairHash 是 Tair 团队在早期退出的 Redis module 之一,大幅改良了 Redis Hash 的不足,实现了基于 field 的过期机制,无须对整个哈希表进行过期。
用户在使用 Redis Hash 时非常容易出现的问题是大 KEY 。其原因有二:第一是构建的时候没有设计好的数据结构的过期方案,导致随着逻辑的迭代出现了字段累积;第二点,也是最核心的一点是用户在使用数据服务的过程中没有对数据做良好的维护,导致 field 出现累积,进而出现巨大 KEY。
大 KEY 对 Redis 使用会造成非常大的影响,可能带来各种隐患。有了 TairHash 之后,用户在构建哈希存储每个 field 时,可以指定过期时间,到了过期时间,此数据就会被自动更新,极大方便了用户的使用。
基于 TairHash 能够构建出非常多场景,比如账号系统、安全审计规则、流控器等场景。
TairDoc 是 Tair 团队开发的另一个增强型数据结构,它具有以下特点:
- 实现了对于 JSON 语法的解析和查询,并且提供了 JSON 格式的结构化存储。
- 兼容了 reJSON 模块,Tair 用户可以实现系统之间的无缝切换。
- 提供了非常强大的查询功能,同时支持 JSON Pointer 和 JSON Path 两种查询语法。
- 导入导出的支持:支持从 JSON 到 XML/YAML 格式之间的转换。
由于 JSON 是非常广泛使用的序列化方式,易于使用,所以很多数据结构都提供 JSON 的能力,最著名比如 MongoDB 也提供了 JSON 查询的能力。
有了 TairDoc 模块后, Tair 引擎也支持了 JSON 数据结构的查询。 TairDoc 是非常轻量级的模块,适合应用在前端服务和配置中心的服务中。比如有配置中心需要对某一些字段进行查询,有了 TairDoc 后既可以查询,也可以快速更新,且速度和响应非常快。
TairGis 是 Tair 推出的重量级的专业地理信息系统模块。众所周知,Redis 原生提供了 geo 数据结构,也可以实现基本的地理位置查询。 而 TairGis 提供了了点、线、面之间的相交、包含等关系运算,弥补了原生 Redis geo 数据结构只能做点运算的不足。
有了 TairGis 之后,即可实现地理信息的实时查询,特别适用于地图和物流,包括电子围栏等应用场景。比如疫情之下需要划定某些风险区,应用了 TairGis 之后,即可快速确认某个用户是否经过了风险区,可以极大提升防控的时效性和实时性。
三、TairRoaring 实时人群圈选应用
TairRoring 是 Tair 引擎基于 RoaringBitmap 的实现。
Bitmap 是常用的数据结构,拥有去重的能力。 RoaringBitmap 基于 bitmap 做了大量工程上的优化,在压缩的同时尽量不损失查询性能,并且提供了非常良好的 API 接口,能够实现很多应用,比如实时人群圈选。
除此之外, TairRoring 还可以应用在个性化推荐、直播间安全风控,防止虚假用户抢购,甚至在传统的场景比如海量数据去重中也有非常广泛的应用,比如针对 APP 内的推荐模块,能够对推荐数据进行过滤和去重,提升用户使用体验。
Tair 实时人群圈选业务可以分为三个阶段:采集原始用户特征数据,用户特征的分析、处理和存储,圈选出对应人群并且进行后续处理。
传统的人群圈选服务存在以下三个核心痛点:
① 数据非常多,用户基数大,标签多(亿级到几十亿级),传统的 bitmap 无法胜任。
② 计算成本非常高,时延高。如果用 OLAP 系统去做人群的实时查询,响应大概为毫秒级,无法满足实时的查询和检索的需求。
③ 导出非常困难。将海量数据导到 NoSQL 系统,需要做大量的变化和写入操作,成本极高。
TairRoring 针对以上三个痛点做了深度优化。
① 依赖于 RoaringBitmap 实现了高效存储,在保留高性能压缩的同时,尽量保证访问性能不减。
② 依托 Tair 引擎自身的高性能,提供亚毫秒级的处理能力,完全可以应用于实时业务场景的构建。
③ 经过多版本的迭代,吸收了很多用户的意见和建议,提供了非常丰富的 API,已经完全覆盖所有常见业务场景,并提供了非常高效的导入导出接口。比如使用 OLAP 引擎 Hologres 生成了 RoaringBitmap,使用一条命令即可将 RoaringBitmap 导入到 Tair。这是非常高效的操作,可以优化大量业务数据导入导出的过程。
有了 TairRoaring 之后,实时人群圈选的应用就有了数据流上的变化。如上图所示,中间多了一个 Tair 内存数据库的点。从一开始用户行为的产生,到用户标签的生产,再到将标签存入 Tair 内存数据库,使用 TairRoaring 做标签的存储和计算,人群圈选服务即可直接访问 Tair 内存数据库中 TairRoaring 取到标签,做实时查询,实时对下游业务提供圈选服务。
四、使用 TairSearch 构建在线交互式搜索
在线交互搜索有以下五个核心要素:
- 原始数据
- 正排索引管理
- 倒排索引管理
- 索引构建与更新
- 执行搜索
TairSearch 拥有有以下六点非常核心的能力:
① 低延迟、高性能:依赖于 Tair 引擎的高性能,提供了低延迟和高性能可兼得的查询能力,提供了毫秒级的全文搜索能力。
② 局部更新:支持更新文档中某些字段,并且支持 incrby 等常规操作。
③ 语法灵活:有非常灵活的语法,可以支持 JSON 查询语法等。
④ 聚合查询:支持 terms、metrics 和 filter 等聚合算子,可以实现聚合类的查询。
⑤ 支持 Auto-complete Suggestion:支持前缀的模糊搜索和自动补全。
⑥ 分词定制:内置支持中文、英文等主流语言的分词器,并且提供了分词器的定制能力,用户可以基于自己的需求来组合定制分词器。
有了以上功能,TairSearch 即可应用于非常多在线实时的交互式搜索场景。
商品搜索
文档内容为商品信息,比如商品 ID、商品介绍、价格等。索引字段为商品名、商品介绍、商品价格等。
使用示例:假设以水杯作为关键字,在 TairSearch 里进行搜索,并且使用价格进行升序排序。搜索的结果即价格最便宜的水杯相关产品。
视频搜索
文档内容为视频标题、创建时间、视频的作者版权信息等。索引字段为视频标题、作者和播放数。
使用示例:假设查询脱口秀,只需要在 TairSearch 里以脱口秀作为关键字,并且按照播放数进行倒序搜索,即可看到播放量最高的脱口秀节目。