TairCpc是基于CPC(Compressed Probability Counting)压缩算法开发的数据结构,支持仅占用很小的内存空间对采样数据进行高性能计算。

背景信息

在大数据实时决策场景中,通常会将业务日志流入实时计算系统完成计算,然后将计算结果存储至在线存储系统,最终由实时规则或决策系统进行决策,例如:
  • 防控信用卡欺诈交易:快速判断刷卡环境是否可信,若发现异常则需第一时间拦截交易。
  • 防控黄牛团伙恶意牟利:实时识别并阻止通过虚拟设备、虚假地址等方式损害平台利益的行为。

您可以利用TairCpc将实时数据,按不同的去重维度,结构化地存储到Tair数据库中,即可在高速的访问场景中直接获得结果,实现存储、计算一体化。同时TairCpc提供多重聚合运算,可以在纳秒级聚合数据结果,具备实时风控的能力。

TairCpc简介

CPC是一种高性能数据去重算法,可以将不同的值作为数据流进行计数,支持将多个数据块合并、去重,获得去重后的总计数。相比HLL(Hyperloglog) 算法,在相同精度下,CPC大约可节省40%内存空间。

同时,TairCpc在开源CPC算法的基础上,将误差率优化至0.008%(开源CPC为0.67%;HLL误差率为1.95%)。

主要特征
  • 内存占用低,支持增量读写,实现IO最小化。
  • 高性能去重,同时拥有超高去重精度。
  • 误差率稳定收敛。
典型场景
  • 银行安全系统
  • 秒杀限购
  • 防控用户(或黄牛团伙)恶意牟利

前提条件

实例为Tair(Redis企业版):
说明 最新小版本将提供更丰富的功能与稳定的服务,建议将实例的小版本升级到最新,具体操作请参见升级小版本。若实例为集群架构读写分离架构,请将代理节点的小版本也升级到最新,避免代理节点无法识别部分命令。

注意事项

操作对象为Tair(Redis企业版)实例中的TairCpc数据。

命令列表

表 1. TairCpc命令
命令 语法 说明
CPC.UPDATE CPC.UPDATE key item [EX|EXAT|PX|PXAT time]

在指定TairCpc中添加item。若TairCpc不存在则自动新建,若待添加的item已存在于目标TairCpc中,则不会进行操作。

CPC.ESTIMATE CPC.ESTIMATE key

获取指定TairCpc去重后的基数估算值,返回值的数据类型为double类型,您可以仅取整数部分(忽略小数点后的数据)。

CPC.UPDATE2EST CPC.UPDATE2EST key item [EX|EXAT|PX|PXAT time]

在指定TairCpc中添加item,返回更新后的基数估算值。若TairCpc不存在则自动新建。

CPC.UPDATE2JUD CPC.UPDATE2JUD key item [EX|EXAT|PX|PXAT time]

在指定TairCpc中添加item,并返回更新后的基数估算值和其与更新前的差值。若返回的差值为1则表示写入成功且不存在重复;若为0则表示已存在当前item。若TairCpc不存在则自动新建。

CPC.ARRAY.UPDATE CPC.ARRAY.UPDATE key timestamp item [EX|EXAT|PX|PXAT time] [SIZE size] [WIN window_length]
在指定TairCpc中,向目标timestamp对应的时间窗口添加item。若TairCpc不存在则自动新建,SIZE为时间窗口个数,WIN为时间窗口的长度(单位为毫秒)。随着流式数据的写入,TairCpc会持续向前更新并保存SIZE * WIN时间范围内的数据,超过该时间范围的数据会被覆盖、删除。SIZEWIN属性仅在新建TairCpc的时生效。
说明 例如目标key为计算近10分钟内每分钟的数据:可以设置SIZE为10(10个时间窗口)、WIN为60000(每个时间窗口为1分钟)。当目标key中写入第11分钟的数据时,第1分钟的数据会逐渐被覆盖、删除。
CPC.ARRAY.ESTIMATE CPC.ARRAY.ESTIMATE key timestamp

