当前位置: 首页 > 科技观察

用户行为大数据计算

时间:2023-03-19 01:53:19 科技观察

用户行为数据的特点是用户数量多,但每个用户的行为数量少,用户行为的计算比较复杂,用户之间的相关性计算比较小.用户数量巨大。通话记录中的电话号码、访问日志中的用户号码、账户信息中的银行账户、交易记录中的股票账户、保单信息中的参保人等,都是用户行为数据中的用户。用户数量通常非常庞大,高达一亿甚至更多,甚至几百万。每个用户的操作数很少。相对于大量的用户,每个用户的动作通常很小。单个电话号码,平均每月通话记录只有几百条,每年不超过一万条。即使是网站的活跃用户,每天也最多只能产生数百条行为记录,每年也不会超过10万条记录。用户行为的计算比较复杂。计算用户两次登录的间隔天数、重复购买的产品、累计在线时间等,都是对用户行为的计算,通常具有一定的复杂度。用户之间的关联较少计算。用户的行为相对独立,一般可以在不知道其他用户的情况下实现计算。相应地,用户之间的相关性计算也较少,例如:一个人的通话记录中接听电话的一方的通话时长;用户的朋友在社交网站上买了什么产品,这些计算存在但并不多。根据用户行为大数据的特点,不难看出最直观易写的算法可以设计为:一次性将某个用户的所有数据加载到内存中进行计算,而不是反复访问硬盘读取用户的部分数据,也不要同时将大量用户数据加载到内存中。将一个用户的所有数据加载到内存中进行计算。这样做是因为用户之间的相关性计算很少,单个用户行为的计算比较复杂。计算同一用户的数据可以让程序员减少无关数据的干扰。例如,计算用户重复购买的商品。首先,将一个用户的数据按产品分组,汇总每个产品的购买次数;然后按次数倒序排序;过滤掉只购买过一次的产品,剩下的是重复购买的产品和购买次数。另一个例子是计算用户的累计在线时间。用户会多次访问,每次都会形成一对登录和注销,所以先过滤掉所有的登录和注销记录;然后对于每次访问,将登出时间减去登入时间,即为单次时长;多个单一持续时间的总和就是累积持续时间。另外,由于每个用户的行为数量比较少,可以全部加载到内存中进行自由灵活的计算。不要反复访问硬盘读取用户的部分数据。由于用户行为的复杂计算,同一用户的数据之间存在关联。读取某个用户的一些记录进行计算,会使算法难以编写,性能很低。不要同时将大量用户数据加载到内存中。由于用户数量庞大,一次将所有用户数据加载到内存中显然是不可能的,必须分批读取。上面已经分析了批处理的标准:按用户进行批处理。至于用户之间计算结果的合并,可以留到最后一步。由于用户之间的关联计算很少,所以这种合并非常简单。例如,计算所有用户重复购买的商品或累计在线时间,只需要计算每个用户重复购买的商品或累计在线时间,然后将所有用户的计算结果简单合并即可。另外可以看出,由于用户之间的相关性较低,这类算法非常适合并行计算,即给每个节点机分配一定数量的用户,不会增加难度,大大提高表现。将同一用户的所有数据加载到内存中进行计算,这就需要事先将数据按用户分成多组。例如,通过对零售门店会员进行分组,每组为一个会员对应的多条购买记录;或者按用户ID,每组是一个用户对应的网页访问记录。分组的本质是排序,即按用户对数据进行排序,使同一用户的数据相邻。可以想象,对上亿用户、每个用户上万个用户的数据进行排序,将是一个非常缓慢的过程。提前排序可以加快分组过程。数据由用户预先排序,不同的计算目标使用相同的排序数据。排序时间花在前面,而且只花一次,可以避免计算时进行大排序。同一个计算对象不同参数也可以重复计算,不需要重复排序。不同的计算对象也可以保存相同的排序过程。但是,不幸的是,通用的计算工具很难实现上述算法,也不能有效地利用预先排序的数据。比如SQL(包括Hive)和MapRreduce。SQL有困难。SQL集合是无序的,事先按照索引重新插入排序好的数据,往往不能被优化器正确优化,这是非常偶然的,也不能保证在查询时能够按照排序好的顺序查询到需要的数据。Hive具有SQL的语法风格,也支持并行计算,但不适合用户行为的大数据计算。这是因为用户行为的计算比较复杂,需要窗口函数甚至存储过程来解决。但是Hive只支持基本的SQL语法,不支持窗口函数和存储过程。用户行为的计算之所以比较复杂,是因为需要在同一个用户的多条数据之间进行计算,而这个计算大部分是跟顺序相关的。SQL对有序计算的支持有限,只有窗口函数可以实现一些简单的有序计算,但是对于复杂的业务逻辑还是很繁琐的,而且往往会因为大排序导致性能不佳。使用过程化存储过程编写复杂的代码,可以实现复杂的有序计算,但难以复用SQL的集合运算能力。所有处理都必须从基本操作开始写,其性能通常低于SQL。MapReduce的困难。MapReduce支持大数据并行计算,使用过程式JAVA语言编写,类似于存储过程。但是MapReduce使用的JAVA语言缺少结构化数据计算的类库,所有的底层功能都必须自己实现:分组、排序、查询、关联等,更多、更难编写、更难维护。同样,MapReduce不能使用排序后的数据,需要在shuffle阶段进行大排序。SQL和MapReduce不能使用预排序的数据,很难将同一个用户的所有数据加载到内存中进行高性能计算。因此,用户级大数据计算在性能、可扩展性和开发难度上都会遇到挑战。如何利用预排序的数据来简化代码编写,提高计算性能?集算器是一种支持多节点并行计算并提供丰富的顺序计算的编程语言。如果预先对数据进行排序,集算器支持通过游标按组读取数据,每次读取一组数据到内存中,避免了重复的外存访问,整个数据只需要遍历一次,大大提高了效率表现。对于组内的复杂计算,集算器有完善的批量数据计算类库,可以轻松实现各种复杂有序的计算。.集算器支持灵活自由的多节点并行计算,可进一步优化性能。其中一种方法是通过某种方式对用户进行细分,实现分布式存储后的高效并行处理。例如,会员零售数据按照会员号的前两位分为100个Segment存储在HDFS中,每个Segment存储10万个会员的1亿条数据。或者将网站日志按照用户ID首字母和年份进行分段,每段存储百万级用户的数据。或者根据区号和用户数,将通话记录合并成30段,每段存储一个州或几个州的用户。分段处理后,每段数据都经过排序,可以由节点机的一个线程独立处理,并行计算的性能更高。针对以上困难,下面以“每个用户在每个产品上的累计在线时间”为例,说明集算器的一般解决方案。大分组的困难:提前对数据进行排序以用于多个计算目标。在节点机的运行中,可以直接将数据按用户分组,有效利用有序数据,提高性能。群内复杂计算:集算器拥有完善的批量数据计算类库,可以轻松实现各种复杂有序的计算。完整代码如下:原文链接:http://www.36dsj.com/archives/6812