在 VoltDB(这是一种数据库) 经常使用到的术语,快速数据管道(Fast data pipeline),这是一种全新的现代应用程序 —— 这种应用程序将流式传输(或者说 “快速数据”) 与大数据紧密结合在了一起。
首先,对快速数据流水线架构进行快速的高度总结:
首先需要注意的事情是,快(Fast) 与 大(Big) 是紧密耦合的,即使他们是独立的系统。他们必须是紧密耦合的,至少是在规模上。设计用于每秒处理数百万次事件决策的数据库系统,与设计用于容纳数 PB 数据并生成机器学习(ML,Machine Learning)模型的系统完全不同。
要充分利用快速数据管道,有许多关键需求。这包括以下列出的能力:
有数百个快速管道应用程序已经被构建与部署,它们使用 VoltDB 作为 “快” 与 ”大“ 之间的快速操作数据库(正如胶水)。这些应用程序为金融欺诈检测、数字广告技术优化、智能电网、手机游戏,以及物联网等行业提供实时决策引擎。
本篇博客将深入探讨如何实现这一快速数据管道的特定部分,也就是最后一个重点:关闭数据循环,从大数据系统获取知识,并将这些知识在线应用于实时决策引擎(VoltDB)的能力。
“每一事件的决策” 意味着为每个传入事件(即每次事务)进行计算操作。通常,一些事实的集合会告知我们决策,而这些事实一般是从历史数据中计算而来的。我们可以在机器学习模型中捕获到这些 “事实(Fact)”,或者用一组生成的规则来组成 “事实”,从而在每个进入的事件上执行。或者,这些事实可以表示为数据库表中的行,并用于为每个事件进行过滤,并生成优化的决策。这篇博文将重点介绍后者:存储与更新数据库表中的事实。
将事实存储在数据库表中时,每一行对应着某特定值或一组值的一些情报。举个例子,航空公司航班的定价表,表中每一行对应于航线以及服务等级。或者,这些值可能是为浏览器 Cookie、设备 ID 而准备的人口统计分段列表(Demographic segmentation buckets)(其中内容包括收入中位数、婚姻状况等等),用于给特定人群提供针对性的广告。
事实表是面向具体应用(Application-specific)的,它可以是简单的,也可以是复杂的,并且通常是从诸如 Spark,Hadoop 或商业数据仓库等,这般历史 “大数据” 数据集计算而来的。事实表通常可以非常大,并且可以频繁地重新计算(也许周期是一周、一天,甚至一个小时)。
对这些事实集合来说,其变化是原子性(Atomically)的,这一点通常很重要。换句话说,如果成千上万的航班的航线价格发生了变化,则所有的价格都应该即刻进行变化。某些事务在加载数百万行新数据所需的时间段内引用到较旧的价格和一些较新的价格,这种情况是不可接受的。在处理大型事实表时,这个问题极具挑战性,因为事务性地改变数百万个值可能是一个缓慢的阻塞操作。当您的应用程序正每秒处理数十万个事务时,锁住表格以阻止正在进行的操作是无法接受的。
VoltDB 以非常简单和高效的方式解决了这一挑战。VoltDB 能够在单个操作中事务性地交换表。其工作逻辑如下所示:
Facts_Table
与 Facts_Table_2
。Facts_Table
中的行来做决策)时,用你想给未来的事务进行查询的新数据集合来填充 Facts_Table_2
。这张表格可以按照你喜欢的方式慢慢(或者快速)地填充,也许是在一天之内。Facts_Table_2
已被填充,并准备好使其在应用程序中 “实时(Live)” 时,请调用 VoltDB 的系统程序 @SwapTables
。该操作实质上通过交换内部存储器指针来切换表的数据。因此,它的执行时间在单毫秒范围之内。Facts_Table_2
的数据都已经在 Facts_Table
中,并且 Facts_Table
的旧数据现在驻留在Facts_Table_2
中。您可以考虑截断 Facts_Table_2
,以准备下一次刷新事实表(同时减少内存占用)。让我们来看一个特定的例子:使用 VoltDB 的选民示例应用。这是一个对美国偶像投票系统的简单模拟。我们假设每天都会有不同的参赛者,调用者可以对他们进行投票。投票需要每天(24 × 7 不间断地)进行。参赛者在每天午夜时分发生变化。我们不希望出现任何停机时间 —— 例如,当更改我们的参赛者名单时,不需要使用维护窗口。
以下是我们需要对选民示例执行此操作的方法:
1.首先,创建一个我们的 CONTESTANTS
表的精确副本,并将其命名为 CONTESTANTS_2
:
-- contestants_2 table holds the next day's contestants numbers -- (for voting) and names
CREATE TABLE contestants_2
(
contestant_number integer NOT NULL
, contestant_name varchar(50) NOT NULL
, CONSTRAINT PK_contestants_2 PRIMARY KEY
(
contestant_number
)
);
2.模式是相同的,并且该表不是一个实体化视图的来源。
3.在基准测试开始时,选民应用预先加载的 CONTESTANTS
表为以下列内容:
>;; select * from contestants;
CONTESTANT_NUMBER CONTESTANT_NAME
------------------ ----------------
1 Edwina Burnam
2 Tabatha Gehling
3 Kelly Clauss
4 Jessie Alloway
5 Alana Bregman
6 Jessie Eichman
$ cat contestants_2.csv
1, Tom Brady
2, Matt Ryan
3, Aaron Rodgers
4, Drew Brees
5, Andrew Luck
6, Kirk Cousins
$ csvloader contestants_2 -f contestants_2.csv
Read 6 rows from file and successfully inserted 6 rows (final)
Elapsed time: 0.905 seconds
$ sqlcmd
SQL Command :: localhost:21212
1>;; select * from contestants_2;
CONTESTANT_NUMBER CONTESTANT_NAME
------------------ ----------------
1 Tom Brady
2 Matt Ryan
3 Aaron Rodgers
4 Drew Brees
5 Andrew Luck
6 Kirk Cousins(Returned 6 rows in 0.01s)
4.现在我们已经加载并展示了新的参赛者(事实表),当我们准备好(即在午夜)时,我们将交换这两个表,使得新的参赛者立即可用于投票而不中断应用。我们将通过调用系统程序来完成此操作,如下所示:
$ sqlcmd
SQL Command :: localhost:21212
1>;; exec @SwapTables contestants_2 contestants;
modified_tuples
----------------
12
(Returned 1 rows in 0.02s)
2>;; select * from contestants;
CONTESTANT_NUMBER CONTESTANT_NAME
------------------ ----------------
6 Kirk Cousins
5 Andrew Luck
4 Drew Brees
3 Aaron Rodgers
2 Matt Ryan
1 Tom Brady
(Returned 6 rows in 0.01s)
5.最后,我们将截断 CONTESTANTS_2
表,并再次初始化它,以便它可以继续加载第二天的参赛者:
$ sqlcmd
SQL Command :: localhost:21212
1>;; truncate table contestants_2;
(Returned 6 rows in 0.03s)
2>;; select * from contestants_2;
CONTESTANT_NUMBER CONTESTANT_NAME
------------------ ----------------
(Returned 0 rows in 0.00s)
请注意,第 3 至第 5 步 —— 加载,交换和截断新事实表,都可以以自动方式完成,而不是像我在这个简单示例中演示的那样手动完成。运行选民示例并在运行过程中任意调用 @SwapTables
,可得出以下结果:
A total of 15,294,976 votes were received during the benchmark...
- 15,142,056 Accepted
- 152,857 Rejected (Invalid Contestant)
- 63 Rejected (Maximum Vote Count Reached)
- 0 Failed (Transaction Error)
Contestant Name Votes Received
Tom Brady 4,472,147
Kirk Cousins 3,036,647
Andrew Luck 2,193,442
Matt Ryan 1,986,615
Drew Brees 1,963,903
Aaron Rodgers 1,937,391
The Winner is: Tom Brady
对那些非新英格兰的人道一声抱歉!正如您可能已经猜到的那样,VoltDB 的总部位于波士顿的马萨诸塞州之外!