获取指定TairCpc中目标timestamp所在时间窗口的基数估算值。

CPC.ARRAY.ESTIMATE.RANGE CPC.ARRAY.ESTIMATE.RANGE key start_time end_time

获取指定TairCpc的指定时间段内(包含指定时间点)各个时间窗口的基数估算值。

CPC.ARRAY.ESTIMATE.RANGE.MERGE CPC.ARRAY.ESTIMATE.RANGE.MERGE key timestamp range

获取指定TairCpc在指定时间点及往后的range时间段内,时间窗口合并、去重后的基数估算值。

CPC.ARRAY.UPDATE2EST CPC.ARRAY.UPDATE2EST key timestamp item [EX|EXAT|PX|PXAT time] [SIZE size] [WIN window_length] 在指定TairCpc中,向目标timestamp对应的时间窗口添加item,并返回该时间窗口更新后的基数估算值。若TairCpc不存在则自动新建,新建参数用法与CPC.ARRAY.UPDATE一致。
CPC.ARRAY.UPDATE2JUD CPC.ARRAY.UPDATE2JUD key timestamp item [EX|EXAT|PX|PXAT time] [SIZE size] [WIN window_length] 在指定TairCpc中,向目标timestamp对应的时间窗口添加item,并返回该时间窗口更新后的基数估算值和其与更新前的差值。若返回的差值为1,则表示写入成功且不存在重复;若为0则表示已存在当前item。若TairCpc不存在则自动新建,新建参数用法与CPC.ARRAY.UPDATE一致。
DEL DEL key [key ...] 使用原生Redis的DEL命令可以删除一条或多条TairCpc数据。
说明 本文的命令语法定义如下:
  • 大写关键字:命令关键字。
  • 斜体:变量。
  • [options]:可选参数,不在括号中的参数为必选。
  • A|B:该组参数互斥,请进行二选一或多选一。
  • ...:前面的内容可重复。

CPC.UPDATE

类别 说明
语法 CPC.UPDATE key item [EX|EXAT|PX|PXAT time]
时间复杂度 O(1)
命令描述

在指定TairCpc中添加item。若TairCpc不存在则自动新建,若待添加的item已存在于目标TairCpc中,则不会进行操作。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • item:待添加的数据。
  • EX:指定key的相对过期时间,单位为秒,不传此参数表示不过期。
  • EXAT:指定key的绝对过期时间(Unix时间戳),单位为秒,不传此参数表示不过期。
  • PX:指定key的相对过期时间,单位为毫秒,不传此参数表示不过期。
  • PXAT:指定key的绝对过期时间(Unix时间戳),单位为毫秒 ,不传此参数表示不过期。
返回值
  • OK:表示执行成功。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.UPDATE foo f1 EX 3600

返回示例:

OK

CPC.ESTIMATE

类别 说明
语法 CPC.ESTIMATE key
时间复杂度 O(1)
命令描述

获取指定TairCpc去重后的基数估算值,返回值的数据类型为double类型,您可以仅取整数部分(忽略小数点后的数据)。

选项
  • key:Key名称(TairCpc数据结构)。
返回值
  • 执行成功:返回估算值,数据类型为double类型。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.ESTIMATE foo

返回示例:

"19.000027716212127"

CPC.UPDATE2EST

类别 说明
语法 CPC.UPDATE2EST key item [EX|EXAT|PX|PXAT time]
时间复杂度 O(1)
命令描述

在指定TairCpc中添加item,返回更新后的基数估算值。若TairCpc不存在则自动新建。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • item:待添加的数据。
  • EX:指定key的相对过期时间,单位为秒,不传此参数表示不过期。
  • EXAT:指定key的绝对过期时间(Unix时间戳),单位为秒,不传此参数表示不过期。
  • PX:指定key的相对过期时间,单位为毫秒,不传此参数表示不过期。
  • PXAT:指定key的绝对过期时间(Unix时间戳),单位为毫秒 ,不传此参数表示不过期。
