营销系统黑名单优化:位图的应用解析 | 京东云技术团队

背景

营销系统中,客户投诉是业务发展的一大阻碍,一般会过滤掉黑名单高风险账号,并配合频控策略,来减少客诉,进而增加营销效率,减少营销成本,提升营销质量。

营销系统一般是通过大数据分析建模,在CDP(客户数据平台,以客户为核心,围绕数据融合、人群圈选、用户洞察等提供产品能力)创建营销目标客户群体,黑名单同样也是通过CDP维护。下面的图片简单描述了过滤黑名单的处理流程,流程是相对简单的。但是,测试过程中却发现一个问题,对于一个近30万的营销群体,整个触达流程需要处理一个多小时,而其中过滤黑名单就占用了近半个小时的时间,业务有点难以接受这个性能。

黑名单处理流程

性能优化

引入多线程优化

其实很容易就能想到,对于调用RPC接口这种含有I/O操作的场景,可以引入多线程优化,将一个几十万的账号集合拆分为多个子任务提交给线程池处理,从而加快处理速度。从下图可以看出引入多线程后性能有很明显的改善,单线程处理25万、50万个账号的群体分别需要近半小时、近一小时,改为25个线程处理后可以分别控制在1分钟、2分钟左右。

多线程处理

引入位图优化

进一步了解CDP的底层原理后,会发现这个问题应该还有其他的解决方案,即通过位图优化。CDP的群体都会有对应的位图文件,也就是说营销客户群体和黑名单群体都是以位图的数据结构存储的,通过CDP下载群体的SDK就可以获取到位图文件,营销群体的位图与黑名单群体位图进行与非操作(andNot,就是从一个位图中移除另一个位图中存在的元素,而保留不在另一个位图中的元素),得到的新的位图就是过滤掉黑名单账号后的目标客户的位图。代码实现很简单,使用CDP SDK的示例代码如下(也可以参考GitHub示例代码,但不适用于CDP群体位图处理):

DataLoader dataLoader = new DataLoader(token, bitMapBaseUrl);
ABitmap customerBitmap = dataLoader.loadGroup(customerGroupCode);
ABitmap blacklistBitmap = dataLoader.loadGroup(blacklistGroupCode);
customerBitmap.andNot(blacklistBitmap);

位图存储相当节省空间,50万群体的位图文件也就约2MB大小。同时位图的与非操作是相当快的,上边例子中的25万、50万的群体都可以在80毫秒左右过滤掉黑名单账号。从近半小时、近一小时到几十毫秒这个对比非常惊人了,那么为什么位图的处理速度可以这么快呢?

位图简介

位图原理

位图的基本思想是使用bit来标记一个数值,1表示该数值存在,0表示不存在。由于以位为单位存储数据,因此可以大大节省存储空间。通过这种方式,可以非常高效地表示和操作数值集合。

举个直观的例子,有40亿个不重复的随机自然数,如果使用long型数值存储,一个long型数值8个字节,40亿个数值占用约29.8GB,但如果是存储为40亿个bit,则只需要约0.47GB。

在Java中一个long型数值占64位,可以用一个long型数组long[] words = new long[(nBits - 1) / 64 + 1]存储位图,其中nBits表示位图的初始大小。对于给定任意自然数xx / 64就能得到x在数组中的下标,x % 64就能得到x在此下标的哪个位。数组的第一个下标words[0]可以表示数值0~63,第二个下标words[1]可以表示数值64~127,之后依此类推。

如果将 3, 4, 6 几个数值存入位图,则如下图所示,对应数组的第一个下标的 3, 4, 6 位被标记为1,其他位均为0。

位图

对于添加操作,假设要添加数值2,可以计算出其在数组中的下标为2 / 640,在words[0]的位置为2 % 642,只需将1按位左移2位,然后和words[0]进行按位或操作,将相应位置置为1

位图添加成员

对于移除操作,假设要移除刚添加的数值2,和添加操作一样,可以通过计算得到其在数组的下标为0, 在words[0]的位置为2,只需将1按位左移2位再按位取反,然后和words[0]进行按位与操作,将相应位置置为0

