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:
说明 最新小版本将提供更丰富的功能与稳定的服务,建议将实例的小版本升级到最新,具体操作请参见升级小版本。如果您的实例为集群实例或读写分离架构,请将代理节点的小版本也升级到最新,否则可能出现命令无法识别的情况。
注意事项
操作对象为Tair实例中的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 时间范围内的数据,超过该时间范围的数据会被覆盖、删除。SIZE 和WIN 属性仅在新建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数据。 |
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时间戳),单位为毫秒 ,不传此参数表示不过期。
|
返回值 | |
示例 | 命令示例: CPC.UPDATE foo f1 EX 3600
返回示例: OK
|
CPC.ESTIMATE
类别 | 说明 |
语法 | CPC.ESTIMATE key
|
时间复杂度 | O(1) |
命令描述 | 获取指定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时间戳),单位为毫秒 ,不传此参数表示不过期。
|
返回值 | |
示例 | 命令示例: 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时间戳),单位为毫秒 ,不传此参数表示不过期。
|
返回值 | |
示例 | 命令示例: 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 时间范围内的数据,超过该时间范围的数据会被覆盖、删除。SIZE 和WIN 属性仅在新建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分钟)。
|
返回值 | |
示例 | 命令示例: CPC.ARRAY.UPDATE foo 1645584510000 f1 SIZE 120 WIN 10000
返回示例: OK
|
CPC.ARRAY.ESTIMATE
类别 | 说明 |
语法 | CPC.ARRAY.ESTIMATE key timestamp
|
时间复杂度 | O(1) |
命令描述 | 获取指定TairCpc中目标timestamp所在时间窗口的基数估算值。 |
选项 | |
返回值 | 执行成功:返回对应时间窗口的基数估算值。 其它情况返回相应的异常信息。
|
示例 | 命令示例: 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(含当前窗口)个时间窗口内,时间窗口合并、去重后的基数估算值。 |
选项 | |
返回值 | |
示例 | 命令示例: CPC.ARRAY.ESTIMATE.RANGE.MERGE foo 1645584510000 3
返回示例: "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对象。 timestamp:指定的Unix时间戳,单位为毫秒。 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
|