返回值
  • 执行成功:返回更新后的估算值,数据类型为double类型。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.UPDATE2EST foo f3

返回示例:

"3.0000004768373003"

CPC.UPDATE2JUD

类别 说明
语法 CPC.UPDATE2JUD key item [EX|EXAT|PX|PXAT time]
时间复杂度 O(1)
命令描述

在指定TairCpc中添加item,并返回更新后的基数估算值和其与更新前的差值。若返回的差值为1则表示写入成功且不存在重复;若为0则表示已存在当前item。若TairCpc不存在则自动新建。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • item:待添加的数据。
  • EX:指定key的相对过期时间,单位为秒,不传此参数表示不过期。
  • EXAT:指定key的绝对过期时间(Unix时间戳),单位为秒,不传此参数表示不过期。
  • PX:指定key的相对过期时间,单位为毫秒,不传此参数表示不过期。
  • PXAT:指定key的绝对过期时间(Unix时间戳),单位为毫秒 ,不传此参数表示不过期。
返回值
  • 执行成功:返回更新后的估算值和该值与更新前的差值,数据类型均为double类型。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.UPDATE2JUD foo f20

返回示例:

1) "20.000027716212127"    // 更新后,TairCpc的估算值为20。
2) "1.0000014901183398"    // 20 - 19 = 1

CPC.ARRAY.UPDATE

类别 说明
语法 CPC.ARRAY.UPDATE key timestamp item [EX|EXAT|PX|PXAT time] [SIZE size] [WIN window_length]
时间复杂度 O(1)
命令描述
在指定TairCpc中,向目标timestamp对应的时间窗口添加item。若TairCpc不存在则自动新建,SIZE为时间窗口个数,WIN为时间窗口的长度(单位为毫秒)。随着流式数据的写入,TairCpc会持续向前更新并保存SIZE * WIN时间范围内的数据,超过该时间范围的数据会被覆盖、删除。SIZEWIN属性仅在新建TairCpc的时生效。
说明 例如目标key为计算近10分钟内每分钟的数据:可以设置SIZE为10(10个时间窗口)、WIN为60000(每个时间窗口为1分钟)。当目标key中写入第11分钟的数据时,第1分钟的数据会逐渐被覆盖、删除。
选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • timestamp:指定的Unix时间戳,单位为毫秒。
  • item:待添加的数据。
  • EX:指定key的相对过期时间,单位为秒,不传此参数表示不过期。
  • EXAT:指定key的绝对过期时间(Unix时间戳),单位为秒,不传此参数表示不过期。
  • PX:指定key的相对过期时间,单位为毫秒,不传此参数表示不过期。
  • PXAT:指定key的绝对过期时间(Unix时间戳),单位为毫秒 ,不传此参数表示不过期。
  • SIZE:时间窗口个数,默认为10,范围为[1,1000],建议设置在120以内。
  • WIN:时间窗口的长度(单位为毫秒),默认为60000毫秒(1分钟)。
返回值
  • OK:表示执行成功。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.ARRAY.UPDATE foo 1645584510000 f1 SIZE 120 WIN 10000

返回示例:

OK

CPC.ARRAY.ESTIMATE

类别 说明
语法 CPC.ARRAY.ESTIMATE key timestamp
时间复杂度 O(1)
命令描述

获取指定TairCpc中目标timestamp所在时间窗口的基数估算值。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • timestamp:指定的Unix时间戳,单位为毫秒。
返回值
  • 执行成功:返回对应时间窗口的基数估算值。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.ARRAY.ESTIMATE foo 1645584532000

返回示例:

"2"

CPC.ARRAY.ESTIMATE.RANGE

类别 说明
语法 CPC.ARRAY.ESTIMATE.RANGE key start_time end_time
时间复杂度 O(1)
命令描述

获取指定TairCpc的指定时间段内(包含指定时间点)各个时间窗口的基数估算值。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • start_time:查询的开始时间(Unix时间戳),单位为毫秒。
  • end_time:查询的结束时间(Unix时间戳),单位为毫秒。
