【大数据存储与处理】

1.任务说明

1.1任务描述

用户画像可以了解用户对哪些类型的短视频感兴趣,推荐用户喜欢的短视频,吸引更多的用户使用。同时可以了解各年龄段或不同性别的用户喜欢类型视频占比情况。要求多线程生成1000万条以上的数据并将数据存入hbase,之后采用hadoop或spark等离线技术处理数据并将结果数据存入redis等NoSQL数据库中,最后可视化展示处理后的结果,能够通过hive实现用户交互式查询。

1.2架构设计

项目整体架构如图所示,总共分为五层,数据来源层、数据存储层、数据处理层、业务层、展示层。数据来源层中,通过python多线程生成数据并将数据保存在多个csv文件中。原始数据存储在定义好的hbase表中,hbase表结构为一个列族有15列。Redis数据库中存储的是处理后的以有序集合形式存储的结果数据。数据处理层中,因为spark处理数据速度相比hadoop来说更好,选用spark sql来处理数据,对数据进行统计。同时选用hive实现交互式查询,对二者进行一个简单的比较。业务层中,需要实现一些榜单等数据的展示以及满足用户通过id交互式查询的需求。展示层中,使用html,css,js来完成前端UI界面的设计,通过ajax向servlet请求数据的方式实现从后端获取数据,也可以选用flask+ajaxphp+ajax获取数据。
项目架构设计图

1.3数据流动图

数据流动图如图所示,生成的原始数据存储在csv文件中,后保存在Hbase表中,通过Spark sql对原始数据处理后将结果数据存储在redis有序集合中,最终将Hive交互式查询结果和Redis有序集合保存的结果数据通过界面展示。
数据流动图

1.4运行环境

hadoop集群,spark集群(不用spark无需配置),tomcat(不使用JavaWeb不用配置)

2.数据生成

2.1 生成数据属性说明

属性类型说明
uidString用户ID,唯一
unameSring用户名
agelnt年龄
genderString性别
aidString作者ID
anameString作者名称
vidString视频ID
typeString视频类型
dateDatetime日期
playInt播放时长
commentInt评论数
likeBool是否点赞
favoriteBool是否收藏
shareBool是否转发
followBool是否关注

2.2 数据生成代码

import datetime
import re
import pandas as pd
import threading
import random
import time
from tqdm import tqdm

# @Author: wzj
# @Time: 2022-03-10    
# @Function: makedata

first_name_array = [
    '赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '楮', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施',
    '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范',
    '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷',
    '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜',
    '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成',
    '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '梁', '杜', '阮', '蓝', '闽', '席', '季', '麻', '强', '贾', '路',
    '娄', '危', '江', '童', '颜', '郭', '梅', '盛', '林', '刁', '锺', '徐', '丘', '骆', '高', '夏', '蔡', '田', '樊', '胡', '凌', '霍', '虞',
    '万', '支', '柯', '昝', '管', '卢', '莫', '经', '房', '裘', '缪', '干', '解', '应', '宗', '丁', '宣', '贲', '邓', '郁', '单', '杭', '洪',
    '包', '诸', '左', '石', '崔', '吉', '钮', '龚', '程', '嵇', '邢', '滑', '裴', '陆', '荣', '翁', '荀', '羊', '於', '惠', '甄', '麹', '家',
    '封', '芮', '羿', '储', '靳', '汲', '邴', '糜', '松', '井', '段', '富', '巫', '乌', '焦', '巴', '弓', '牧', '隗', '山', '谷', '车', '侯',
    '宓', '蓬', '全', '郗', '班', '仰', '秋', '仲', '伊', '宫', '宁', '仇', '栾', '暴', '甘', '斜', '厉', '戎', '祖', '武', '符', '刘', '景',
    '詹', '束', '龙', '叶', '幸', '司', '韶', '郜', '黎', '蓟', '薄', '印', '宿', '白', '怀', '蒲', '邰', '从', '鄂', '索', '咸', '籍', '赖',
    '卓', '蔺', '屠', '蒙', '池', '乔', '阴', '郁', '胥', '能', '苍', '双', '闻', '莘', '党', '翟', '谭', '贡', '劳', '逄', '姬', '申', '扶',
    '堵', '冉', '宰', '郦', '雍', '郤', '璩', '桑', '桂', '濮', '牛', '寿', '通', '边', '扈', '燕', '冀', '郏', '浦', '尚', '农', '温', '别',
    '庄', '晏', '柴', '瞿', '阎', '充', '慕', '连', '茹', '习', '宦', '艾', '鱼', '容', '向', '古', '易', '慎', '戈', '廖', '庾', '终', '暨',
    '居', '衡', '步', '都', '耿', '满', '弘', '匡', '国', '文', '寇', '广', '禄', '阙', '东', '欧', '殳', '沃', '利', '蔚', '越', '夔', '隆',
    '师', '巩', '厍', '聂', '晁', '勾', '敖', '融', '冷', '訾', '辛', '阚', '那', '简', '饶', '空', '曾', '毋', '沙', '乜', '养', '鞠', '须',
    '丰', '巢', '关', '蒯', '相', '查', '后', '荆', '红', '游', '竺', '权', '逑', '盖', '益', '桓', '公', '晋', '楚', '阎', '法', '汝', '鄢',
    '涂', '钦', '岳', '帅', '缑', '亢', '况', '后', '有', '琴', '商', '牟', '佘', '佴', '伯', '赏', '墨', '哈', '谯', '笪', '年', '爱', '阳',
    '佟', '万俟', '司马', '上官', '欧阳', '夏侯', '诸葛', '闻人', '东方', '赫连', '皇甫', '尉迟', '公羊', '澹台', '公冶', '宗政', '濮阳', '淳于', '单于',
    '太叔', '申屠', '公孙', '仲孙', '轩辕', '令狐', '锺离', '宇文', '长孙', '慕容', '鲜于', '闾丘', '司徒', '司空', '丌官', '司寇', '仉', '督', '子车',
    '颛孙', '端木', '巫马', '公西', '漆雕', '乐正', '壤驷', '公良', '拓拔', '夹谷', '宰父', '谷梁', '段干', '百里', '东郭', '南门', '呼延', '归', '海',
    '羊舌', '微生', '梁丘', '左丘', '东门', '西门', '南宫']