位图移除成员

而对于查找操作,假设要查找数值3,可以计算得到其在数组的下标为0, 在words[0]的位置为3,只需将1按位左移3位,然后和words[0]按位与操作不等于0即可判断数值是否存在。

位图查询成员

以上内容简单介绍了 Java 中的BitSet的实现原理,实际代码还会稍微复杂一些,比如会涉及到数组扩容,范围边界的检测等等。有意思的是BitSet中计算数组下标和位置并没有使用除法和取模,都是通过位移操作实现的,x / 64是通过右移操作x >> 61按位左移x % 64位是直接将1左移x位即1 << x

位图对象还支持一些常用的位运算,如求交集(and, 按位与操作),求并集(or, 按位或操作),求差集(andNot, 按位与非操作)。

位图非常节省存储空间,位操作也非常高效,这也是为什么引入位图过滤黑名单能在毫秒级别处理完成的原因。

RoaringBitmap

遗憾的是,BitSet会占用过多内存。如果BitSet中只存储一个数值200000000,通过GraphLayout发现BitSet会占用约23MB内存,这种情况对空间的浪费极其严重。为了弥补这一缺陷,通常使用压缩位图。

RoaringBitmap是一种压缩位图,其性能往往优于WAHEWAHConcise等传统压缩位图。在某些情况下,RoaringBitmap的速度可以快上数百倍,而且压缩效果往往要好得多。它们甚至比未压缩的位图更快。如果使用RoaringBitmap只存储一个数值200000000,只需要144B的内存。

RoaringBitmap将一个int数值x划分为高16位和低16位,高16位下标可以通过x >>> 16得到,高位container中维护了一个数组,数组的元素中存储了低位container,低位container中的元素数量未达到4096时,使用ArrayContainer存储,其内部实现是一个char数组,数组中存放低位数值,达到4096后低位container会转换为BitmapContainer,其内部实现就是一个位图。此外还有一个RunContainer的实现,不过较少使用。

RoaringBitmap

为什么要使用4096这个阈值呢?是因为超过4096后,BitmapContainer会比ArrayContainer更节省空间。

container

存储long型数值时可以使用Roaring64NavigableMap,区别是它会将数值分为高32位和低32位。CDP存储人群的位图就是基于Roaring64NavigableMap实现的。

位图的应用场景

位图可以用较少的内存来表示大规模的布尔值集合,节省内存空间,并且支持高效的位操作,如ANDORXOR等,使得对集合进行复杂操作变得简单高效,对于存在性查询,位图可以在常数时间内完成,具有高效的查询性能。一些面试题中出现的几十亿数据的去重、排序、计数或者成员查询等问题,都可以通过位图解决,此外还有很多场景应用到了位图。

Java 中的位图应用

ArrayList为了提升性能并节省空间,重写了Collection接口默认的removeIf方法,重写后的方法使用了位图,首先遍历一遍元素用位图标记待删除的元素位置,然后遍历第二遍才真正删除元素,通过这种方式实现,可以高效移除元素,减少不必要的数组复制和元素移动次数,并且使用位图标记待删除位置也没有过多浪费空间。

位图索引

位图索引是一种特别适合于处理具有较少唯一值的列(例如性别、婚姻状况等)查询的数据结构,它在数据仓库等场合中非常有用,因为这些环境通常包含大量的数据读取操作和复杂的布尔逻辑查询,同时数据更新的频率相对较低。位图索引通过将列值映射到位上,并利用位运算来快速完成查询,能够有效提高查询效率,但它不适合那些具有高基数值和频繁更新的场景,因为这些场景下位图索引会占用大量空间并且更新成本很高。

Redis 的位图

Redis的位图非常适合于处理大量的布尔值数据,例如追踪用户的在线状态、记录用户每日签到或统计活跃用户数量等场景,因为位图通过每个位代表一个布尔值,可以极大地节省存储空间,并且Redis提供了丰富的位操作命令来高效地执行各种计算,如统计特定位上值为1的数量或者对多个位图进行位运算以实现快速的集合操作,这些特性使得位图在特征标记、实验分组以及AB测试等方面也非常有用;但是,需要注意的是,由于Redis将位图存储为字符串,因此其大小会受到字符串最大长度的限制,并且当数据量巨大时,对内存的使用效率也是一个需要考虑的因素。