返回值
  • 执行成功:返回目标时间窗口的基数估算值。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.ARRAY.ESTIMATE.RANGE foo 1645584510000 1645584550000

返回示例:

1) "2"
2) "0"
3) "1"
4) "0"
5) "0"

CPC.ARRAY.ESTIMATE.RANGE.MERGE

类别 说明
语法 CPC.ARRAY.ESTIMATE.RANGE.MERGE key timestamp range
时间复杂度 O(1)
命令描述

获取指定TairCpc在指定时间点及往后的range时间段内,时间窗口合并、去重后的基数估算值。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • timestamp:查询的开始时间(Unix时间戳),单位为毫秒。
  • range:查询的时间范围(Unix时间戳),单位为毫秒。
返回值
  • 执行成功:返回目标key在指定时间段内去重后的基数估算值。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.ARRAY.ESTIMATE.RANGE.MERGE foo 1645584510000 100000

返回示例:

"6"

CPC.ARRAY.UPDATE2EST

类别 说明
语法 CPC.ARRAY.UPDATE2EST key timestamp item [EX|EXAT|PX|PXAT time] [SIZE size] [WIN window_length]
时间复杂度 O(1)
命令描述

在指定TairCpc中,向目标timestamp对应的时间窗口添加item,并返回该时间窗口更新后的基数估算值。若TairCpc不存在则自动新建,新建参数用法与CPC.ARRAY.UPDATE一致。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • timestamp:指定的Unix时间戳,单位为毫秒。
  • item:待添加的数据。
  • EX:指定key的相对过期时间,单位为秒,不传此参数表示不过期。
  • EXAT:指定key的绝对过期时间(Unix时间戳),单位为秒,不传此参数表示不过期。
  • PX:指定key的相对过期时间,单位为毫秒,不传此参数表示不过期。
  • PXAT:指定key的绝对过期时间(Unix时间戳),单位为毫秒 ,不传此参数表示不过期。
  • SIZE:时间窗口个数,默认为10,范围为[1,1000],建议设置在120以内。
  • WIN:时间窗口的长度(单位为毫秒),默认为60000毫秒(1分钟)。
返回值
  • 执行成功:返回目标时间窗口更新后的估算值。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.ARRAY.UPDATE2EST foo 1645584530000 f3

返回示例:

"3"

CPC.ARRAY.UPDATE2JUD

类别 说明
语法 CPC.ARRAY.UPDATE2JUD key timestamp item [EX|EXAT|PX|PXAT time] [SIZE size] [WIN window_length]
时间复杂度 O(1)
命令描述

在指定TairCpc中,向目标timestamp对应的时间窗口添加item,并返回该时间窗口更新后的基数估算值和其与更新前的差值。若返回的差值为1,则表示写入成功且不存在重复;若为0则表示已存在当前item。若TairCpc不存在则自动新建,新建参数用法与CPC.ARRAY.UPDATE一致。

选项
  • key:Key名称(TairCpc数据结构),用于指定命令调用的TairCpc对象。
  • item:待添加的数据。
  • EX:指定key的相对过期时间,单位为秒,不传此参数表示不过期。
  • EXAT:指定key的绝对过期时间(Unix时间戳),单位为秒,不传此参数表示不过期。
  • PX:指定key的相对过期时间,单位为毫秒,不传此参数表示不过期。
  • PXAT:指定key的绝对过期时间(Unix时间戳),单位为毫秒 ,不传此参数表示不过期。
  • SIZE:时间窗口个数,默认为10,范围为[1,1000],建议设置在120以内。
  • WIN:时间窗口的长度(单位为毫秒),默认为60000毫秒(1分钟)。
返回值
  • 执行成功:返回目标时间窗口更新后的估算值和该值与更新前的差值。
  • 其它情况返回相应的异常信息。
示例

命令示例:

CPC.ARRAY.UPDATE2JUD foo 1645584530000 f7

返回示例:

1) "8"            // 更新后,TairCpc的估算值为8。
2) "1"            // 8 - 7 = 1