ruoyi+Hadoop+hbase实现大数据存储查询

前言

有个现实的需求,数据量可能在100亿条左右。现有的数据库是SQL Server,随着采集的数据不断的填充,查询的效率越来越慢(现有的SQL Server查询已经需要数十秒钟的时间),看看有没有优化的方案。

考虑过SQL Server加索引、分区表、分库分表等方案,但数据量增长太快,还是很快就会遇到瓶颈,因此需要更优化的技术。在众多的NOSQL和大数据技术之下,针对此场景,主要考虑了两种方案:

  1. MongoDB:json文档型数据库,可以通过集群拓展。但更适合列比较复杂的场景快速查询。

  2. Hadoop:大数据领域的瑞士军刀,周边有很多相配套的工具可以使用,后期拓展性较强。

因为此需求只是简单的根据编码找到对应的卷号,因此最终选择Hadoop实现。

部署Hadoop

直接去官方下载,https://hadoop.apache.org/。

要注意版本的问题,版本不匹配会带来很多麻烦。我这里选择的是hadoop 3.3.4的版本。

步骤:

  1. 找到hadoop对应版本的winutils.exe、hadoop.dll文件

复制hadoop 3.3.4版本对应的winutils.exe和hadoop.dll文件到hadoop的bin文件夹下面。同步复制这两个文件,到C:\Windows\System32下面。

这两个文件可以去github上面搜索,一定要注意跟你的hadoop版本一致,否则不通过。

  1. 文件配置(下面的配置文件都在 hadoop 3.3.4/etc/hadoop 文件夹内)

a). hadoop-env.cmd文件配置

set JAVA_HOME=C:\Users\Administrator\.jdks\corretto-11.0.21

注意:这里的JAVA_HOME是指向的openjdk(开源)的版本,oracle的jdk用不起来。必须要安装openjdk。
b). core-site.xml

<configuration>
    <property> 
        <name>fs.defaultFS</name> 
        <value>hdfs://localhost:9000</value> 
    </property>
</configuration>

c). hdfs-site.xml

<configuration>
    <property> 
        <name>dfs.replication</name> 
        <value>1</value> 
    </property> 
    <property> 
        <name>dfs.namenode.name.dir</name> 
        <value>/hadoop-3.3.4/data/namenode</value> 
    </property> 
    <property> 
        <name>dfs.datanode.data.dir</name> 
        <value>/hadoop-3.3.4/data/datanode</value> 
    </property> 
</configuration>

d). yarn-site.xml

<configuration>
    <property> 
        <name>yarn.nodemanager.aux-services</name> 
        <value>mapreduce_shuffle</value> 
    </property> 
    <property> 
        <name>yarn.nodemanager.auservices.mapreduce.shuffle.class</name> 
        <value>org.apache.hadoop.mapred.ShuffleHandler</value> 
    </property> 
</configuration>
  1. 配置环境变量
    在这里插入图片描述
    再添加到Path,%HADOOP_HOME%\bin
    可以在控制台输入:hadoop version,验证是否安装配置正确
    在这里插入图片描述
    最后在控制台输入:start-all.cmd ,启动Hadoop。没有错误信息,表示Hadoop启动成功。
    在这里插入图片描述

部署Hbase

安装Hbase可以到官网下载:https://hbase.apache.org/。

同样要非常关注版本的问题,因为我上面选择的Hadoop是3.3.4,与之配套的Hbase的版本是2.5.5。

步骤:

  1. 将之前下载的winutils.exe和hadoop.dll文件拷贝到 hbase的bin目录下,比如我的:E:\hbase-2.5.5\bin。

  2. 文件配置

在hbase的conf目录下,打开hbase-site.xml文件,添加如下内容:

<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>file:///E:/hbase-2.5.5/root</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>false</value>
  </property>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>127.0.0.1</value>
  </property>
  <property>
    <name>hbase.tmp.dir</name>
    <value>./tmp</value>
  </property>
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>
</configuration>