last_name_array = [
    '一', '乙', '二', '十', '丁', '厂', '七', '卜', '人', '入', '八', '九', '几', '儿', '了', '力', '乃', '刀', '又', '三',
    '于', '干', '亏', '士', '工', '土', '才', '寸', '下', '大', '丈', '与', '万', '上', '小', '口', '巾', '山', '千', '乞',
    '川', '亿', '个', '勺', '久', '凡', '及', '夕', '丸', '么', '广', '亡', '门', '义', '之', '尸', '弓', '己', '已', '子',
    '卫', '也', '女', '飞', '刃', '习', '叉', '马', '乡', '丰', '王', '井', '开', '夫', '天', '无', '元', '专', '云', '扎',
    '艺', '木', '五', '支', '厅', '不', '太', '犬', '区', '历', '尤', '友', '匹', '车', '巨', '牙', '屯', '比', '互', '切',
    '瓦', '止', '少', '日', '中', '冈', '贝', '内', '水', '见', '午', '牛', '手', '毛', '气', '升', '长', '仁', '什', '片',
    '仆', '化', '仇', '币', '仍', '仅', '斤', '爪', '反', '介', '父', '从', '今', '凶', '分', '乏', '公', '仓', '月', '氏',
    '勿', '欠', '风', '丹', '匀', '乌', '凤', '勾', '文', '六', '方', '火', '为', '斗', '忆', '订', '计', '户', '认', '心',
    '尺', '引', '丑', '巴', '孔', '队', '办', '以', '允', '予', '劝', '双', '书', '幻', '玉', '刊', '示', '末', '未', '击',
    '打', '巧', '正', '扑', '扒', '功', '扔', '去', '甘', '世', '古', '节', '本', '术', '可', '丙', '左', '厉', '右', '石',
    '布', '龙', '平', '灭', '轧', '东', '卡', '北', '占', '业', '旧', '帅', '归', '且', '旦', '目', '叶', '甲', '申', '叮',
    '电', '号', '田', '由', '史', '只', '央', '兄', '叼', '叫', '另', '叨', '叹', '四', '生', '失', '禾', '丘', '付', '仗',
    '代', '仙', '们', '仪', '白', '仔', '他', '斥', '瓜', '乎', '丛', '令', '用', '甩', '印', '乐', '句', '匆', '册', '犯',
    '外', '处', '冬', '鸟', '务', '包', '饥', '主', '市', '立', '闪', '兰', '半', '汁', '汇', '头', '汉', '宁', '穴', '它',
    '讨', '写', '让', '礼', '训', '必', '议', '讯', '记', '永', '司', '尼', '民', '出', '辽', '奶', '奴', '加', '召', '皮',
    '边', '发', '孕', '圣', '对', '台', '矛', '纠', '母', '幼', '丝', '式', '刑', '动', '扛', '寺', '吉', '扣', '考', '托',
    '老', '执', '巩', '圾', '扩', '扫', '地', '扬', '场', '耳', '共', '芒', '亚', '芝', '朽', '朴', '机', '权', '过', '臣',
    '再', '协', '西', '压', '厌', '在', '有', '百', '存', '而', '页', '匠', '夸', '夺', '灰', '达', '列', '死', '成', '夹',
    '轨', '邪', '划', '迈', '毕', '至', '此', '贞', '师', '尘', '尖', '劣', '光', '当', '早', '吐', '吓', '虫', '曲', '团',
    '同', '吊', '吃', '因', '吸', '吗', '屿', '帆', '岁', '回', '岂', '刚', '则', '肉', '网', '年', '朱', '先', '丢', '舌',
    '竹', '迁', '乔', '伟', '传', '乒', '乓', '休', '伍', '伏', '优', '伐', '延', '件', '任', '伤', '价', '份', '华', '仰',
    '仿', '伙', '伪', '自', '血', '向', '似', '后', '行', '舟', '全', '会', '杀', '合', '兆', '企', '众', '爷', '伞', '创',
    '肌', '朵', '杂', '危', '旬', '旨', '负', '各', '名', '多', '争', '色', '壮', '冲', '冰', '庄', '庆', '亦', '刘', '齐',
    '交', '次', '衣', '产', '决', '充', '妄', '闭', '问', '闯', '羊', '并', '关', '米', '灯', '州', '汗', '污', '江', '池',
    '汤', '忙', '兴', '宇', '守', '宅', '字', '安', '讲', '军', '许', '论', '农', '讽', '设', '访', '寻', '那', '迅', '尽',
    '导', '异', '孙', '阵', '阳', '收', '阶', '阴', '防', '奸', '如', '妇', '好', '她', '妈', '戏', '羽', '观', '欢', '买',
    '红', '纤', '级', '约', '纪', '驰', '巡', '寿', '弄', '麦', '形', '进', '戒', '吞', '远', '违', '运', '扶', '抚', '坛',
    '技', '坏', '扰', '拒', '找', '批', '扯', '址', '走', '抄', '坝', '贡', '攻', '赤', '折', '抓', '扮', '抢', '孝', '均',
    '抛', '投', '坟', '抗', '坑', '坊', '抖', '护', '壳', '志', '扭', '块', '声', '把', '报', '却', '劫', '芽', '花', '芹',
    '芬', '苍', '芳', '严', '芦', '劳', '克', '苏', '杆', '杠', '杜', '材', '村', '杏', '极', '李', '杨', '求', '更', '束',
    '豆', '两', '丽', '医', '辰', '励', '否', '还', '歼', '来', '连', '步', '坚', '旱', '盯', '呈', '时', '吴', '助', '县',
    '里', '呆', '园', '旷', '围', '呀', '吨', '足', '邮', '男', '困', '吵', '串', '员', '听', '吩', '吹', '呜', '吧', '吼',
    '别', '岗', '帐', '财', '针', '钉', '告', '我', '乱', '利', '秃', '秀', '私', '每', '兵', '估', '体', '何', '但', '伸',
    '作', '伯', '伶', '佣', '低', '你', '住', '位', '伴', '身', '皂', '佛', '近', '彻', '役', '返', '余', '希', '坐', '谷',
    '妥', '含', '邻', '岔', '肝', '肚', '肠', '龟', '免', '狂', '犹', '角', '删', '条', '卵', '岛', '迎', '饭', '饮', '系',
    '言', '冻', '状', '亩', '况', '床', '库', '疗', '应', '冷', '这', '序', '辛', '弃', '冶', '忘', '闲', '间', '闷', '判',
    '灶', '灿', '弟', '汪', '沙', '汽', '沃', '泛', '沟', '没', '沈', '沉', '怀', '忧', '快', '完', '宋', '宏', '牢', '究',
    '穷', '灾', '良', '证', '启', '评', '补', '初', '社', '识', '诉', '诊', '词', '译', '君', '灵', '即', '层', '尿', '尾',
    '迟', '局', '改', '张', '忌', '际', '陆', '阿', '陈', '阻', '附', '妙', '妖', '妨', '努', '忍', '劲', '鸡', '驱', '纯',
    '纱', '纳', '纲', '驳', '纵', '纷', '纸', '纹', '纺', '驴', '纽', '奉', '玩', '环', '武', '青', '责', '现', '表', '规',
    '抹', '拢', '拔', '拣', '担', '坦', '押', '抽', '拐', '拖', '拍', '者', '顶', '拆', '拥', '抵', '拘', '势', '抱', '垃',
    '拉', '拦', '拌', '幸', '招', '坡', '披', '拨', '择', '抬', '其', '取', '苦', '若', '茂', '苹', '苗', '英', '范', '直',
    '茄', '茎', '茅', '林', '枝', '杯', '柜', '析', '板', '松', '枪', '构', '杰', '述', '枕', '丧', '或', '画', '卧', '事',
    '刺', '枣', '雨', '卖', '矿', '码', '厕', '奔', '奇', '奋', '态', '欧', '垄', '妻', '轰', '顷', '转', '斩', '轮', '软',
    '到', '非', '叔', '肯', '齿', '些', '虎', '虏', '肾', '贤', '尚', '旺', '具', '果', '味', '昆', '国', '昌', '畅', '明',
    '易', '昂', '典', '固', '忠', '咐', '呼', '鸣', '咏', '呢', '岸', '岩', '帖', '罗', '帜', '岭', '凯', '败', '贩', '购',
    '图', '钓', '制', '知', '垂', '牧', '物', '乖', '刮', '秆', '和', '季', '委', '佳', '侍', '供', '使', '例', '版', '侄',
    '侦', '侧', '凭', '侨', '佩', '货', '依', '的', '迫', '质', '欣', '征', '往', '爬', '彼', '径', '所', '舍', '金', '命',
    '斧', '爸', '采', '受', '乳', '贪', '念', '贫', '肤', '肺', '肢', '肿', '胀', '朋', '股', '肥', '服', '胁', '周', '昏',
    '鱼', '兔', '狐', '忽', '狗', '备', '饰', '饱', '饲', '变', '京', '享', '店', '夜', '庙', '府', '底', '剂', '郊', '废',
    '净', '盲', '放', '刻', '育', '闸', '闹', '郑', '券', '卷', '单', '炒', '炊', '炕', '炎', '炉', '沫', '浅', '法', '泄',
    '河', '沾', '泪', '油', '泊', '沿', '泡', '注', '泻', '泳', '泥', '沸', '波', '泼', '泽', '治', '怖', '性', '怕', '怜',
    '怪', '学', '宝', '宗', '定', '宜', '审', '宙', '官', '空', '帘', '实', '试', '郎', '诗', '肩', '房', '诚', '衬', '衫',
    '视', '话', '诞', '询', '该', '详', '建', '肃', '录', '隶', '居', '届', '刷', '屈', '弦', '承', '孟', '孤', '陕', '降',
    '限', '妹', '姑', '姐', '姓', '始', '驾', '参', '艰', '线', '练', '组', '细', '驶', '织', '终', '驻', '驼', '绍', '经',
    '贯', '奏', '春', '帮', '珍', '玻', '毒', '型', '挂', '封', '持', '项', '垮', '挎', '城', '挠', '政', '赴', '赵', '挡',
    '挺', '括', '拴', '拾', '挑', '指', '垫', '挣', '挤', '拼', '挖', '按', '挥', '挪', '某', '甚', '革', '荐', '巷', '带',
    '草', '茧', '茶', '荒', '茫', '荡', '荣', '故', '胡', '南', '药', '标', '枯', '柄', '栋', '相', '查', '柏', '柳', '柱',
    '柿', '栏', '树', '要', '咸', '威', '歪', '研', '砖', '厘', '厚', '砌', '砍', '面', '耐', '耍', '牵', '残', '殃', '轻',
    '鸦', '皆', '背', '战', '点', '临', '览', '竖', '省', '削', '尝', '是', '盼', '眨', '哄', '显', '哑', '冒', '映', '星',
    '昨', '畏', '趴', '胃', '贵', '界', '虹', '虾', '蚁', '思', '蚂', '虽', '品', '咽', '骂', '哗', '咱', '响', '哈', '咬',
    '咳', '哪', '炭', '峡', '罚', '贱', '贴', '骨', '钞', '钟', '钢', '钥', '钩', '卸', '缸', '拜', '看', '矩', '怎', '牲',
    '选', '适', '秒', '香', '种', '秋', '科', '重', '复', '竿', '段', '便', '俩', '贷', '顺', '修', '保', '促', '侮', '俭',
    '俗', '俘', '信', '皇', '泉', '鬼', '侵', '追', '俊', '盾', '待', '律', '很', '须', '叙', '剑', '逃', '食', '盆', '胆',
    '胜', '胞', '胖', '脉', '勉', '狭', '狮', '独', '狡', '狱', '狠', '贸', '怨', '急', '饶', '蚀', '饺', '饼', '弯', '将',
    '奖', '哀', '亭', '亮', '度', '迹', '庭', '疮', '疯', '疫', '疤', '姿', '亲', '音', '帝', '施', '闻', '阀', '阁', '差',
    '养', '美', '姜', '叛', '送', '类', '迷', '前', '首', '逆', '总', '炼', '炸', '炮', '烂', '剃', '洁', '洪', '洒', '浇',
    '浊', '洞', '测', '洗', '活', '派', '洽', '染', '济', '洋', '洲', '浑', '浓', '津', '恒', '恢', '恰', '恼', '恨', '举',
    '觉', '宣', '室', '宫', '宪', '突', '穿', '窃', '客', '冠', '语', '扁', '袄', '祖', '神', '祝', '误', '诱', '说', '诵',
    '垦', '退', '既', '屋', '昼', '费', '陡', '眉', '孩', '除', '险', '院', '娃', '姥', '姨', '姻', '娇', '怒', '架', '贺',
    '盈', '勇', '怠', '柔', '垒', '绑', '绒', '结', '绕', '骄', '绘', '给', '络', '骆', '绝', '绞', '统', '耕', '耗', '艳',
    '泰', '珠', '班', '素', '蚕', '顽', '盏', '匪', '捞', '栽', '捕', '振', '载', '赶', '起', '盐', '捎', '捏', '埋', '捉',
    '捆', '捐', '损', '都', '哲', '逝', '捡', '换', '挽', '热', '恐', '壶', '挨', '耻', '耽', '恭', '莲', '莫', '荷', '获',
    '晋', '恶', '真', '框', '桂', '档', '桐', '株', '桥', '桃', '格', '校', '核', '样', '根', '索', '哥', '速', '逗', '栗',
    '配', '翅', '辱', '唇', '夏', '础', '破', '原', '套', '逐', '烈', '殊', '顾', '轿', '较', '顿', '毙', '致', '柴', '桌',
    '虑', '监', '紧', '党', '晒', '眠', '晓', '鸭', '晃', '晌', '晕', '蚊', '哨', '哭', '恩', '唤', '啊', '唉', '罢', '峰',
    '圆', '贼', '贿', '钱', '钳', '钻', '铁', '铃', '铅', '缺', '氧', '特', '牺', '造', '乘', '敌', '秤', '租', '积', '秧',
    '秩', '称', '秘', '透', '笔', '笑', '笋', '债', '借', '值', '倚', '倾', '倒', '倘', '俱', '倡', '候', '俯', '倍', '倦',
    '健', '臭', '射', '躬', '息', '徒', '徐', '舰', '般', '航', '途', '拿', '爹', '爱', '颂', '翁', '脆', '脂', '胸',
    '胳', '脏', '胶', '脑', '狸', '狼', '逢', '留', '皱', '饿', '恋', '桨', '浆', '衰', '高', '席', '准', '座', '脊', '症',
    '病', '疾', '疼', '疲', '效', '离', '唐', '资', '凉', '站', '剖', '竞', '部', '旁', '旅', '畜', '阅', '羞', '瓶', '拳',
    '粉', '料', '益', '兼', '烤', '烘', '烦', '烧', '烛', '烟', '递', '涛', '浙', '涝', '酒', '涉', '消', '浩', '海', '涂',
    '浴', '浮', '流', '润', '浪', '浸', '涨', '烫', '涌', '悟', '悄', '悔', '悦', '害', '宽', '家', '宵', '宴', '宾', '窄',
    '容', '宰', '案', '请', '朗', '诸', '读', '扇', '袜', '袖', '袍', '被', '祥', '课', '谁', '调', '冤', '谅', '谈', '谊',
    '剥', '恳', '展', '剧', '屑', '弱', '陵', '陶', '陷', '陪', '娱', '娘', '通', '能', '难', '预', '桑', '绢', '绣', '验',
    '继', '球', '理', '捧', '堵', '描', '域', '掩', '捷', '排', '掉', '堆', '推', '掀', '授', '教', '掏', '掠', '培', '接',
    '控', '探', '据', '掘', '职', '基', '著', '勒', '黄', '萌', '萝', '菌', '菜', '萄', '菊', '萍', '菠', '营', '械', '梦',
    '梢', '梅', '检', '梳', '梯', '桶', '救', '副', '票', '戚', '爽', '聋', '袭', '盛', '雪', '辅', '辆', '虚', '雀', '堂',
    '常', '匙', '晨', '睁', '眯', '眼', '悬', '野', '啦', '晚', '啄', '距', '跃', '略', '蛇', '累', '唱', '患', '唯', '崖',
    '崭', '崇', '圈', '铜', '铲', '银', '甜', '梨', '犁', '移', '笨', '笼', '笛', '符', '第', '敏', '做', '袋', '悠', '偿',
    '偶', '偷', '您', '售', '停', '偏', '假', '得', '衔', '盘', '船', '斜', '盒', '鸽', '悉', '欲', '彩', '领', '脚', '脖',
    '脸', '脱', '象', '够', '猜', '猪', '猎', '猫', '猛', '馅', '馆', '凑', '减', '毫', '麻', '痒', '痕', '廊', '康', '庸',
    '鹿', '盗', '章', '竟', '商', '族', '旋', '望', '率', '着', '盖', '粘', '粗', '粒', '断', '剪', '兽', '清', '添', '淋',
    '淹', '渠', '渐', '混', '渔', '淘', '液', '淡', '深', '婆', '梁', '渗', '情', '惜', '惭', '悼', '惧', '惕', '惊', '惨',
    '惯', '寇', '寄', '宿', '窑', '密', '谋', '谎', '祸', '谜', '逮', '敢', '屠', '弹', '随', '蛋', '隆', '隐', '婚', '婶',
    '颈', '绩', '绪', '续', '骑', '绳', '维', '绵', '绸', '绿', '琴', '斑', '替', '款', '堪', '搭', '塔', '越', '趁', '趋',
    '超', '提', '堤', '博', '揭', '喜', '插', '揪', '搜', '煮', '援', '裁', '搁', '搂', '搅', '握', '揉', '斯', '期', '欺',
    '联', '散', '惹', '葬', '葛', '董', '葡', '敬', '葱', '落', '朝', '辜', '葵', '棒', '棋', '植', '森', '椅', '椒', '棵',
    '棍', '棉', '棚', '棕', '惠', '惑', '逼', '厨', '厦', '硬', '确', '雁', '殖', '裂', '雄', '暂', '雅', '辈', '悲', '紫',
    '辉', '敞', '赏', '掌', '晴', '暑', '最', '量', '喷', '晶', '喇', '遇', '喊', '景', '践', '跌', '跑', '遗', '蛙', '蛛',
    '蜓', '喝', '喂', '喘', '喉', '幅', '帽', '赌', '赔', '黑', '铸', '铺', '链', '销', '锁', '锄', '锅', '锈', '锋', '锐',
    '短', '智', '毯', '鹅', '剩', '稍', '程', '稀', '税', '筐', '等', '筑', '策', '筛', '筒', '答', '筋', '筝', '傲', '傅',
    '牌', '堡', '集', '焦', '傍', '储', '奥', '街', '惩', '御', '循', '艇', '舒', '番', '释', '禽', '腊', '脾', '腔', '鲁',
    '猾', '猴', '然', '馋', '装', '蛮', '就', '痛', '童', '阔', '善', '羡', '普', '粪', '尊', '道', '曾', '焰', '港', '湖',
    '渣', '湿', '温', '渴', '滑', '湾', '渡', '游', '滋', '溉', '愤', '慌', '惰', '愧', '愉', '慨', '割', '寒', '富', '窜',
    '窝', '窗', '遍', '裕', '裤', '裙', '谢', '谣', '谦', '属', '屡', '强', '粥', '疏', '隔', '隙', '絮', '嫂', '登', '缎',
    '缓', '编', '骗', '缘', '瑞', '魂', '肆', '摄', '摸', '填', '搏', '塌', '鼓', '摆', '携', '搬', '摇', '搞', '塘', '摊',
    '蒜', '勤', '鹊', '蓝', '墓', '幕', '蓬', '蓄', '蒙', '蒸', '献', '禁', '楚', '想', '槐', '榆', '楼', '概', '赖', '酬',
    '感', '碍', '碑', '碎', '碰', '碗', '碌', '雷', '零', '雾', '雹', '输', '督', '龄', '鉴', '睛', '睡', '睬', '鄙', '愚',
    '暖', '盟', '歇', '暗', '照', '跨', '跳', '跪', '路', '跟', '遣', '蛾', '蜂', '嗓', '置', '罪', '罩', '错', '锡', '锣',
    '锤', '锦', '键', '锯', '矮', '辞', '稠', '愁', '筹', '签', '简', '毁', '舅', '鼠', '催', '傻', '像', '躲', '微', '愈',
    '遥', '腰', '腥', '腹', '腾', '腿', '触', '解', '酱', '痰', '廉', '新', '韵', '意', '粮', '数', '煎', '塑', '慈', '煤',
    '煌', '满', '漠', '源', '滤', '滥', '滔', '溪', '溜', '滚', '滨', '粱', '滩', '慎', '誉', '塞', '谨', '福', '群', '殿',
    '辟', '障', '嫌', '嫁', '叠', '缝', '缠', '静', '碧', '璃', '墙', '撇', '嘉', '摧', '截', '誓', '境', '摘', '摔', '聚',
    '蔽', '慕', '暮', '蔑', '模', '榴', '榜', '榨', '歌', '遭', '酷', '酿', '酸', '磁', '愿', '需', '弊', '裳', '颗', '嗽',
    '蜻', '蜡', '蝇', '蜘', '赚', '锹', '锻', '舞', '稳', '算', '箩', '管', '僚', '鼻', '魄', '貌', '膜', '膊', '膀', '鲜',
    '疑', '馒', '裹', '敲', '豪', '膏', '遮', '腐', '瘦', '辣', '竭', '端', '旗', '精', '歉', '熄', '熔', '漆', '漂', '漫',
    '滴', '演', '漏', '慢', '寨', '赛', '察', '蜜', '谱', '嫩', '翠', '熊', '凳', '骡', '缩', '慧', '撕', '撒', '趣', '趟',
    '撑', '播', '撞', '撤', '增', '聪', '鞋', '蕉', '蔬', '横', '槽', '樱', '橡', '飘', '醋', '醉', '震', '霉', '瞒', '题',
    '暴', '瞎', '影', '踢', '踏', '踩', '踪', '蝶', '蝴', '嘱', '墨', '镇', '靠', '稻', '黎', '稿', '稼', '箱', '箭', '篇',
    '僵', '躺', '僻', '德', '艘', '膝', '膛', '熟', '摩', '颜', '毅', '糊', '遵', '潜', '潮', '懂', '额', '慰', '劈', '操',
    '燕', '薯', '薪', '薄', '颠', '橘', '整', '融', '醒', '餐', '嘴', '蹄', '器', '赠', '默', '镜', '赞', '篮', '邀', '衡',
    '膨', '雕', '磨', '凝', '辨', '辩', '糖', '糕', '燃', '澡', '激', '懒', '壁', '避', '缴', '戴', '擦', '鞠', '藏', '霜',
    '霞', '瞧', '蹈', '螺', '穗', '繁', '辫', '赢', '糟', '糠', '燥', '臂', '翼', '骤', '鞭', '覆', '蹦', '镰', '翻', '鹰',
    '警', '攀', '蹲', '颤', '瓣', '爆', '疆', '壤', '耀', '躁', '嚼', '嚷', '籍', '魔', '灌', '蠢', '霸', '露', '囊', '罐']
