阅读更多

虽然现在最火的是AI,但是大数据和计算能力仍然是机器学习/AI算法的重要支撑,我们的业务场景大部分是通过手机终端、服务器日志不断产生日志数据,通过消息通道发送到大数据平台进行存储、加工和统计,然后在统计数据之上提供算法挖掘用户偏好行为和画像,为此,我们的关键任务是需要从海量数据里统计分析每项产品的去重用户、新增用户、pv、uv、dau(日活)、mau(月活)等指标,这个过程存储占用越少,计算时间越快越好。Fourinone(CoolHash)拥有原创数据库引擎设计能力和知识产权,能够在引擎层面灵活扩充各种功能支持,为了提供大数据统计计算的最优解决方案,4.17在引擎上增强了以下特性:

 

一、增加了自加和存在新增两个原子操作

1、Object putPlus(String key, T plusValue)

如果key对应的value是数字类型(int、long、double、float),自增加plusValue(数字类型),如plusValue=1,表示每次自增1,plusValue也可以是小数。如果key对应的value是字符串类型,自增加plusValue(字符串),会累加到原字符串后面,可以用分隔符隔开。putPlus的返回值为该key的上一个值。

 

2、Object putNx(String key, T value)

如果key存在,则不操作,如不存在写入value。putNx返回值为key操作前值,为null表示不存在,否则返回已有值。

 

利用putPlus和putNx可以完成很多原子操作,如count类计数统计,在开源包指南附带的CountDemo.java里的countTest方法演示了putPlus的使用,在ThreadClient.java的putPlusTest方法和putNxTest方法演示了多线程下的使用。

pvTest方法演示了计算pv,如果id不存在则写入,并将pv数自加1,其他线程发现id存在,则无法更新pv数

Object nx = chc.putNx("v0_"+i, i);

if(nx==null)

chc.putPlus("pv_v0",1);

 

二、增加了客户端本地和存储引擎端强大的bitmap支持

上面通过putPlus和putNx原子操作可以计算pv,但并不是最高效的方案,使用bitmap有两个非常显著的优势:位存储占用空间低,位计算效率高。将需要做统计计算的id转换成数字序号,每个只占1个bit,对于20亿的用户id,只需要20亿bit约238m大小,压缩后占用空间更小,最少只要200k;通过单个bitmap可以完成去重操作,通过多个bitmap的且、或、异或、反等位操作可以完成日活、月活、小时分钟活跃、重度用户、新增用户、用户流向等绝大部分的统计计算,而且能在单机毫秒级完成,真正做到实时计算出结果,同比hadoop/hive离线计算执行“select distinct count…from…groupby join…”类似sql的方式统计,往往需要几百台机器,耗用30分钟才能完成,对比非常悬殊,而且容易形成大量sql任务调度和大表join给集群带来繁重压力。(图)

 

 

 

 

 

1、去重用户:求1的总数

2、活跃用户:取或

bitmap1 | bitmap2

3、非活跃用户:取反:

~bitmap1

4、重度用户:取且:

Bitmap1 & bitmap2

5、新增用户:取或加异或:

(Bitmap1 | bitmap2)^bitmap1

6、多种指标组合:

Bitmap1 & bitmap2 & bitmap3 &…

等等

 

同时提供bitmap本地和引擎端互通实现,能够进行更灵活的架构设计,可以将bitmap压缩存储到任何数据库上,客户端拉回后完成聚合计算,计算完成的结果再写回数据库。也可以多个客户端同时连接到CoolHash存储引擎上,通过引擎的bitmap操作支持完成去重、聚合、解压缩等支持。BitMap结合存储引擎如下图:



 

 

1、本地内存实现,CoolBitSet实现了以下bitmap功能:

CoolBitSet(int maxSize),可指定大小限制,默认1000万大小,本地没有最大限制,可以使用多个分区的bitmap表示整型范围或长整型范围的数据,每个1000万的bitmap压缩后在2m以内,很适合放入kv存储。

(1)基本操作:CoolBitSet提供基本的get(int n)、set(int n)、put(int n)操作,其中put为存在返回get,不存在set,除外还提供批量操作:int set(CoolBitSet cbs): 将另外一个bitmap对象合并到当前bitmap,并返回新增的数量。

(2)聚合操作:求且、求或、异或、求反、求新增

CoolBitSet and(CoolBitSet cbs):两个CoolBitSet求且,更新到当前对象,并返回该对象引用

CoolBitSet or(CoolBitSet cbs):两个CoolBitSet求或,同上

CoolBitSet xor(CoolBitSet cbs):两个CoolBitSet求异或,同上

CoolBitSet andnot():将该CoolBitSet对象求反,同上

