首页 行业资讯 宠物日常 宠物养护 宠物健康 宠物故事
您的当前位置:首页正文

基于Hadoop平台分析用户音乐播放日志的实现

来源:画鸵萌宠网
ComputerSystemNetworkingandTelecommunications

计算机系统网络和电信,2019,1(2)

ISSN:2661-3719(Print);2661-3727(Online)BasedonHadoopPlatformAnalysisUserMusicPlaybackLogImplementation

SipingWANGZhengdeBAOChenxiLISchoolofComputerandSoftware,JinchengCollege,SichuanUniversity,Chengdu,611731Abstract

With the rapid development of big data technology, the application of big data technology to deal with relevant data in enterprises and society has become more and more common. This paper starts from the social development to analyze the demand of Internet music company for data processing, and develops a music log statistics system based on hadoop platform. The system is mainly composed of the log acquisition component and the calculation component. The log data generated in the process of playing music by the user is counted on the basis of year and month. Finally, the results of the calculated components are put into the Database. The system is developed to help enterprises quickly analyze massive logs and improve the low efficiency of traditional database analysis.Key Words

Big Data Technology; Music; Log Analysis; Hadoop PlatformDOI:10.18686/jsjxt.v1i2.692

基于Hadoop平台分析用户音乐播放日志的实现王思平

鲍正德

李晨曦

四川大学锦城学院计算机与软件学院,四川成都,611731摘要

伴随大数据技术的快速发展,使用大数据技术处理相关数据在企业和社会中的应用愈加普遍。本文从社会发展开始分析互联网音乐公司对数据处理的需求,并且开发了一个基于hadoop平台的音乐日志统计系统。该系统主要由日志采集组件和计算组件组成,对用户播放音乐过程中产生的日志数据进行了关于年月为单位的统计。最后把计算组件的结果放入了Database中。该系统开发是为能助力企业快速分析海量日志,改善传统数据库分析方式效率低下的问题。关键字

大数据技术;音乐日志分析;Hadoop平台1.引言

互联网特别是移动互联网的发展,加快了信息化向社会经济各方面、大众日常生活的渗透[1]。人们播放歌曲的方式也在不断地更新,从最初的DVD+音响到MP3+耳机,到现在的智能手机。人们能够随心所欲播放自己想听的歌曲,不用像以前要在电脑上下载或者购买CD等。这些播放方式的改变也推动了在线音乐的蓬勃发展。人们听歌的次数增加,收听音乐的时间也在增长。用户使用Musicsoftware产生的日志数量愈加增多。快速处理并从庞大的数据量中分析出有效的数据结果,能够帮助企业更好的发展。音乐公司可以根据使用次数等信息分析出用户是否是“忠实粉丝”,也可以分析用户的浏览信息等,为用户挖掘出更加与其爱好符合的音乐。本文利用大数据系统分析用户音乐日志,统计了一些用户使用信息。2.用户音乐播放日志系统目标

在大数据分析领域最基础的应用是统计相关数据,这些数据不仅体量巨大而且大部分为非结构化数据,直接利用传统的db数据库存储很难做到,所以要先用Hadoop分析平台对这些数据实行统计,最后将系统计算结果写入进传统Database,减轻数据库的压力。本系259ComputerSystemNetworkingandTelecommunications

计算机系统网络和电信,2019,1(2)

ISSN:2661-3719(Print);2661-3727(Online)统主要实现目标包括(1)统计每位使用者在Musicsoftware中的年度音乐收听次数和年度音乐收听时长;(2)统计每位使用者在Musicsoftware中的月度收听次数和月度收听时长;(3)统计不同歌曲在Musicsoftware中的年度收听频率和年度收听时长。这三个目标是对用户数据的基本分析。有利于音乐公司快速了解每个用户的使用频率和每首歌曲的详细信息。3.用户音乐播放日志系统结构

FlumeKafkaHbaseMysqlMapReduce4.系统功能实现