first_name_size = first_name_array.__len__() - 200
last_name_size = last_name_array.__len__() - 1499


def fullname():
    """
    获取一个随机名,名的长度1或2
    :return:
    """
    first_name = first_name_array[random.randint(0, first_name_size - 1)]
    last_name = ''.join(
        (last_name_array[random.randint(0, last_name_size - 1)] for _ in range(0, random.randint(1, 2))))
    return first_name + last_name


def user_age():
    """
    随机生成年龄
    0-17占10%,18-30占40%,
    30-45占40%,45及以上占10%
    """
    num = random.randint(0, 9)
    if num == 0:
        age = random.randint(5, 17)
    elif num < 5:
        age = random.randint(18, 30)
    elif num < 9:
        age = random.randint(31, 45)
    else:
        age = random.randint(46, 70)
    return age


def _id():
    """
    获取一个用户id,长度为7位数字
    获取一个视频id,v+7位数字
    :return:9*10*10*10*10
    """
    uid = str(random.choice(range(1, 9))) + \
          ''.join(str(random.choice(range(0, 9))) for _ in range(4))

    aid = str(random.choice(range(1, 9))) + \
          ''.join(str(random.choice(range(0, 9))) for _ in range(4))

    vid = 'v' + str(random.choice(range(1, 9))) + \
          ''.join(str(random.choice(range(0, 9))) for _ in range(5))
    return uid, aid, vid