CoolBitSet setNew(CoolBitSet cbs):求当前CoolBitSet的新增用户,并返回新增用户结果的对象引用

(3)求总数:int getTotal()返回该CoolBitSet的用户总数,bit位是1的总数量

(4)求容量:int getSize()返回该CoolBitSet的容量大小

(5)调试查看:String toString(int num)返回该CoolBitSet的二进制字符串,为了减少长度,参数num为需要查看的byte数,如num=5表示查看前5个byte的二进制串

 

和java的bitmap的实现区别:jdk自带的BitSet类是以long数组实现,而且只能初始化大小,无法限制大小,每个bitset要耗用几百m的内存,多个bitmap容易造成空间大量浪费,BitSet类只是本地内存实现,没有分布式存储引擎持久化支持。

 

2、引擎端持久化实现,CoolHashClient提供了以下接口用来操作存储引擎:

(1)int putBitSet(String key, int index):

单项操作,类似CoolBitSet的put,第一个参数为bitmap的key,第二个参数将该bitmap的index位置设为1。

(2)boolean getBitSet(String key, int index):

单项操作,类似CoolBitSet的get,第一个参数为bitmap的key,第二个参数需要获取的index位置的值。

(3)int putBitSet(String key, CoolBitSet cbs):

批量操作,类似CoolBitSet的批量set,将另外一个bitmap对象合并到指定key的bitmap,并返回新增的数量。获取CoolBitSet对象仍然使用get接口Object get(String key)

(4)Object putBitSet(String key, CoolBitSet cbs, String logical):

聚合操作,参数logical可以设置为“and”,“or”,“xor”,“andnot”,”new”之一,对于“andnot”,参数cbs并不起作用,可以传入任意不为空的CoolBitSet对象。聚合操作会作用到该key指定的bitmap上,返回值为聚合后的CoolBitSet对象。

 

以上操作遵循CoolHash的k/v存储约束,k为字符串,v不超过2m(可修改默认配置大小)。

注意CoolBitSet对象可以用三种方式进行k/v存储和压缩:

(1)存储为bitSet格式,合并数据:putBitSet(String key, CoolBitSet cbs)

(2)存储为bitSet格式,直接覆盖:put(String key, CoolBitSet cbs)

(3)普通kv存储格式,非bitSet格式:put(String key, cbs.getBytes());

由于是对象存储,三种put方式都会对value数据进行压缩,采用压缩率和耗时比较平衡的gzip压缩。

前两种bitSet格式存储方式,会验证CoolBitSet大小不能超过1亿,否则不能提交。

第三种普通kv存储格式,没有1亿的限制,只要压缩后大小不超过2m,可以正常提交,但由于不是CoolBitSet格式,存储引擎无法识别做聚合等操作。

 

和redis的bitmap的实现区别:redis实现了bitmap的单项操作和聚合操作,但是没有批量操作,也没有压缩,通过offset指定偏移量的方式分配空间容易造成浪费。

 

开源包指南附带CountDemo.java里的演示:

bitSetTest方法:先演示了全量存储,写入10亿数据到1个bitmap,耗时不到1秒;再演示了分区存储,将1亿大小的数据分成10个1000万大小的bitmap存储。

realtimeStatistics方法:演示基于bitmap做用户去重、活跃用户、非活跃用户、重度用户、新增用户等实时计算

retainLocal方法和retainServer方法:分别演示了如何使用本地内存和存储引擎计算用户留存

 

3、增加String类型的bitmap支持:

StringBitMap实现了String类型的bitMap,通过对hash算法的改进,能够做到1亿字符串数据只有200多的碰撞率,5000万内数据几乎没有碰撞率,对于不超过1亿的数据是很合适的,但1亿以上的字符串数量仍然不合适,碰撞率会大幅上升。开源包指南附带CountDemo.java里的stringBitMapTest方法演示了模拟1000万随机生成的15位IMEI设备号,并返回碰撞个数。

 

4.17.10版本同时提供jdk1.8.0_151编译下"fourinone.jar"包和jdk1.7.0_80编译下"fourinone-jdk7.jar"包。4.17.10版本更新github code和gitee code,本版本所有开源内容已经进行了公司报备,感谢领导对开源的支持。

https://github.com/fourinone/fourinone 

https://gitee.com/fourinone/fourinone 

 