布隆过滤器

数值可以很方便地使用位图处理,但是有些场景需要处理的可能是字符串,比如用户账号、URL等,一般需要将字符串跟数值做一个映射,CDP是将用户账号和偏移量offset做了一个映射表,再将偏移量offset存储到位图。布隆过滤器则是通过多个哈希函数将元素映射到了位图上,它是一种空间效率极高的概率型数据结构,它用于判断一个元素是否在一个集合中,并且能够非常快速地进行查询,常见的应用场景包括网络爬虫中避免重复爬取相同的URL、数据库中快速判断某个元素是否存在以减少不必要的磁盘IO操作、防止缓存击穿,以及各种需要快速集合检测且可以容忍一定误报率的场合,误报是指布隆过滤器可能会错误地判断某个不存在集合中的元素为存在,但它绝不会错误地判断存在的元素为不存在,因此在不需要百分之百准确性的情况下,布隆过滤器是一种非常有用的工具。

总结

通过探讨营销系统中优化黑名单过滤的策略,本文引入了位图这一数据结构,并详细阐述了其背后的实现机制及适用场合。位图特别适用于那些对空间效率和查询速度有极高要求的场景。在处理大数据时,位图通过压缩和优化可以极大地减少内存占用,提升数据处理的性能,希望本文能为大家提供有益的参考和帮助。

作者:京东科技 冯浩

来源:京东云开发者社区 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/398183.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 驱动开发基础知识——APP 怎么读取按键值(十二)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

使用Dasviewer时怎样让分屏且全屏状态下,模型能持续转动?

答&#xff1a;轻微甩动下就可以旋转了&#xff0c;此外直接拖入打开模型也可以旋转。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便快捷的数据浏览…

STL常用之vector,list,stack,queue,deque总结与对比

一&#xff0c;vector 1&#xff09;底层 vector的底层是开辟出来的一块连续空间&#xff0c;类似于数组&#xff0c;每次空间满了之后会根据不同的编译器有不同的扩容倍数。 2&#xff09;优劣 优点&#xff1a;随机访问效率高&#xff0c;因为地址是连续的&#xff0c;底层…

接口测试总结及其用例设计方法

接口测试的总结文档 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xff1a;主要介绍为什…

【JavaEE】_synchronized关键字——监视器锁monitor lock

目录 1. synchronized的特性 2. synchronized的使用 3. Java标准库中的线程安全类 1. synchronized的特性 &#xff08;1&#xff09;互斥&#xff1a; 前文已经介绍&#xff0c;某个线程执行到某个对象的synchronized中时&#xff0c;其他线程如果也执行到同一个对象&…

卡在Installing CocoaPods dependencies (this may take a few minutes)这一步

卡在了Installing CocoaPods dependencies (this may take a few minutes)这一步怎么办 前置条件 注意一&#xff1a;请不要在目录、文件名中使用中文、空格等特殊符号。请不要单独使用常见的关键字作为项目名&#xff08;如 class, native, new, package 等等&#xff09;。请…

IP详细地理位置查询:技术原理与应用实践

IP地址是互联网上设备的唯一标识&#xff0c;在网络安全、个性化服务等领域具有重要意义。通过IP详细地理位置查询&#xff0c;可以获取到IP地址所在地的具体信息&#xff0c;为网络管理、定位服务等提供支持。IP数据云将深入探讨IP详细地理位置查询的技术原理、应用实践以及相…

Android Studio插件版本与Gradle 版本对应关系

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、Gradle各版本对应关系3.1 Gradle 版…

psm的stata实现

1. PSM 简介 在经济学中&#xff0c;我们通常希望评估某项公共政策实施后的效应&#xff0c;为此&#xff0c;我们构建 "处理组" 和 "控制组" 以评估「处理效应 (treatment effect)」。然而&#xff0c;我们的数据通常来自非随机的观察研究中&#xff0c;处…