v_type = ['搞笑类', '明星类', '美食类', '时尚类', '美妆类', '街坊类', '旅游类', '娱乐类', '生活类', '资讯类',
          '亲子类', '知识类', '游戏类', '汽车类', '财经类', '励志类', '萌宠类', '运动类', '音乐类', '二次元类',
          '科技类', '运动健身类', '故事类', '教学类', '才艺类', '技术流', '干货分享类', '视频分享类', '情感类',
          '颜值类', '剧情类', '园艺类', '种草类', '科技数码类', '热点类']


def video_attribute():
    """
    观看一个视频的播放时长,单位为秒
    一个视频的评论数,单位为条
    为一个视频获取其类型,从v_type中随机选择
    :return:
    """
    _type = v_type[random.choice(range(len(v_type)))]
    play = random.randint(1, 120)
    comment = random.randint(0, 10)

    return _type, play, comment


def date():
    """
    在一年中选择随机日期
    :return:
    """
    a1 = (2021, 1, 1, 0, 0, 0, 0, 0, 0)
    a2 = (2021, 12, 31, 23, 59, 59, 0, 0, 0)
    start = time.mktime(a1)
    end = time.mktime(a2)
    t = random.randint(start, end)
    date_tuple = time.localtime(t)
    return time.strftime("%Y-%m-%d %H:%M:%S", date_tuple)