按照上述的配置说明,在hbase目录下,添加root和tmp文件夹。

3.配置环境变量(此处省略,参考上面的hadoop的截图)

找到hbase的bin目录下的start-hbase.cmd文件,双击启动。

hbase启动完成后的界面:
在这里插入图片描述

基于若依进行二次开发

直接引用ruoyi的项目,在里面添加功能,当然首先需要导入相应的jar包(这些jar包在hadoop和hbase里面都有,直接引用即可)。
在这里插入图片描述
当然下面还有引用的jar包,这里就不截图了,供参考。
在这里插入图片描述
该项目基于SpringBoot框架,实现了基于HDFS、hbase的基础功能。

控制器代码如下:

package com.ruoyi.web.controller.roll;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.roll.RollEntity;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.client.coprocessor.AggregationClient;
import org.apache.hadoop.hbase.client.coprocessor.LongColumnInterpreter;
import org.apache.hadoop.hbase.filter.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.CompareOperator;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.mapreduce.Job;

@Controller
@RequestMapping("/roll")
public class RollController extends BaseController {
    private String prefix = "/roll";

    /**
     * 新增角色
     */
    @GetMapping("/add")
    public String add() {
//        long count = rowCountByCoprocessor("mytb");
//        System.out.println("总记录数->>>"+count + "");
        return prefix + "/add";
    }

    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(String inputEPC) {
//        startPage();
//        List<SysRole> list = roleService.selectRoleList(role);

        //String epc = "E280117020000333BF040B34";
        //String epc = "E280119120006618A51D032D"; //查询的EPC
        String epc = inputEPC;
        String tableName = "mytb";
        String columnFamily = "mycf";

//        create(tableName, columnFamily);
//        insert(tableName,columnFamily);

        long startTime = System.currentTimeMillis();
        //E280119120006BEEA4E5032
        String reVal = query(tableName, columnFamily, epc);
        long endTime = System.currentTimeMillis();
        System.out.println("卷号查询时间为:" + (endTime - startTime) + "ms");
        RollEntity model = new RollEntity();
        model.epc = epc;
        model.rollName = reVal;
        model.searchTime = (endTime - startTime) + "ms";
        List<RollEntity> list = new ArrayList<>();
        list.add(model);
        return getDataTable(list);
    }

