GBase 8s TimeSeries(时间序列) 指南
时间序列概念
时间序列数据类型(TimeSeries data type)
元素(Element)
包装元素(Packed Element)
时间点(Time point)
起点(Origin):
时间序列实例(TimeSeries Instance)
日历(Calendar)
日历模式(Calendar pattern)
容器(Container)
规则性(Regularity)
虚表(Virtual table)
时间序列存储在容器中,容器类型似于表,时间序列的数据是连续的。容器池是一组容器的集合。
滚动窗口容器的概念,相关活动窗口、休眠窗口,分区销毁。
数据类型和系统表:
数据类型包括:CalendarPattern、Calendar、TimeSeries
系统表包括:CalendarPatterns、 CalendarTable、TSInstanceTable、TSContainerTable
时间序列环境及测试
操作系统:CentOS 7U6 64bit
数据库版本:GBase 8s V8.7 2.0.1a2_2
数据库空间:datadbs01,datadbs02
创建名为tsdb的数据库,位于datadbs01中,以下操作均位于tsdb中
注册时间序列组件
使用gbasedbt用户注册timeseries组件
1 2 3 4 5 6 7 | [gbasedbt@centos7 extend]$ blademgr gbase01> register TimeSeries.6.00.FC4 tsdb Register module TimeSeries.6.00.FC4 into database tsdb? [Y/n]Y Registering DataBlade module... (may take a while). DataBlade TimeSeries.6.00.FC4 was successfully registered in database tsdb. gbase01>gbase01>exit Disconnecting... |
说明:
1)、使用blademgr前应当unset DB_LOCALE及CLIENT_LOCALE,否则会报core dump;
2)、TimeSeries.6.00.FC4的版本号来源于$GBASEBDTDIR/extend/目录下;
3)、tsdb为需要使用timeseries的数据库名称
以主机性能数据信息(包含主机信息、CPU IDLE和内存剩余量)为例创建时间序列。
1,定义日历模版
定义一个日历模版host_1min,时间间隔为1minute
1 | insert into CalendarPatterns values ( 'host_1min' , '{1 on},minute' ); |
2,定义日历
定义一个日历host_ctab,开始时间是2020-01-01 00:00:00.00000,使用日历模版host_1min。
1 2 | INSERT INTO CalendarTable(c_name, c_calendar) VALUES ( 'host_ctab' , 'startdate(2020-01-01 00:00:00.00000), pattstart(2020-01-01 00:00:00.00000), pattname(host_1min)' ); |
3,定义时间序列数据类型
定义一个时间序列的数据类型host_rowtype,含三个字段:时间,cpuidle,memfree
1 2 3 4 5 | CREATE ROW TYPE host_rowtype ( tv datetime year to fraction(5), cpuilde decimal (5,2), memfree decimal (12,0) ); |
4,创建包含时间序列的表
表host_list是主机信息表,记录host详细信息;host_table为包含时间序列的表,用于记录时间序列信息。
1 2 3 4 5 6 7 8 9 10 11 12 | CREATE TABLE host_list ( hostid varchar (255), ipaddr char (20), description varchar (255), PRIMARY KEY (hostid) ) LOCK MODE ROW; CREATE TABLE host_table ( hostid varchar (255), meter_data timeseries(host_rowtype), PRIMARY KEY (hostid) ) LOCK MODE ROW; |
5,创建容器
TimeSeries 表数据存储在表之外的的容器(Container)中。通过指针指向不同的容器,可以通过多个容器来提高横向的扩展性,提高并行处理能力,提高并行性能。在向时间序列中插入数据的时候,我们无需指定容器的名字,数据库服务器将会检查所有的容器,并找到与我们将要插入的数据适合的容器,如果没有合适的容器,数据库服务器会自动创建一个新的容器。可以使用如下所示的语句创建存储数据的容器。
1 2 | execute procedure tscontainercreate( 'host01' , 'datadbs01' , 'host_rowtype' ,16,16); execute procedure tscontainercreate( 'host02' , 'datadbs01' , 'host_rowtype' ,16,16); |
说明:
TSContainerCreate函数创建容器的主要参数如下:
字段名 | 数据类型 | 说明 |
---|---|---|
container_name | varchar(128,1) | 容器名称 |
dbspace_name | varchar(128,1) | 所在dbspace |
ts_type | varchar(128,1) | 存储的时间序列数据类型 |
container_size | integer | 容器初始大小 |
container_grow | integer | 容器增长大小 |
6,创建容器池
容器池是一系列容器的集合。使我们可以管理时间序列数据的插入操作,将不同类型的数据插入不同的容器中。比如可以采用轮询的插入策略使要插入的数据依次轮流插入已存在的容器中。只需在插入数据时使用 TSContainerPoolRoundRobin 函数。也可以采用自定义的策略来管理数据的插入。如下所示为将创建好的容器加入名为 hostpool 的容器池中。
1 2 | EXECUTE PROCEDURE TSContainerSetPool( 'host01' , 'hostpool' ); EXECUTE PROCEDURE TSContainerSetPool( 'host02' , 'hostpool' ); |
7,初始化基本数据
导入主机基本数据到host_list
1 2 3 | insert into host_list values ( 'centos7host-1' , '192.168.80.61' , 'CENTOS7 Server 1' ); insert into host_list values ( 'centos7host-2' , '192.168.80.62' , 'CENTOS7 Server 2' ); insert into host_list values ( 'centos7host-3' , '192.168.80.63' , 'CENTOS7 Server 3' ); |
通过host_list初始化时间序列表host_table:使用host_ctab日历,使用容器池轮转方式TSContainerPoolRoundRobin(hostpool),时间序列原点是2020-01-01 00:00:00.00000,阀值不限制(存在容器中),使用规则的时间序列,无初始数据。
1 2 3 4 | INSERT INTO host_table SELECT hostid, "calendar(host_ctab), origin(2020-01-01 00:00:00.00000), threshold(0), container(TSContainerPoolRoundRobin(hostpool)), regular,[]" FROM host_list; |
说明:
初始化语句中各字段含义:
字段名称 | 含义说明 |
---|---|
calendar ( calendar_name ) | 使用的日历名称 |
container ( container_name ) | 使用的容器名称 |
origin ( origin ) | 时间序列原点 |
threshold ( 0 ) | 阀值:决定时间序列存在表内还是专用容器中 |
regular | 时间序列的规则,这里使用规则的序列 |
[] | 初始时的值 |
注:如果只是初始数据到单个容器,指定到具体的容器中,语法基本相同
1 2 3 4 | INSERT INTO host_table SELECT hostid, "calendar(host_ctab), origin(2020-01-01 00:00:00.00000), threshold(0), container(host01), regular, []" FROM host_list; |
8,导入数据
导入数据有很多种方法,以下将介绍其中的几种:
1)、使用bulkload导入数据。
1 2 | update host_table set meter_data = bulkload (meter_data, '/home/gbase/temp/data.unl' , 0) where hostid = 'centos7host-1' ; |
其中,data.unl的格式如下,结构与时间序列数据类型相同
1 2 3 4 5 | ROW(2020-01-01 00:00:00.00000,91.3261,990825) ROW(2020-01-01 00:01:00.00000,95.0701,920513) ROW(2020-01-01 00:02:00.00000,83.2109,992005) ROW(2020-01-01 00:03:00.00000,87.4836,990184) ROW(2020-01-01 00:04:00.00000,82.9825,918096) |
2)、使用虚表
建立虚表vti_host_table,然后可以像正常表样插入数据到时间序列表中,该方法速度较慢。
1 | EXECUTE PROCEDURE TSCreateVirtualTab( 'vti_host_table' , 'host_table' ); |
正常导入数据
1 | INSERT INTO vti_host_table VALUES ( 'centos7host-1' , '2020-01-14 21:21:00.00000' ,98.99,933599); |
注:虚表可以查询和插入记录,但不能更新或者删除记录!
3)、使用导入程序TSL_Put
TSL_Put程序可以快速的批量导入数据。
1 2 3 4 5 6 7 8 9 10 | EXECUTE FUNCTION TSL_Init( 'host_table' , 'meter_data' ); -- 初始化装入器 EXECUTE FUNCTION TSL_Put( 'host_table|meter_data' , FileToClob( '/home/gbase/temp/data2.unl' , 'server' )); -- 装入数据 BEGIN WORK ; EXECUTE FUNCTION TSL_Flush ( 'host_table|meter_data' ); -- 保存数据 COMMIT WORK ; EXECUTE FUNCTION TSL_SessionClose ( 'host_table|meter_data' ); -- 关闭会话 EXECUTE PROCEDURE TSL_Shutdown( 'host_table|meter_data' ); -- 关闭装入器 |
其实data2.unl的数据格式与普通表的数据格式相同,如下:
1 2 3 4 | centos7host-2|2020-01-01 00:00:00.00000|91.3261|990825| centos7host-3|2020-01-01 00:00:00.00000|91.3261|990825| centos7host-2|2020-01-01 00:01:00.00000|95.0701|920513| centos7host-3|2020-01-01 00:01:00.00000|95.0701|920513| |
需要注意的是,使用TSL_Put,必须指定容器,而不能将时间序列数据放置于表内。
9,删除记录操作
删除记录是正常的数据操作,有很多种方法,以下将介绍其中的几种:
1)、使用DelElem函数删除单条记录
1 2 3 | UPDATE host_table SET meter_data = DelElem(meter_data, '2020-01-01 00:00:00.00000' ::datetime year to fraction(5)) WHERE hostid = 'centos7host-1' ; |
主要用于删除少量的数据,如上语句仅删除删除时间序列其中的一条记录。
2)、使用DelRange函数删除范围内的记录
1 2 3 4 5 6 | UPDATE host_table SET meter_data = DelRange(meter_data, '2020-01-01 00:01:00.00000' ::datetime year to fraction(5), '2020-01-01 00:10:00.00000' ::datetime year to fraction(5) ) WHERE hostid = 'centos7host-1' ; |
使用DelRange函数可以删除时间序列中指定范围内的记录。
3)、使用滚动窗口方式删除分区数据
该方法将具体介绍如下。
时间序列的滚动窗口
时间序列按日期时间间隔分发,每个日期时间间隔都存储在自己的分区中。分区可以存储在多个数据库空间中。
活动窗口包含可以将数据插入到的分区。
休眠窗口包含不再需要查询但尚未准备好将其删除的分区。
插入下一个时间间隔的数据时,活动窗口将在时间上向前推进。插入晚于最新分区的数据时,将添加新的分区,并且活动窗口向前推进。当活动窗口超出最大分区数时,最旧的分区将移至休眠窗口。当休眠窗口超出最大分区数时,依据创建滚动窗口容量时的参数确定是否自动销毁。
以下使用具体的示例来说明:
1,创建包含时间序列的表host_rw_table
使用与之前相同的时间序列数据类型
1 2 3 4 5 | CREATE TABLE host_rw_table ( hostid varchar (255), meter_data timeseries(host_rowtype), PRIMARY KEY (hostid) ) LOCK MODE ROW; |
2, 创建滚动窗口容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | EXECUTE PROCEDURE TSContainerCreate( 'host_rw' , -- 滚动窗口容器名称 'datadbs01' , -- 滚动窗口容器所在的dbspace 'host_rowtype' , -- timeseries 的类型 16, -- 滚动窗口容器的首区段大小,单位是KB 16, -- 滚动窗口容器的扩展区段大小 '2020-01-01 00:00:00.00000' ::datetime year to fraction(5), -- 滚动窗口的原点时间 'day' , -- 滚动窗口的间隔 year|month|week|day 2, -- 活动窗口的个数,0为不限制 2, -- 休眠窗口的个数,0为不限制 'datadbs02' , -- 滚动窗口所在的dbspace,默认NULL(使用滚动窗口所在的dbspace),使用逗号分隔符指定具体的dbspace 1, -- 控制分区删除方式,0为不删除,1为自动删除,2 16, -- 滚动窗口分区首区段大小,单位是KB 16 -- 滚动窗口分区扩展区段大小 ); |
创建滚动窗口容器的语句与创建普通窗口均使用TSContainerCreate,只是相对更具体的指定滚动窗口的参数。
示例中:创建一个名为host_rw的滚动窗口容器,时间序列数据初始化datadbs01上,使用的时间序列数据类型是host_rowtype,其第一个区段大小是16KB,扩展区段大小是16KB,容器的时间序列原点是2020-01-01 00:00:00.00000,滚动窗口的时间间隔是day(即:分区将会按照day进行分区),指定活动窗口的数量为2个,休眠窗口的数据为2个,滚动窗口分区所在的dbspace是datadbs02(可以使用逗号分隔符指定多个dbspace),控制超出最大休眠窗口数量的分区为自动销毁,滚动窗口分区的第一区段大小是16KB,扩展区段大小是16KB。
3, 初始化基本数据
初始化表host_rw_table
1 2 3 4 5 | INSERT INTO host_rw_table SELECT hostid, "calendar(host_ctab),origin(2020-01-01 00:00:00.00000),threshold(0), container(host_rw), regular, []" FROM host_list WHERE hostid = 'centos7host-1' ; |
同时,创建虚表vti_host_rw_table,用于验证活动窗口特性。
1 | EXECUTE PROCEDURE TSCreateVirtualTab( 'vti_host_rw_table' , 'host_rw_table' ); |
4, 导入数据,验证滚动窗口特性
1)、插入第一条记录,所在的分区将为活动窗口分区。
1 2 3 | UPDATE host_rw_table SET meter_data = PutElem(meter_data, ROW( '2020-01-01 01:00:00.00000' , 98.98, 955633)::host_rowtype) WHERE hostid = 'centos7host-1' ; |
为验证创建了一个分区,可以使用oncheck -pe datadbs02 检查区段生成,结果发现生成了一个8页的区段。
1 | tsdb:'gbasedbt'.host_rw 53 8 |
注:该示例使用了新的PutElem函数方式插入少量数据,数据格式与bulkload导入方式类似。
2)、插入第二条记录,时间间隔为1天,应当会再增加一个活动窗口分区。
1 2 3 | UPDATE host_rw_table SET meter_data = PutElem(meter_data, ROW( '2020-01-02 01:00:00.00000' , 96.98, 933633)::host_rowtype) WHERE hostid = 'centos7host-1' ; |
通过oncheck验证,应生成有两个8页的区段
1 2 | tsdb:'gbasedbt'.host_rw 53 8 tsdb:'gbasedbt'.host_rw 61 8 |
通过查询虚表vti_host_rw_table,可以确认两条记录都在活动窗口中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [gbasedbt@centos7 ~]$ dbaccess tsdb - Database selected. > select * from vti_host_rw_table; hostid centos7host-1 tv 2020-01-01 01:00:00.00000 cpuilde 98.98 memfree 955633 hostid centos7host-1 tv 2020-01-02 01:00:00.00000 cpuilde 96.98 memfree 933633 2 row(s) retrieved. |
3)、插入第三条时间间隔的记录时,第一条记录所在的分区将移至休眠分区,不可再被查询。
1 2 3 | UPDATE host_rw_table SET meter_data = PutElem(meter_data, ROW( '2020-01-03 01:00:00.00000' , 93.88, 944633)::host_rowtype) WHERE hostid = 'centos7host-1' ; |
通过oncheck验证,应生成有三个8页的区段
1 2 3 | tsdb:'gbasedbt'.host_rw 53 8 tsdb:'gbasedbt'.host_rw 61 8 tsdb:'gbasedbt'.host_rw 69 8 |
通过查询虚表vti_host_rw_table,应为最新的两条记录,第一条记录已经移动休眠分区。
1 2 3 4 5 6 7 8 9 10 11 12 13 | > select * from vti_host_rw_table; hostid centos7host-1 tv 2020-01-02 01:00:00.00000 cpuilde 96.98 memfree 933633 hostid centos7host-1 tv 2020-01-03 01:00:00.00000 cpuilde 93.88 memfree 944633 2 row(s) retrieved. |
4)、插入第四条时间间隔的记录时,第二条记录所在的分区将移至休眠分区,不可再被查询。
1 2 3 | UPDATE host_rw_table SET meter_data = PutElem(meter_data, ROW( '2020-01-04 01:00:00.00000' , 93.88, 944633)::host_rowtype) WHERE hostid = 'centos7host-1' ; |
通过oncheck -pe datadbs02验证,应生成有四个8页的区段
1 2 3 4 | tsdb:'gbasedbt'.host_rw 53 8 tsdb:'gbasedbt'.host_rw 61 8 tsdb:'gbasedbt'.host_rw 69 8 tsdb:'gbasedbt'.host_rw 77 8 |
通过查询虚表vti_host_rw_table,应为最新的两条记录,第二条记录也已经移动休眠分区
1 2 3 4 5 6 7 8 9 10 11 12 13 | > select * from vti_host_rw_table; hostid centos7host-1 tv 2020-01-03 01:00:00.00000 cpuilde 93.88 memfree 944633 hostid centos7host-1 tv 2020-01-04 01:00:00.00000 cpuilde 93.88 memfree 944633 2 row(s) retrieved. |
5)、插入第五条时间间隔的记录时,第三条记录所在的分区将移至休眠分区,不可再被查询;第一条记录所在的分区将自动被销毁。
1 2 3 | UPDATE host_rw_table SET meter_data = PutElem(meter_data, ROW( '2020-01-05 01:00:00.00000' , 93.88, 944633)::host_rowtype) WHERE hostid = 'centos7host-1' ; |
通过oncheck -pe datadbs02验证, 应有四个8页的区段,第一条记录所在的分区自动销毁。
1 2 3 4 5 | FREE 53 8 tsdb:'gbasedbt'.host_rw 61 8 tsdb:'gbasedbt'.host_rw 69 8 tsdb:'gbasedbt'.host_rw 77 8 tsdb:'gbasedbt'.host_rw 85 8 |
通过查询虚表vti_host_rw_table,应为最新的两条记录,第三条记录也已经移动休眠分区
1 2 3 4 5 6 7 8 9 10 11 12 13 | > select * from vti_host_rw_table; hostid centos7host-1 tv 2020-01-04 01:00:00.00000 cpuilde 93.88 memfree 944633 hostid centos7host-1 tv 2020-01-05 01:00:00.00000 cpuilde 93.88 memfree 944633 2 row(s) retrieved. |
总结:GBase 8s TimeSeries功能使用自带的大量函数进行数据操作,为处理海量的时许数据提供了一个快捷高效的方法。对于时间序列的大量函数介绍,需要参考《GBase 8s TimeSeries Data 用户指南》一书介绍。