def make_action(i):
    """
    生成数据
    :return:
    """
    _type, play, comment = video_attribute()
    uid, aid, vid = _id()
    action = {'num': i,
              'uid': uid,
              'uname': fullname(),
              'age': user_age(),
              'gender': random.choice(['男', '女']),
              'aid': aid,
              'aname': fullname(),
              'vid': vid,
              'type': _type,
              'date': date(),
              'play': play,
              'comment': comment,
              'like': bool(random.getrandbits(1)),
              'favorite:': bool(random.getrandbits(1)),
              'share': bool(random.getrandbits(1)),
              'follow': bool(random.getrandbits(1)),
              # 'advertisement': bool(random.getrandbits(1))
              }
    return action


def make_file(i):
    filename = "C:/Users/zjs/Desktop/data/" + time.strftime("%Y-%m-%d-%H_%M_%S",
                                                            time.localtime(time.time())) + '_' + str(i) + '.csv'

    dataList = []
    for i in tqdm(range(1000000)):
        dataList.append(make_action(i))

    data = pd.DataFrame(dataList)
    data.to_csv(filename, index=False, sep=',', encoding='utf-8')


def thread_num(num):
    threading.Lock()
    threads = []
    for i in range(num):
        thread = threading.Thread(target=make_file(i + 1), args=(i, 1))
        thread.start()
        threads.append(thread)
    for thread in threads:
        thread.join()