如何使用IP代理解决亚马逊账号IP关联问题?

亚马逊账号IP关联问题是指当同一个IP地址下有多个亚马逊账号进行活动时&#xff0c;亚马逊会将它们关联在一起&#xff0c;从而可能导致账号被封禁或限制。 为了避免这种情况&#xff0c;许多人选择使用IP代理。 IP代理为什么可以解决亚马逊IP关联问题&#xff1f; IP代理是…

光芒绽放:妙用“GLAD原则”打造标准的数据可视化图表

光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表 文章目录 光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表前言一、可视化工具有哪些&#xff1f;二、那如何做出正确可视化图表 &#xff1f;GLAD原则1.G原则2.L原则3.A原则4.D原则 三、总结最后…

软件测试方法_边界值分析法

目录&#xff1a; ①边界值分析法的介绍和概念 ②边界值分析法的原理和思想 ③单缺陷假设和多缺陷假设 ④边界值测试数据类型 ⑤内部边界值分析 ⑥各类边界值测试介绍 ⑦基于边界值分析方法选择测试用例的原则 ⑧边界值分析法的实例分析 1、边界值分析法的介绍和概念 …

Apipost forEach循环控制器如何使用

最近&#xff0c;Apipost对自动化测试进行了优化&#xff0c;新增foreach控制器。这个新功能的引入为自动化测试带来了更高的效率和灵活性。本文将介绍Apipost的foreach控制器&#xff0c;解释其用途和优势&#xff0c;帮助您更好地利用这一功能提升自己的测试工作。 什么是fo…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(8)模型训练

好吧&#xff0c;搞了半天&#xff0c;都是围绕数据在干活&#xff0c;这也就验证了&#xff0c;我们说的&#xff0c;数据准备等工作&#xff0c;要占到机器学习项目一半以上的工作量和时间。而且数据决定了模型的天花板&#xff0c;算法只是去达到上限。 我们今天来学习模型…

3.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-游戏启动流程的分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;项目搭建 首先下图红框里是游戏启动的程序 游戏启动之后的名字&#xff08;fxgame.exe&#xff09; 一般游戏启动的架构&#xff1a; 第一种&#xff1a;登录器程序启动游戏主程序&#xff0c;然后游…

企业级 文件传输加密应用,干货分享

企业级 文件传输加密应用 简历一直在投&#xff0c;一直无音讯&#xff0c;今天我又从硬盘里翻出一个 好玩的加密软件&#xff0c;这个是 2017年的时候和荷兰某世界500强公司合作的小项目。 今天分享给大家 。 文章目录 企业级 文件传输加密应用1.目的2.软件介绍3.下载好 安装…

多进程(1)

1> 使用多个进程实现文件拷贝 #include<myhead.h> int main(int argc, const char *argv[]) {pid_t pid;pidfork();int fdr;char buf;if((fdropen(argv[1],O_RDONLY))-1){perror("open error");return -1;}int lenlseek(fdr,0,SEEK_END)-lseek(fdr,0,SEEK_…

基于springboot实现的音乐网站

一、系统架构 前端&#xff1a;html | js | css | bootstrap 后端&#xff1a;springboot | mybatis 环境&#xff1a;jdk1.8 | mysql | maven 二、 代码及数据库 三、功能介绍 01. 登录页 02. 用户注册 03. 首页 04. 喜欢 05. 查询

银河麒麟操作系统自动同步时间更新

1、银河麒麟操作系统基于Centos8的&#xff0c;因centos8取消了ntp服务器&#xff0c;所以导致之前使用ntpdate命令无法同步时间 2、centos默认使用chrony模块来进行同步时间 3、修改chrony配置同步时间服务器 vim /etc/chrony.conf 4、目前使用的是阿里云的时间服务器&…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(9)模型优化

模型训练后&#xff0c;就要进行模型优化了。 一般来讲&#xff0c;很简单&#xff0c;优化就是不换模型换参数&#xff0c;或者直接换模型。 换了之后来对比&#xff0c;最后选个最好的。 比如在本案例中&#xff0c;选择LinearRegression后&#xff0c;MSE从22下降到12&am…