4.1搭建hadoop高可用集群和安装mysql数据库音乐日志统计系统使用环境:Centos6.8系统。在本系统中建立了多台Hadoop环境节点,分别命名为linux01,linux02,linux03并且这三台linux节点可以相互通信。在集群中一共创建两个NameNode,保证当其中一个NameNode出现错误时,另一个可以接着工作。在分布式集群平台中,每一台服务器可视为分布式环境中的一个节点[2]。运行节点的数量越多,分布式集群平台的运行效率越高[2]。4.2搭建日志采集组件本系统中的日志采集组件是通过Flume+kafka+Hbase组成。Flume是一个非常优秀的日志聚合系统,适合采集分布式系统中零散的日志,且具有高可用、高可靠和可扩展等特性,同时flume接收的数据可以是来自于多样化的、自定义的数据发送方[3]。ApacheKafka是由LinkedIn公司开发一种分布式的发布-订阅消息系统,是一种快速的、可扩展的、分布式的、分区的和可复制的提交日志服务机制[4]。Kafka核心组件有Producer、Consumer、Topic(可扩展性高)。kafka在企业开发中常常被用于消息中间件用途广泛,起一个缓冲数据和应对突发高流量的情况。日志采集组件使用Flume+kafka来缓冲和拉取数据,并且将数据写入到HBase中。HBase使用HDFS作为底层文件存储系统[5],本组件中用于存储音乐日志中的结构化信息。Hbase能够在低延时情况下稳定地存储大量结构化数据,适合于本组件的搭建需求。将Flume,kafka,Hbase的安装包分别上传到三台linux服务器上并解压。(1)创建music.conf用于运行Flume时指定其sources,sinks等运行信息。配置文件部分如下#definea1.sources=r1a1.sinks=k1a1.channels=c1#sourcea1.sources.r1.type=execa1.sources.r1.command/home/wangzi/music/log.csva1.sources.r1.shell=/bin/bash-c#sinka1.sinks.k1.typeorg.apache.flume.sink.kafka.KafkaSinka1.sinks.k1.brokerListlinux01:9092,linux02:9092,linux03:9092a1.sinks.k1.topic=musica1.sinks.k1.batchSize=20260=tail-F-c+0==a1.sinks.k1.requiredAcks=1(2)更改kafka的conf文件。更改三台服务器上的broker.id,保证彼此不重复,并且修改日志存储的地方。(3)原始的日志文件173azc31,2003-06-09,15,2018-10-0309:52:06,0355(举例)分别是用户id,用户生日,对应的音乐id,歌曲时间,歌曲时长。(本数据是由代码生成的测试数据,非企业实际生产数据)在该组件中需要通过Javaapi从kafka中获取数据并且在Hbase中创建表,且写入到表中。在Hbase表设计中采用了预分区键对Hbase存储进行优化,对于Hbase而言,若使用者不预先对表进行分区操作,则数据将会全部被放入到创建表时的region中,当这个预先创建的region记录的列过多时,Hbase将采取主动将region进行split的措施从而避免分区表过大,然而这个过程将消耗大量节点资源。所以需要在Hbase中建立预先分区的存储表,提高Hbase的读写能力。在music:some(创建的表名称)中一共预设立了10个分区,分区号规则是按用户出生的年数值取余运算获得分区号。该分区规则有利于将用户数据均匀地存储在创建的10个region中。(4)在该表的RowKey设计中是通过拼接分区号,用户id,用户年龄,音乐id,播放时间,播放时长组成的。部分HbaseInfo类(预分区键,rowkey)代码如下。//获取预分区号publicstaticStringgetSplitNum(intregion,Stringage){StringyearAge=age.substring(0,4);IntegeryearAge_int=Integer.valueOf(yearAge);intnum=(yearAge_int%(region+1))-1;returnString.valueOf(num);}//拼接rowkey9_173azc33_1999-01-15_20_2018-01-2114:18:16_0211publicstaticStringgetRowKey(StringgetSplitNum,StringuId,StringuAge,StringmId,StringplayTime,StringplayDuration){returngetSplitNum+\"_\"+uId+\"_\"+uAge+\"_\"+mId+\"_\"+playTime+\"_\"+playDuration;}ComputerSystemNetworkingandTelecommunications

计算机系统网络和电信,2019,1(2)