if __name__ == '__main__':
    thread_num(1)

3.数据存储

3.1数据存入Hbase

3.1.1hbase存储设计

上传数据到hbase,需要添加一列rowkey,不然会出现每列数据是原本后一列数据,同时少了一列数据的情况

列族列名说明
infouid用户ID,唯一
infouname用户名
infoage年龄
infogender性别
infoaid作者ID
infoaname作者名称
infovid视频ID
infotype视频类型
infodate日期
infoplay播放时长
infocomment评论数
infolike是否点赞
infofavorite是否收藏
infoshare是否转发
infofollow是否关注

3.1.2数据存入hbase代码

windows本地csv数据上传到hbase有多种方法,这里介绍两种
通过WinSCP软件将Windows本地的csv文件移入到虚拟机中,再通过hdfs命令上传到hdfs中,在hbase中定义好表的结构,再通过hbase函数ImportTsv上传数据到hbase中
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator=“,” -Dimporttsv.columns=HBASE_ROW_KEY,列族:列名,表名 hdfs文件路径

hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="," -Dimporttsv.columns=HBASE_ROW_KEY,info:uid,info:uname,info:age,info:gender,info:aid,info:aname,info:vid,info:type,info:date,info:play,info:comment,info:like,info:favorite,info:share,info:follow data3 /user/root/2022-03-03-11_15_04_1.csv

以下是通过java从本地上传数据到hbase中的代码

import java.io.*;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

/**
 * @author yzg
 * @date 2022-03-10
 */

public class car_hbase {
    public static Connection connection=null;
    public static Admin admin=null;
    // 定义配置对象HBaseConfiguration
    private static Configuration configuration;