0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 详解spring事务失效和回滚失败的场景

    详解spring事务失效的12种场景详解spring事务失效的12种场景前言一 事务不生效1.访问权限问题2. 方法用final修饰3.方法内部调用3.1 新加一个Service方法3.2 在该Service类中注入自己3.3 通过AopContent类4.未被...

  • Spring事务回滚的两种方法

    使用 来配置自动回滚,可以配置在类上,也可以配置在方法上(作用域不同),但对final或private修饰的方法无效,且该类必须是受spring所管控的。 若被配置的方法或类抛出了异常,则事务会被自动回滚,除非你在该...

  • spring事务失效和事务不回滚场景

    读书笔记:担心大佬文章搬家,故整理此学习笔记spring事务底层使用了aop,也就是通过jdk动态代理或者cglib,帮我们生成了代理类,在代理类中实现的事务功能。

  • SpringBoot 事务不回滚的解决方法

    springboot 事务失效的情况和解决方法

  • Hikari整合spring事务不回滚

    今天遇到一个事务不回滚的问题: Service中的A方法,开启了事务注解: 业务是中带有循环然后去查询第三方,然后再插入数据库。出问题的就是一直不回滚,然后各种资料也查了,最后发现不是spring的tx问题,最后发现...

  • spring 内置事务回滚注解

    如果希望无论抛出是 RuntimeException ,还是 Exception,事务都要回滚,请使用如下配置。事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。在取钱这个过程中,用户...

  • Spring @Transactional 事务回滚

    Author 陈秀红 Date 2017/9/30 Spring @Transactional 事务回滚 Spring Transactional 事务回滚一问题描述 二JAVA异常 异常简介 异常架构 ...三事务配置 1如果没有捕获异常事务会回滚 2如果捕获了异常事

  • Spring 事务源码(7)—事务的completeTransactionAfterThrowing回滚、commitTransactionAfterReturning提交以及事务源码总结【一万字】

    基于最新Spring 5.x,详细介绍了Spring 事务源码,包括completeTransactionAfterThrowing尝试回滚事务、commitTransactionAfterReturning尝试提交事务,cleanupTransactionInfo清理事务信息等等方法。

  • Spring事务的传播机制以及手动回滚

    参考: ...wfr=spider&for=pc Spring事务是什么? 一提到事务,我们可能最先想到的就是数据库中的事务。如果MySQL中一个事务中某个操作失败了...而Spring事务和数据库中的事务其实是一样的,也是回滚: Spring事务...

  • SSH spring事务管理不回滚问题

    Spring的事务回滚,当且仅当捕获到RuntimeException类型异常时,才会回滚,对普通Exception异常无效。以下是我Service层捕获异常,并抛出RuntimeException异常到Action层:@Override public void lock(String id) ...

  • Spring中@Transactional事务回滚(含实例详细讲解,附源码)

    为了使用基于@Transactional的事务管理,需要在Spring中进行如下的配置: id = "appTransactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > < property ...

  • SpringBoot异常处理回滚事务详解(自动回滚、手动回滚、部分回滚)

    SpringBoot异常处理回滚事务详解(自动回滚、手动回滚、部分回滚)

  • Spring中@Transactional事务回滚

    Spring中@Transactional事务,默认情况下只对 RuntimeException 回滚。 即: 如果被注解的数据库操作方法中发生了unchecked异常(RuntimeException),所有的数据库操作将rollback; 如果发生的异常是checked...

  • Transaction 事务回滚无效,常见原因!!!

    分析:默认spring事务只在发生未被捕获的 RuntimeException 时才回滚。 spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop...

  • SpringAop学习笔记(二)——Spring事务回滚的原理

    二、Spring 事务失效之谜 一、代码 package com.xiaojie.annotation; import java.lang.annotation.*; /** * 自定义事务注解 */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention...

  • Spring学习笔记三(Spring事务配置)

    Spring的事务配置 这里先举一个例子:A给B转账100,逻辑为 A减少100,B增加100(原本两者都是1000) public void test() { userService.transfer(1, 2, 100.0); } 此时没有开启事务,数据库进行了正常的增加减少...

  • spring 事务回滚

    为了使用基于@Transactional的事务管理,需要在Spring中进行如下的配置: <bean id="appTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  ...

  • 果壳处理器研究小组(Topic基于RISCV64果核处理器的卷积神经网络加速器研究)详细文档+全部资料+优秀项目+源码.zip

    【资源说明】 果壳处理器研究小组(Topic基于RISCV64果核处理器的卷积神经网络加速器研究)详细文档+全部资料+优秀项目+源码.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

  • JSP学生学籍管理系统(源代码+论文+开题报告+外文翻译+答辩PPT)(2024x5).7z

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于计算机科学与技术等相关专业,更为适合;

  • LabVIEW实现NB-IoT通信【LabVIEW物联网实战】

    资源说明:https://blog.csdn.net/m0_38106923/article/details/144637354 一分价钱一分货,项目代码可顺利编译运行~

Global site tag (gtag.js) - Google Analytics