ISSN:2661-3719(Print);2661-3727(Online)(5)在日志组件中通过kafka_cosumer.class拉取kafka生产者中的数据并且写入到Hbase表中。kafka_cosumer类部分代码如下while(true){//不断拉取数据ConsumerRecordspollInfo=kc.poll(10);for(ConsumerRecordrecord:pollInfo){hbaseStart.put_data(record.value());}4.3搭建目标1和目标2的MapReduce计算组件并写入到mysql表中(1)在msyq表中创建user和user_music表分别用于存储mapreduce计算出的年度信息和月度信息。(2)在本组件中一共创建了两个类userMusicInfo和countValue来封装传入和传出的字段。部分代码如下publicclassuserMusicInfoimplementsWritableComparable{privateStringuserId;privateStringuAge;privateStringuName;privateStringplayTime_year;privateStringplayTime_month;publicclasscountValueimplementsWritableComparable{privateintcount;privateintplayDuration;(3)编写MapTask工作阶段。创建user_Mapper类继承TableMapper类并且重写map方法,key中获取从hbase读的每列数据,并且进行切割,然后将这些值封装在userMusicInfo对象中,将该对象作为map的KEYOUT,reduce的KEYIN。将播放时长作为值封装在Text类中,作为map的VALUEOUT。map方法中部分源码如下Textval=newText();val.set(playDuration);//播放时长userMusicInfoInfo1=newuserMusicInfo();//按年算Info1.setUserId(userId);Info1.setuAge(uAge);Info1.setuName(uName);Info1.setPlayTime_year(playTime_year);Info1.setPlayTime_month(\"year\");context.write(Info1,val);261userMusicInfoinfo2=newuserMusicInfo();//按月算info2.setUserId(userId);info2.setuAge(uAge);info2.setuName(uName);info2.setPlayTime_year(playTime_year);info2.setPlayTime_month(playTime_month);context.write(info2,val);(4)ReduceTask任务准备阶段。重写reduce方法,从VALUEIN(Text类)中获取播放时长,循环累加,并且定义一个计数变量用于累加用户播放音乐次数。reducer阶段部分源代码如下countValuecValue=newcountValue();intcount=0;intpD=0;for(Texttext:values){count++;pD=pD+Integer.valueOf(text.toString());}cValue.setCount(count);cValue.setPlayDuration(pD);context.write(key,cValue);(5)自定义OutputFormat类并且判断年度信息和月度信息。在该mapreduce中需要输出到多张mysql表中,所以采用自定义OutputFormat类的模式重写数据输出的格式和目的地。创建mysqlRW类继承RecordWriter类并且重写write方法,这是将计算结果写入mysql中的核心方法。通过比较playTime_month字段来判断是年度信息还是月度信息,如果playTime_month字段值是”year”,则执行插入年度信息的sql语句,否则执行插入月度信息的sql语句。write方法部分源代码如下//说明只带年份不带月份if(playTime_month.equals(\"-1\")){primary_key=userId+age+name+playTime_year;try{ps=connection.prepareStatement(\"insertintouservalues(?,?,?,?,?,?,?)\");ps.setString(1,primary_key);ps.setString(2,userId);ps.setString(3,age);ps.setString(4,name);ps.setString(5,playTime_year);ps.setInt(6,count);ps.setInt(7,playDuration);ps.executeUpdate();ps.close();}catch(SQLExceptione){e.printStackTrace();}}else{ComputerSystemNetworkingandTelecommunications

计算机系统网络和电信,2019,1(2)

ISSN:2661-3719(Print);2661-3727(Online)primary_key=userId+playTime_year+playTime_month;//说明既带年份,也带月份try{ps=connection.prepareStatement(\"insertintouser_musicvalues(?,?,?,?,?,?)\");ps.setString(1,primary_key);ps.setString(2,userId);ps.setString(3,playTime_year);ps.setString(4,playTime_month);ps.setInt(5,count);ps.setInt(6,playDuration);ps.executeUpdate();ps.close();}catch(SQLExceptione){e.printStackTrace();}}4.4实现目标3的MapReduce计算组件并写入到mysql表中(1)创建mysql表。创建musicInfo表,创建mId,mName,count,playDuration四个字段。(2)创建musicBean类。因为本组件只需输出到一张sql表中,所以采用hadoop自带的DBWritable组件用于封装bean数据。musicBean类继承了WritableComparable和DBWritable类,封装了mId,mName,count,playDuration四个字段,分别代表音乐id,音乐名称,播放次数,播放时长。部分musicBean类源代码如下publicclassmusicBeanimplementsWritableComparable,DBWritable{privateStringmId;privateStringmName;privateintcount;privateintplayDuration;(3)MapTask任务准备阶段。创建musicMapper类继承TableMapper类便于从hbase中获取数据,将map方法中的key切割,获得音乐id和其他属性。在类中定义名为musicInfo的HashMap集合,存储音乐id和音乐名称,并且通过音乐id映射音乐名称。部分musicInfo类源代码如下Textval=newText();//拼接键musicBeanmusicBean=newmusicBean();musicBean.setmId(mId);musicBean.setmName(mName);musicBean.setCount(0);musicBean.setPlayDuration(0);val.set(playDuration);//拼接value262ComputerSystemNetworkingandTelecommunications

计算机系统网络和电信,2019,1(2)

ISSN:2661-3719(Print);2661-3727(Online)context.write(musicBean,val);(4)ReduceTask任务准备阶段。在本组件中将全部字段信息封装在musicBean,所以VALUEOUT不需要信息,VALUEOUT用NullWritable类代替部分reducer阶段源代码如下intcount=0;intpD=0;for(Textvalue:values){++count;pD=pD+Integer.valueOf(value.toString());};key.setCount(count);key.setPlayDuration(pD);context.write(key,NullWritable.get());(5)组合map和reduce的任务驱动类。新建musicDriver并且实现Tool接口,重写run方法,便于后续ToolRunner调用musicDriver中的run方法。Hadoop框架通过调用该类找到各阶段功能实现所需的正确的类。部分musicDriver类源代码如下DBConfiguration.configureDB(conf,\"com.mysql.jdbc.Driver\\"jdbc:mysql://192.168.75.10:3306/music\\"music\\"music123456\");JobScanjobscan=Job.getInstance(conf);=newjob.setJarByClass(musicDriver.class);Scan();scan.addFamily(Bytes.toBytes(\"f1\"));//设置Mapper相应属性TableMapReduceUtil.initTableMapperJob(\"music:some\can,musicMapper.class,musicBean.class,Text.class,job);//设置reduce的类job.setReducerClass(musicReducer.class);job.setOutputFormatClass(DBOutputFormat.class);//设置输出格式job.setOutputKeyClass(musicBean.class);job.setOutputValueClass(NullWritable.class);DBOutputFormat.setOutput(job,\"musicInfo\me\5.测试验证

经过建立分析平台,调用日志采集组件,以及运行计算组件代码,查看数据库对应的表数据生成。user表primary_key173azc011999-01-01tom2018173azc011999-01-01tom2019173azc022002-02-21lili2018userId173azc01173azc01173azc02age1999-01-011999-01-012002-02-21user_music表primary_key173azc01201801173azc01201802173azc01201803userId173azc01173azc01173azc01playTime_year201820182018musicinfo表mId11mName卡拉永远OK.mp3count181playDuration47733playTime_month010203count245playDuration55910771361nametomtomliliplayTime_year201820192018count615952playDuration1714516210134532636.总结与展望

本文联系音乐公司在数据分析领域的具体问题。分析了传统数据统计方式的弊端和音乐日志分析平台的架构,并且实现了具有多个部件音乐日志统计系统。扩展了音乐企业对用户数据分析的方式。通过测试验证,该系统能够对大量用户音乐日志做有效的数据统计,提高数据分析的效率。由于本系统只是将统计结果写进mysql数据库中,未展示数据图表,后续进一步研究工作将围绕数据可视化展开。参考文献

[1]邬贺铨.大数据时代的机遇与挑战[J].求是,2013(04):47-49[2]郑文青.基于hadoop的大数据分布式集群平台搭建的研究[J].计算机产品与流通,2017(12):143.ComputerSystemNetworkingandTelecommunications

计算机系统网络和电信,2019,1(2)

ISSN:2661-3719(Print);2661-3727(Online)[3]蒲志明.云平台中日志管理模块的研究与实现[D].电子科技大学,2017.[4]张海华,杨秀波,张非,钟磊.基于Kafka的在线教学平台事件中心设计与实现[J].数字通信世界,2019(02):117-118+129.[5]康毅.HBase大对象存储方案的设计与实现[D].南京大学,2013.作者简介第一作者:王思平(1999-),男,汉,四川省内江市,本科,四川大学锦城学院,研究方向:J2EE和大数据。第二作者(通讯作者):鲍正德(1989-),男,汉,黑龙江哈尔滨,研究生,四川大学锦城学院,研究方向:电子商务。第三作者:李晨曦(1998-7),男,汉,贵州贵阳,本科,四川大学锦城学院,研究方向:大数据技术开发264

因篇幅问题不能全部显示,请点此查看更多更全内容