    public List<String> getAllTables() {
        List<String> tables = null;
        if (admin != null) {
            try {
                HTableDescriptor[] allTable = admin.listTables();
                if (allTable.length > 0)
                    tables = new ArrayList<String>();
                for (HTableDescriptor hTableDescriptor : allTable) {
                    tables.add(hTableDescriptor.getNameAsString());
                    System.out.println(hTableDescriptor.getNameAsString());
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
        return tables;
    }

    public static boolean isExist(String tableName){
        try {
            return admin.tableExists(TableName.valueOf(tableName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }


    public static void createTable(String tableName,String... columnfamily){
        try {
            if(isExist(tableName)){
                System.out.println("表存在,请输入其他表名");
            }else{
                //2.注意:创建表的话,需要创建一个描述器
                HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));

                //3.创建列族
                for(String cf:columnfamily){
                    htd.addFamily(new HColumnDescriptor(cf));
                }

                //4.创建表
                admin.createTable(htd);
                System.out.println("表已经创建成功!");

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void close(){
        try{
            if(admin!=null){
                admin.close();
            }
            if(connection != null){
                connection.close();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //全表扫描
    public static void scanAll(String tableName){
        try {
            Table t = connection.getTable(TableName.valueOf(tableName));
            //1.实例scan
            Scan s = new Scan();
            //2.拿到Scanner对象
            ResultScanner rs = t.getScanner(s);
            //3.遍历
            for (Result r:rs){
                Cell[] cells = r.rawCells();
                //遍历具体数据
                for (Cell c : cells){
                    System.out.print("行键为:"+Bytes.toString(CellUtil.cloneRow(c))+"  ");
                    System.out.print("列族为:"+Bytes.toString(CellUtil.cloneFamily(c))+"  ");
                    System.out.print("列名为:"+Bytes.toString(CellUtil.cloneQualifier(c))+"  ");
                    System.out.println("值为:"+Bytes.toString(CellUtil.cloneValue(c)));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //csv文件传入hbase      实例:test1.csv
    public static void addRow(String tableName,String rowkey,String cf,String column_1,String value_1,String column_2,String value_2,String column_3,String value_3,String column_4,String value_4,String column_5,String value_5){
        try {
            Table t = connection.getTable(TableName.valueOf(tableName));
            //1.表如果存在,请输入其他表名
            if (!isExist(tableName)) {
                System.out.println("表不存在");
            } else {
                //2.用put方式加入数据
                Put p = new Put(Bytes.toBytes(rowkey));
                //3.加入数据
                p.addColumn(Bytes.toBytes(cf),Bytes.toBytes(column_1),Bytes.toBytes(value_1));
                p.addColumn(Bytes.toBytes(cf),Bytes.toBytes(column_2),Bytes.toBytes(value_2));
                p.addColumn(Bytes.toBytes(cf),Bytes.toBytes(column_3),Bytes.toBytes(value_3));
                p.addColumn(Bytes.toBytes(cf),Bytes.toBytes(column_4),Bytes.toBytes(value_4));
                p.addColumn(Bytes.toBytes(cf),Bytes.toBytes(column_5),Bytes.toBytes(value_5));
                t.put(p);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
        // TODO 自动生成的方法存根
        System.setProperty("hadoop.home.dir", "G:\\idea_had\\hadoop-2.6.5");
        Configuration configuration = HBaseConfiguration.create();
        configuration.set("hbase.rootdir", "hdfs://192.168.128.140:9000/HBase");
        configuration.set("hbase.zookeeper.quorum","master,slave1,slave2,slave3");
        connection= ConnectionFactory.createConnection(configuration);
        admin = connection.getAdmin();
        //创建表
        System.out.println("创建表");
        createTable("car","info");
        //读取csv文件按行  插入hbase
        File csv = new File("C:\\Users\\杨-PC\\Desktop\\大三下\\大数据存储课设\\data\\car.csv");
        InputStreamReader isr = new InputStreamReader(new FileInputStream(csv),"UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line = "";
        List<String> allString = new ArrayList<String>();
        try {
            line = br.readLine();
            while(line != null){
                System.out.println(line);
                String sum[];
                sum = line.split(",");

                addRow("car",sum[0],"info","id",sum[0],"License",sum[1],"type",sum[2],"city",sum[3],"province",sum[4]);

                line = br.readLine();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
//        addRow("test1","101","info","name","20");
        scanAll("car");

        close();
    }
}

4.数据处理

4.1 Maven环境依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>hadoop_1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <scala.version>2.11</scala.version>
        <spark.version>2.1.1</spark.version>
<!--        <hadoop.version>2.7.7</hadoop.version>-->
    </properties>

    <repositories>
        <repository>
            <id>scala-tools.org</id>
            <name>Scala-Tools Maven2 Repository</name>
            <url>http://scala-tools.org/repo-releases</url>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>scala-tools.org</id>
            <name>Scala-Tools Maven2 Repository</name>
            <url>http://scala-tools.org/repo-releases</url>
        </pluginRepository>
    </pluginRepositories>

    <dependencies>
        <!--scala-->
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.11.8</version>
            <!--            <scope>provided</scope>-->
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_${scala.version}</artifactId>
            <version>${spark.version}</version>
            <!--            <scope>provided</scope>-->
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_${scala.version}</artifactId>
            <version>${spark.version}</version>
            <!--            <scope>provided</scope>-->
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.4</version>
            <!--<scope>test</scope>-->
        </dependency>
        <dependency>
            <groupId>org.specs</groupId>
            <artifactId>specs</artifactId>
            <version>1.2.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-reflect</artifactId>
            <version>2.11.8</version>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-compiler</artifactId>
            <version>2.11.8</version>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.11.8</version>
        </dependency>
       <!-- hbase-->
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-common</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!--redis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!--hadoop-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.6.5</version>
            <exclusions>
                <exclusion>
                    <groupId>io.netty</groupId>
                    <artifactId>netty</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc -->
        <!--hive-->
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>1.2.1</version>
        </dependency>

    </dependencies>
    <!--maven-assembly-plugin报红没解决但不影响使用-->
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

4.2数据处理代码

package demo;

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.hbase.client.{HBaseAdmin, HTable}
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor, TableName}
import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.functions.monotonically_increasing_id
import org.apache.spark.sql.{DataFrame, SQLContext}
import org.apache.spark.{SparkConf, SparkContext}
import redis.clients.jedis.{Jedis, JedisPool, JedisPoolConfig}

/**
 * @author zjs
 * @date 2022-03-10
 */

object DataProcess {
  /**
   *连接zookeeper
   * @param quorum ip
   * @param port 端口
   * @param tableName Hbase表
   * @return
   */
  def getHBaseConfiguration(quorum:String, port:String, tableName:String) = {
    val conf = HBaseConfiguration.create()
    conf.set("hbase.zookeeper.quorum",quorum)
    conf.set("hbase.zookeeper.property.clientPort",port)

    conf
  }

  /**
   *连接Hbase
   * @param conf Hbaseconf配置参数
   * @param tableName Hbase表
   * @return
   */
  def getHBaseAdmin(conf:Configuration,tableName:String) = {
    val admin = new HBaseAdmin(conf)
    if (!admin.isTableAvailable(tableName)) {
      val tableDesc = new HTableDescriptor(TableName.valueOf(tableName))
      admin.createTable(tableDesc)
    }

    admin
  }

  /**
   * 获得Hbase表
   * @param conf
   * @param tableName
   * @return
   */
  def getTable(conf:Configuration,tableName:String) = {
    new HTable(conf,tableName)
  }

  /**
   * 将数据以有序集合形式存入redis
   * @param df
   * @param jedis
   * @param key 键值
   */
  def ToRedis(df:DataFrame,jedis:Jedis,key:String) = {
    //将dataframe数据转为列表存储
    val ResultRdd = df.rdd.map(row =>(row.getString(0),row.getInt(1)))
    val result = ResultRdd.collect()
    //遍历存入redis
    for(elem <- result) {
      jedis.zadd(key,elem._2,elem._1)
    }
  }

  /**
   * 榜单数据处理
   */
  def getRank(df:DataFrame,jedis: Jedis) = {
    //计算评论数
    val comment = df.sqlContext.sql("select vid as vid1,int(sum(comment)) as comment from video group by vid order by comment desc limit 10")//.withColumn("comment", col("comment").cast("int"))
    ToRedis(comment,jedis,"comment")
    //计算点赞数
    val like = df.sqlContext.sql("select vid as vid2,int(count(like)) as like from video group by vid order by like desc limit 10")//.withColumn("index",monotonically_increasing_id)
    ToRedis(like,jedis,"like")
    //统计收藏数
    val favorite = df.sqlContext.sql("select vid as vid3,int(count(favorite)) as favorite from video group by vid order by favorite desc limit 10")
    ToRedis(favorite,jedis,"favorite")
    //统计播放量
    val play = df.sqlContext.sql("select vid as vid4,int(count(uname)) as num from video group by vid order by num desc limit 10")
    ToRedis(play,jedis,"play")
    //统计粉丝数
    val fans = df.sqlContext.sql("select aname,int(count(follow)) as follow from video group by aname order by follow desc limit 10")
    ToRedis(fans,jedis,"fans")
  }

  def getDifAgeType(df:DataFrame,jedis: Jedis) = {
    //统计各年龄段用户喜欢视频类型占比情况
    val age_1 = df.sqlContext.sql("select type as type1,int(count(uname)) as num1 from video where age<18 group by type order by num1 desc limit 10").withColumn("index",monotonically_increasing_id)
    val age_2 = df.sqlContext.sql("select type as type2,int(count(uname)) as num2 from video where age between 18 and 30 group by type order by num2 desc limit 10").withColumn("index",monotonically_increasing_id)
    val age_3 = df.sqlContext.sql("select type as type3,int(count(uname)) as num3 from video where age between 31 and 45 group by type order by num3 desc limit 10").withColumn("index",monotonically_increasing_id)
    val age_4 = df.sqlContext.sql("select type as type4,int(count(uname)) as num4 from video where age>45 group by type order by num4 desc limit 10").withColumn("index",monotonically_increasing_id)

    ToRedis(age_1,jedis,"age_1")
    ToRedis(age_2,jedis,"age_2")
    ToRedis(age_3,jedis,"age_3")
    ToRedis(age_4,jedis,"age_4")
  }

  /**
   *统计男性/女性用户喜欢视频类型占比情况
   */
  def getSexType(df:DataFrame,jedis: Jedis) = {
    val male = df.sqlContext.sql("select type as male,int(count(uname)) as num1 from video where gender='男' group by type order by num1 desc limit 10").withColumn("index",monotonically_increasing_id)
    val female = df.sqlContext.sql("select type as female,int(count(uname)) as num2 from video where gender='女' group by type order by num2 desc limit 10").withColumn("index",monotonically_increasing_id)

    ToRedis(male,jedis,"male")
    ToRedis(female,jedis,"female")
  }

  /**
   *统计各年龄段用户喜欢视频类型占比情况
   */
  def getDifAgeNum(df:DataFrame,jedis: Jedis) = {
    val age1 = df.sqlContext.sql("select string(count(uname)) as num1 from video where age<18").withColumn("index",monotonically_increasing_id)
    val age2 = df.sqlContext.sql("select string(count(uname)) as num2 from video where age between 18 and 30").withColumn("index",monotonically_increasing_id)
    val age3 = df.sqlContext.sql("select string(count(uname)) as num3 from video where age between 31 and 45").withColumn("index",monotonically_increasing_id)
    val age4 = df.sqlContext.sql("select string(count(uname)) as num4 from video where age>45").withColumn("index",monotonically_increasing_id)

    val DifAgeNum = age1.join(age2,"index")
      .join(age3,"index")
      .join(age4,"index")

    //将数据存入redis的列表中
    val AgeRdd = DifAgeNum.rdd.map(row=>(row.getString(1),row.getString(2),row.getString(3),row.getString(4))).collect()
    for(row <- AgeRdd) {
      jedis.rpush("DifAgeNum",row._1,row._2,row._3,row._4)
    }
  }

  /**
   *统计每个月的访问流量
   */
  def getStream(df: DataFrame,jedis: Jedis,sqlContext:SQLContext) = {
    val dates = df.sqlContext.sql("select vid,date from video")
    val some = dates.rdd.map(x=>{
      val vid = x.getString(0)
      val time1 = x.getString(1)
      val times = time1.split("/")(1) //取月份

      (vid,times)
    })
    import sqlContext.implicits._
    val df2 = some.toDF("vid","date")
    df2.registerTempTable("MonTime")
    val DifMonNum = df2.sqlContext.sql("select String(date),int(count(vid)) as num from MonTime group by date order by date")//.withColumn("index",monotonically_increasing_id)
    ToRedis(DifMonNum,jedis,"month")
  }

  def main(args: Array[String]): Unit = {
    val startTime = System.currentTimeMillis //获取开始时间
    //参数配置
    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
    val sparkConf = new SparkConf().setAppName("DataProcess").setMaster("local[2]")
    val sc = new SparkContext(sparkConf)
    val sqlContext = new SQLContext(sc)

    val tableName = "data2"
    val quorum = "slave1,slave2,slave3"
    val port = "2181"

    //连接redis
    // 获取连接池配置对象
    val config = new JedisPoolConfig()
    // 设置最大连接数
    config.setMaxTotal(1000);
    // 设置最大的空闲连接数
    config.setMaxIdle(100)
    val pool: JedisPool = new JedisPool(config, "192.168.150.134",6379)
    val jedis: Jedis = pool.getResource


    // 配置相关信息
    val conf = getHBaseConfiguration(quorum,port,tableName)
    conf.set(TableInputFormat.INPUT_TABLE,tableName)

    // HBase数据转成RDD
    val hBaseRDD = sc.newAPIHadoopRDD(conf,classOf[TableInputFormat],
      classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
      classOf[org.apache.hadoop.hbase.client.Result]).cache()

    // RDD数据操作
    //hBaseRDD.foreach(println)
    val data = hBaseRDD.map(x => {
      val result = x._2
      val key = Bytes.toString(result.getRow)
      val uid = Bytes.toString(result.getValue("info".getBytes,"uid".getBytes))
      val uname = Bytes.toString(result.getValue("info".getBytes,"uname".getBytes))
      val age = Bytes.toString(result.getValue("info".getBytes,"age".getBytes))
      val gender = Bytes.toString(result.getValue("info".getBytes,"gender".getBytes))
      val aid = Bytes.toString(result.getValue("info".getBytes,"aid".getBytes))
      val aname = Bytes.toString(result.getValue("info".getBytes,"aname".getBytes))
      val vid = Bytes.toString(result.getValue("info".getBytes,"vid".getBytes))
      val types = Bytes.toString(result.getValue("info".getBytes,"type".getBytes))
      val date = Bytes.toString(result.getValue("info".getBytes,"date".getBytes))
      val play = Bytes.toString(result.getValue("info".getBytes,"play".getBytes))
      val comment = Bytes.toString(result.getValue("info".getBytes,"comment".getBytes))
      val like = Bytes.toString(result.getValue("info".getBytes,"like".getBytes))
      val favorite = Bytes.toString(result.getValue("info".getBytes,"favorite".getBytes))
      val share = Bytes.toString(result.getValue("info".getBytes,"share".getBytes))
      val follow = Bytes.toString(result.getValue("info".getBytes,"follow".getBytes))
      (uid,uname,age,gender,aid,aname,vid,types,date,play,comment,like,favorite,share,follow)
    })

    //RDD转DATAFRAME
    import sqlContext.implicits._
    val df = data.toDF("uid","uname","age","gender","aid","aname","vid","type","date","play","comment","like","favorite","share","follow")
    df.registerTempTable("video")


    //处理函数
    getRank(df,jedis)
    getDifAgeType(df,jedis)
    getSexType(df,jedis)
    getDifAgeNum(df,jedis)
    getStream(df,jedis,sqlContext)

    sc.stop()
    val endTime = System.currentTimeMillis //获取结束时间
    System.out.println("Spark sql查询运行时间: "+(endTime-startTime)+"ms")
  }
}

5.可视化展示

因为可视化代码太多,详情请见界面代码链接
图形界面希望可以帮助到有需要的朋友,也希望大家可以指出文中的错误。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值