为什么选择 Spring data hadoop

👉 请点赞支持这款 全新设计的脚手架 ,让 Java 再次伟大!

在这里插入图片描述

spring-data-hadoop

hbase 常见的操作方式有以下三种:

Native Api

原生 api 操作繁琐,就像用 JDBC 操作关系型数据库一样,类似 flush、submit、close 的使用让人眼花缭乱。如果碰巧你的应用程序使用 java 开发,那就又多了一条不使用 Native Api 的理由 —— 在问题周围兜一个圈子再解决才是真正的 java 式设计。

Phoenix

apache 提供的 phoenix 提供了 mybatis-like 的支持,帮你「隐藏」了行键的麻烦,还支持在 mapper 文件中像操作关系型数据库一样,直接创建某个字段的索引,以优化大量数据操作时可能产生的性能问题。

这实在是太「夸张」了。在我有限的认知中不记得 Hbase 原生支持这样的功能。尽管我的目的只是「简单的操作 Hbase」,却还是怀着对 phenix 项目的崇敬,下载了相关依赖导入项目中。

可是结果让我失望。hbase-client.jar、hbase-server.jar、phoenix-core .jar 这三者在导入项目后产生了大量的依赖冲突。在我尝试了各种冲突排查手段都无解正焦头烂额时,先哲的一句话将我从泥潭拉了出来:

当你在一件事情上遇到困难时,就放弃这件事。 —— 鲁迅

Spring data hadoop

我的目的毕竟只是「简单的操作 Hbase」。而 spring data 使用 Hbase 所需配置不过一行,还没有讨厌的 checked exception,更不会提供某些「夸张」的功能,最重要的是没有依赖冲突!这些特点深深的打动了我。

如何配置 Spring data hadoop

配置 spring data hadoop 分 3 步。

第一步:导入依赖包。

exclusion 选项最好根据你自己的情况来配置,重点注意 hbase-client 相关的版本一定要使用 1.2.0 以上,不然可能会和项目中既存的 guava 包产生冲突。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-hadoop</artifactId>
    <version>2.5.0.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>1.3.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-x-discovery</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </exclusion>
    </exclusions>
</dependency>

第二步:编写相关配置。

spring 官方文档 Working with HBase 只提供了 xml 配置示例,这让我十分头疼,毕竟不是谁都有心情去看源码的。但考虑到 spring boot 的项目最好还是用 java configuration 为好,所以只好提供一个非官方配置供参考使用。

public class HbaseConfiguration {
    @Bean
    public HbaseTemplate hbaseTemplate() {
        org.apache.hadoop.conf.Configuration configuration = HBaseConfiguration.create();
        configuration.set("hbase.zookeeper.quorum", "address1:port","address2:port");
        return new HbaseTemplate(configuration);
    }
}

第三步:开始运行。

public class HbaseTemplateTest extends BaseTest {

    @Autowired
    private HbaseTemplate hbaseTemplate;

