使用Redis作为时间序列数据库:原因及方法

自从Redis出现以来,就在时间序列数据的存储与分析方面得到了一定程度的使用。Redis最初只是被实现为一种缓冲,其目的是用于日志的记录,而随着其功能的不断发展,它已经具备了5种显式、3种隐式的结构或类型,为Redis中的数据分析提供了多种方法。本文将为读者介绍使用Redis进行时间序列分析最灵活的一种方法。

关于竞态与事务

在Redis中,每个单独的命令本身都是原子性的,但按顺序执行的多条命令却未必是原子性的,有可能因出现竞态而导致不正确的行为。为了应对这一限制,本文将使用“事务管道”以及“Lua脚本"这两种方式避免出现数据的竞态冲突。

在使用Redis以及用于连接Redis的Python客户端时,我们会调用Redis连接的.pipeline()方法以创建一个“事务管道”(在使用其他客户端时,通常也将其称为“事务”或“MULTI/EXEC 事务”),在调用时无需传入参数,或者可以传入一个布尔值True。通过该方法创建的管道将收集所有传入的命令,直到调用.execute()方法为止。当.execute()方法调用之后,客户端将对Redis发送MULTI命令,然后发送所收集的全部命令,最后是EXEC命令。当Redis在执行这一组命令时,不会被其他任何命令所打断,从而确保了原子性的执行。

在Redis中对一系列命令进行原子性的执行还存在着另一种选择,即服务端的Lua脚本。简单来说,Lua脚本的行为与关系型数据库中的存储过程非常相似,但仅限于使用Lua语言以及一种专用的Redis API以执行Lua。与事务的行为非常相似,Lua中的脚本在执行时通常来说不会被打断 1 ,不过未处理的错误也会造成Lua脚本提前中断。从语法上说,我们将通过调用Redis连接对象的.register_script()方法以加载一个Lua脚本,该方法所返回的对象可以作为一个函数,以调用Redis中的脚本,而无需再调用Redis连接中的其他方法,并结合使用SCRIPT LOAD与EVALSHA命令以加载与执行脚本。

用例

当谈到Redis以及使用它作为一个时间序列数据库时,我们首先提出的一个问题是:“时间序列数据库的用途或目的是什么?”时间序列数据库的用例更多地与数据相关,尤其在你的数据结构被定义为一系列事件、一个或多个值的示例、以及随着时间推移而变化的度量值的情况下。以下是这些方面应用的一些示例(但不仅限于此):

股票交易的卖价与交易量

在线零售商的订单总价与送货地址

视频游戏中玩家的操作

IoT设备中内嵌的传感器中收集的数据

我们将继续进行深入的探讨,不过基本上来说,时间序列数据库的作用就是如果发生了某件事,或是你进行了一次评估操作后,可以在记录的数据中加入一个时间戳。一旦你收集了某些事件的信息,就可以对这些事件进行分析。你可以选择在收集的同时进行实时分析,也可以在事件发生后需要进行某些更复杂的查询时进行分析。

使用通过有序集合与哈希进行高级分析

在Redis中,对于时间序列数据的保存与分析有一种最为灵活的方式,它需要结合使用Redis中的两种不同的结构,即有序集合(Sorted Set)与哈希(Hash)。

在Redis中,有序集合这种结构融合了哈希表与排序树(Redis在内部使用了一个跳表结构,不过你可以先忽略这一细节)的特性。简单来说,有序集合中的每个项都是一个字符串型的“成员”以及一个double型的“分数”的组合。成员在哈希中扮演了键的角色,而分数则承担了树中的排序值的作用。通过这种组合,你就可以通过成员或分数的值直接访问成员与分数,此外,你也可以通过多种方式对按照分数的值排好序的成员与分数进行访问 2 。

保存事件

如今,从各种方面来说,使用一个或多个有序集合以及部分哈希的组合用于保存时间序列数据的做法都是Redis最常见的用例之一。它表现了一种底层的构建块,用于实现各种不同的应用程序。包括像Twitter一样的社交网络,以及类似于Reddit和Hacker News一样的新闻网站,乃至于基于Redis本身的一种接近完成的关系-对象映射器

在本文的示例中,我们将获取用户在网站中的各种行为所产生的事件。所有的事件都将共享4种属性,以及不同数量的其他属性,这取决于事件的类型。我们已知的属性包括:id、timestamp、type以及user。为了保存每个事件,我们将使用一个Redis哈希,它的键由事件的id所派生而来。为了生成事件的id,我们将在大量的源中选择一种方式,但现在我们将通过Redis中的一个计数器来生成我们的id。如果在64位的平台上使用64位的Redis,我们将能够创建最多2 63 -1个事件,主要的限制取决于可用的内存大小。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/cfdd0e78bc86b64f923c0877d24edd97.html