    // 创建表
    public static void create(String tableName, String columnFamily) {
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
        conf.set("hbase.zookeeper.quorum", "localhost");
        try {
            Connection conn = ConnectionFactory.createConnection(conf);

            if (conn.getAdmin().tableExists(TableName.valueOf(tableName))) {
                System.err.println("Table exists!");
            } else {
                HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(tableName));
                try {
                    tableDesc.addFamily(new HColumnDescriptor(columnFamily));
                    conn.getAdmin().createTable(tableDesc);
                    System.err.println("Create Table SUCCESS!");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    // 插入数据
    public static void insert(String tableName, String columnFamily) {
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
        conf.set("hbase.zookeeper.quorum", "localhost");
        try {
            Connection conn = ConnectionFactory.createConnection(conf);

            TableName tn = TableName.valueOf(tableName);
            Table table = conn.getTable(tn);
            try {

//                for (int i = 17742000; i <= 100000000; i++) {
//                    Put put = new Put(Bytes.toBytes("row" + i));
//                    put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes("code"),
//                            Bytes.toBytes("E280119120006BEEA4E5032" + i));
//                    table.put(put);
//                }

//                Put put = new Put(Bytes.toBytes("E280119120006618A51D032D"));
//                put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes("code"),
//                            Bytes.toBytes("CQ-230308009"));
//                table.put(put);

                Put put = new Put(Bytes.toBytes("E280117020000333BF040B34"));
                put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes("code"),
                        Bytes.toBytes("CQ-230309002"));
                table.put(put);


                table.close();// 释放资源
                System.err.println("record insert SUCCESS!");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    // 查询
    public static String query(String tableName, String columnFamily, String rowName) {

        String reVal = "";

        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
        conf.set("hbase.zookeeper.quorum", "localhost");
        try {
            Connection conn = ConnectionFactory.createConnection(conf);

            TableName tn = TableName.valueOf(tableName);
            Table table = conn.getTable(tn);
            try {
                Get get = new Get(rowName.getBytes());
                Result r = table.get(get);
                for (Cell cell : r.rawCells()) {
                    String family = new String(CellUtil.cloneFamily(cell));

                    String qualifier = new String(CellUtil.cloneQualifier(cell));
                    String value = new String(CellUtil.cloneValue(cell));
                    System.out.println("列:" + family + ":" + qualifier + " 值:" + value);
                    reVal = value;
                    break;
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                conn.close();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return reVal;
    }

    //过滤查询
    public static void queryFilter(String tableName, String columnFamily, String rowName, String value) {
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
        conf.set("hbase.zookeeper.quorum", "localhost");

        try {
            Connection conn = ConnectionFactory.createConnection(conf);

            TableName tn = TableName.valueOf(tableName);
            Table table = conn.getTable(tn);
            try {
                Scan scan = new Scan();
                Filter filter = new ValueFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes(value)));
                scan.setFilter(filter);
                ResultScanner rs = table.getScanner(scan);
                for (Result res : rs) {
                    System.out.println(res);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //读取HDFS文件
    private static void readHDFSFileContents() {

        InputStream is = null;
        OutputStream os = null;
        BufferedInputStream bufferInput = null;
        BufferedOutputStream bufferOutput = null;
        try {
            is = new URL("hdfs://127.0.0.1:9000/myHadoop/1.txt").openStream();
            bufferInput = new BufferedInputStream(is);
            // IOUtils.copyBytes(is, os, 4096,false);

            byte[] contents = new byte[1024];

            int bytesRead = 0;
            String strFileContents = "";
            while ((bytesRead = is.read(contents)) != -1) {
                strFileContents += new String(contents, 0, bytesRead);
            }
            System.out.println(strFileContents);

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            // IOUtils.closeStream(is);
        }
    }

    //创建HDFS目录
    private static void createHDFSDirectory() {
        // TODO Auto-generated method stub
        try {
            Configuration conf = new Configuration();
            conf.set("fs.defaultFS", "hdfs://127.0.0.1:9000");
            FileSystem fs = FileSystem.get(conf);
            boolean result = fs.mkdirs(new Path("/myHadoop"));
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //查询Hbase有多少条记录
    public long rowCountByCoprocessor(String tablename){
        long count = 0;
        try {
            Configuration conf = HBaseConfiguration.create();
            conf.set("hbase.rootdir", "hdfs://localhost:9000/hbase");
            conf.set("hbase.zookeeper.quorum", "localhost");

            Connection connection = ConnectionFactory.createConnection(conf);
            //提前创建connection和conf
            Admin admin = connection.getAdmin();
            //admin.enableTable(TableName.valueOf("mytb"));
            TableName name=TableName.valueOf(tablename);
            //先disable表,添加协处理器后再enable表
            //admin.disableTable(name);
            HTableDescriptor descriptor = new HTableDescriptor(name); //admin.getTableDescriptor(name);
            //descriptor.setReadOnly(false);
            String coprocessorClass = "org.apache.hadoop.hbase.coprocessor.AggregateImplementation";
            if (! descriptor.hasCoprocessor(coprocessorClass)) {
                descriptor.addCoprocessor(coprocessorClass);
            }
            //admin.modifyTable(name, descriptor);
            //admin.enableTable(name);

            //计时
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();

            Scan scan = new Scan();
            AggregationClient aggregationClient = new AggregationClient(conf);

            //System.out.println("RowCount: " + aggregationClient.rowCount(name, new LongColumnInterpreter(), scan));

            count = aggregationClient.rowCount(name, new LongColumnInterpreter(), scan);
            stopWatch.stop();
            System.out.println("统计耗时:" +stopWatch.getTotalTimeMillis());
            connection.close();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return count;
    }
}

最终效果

在这里插入图片描述

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

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

相关文章

vue中使用echarts实现省市地图绘制,根据数据在地图上显示柱状图信息,增加涟漪特效动画效果

一、实现效果 使用echarts实现省市地图绘制根据数据在地图显示柱状图根据数据显示数据&#xff0c;涟漪效果 二、实现方法 1、安装echarts插件 npm install echarts --save2、获取省市json数据 https://datav.aliyun.com/portal/school/atlas/area_selector 通过 阿里旗下…

(2)(2.2) Lightware SF45/B(350度)

文章目录 前言 1 安装SF45/B 2 连接自动驾驶仪 3 通过地面站进行配置 4 参数说明 前言 Lightware SF45/B 激光雷达(Lightware SF45/B lidar)是一种小型扫描激光雷达&#xff08;重约 50g&#xff09;&#xff0c;扫描度可达 350 度&#xff0c;扫描范围 50m。 1 安装SF45…

老技术告诉你如何选择代理IP以满足数据采集需求

根据IDC发布的大数据行业最新报道显示&#xff0c;目前已经有越来越多的企业将重点放在大数据技术之上&#xff0c;以大数据来进行创新工业互联网的建设&#xff0c;携手央国企共同推进新型工业化。由此可见大数据的重要性。不过具体到每一位技术人员来说&#xff0c;在进行数据…

[读论文][跑代码]BK-SDM: A Lightweight, Fast, and Cheap Version of Stable Diffusion

github: GitHub - Nota-NetsPresso/BK-SDM: A Compressed Stable Diffusion for Efficient Text-to-Image Generation [ICCV23 Demo] [ICML23 Workshop] ICML 2023 Workshop on ES-FoMo 简化方式 蒸馏方式&#xff08;训练Task蒸馏outKD-FeatKD&#xff09; 训练数据集 评测指标…

【赠书第10期】从概念到现实:ChatGPT和Midjourney的设计之旅

文章目录 前言 1 ChatGPT的崛起 2 Midjourney的探索 3 技术创新的交汇 4 对未来的影响 5 结论 6 推荐图书 7 粉丝福利 前言 在过去的几年里&#xff0c;自然语言处理和聊天模型的领域取得了飞速的发展。ChatGPT 作为一个由OpenAI 开发的大型语言模型&#xff0c;以其强…

设计中的经验规则 - 3W规则

设计中的经验规则 - 3W规则 摘要应用 3W 规则还是有很多地方需要注意12 33W规则范围 摘要 PCB板上两条走线截面图&#xff0c;电流通过时产生的辐射。距离比较近 3W 经验规则总体来说&#xff0c;是一条可以放心使用的规则。毕竟传播的电磁场强度与距离的平方成反比&#xff…

VS2017 C++ Qt工程打包软件

在Debug模式下或者Release模式下编译成功&#xff0c;会在工程的Debug文件夹和Release文件夹生成exe执行文件&#xff0c;以Debug为例&#xff0c;将Debug模式下的exe复制到新的文件夹路径下&#xff0c;然后打开Qt中的MSVC 2017 64-bit 打开后然后在命令窗口cd到exe的路径下&…

JDK8新特性

目录 传送门一、Lambda表达式1、概念2、语法基本语法&#xff1a;Lambda简写&#xff1a;Lambda 表达式与匿名内部类区别&#xff1a; 3、案例 二、接口中新增方法1、概念2、默认方法3、静态方法 三、函数式接口1、概念2、函数式接口的由来3、常见的函数式接口 四、方法引用1、…

mongoDB非关系型数据库学习记录

一、简介 1.1Mongodb是什么 MongoDB是一个基于分布式文件存储的数据库,官方地址https://www.mongodb.com/ 1.2数据库是什么 数据库(DataBase)是按照数据结构来组织、存储和管理数据的应用程序 1.3数据库的作用 数据库的主要作用就是管理数据,对数据进行增©、删(d)、…

项目实战之RabbitMQ冗余双写架构

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;项…

YOLOv7全网独家首发改进:SENet v2,Squeeze-Excitation模块融合Dense Layer,效果秒杀SENet

💡💡💡本文自研创新改进:SENet v2,针对SENet主要优化点,提出新颖的多分支Dense Layer,并与Squeeze-Excitation网络模块高效融合,融合增强了网络捕获通道模式和全局知识的能力 推荐指数:五星 收录 YOLOv7原创自研 https://blog.csdn.net/m0_63774211/category_12…

【localhost refused to connect】解决 linux服务器启动 jupyter notebook 后本地浏览器打不开

问题描述 在linux上输入&#xff1a; jupyter notebook 命令后&#xff0c;弹出的火狐浏览器可以打开笔记本&#xff0c;但是复制它给的加密 url 到 Google 或者 Edge 浏览器都出现如下情况&#xff1a; 解决办法 1. 生成 jupyter notebook 配置文件 在 linux 命令行输入如下…

2023年小美赛认证杯A题太阳黑子预测(Sunspot Forecasting)思路模型代码解析

2023年小美赛认证杯A题&#xff1a;太阳黑子预测&#xff08;Sunspot Forecasting&#xff09; 【请电脑打开本文链接&#xff0c;扫描下方名片中二维码&#xff0c;获取更多资料】 一、问题重述 太阳黑子是太阳光球上的现象&#xff0c;呈暂时性斑点&#xff0c;比周围区域…

Xilinx FPGA——ISE的UCF时序约束

时序约束是我们对FPGA设计的要求和期望&#xff0c;例如&#xff0c;我们希望FPGA设计可以工作在多快的时钟频率下等等。 设计是要求系统中的每一个时钟都进行时序约束。 一、分组约束语法&#xff08;NET、PIN、INST&#xff09; TNM是最基本的分组约束语法&#xff0c;其语法…

ubuntu/vscode下的c/c++开发之-CMake语法与练习

Cmake学习 1 语法特性介绍 基本语法格式&#xff1a;指令(参数 1 参数 2...) 参数使用括弧括起参数之间使用空格或分号分开 指令是大小写无关的&#xff0c;参数和变量是大小写相关的 set(HELLO hello.cpp) add_executable(hello main.cpp hello.cpp) ADD_EXECUTABLE(hello ma…

spring-cloud-alibaba 官方版本说明

版本说明 alibaba/spring-cloud-alibaba Wiki GitHub 云原生应用脚手架 构建方式&#xff1a;maven 语言&#xff1a;java springboot 2.7.6 架构&#xff1a;单模块&#xff0c;mvc 架构 下面是脚手架生成。。。。。。。。。。。。。。。。。。。 单模块pom mvc 代码…

关于PFMEA的风险评估都在这里——SunFMEA软件

1、评价严重度 严重度应该独立于发生度和探测度的评价&#xff0c;不能认为发生概率低或者探测能力强&#xff0c;失效就不会到达顾客手中&#xff0c;不会造成糟糕的失效影响&#xff0c;严重度就低。 其实&#xff0c;严重度评估的是已经识别的失效链的严重程度&#xff0c…

Oracle忘记所有密码怎么办

最近遇到一个Oracle的问题&#xff0c;密码要过期了&#xff0c;但是除了用户密码&#xff0c;其他密码都不知道了&#xff0c;修改不了密码怎么办呢&#xff1f; 试了各种方法&#xff0c;最终下面的方式生效了&#xff1a; 首先&#xff0c;使用orapwd生成新的密码文件&…

六、三台主机免密登录和时钟同步

目录 1、免密登录 1.1 为什么要免密登录 1.2 免密 SSH 登录的原理

CSS 在性能优化方面的实践

前言 CSS&#xff08;层叠样式表&#xff09;是一种用于描述网页外观和格式的语言。随着网页变得越来越复杂&#xff0c;CSS文件的大小也随之增加&#xff0c;这可能会对网页性能产生负面 .box {width: 100px;height: 100px;transition: transform 0.3s; }.box:hover {transf…