    @Test
    public void hbaseTest() {
        hbaseTemplate.put("zl_test", "lch", "lch", "test", "test2".getBytes());
    }

hbase(main):006:0> scan 'zl_test'
ROW                                          COLUMN+CELL
 lch                                         column=lch:test, timestamp=1556627058655, value=test2
1 row(s) in 0.2910 seconds

hbase(main):007:0>

Row key 怎么办?

如果说放弃 phoenix 带来了什么麻烦的话,那就是我们得自己考虑行键问题了。

如果你的项目属于「用户消费内容」且不涉及「高并发」,那基本上可以跳过这一小节。
如果你的项目属于「用户生成内容」或涉及「高并发」那就要好好考虑行键设计。

为写优化

管理 hbase 数据的最小逻辑单元 region ,是按照 rowkey 字典顺序来进行分区划分的。当频繁写入某些连续字符时,可能会造成同一 region 下写入数据过多的情况。

比如,在一个「用户生成内容」的应用程序中,常常使用时间戳作为 rowkey,这样就可能造成同一时间段内大量数据被写入到一个 region 下,产生热点效应。

为了使我们的写入平均分配到各 region 中,必须对 rowkey 做出一些处理。一个简便的方式便是利用散列算法与集群数量做加盐处理。

Long now = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
String saltedInput = String.format("%s|%s", now.hashCode() % 6, now);
System.out.println(saltedInput);

sout:
4|1556729837940

大功告成,现在 0 ~ 9 会平均分配到不同的 region 分区上,避免了热点效应。

为读(扫描)优化

同样以「在一个用户生成内容的应用程序中使用时间戳作为 rowkey 的情况」作为示例。

为读(扫描)优化意味着你最好把所有的数据尽量放到同一个列族与同一个 region 分区中。
另外,使用倒序时间戳作为 rowkey 也是一个不错的选择。hfile 的有序特性使最新的时间戳数据总是保持在文件起始位,这样在读取操作时就避免了过多的硬盘读,也不需要做额外的排序工作。

到底应该为读还是为写?

回顾上面小节的内容,为写优化意味着在读操作上需要付出相应的代价。现在扫描操作不得不在所有的 region 分区上进行遍历了,这大大增加了 IO 开销。

而为读优化,和为写优化的做法背道而驰,容易造成写入时的热点效应。

是的,读与写无法同时兼顾。为了构建出完整的应用程序你需要做出取舍。

结语

虽然最终选择了使用 spring data 来操作 hbase,但这并不代表其他的方式都不好。每种工具都有自己的特点和不足,结合自己的实际情况做出选择才是最明智的做法。

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

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

相关文章

Windows系统启动MongoDB报错无法连接服务器

文章目录 发现问题解决办法 发现问题 1&#xff09;、先是发现执行 mongo 命令&#xff0c;启动报错&#xff1a; error: MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017&#xff1b; 2&#xff09;、再检查 MongoDB 进程 tasklist | findstr mongo 发现没有进程&a…

【最全基础知识2】机器视觉系统硬件组成之工业相机镜头篇--51camera

机器视觉系统中,工业镜头作为必备的器件之一,须和工业相机搭配。工业镜头是机器视觉系统中不可或缺的重要组成部分,其质量和性能直接影响到整个系统的成像质量和检测精度。 目录 一、基本功能和作用 二、分类 1、按成像方式分 2、按焦距分 3、按接口类型分 4、按应用…

时间序列预测(九)——门控循环单元网络(GRU)

目录 一、GRU结构 二、GRU核心思想 1、更新门&#xff08;Update Gate&#xff09;&#xff1a;决定了当前时刻隐藏状态中旧状态和新候选状态的混合比例。 2、重置门&#xff08;Reset Gate&#xff09;&#xff1a;用于控制前一时刻隐藏状态对当前候选隐藏状态的影响程度。…

STM32实现毫秒级时间同步

提起“时间同步”这个概念&#xff0c;大家可能很陌生。一时间搞不清楚是什么意思。 我理解“时间同步”可以解决多个传感器采集数据不同时的问题&#xff0c;让多个传感器同时采集数据。 打个比方。两个人走路&#xff0c;都是100毫秒走一步&#xff08;频率相同是前提&…

2024数学分析【南昌大学】

计算极限 lim ⁡ n → ∞ 2024 n ( 1 − cos ⁡ 1 n 2 ) n 3 1 + n 2 − n \mathop {\lim }\limits_{n \to \infty } \frac{{\sqrt[n]{{2024}}\left( {1 - \cos \frac{1}{{{n^2}}}} \right){n^3}}}{{\sqrt {1 + {n^2}} - n}} n→∞lim​1+n2 ​−nn2024 ​(1−cosn21​)n3​ …

XJ02、消费金融|消费金融业务模式中的主要主体

根据所持有牌照类型的不同,消费金融服务供给方主要分为商业银行、汽车金融公司、消费金融公司和小贷公司,不同类型机构定位不同、提供消费金融服务与产品类型也各不相同。此外,互联网金融平台也成为中国消费金融业务最重要的参与方之一,虽其并非持牌金融机构,但借助其流量…

React 分装webSocket

背景 AI 实时对话 需要流式数据 React Hooks 写法。新建WebSocket.tsx 放在根目录components import { useCallback, useRef, useState } from react;type MessageHandler (message: MessageEvent) > void; type ErrorHandler (event: Event) > void;export functi…

深度学习(一)基础:神经网络、训练过程与激活函数(1/10)

深度学习基础&#xff1a;神经网络、训练过程与激活函数 引言&#xff1a; 深度学习作为机器学习的一个子领域&#xff0c;近年来在人工智能的发展中扮演了举足轻重的角色。它通过模仿人脑的神经网络结构&#xff0c;使得计算机能够从数据中学习复杂的模式和特征&#xff0c;…

List、Set、数据结构、Collections

一、数据结构 1.1 常用的数据结构 栈 栈&#xff1a;stack,又称堆栈&#xff0c;它是运算受限的线性表&#xff0c;其限制是仅允许在标的一端进行插入和删除操作&#xff0c;不允许在其他任何位置进行添加、查找、删除等操作。 简单的说&#xff1a;采用该结构的集合&#…

【网络协议栈】Tcp协议(下)的可靠性和高效性(超时重传、快速重传、拥塞控制、流量控制)

绪论: 承接上文&#xff0c;上文写到Tcp协议的结构以及对tcp协议的性能优化的滑动窗口&#xff0c;本章我们将继续了解Tcp协议的可靠性和高效性的具体展示。后面我将继续完善网络协议栈的网络层协议敬请期待&#xff01; 话不多说安全带系好&#xff0c;发车啦&#xff08;建议…

【AI绘画】Midjourney进阶:对角线构图详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;什么是构图为什么Midjourney要使用构图 &#x1f4af;对角线构图特点应用场景提示词书写技巧测试 &#x1f4af;小结 &#x1f4af;前言 【AI绘画】Midjourney进阶&a…

Linux常用命令1

切换目录 cd [rootlocalhost menge]# cd /[rootlocalhost /]# cd: cd [-L|[-P [-e]] [-]] [目录] 查看当前的目录 pwd 浏览目录内容 ls ls浏览后颜色表示 白色&#xff1a;普通文件 蓝色&#xff1a;目录 红色&#xff1a;压缩包文件 黄色&#xff1a;设备文件 绿…

以 6502 为例讲讲怎么阅读 CPU 电路图

开篇 你是否曾对 CPU 的工作原理充满好奇&#xff0c;以及简单的晶体管又是如何组成逻辑门&#xff0c;进而构建出复杂的逻辑电路实现&#xff1f;本文将以知名的 6502 CPU 的电路图为例&#xff0c;介绍如何阅读 CPU 电路图&#xff0c;并向你演示如何从晶体管电路还原出逻辑…

.NET Core WebApi第2讲:前后端分离,Restful

动态页面&#xff1a;数据流动 / Web服务器 / Ajax / 前后端分离 / restful风格源栈课堂一起帮https://17bang.ren/Code/261 一、Ajax&#xff1a;页面可以局部刷新 1、PPT演示:使用Ajax也无法减小带宽耗用 请求第一个页面&#xff0c;用AJAX从服务器端加载了一个页头。 请求第…

Maven进阶——坐标、依赖、仓库

目录 1.pomxml文件 2. 坐标 2.1 坐标的概念 2.2 坐标的意义 2.3 坐标的含义 2.4 自己项目的坐标 2.5 第三方项目坐标 3. 依赖 3.1 依赖的意义 3.2 依赖的使用 3.3 第三方依赖的查找方法 3.4 依赖范围 3.5 依赖传递和可选依赖 3.5.1 依赖传递 3.5.2 依赖范围对传…

ollama 在 Linux 环境的安装

ollama 在 Linux 环境的安装 介绍 他的存在在我看来跟 docker 的很是相似&#xff0c;他把市面上已经存在的大语言模型集合在一个仓库中&#xff0c;然后通过 ollama 的方式来管理这些大语言模型 下载 # 可以直接通过 http 的方式吧对应的 shell 脚本下载下来&#xff0c;然…

【10天速通Navigation2】(三) :Cartographer建图算法配置:从仿真到实车,从原理到实现

前言 往期内容&#xff1a; 第一期&#xff1a;【10天速通Navigation2】(一) 框架总览和概念解释第二期&#xff1a;【10天速通Navigation2】(二) &#xff1a;ROS2gazebo阿克曼小车模型搭建-gazebo_ackermann_drive等插件的配置和说明 本教材将贯穿nav2的全部内容&#xff0c…

【Android】Kotlin教程(4)

文章目录 1.field2.计算属性3.主构造函数4.次构造函数5.默认参数6.初始化块7.初始化顺序7.延迟初始化lateinit8.惰性初始化 1.field field 关键字通常与属性的自定义 getter 和 setter 一起使用。当你需要为一个属性提供自定义的行为时&#xff0c;可以使用 field 来访问或设置…

Visual Studio2022 Profile 工具使用

本篇研究下Visual Studio自带的性能分析工具&#xff0c;针对C代码&#xff0c;基于Visual Studio2022 文章目录 CPU使用率检测并发可视化工具使用率视图线程视图内核视图并发可视化工具SDK 参考资料 CPU使用率 对于CPU密集型程序&#xff0c;我们可以通过分析程序的CPU使用率…

【MySQL】MySQL数据库中密码加密和查询的解决方案

本篇博客是为了记录自己在遇到password函数无法生效时的解决方案。通过使用AES_ENCRYPT(str,key)和AES_DECRYPT(str,key)进行加密和解密。 一、问题 自己想创建一个user表&#xff0c;user表中有一个password属性列&#xff0c;自己想对密码进行加密后再存入数据库&#xff0c…