美文网首页我爱编程
HBase(单机win10+WSL、集群独立安装)

HBase(单机win10+WSL、集群独立安装)

作者: Queen〇fLaponia | 来源:发表于2018-07-03 16:33 被阅读0次

      HBase的分区Region/RegionServer 设计与 Akka的分片 Region/ShardRegion 设计类似、其Master也和Akka中出现的Master类似都是轻量级主。在数据的分布上差异较大,Akka和Cassandra一样都是基于consistent hash,而HBase是完全按照rowKey字典序划分范围也就是Region,再将这些Region分布到各个RS(RegionServer)上去。Akka persistence enables stateful actors to persist their state so that it can be recovered when an actor is either restarted, such as after a JVM crash, by a supervisor or a manual stop-start, or migrated within a cluster. — Akka persistence的最佳选择是Cassandra、其次才是HBase,持久化可以令有状态actor实体持久化自身状态,以便可以从崩溃当中(JVM Crash导致的监管重启、或者手动重启、再或者是在集群的再平衡迁移导致)做状态恢复。

      阿里的HBase

      编译HBase官方架构文档

    简单粗暴

      HBase是兼具列式存储、键值存储特性的NoSQL.  和传统RDB比较来说,它的列族更像RDB的表,而它的表更像RDB的表空间,因为即使属于同一张表,不同列族都是互相独立的,属性设置、物理存储位置都可以完全不同,和和传统RDB正相反,HBase中的表和行变成了最不重要的纯逻辑概念,而列族和rowKey才是最重要的,你查询得到的一行数据之所以成为一行,仅仅是因为这几个列的rowKey相同而已。最佳定义:“HBase is a sparse, distributed, persistent multidimensional sorted map. The map is indexed by a row key, column key, and a timestamp; each value in the map is an uninterpreted array of bytes.”

      技术上来说,HBase更像是"Data Store" 而不是 "Data Base",因为HBase不具备喜大普奔的RDBMS特性如typed columns、 secondary indexes、 triggers、事务以及SQL,  但是,HBase具备一身Scale-Out横练功夫,HBase集群可以添加商(便)用(宜)Server扩展,如果集群从10台扩展到20台RS那么存储翻倍、系统的数据处理容量也翻倍。

    HBase关键features

    一、自动化

    1、自动分区Automatic sharding:HBase表跨region存储于集群,随着数据增长,region自动split、自动re-distributed;

    2、自动容错:自动化的RS失效处理;分区和容错概念早已有之,NoSQL的一大贡献是使之自动化。

    二、数据不变

      NoSQL最大特性当属数据不变(HBase basically never overwrites data but only appends.),也就是数据不会就地修改(当已达到最大版本号时, 超出限量版本的老数据在合并时会被丢弃),凡是有讲append就是在说数据不变了比如Kafka、AkkaPersistence对流式事件数据存储到日志的架构同样是appending to storage (nothing is ever mutated) which allows for very high transaction rates and efficient replication.  Akka对流式/时序数据称为events即事实数据,存储目标为journal日志/流水账。数据不变带来两个巨大好处:

    1、避免分布式事务,这是成本很高的老大难问题,要支持则达不到大数据吞吐量。到了NoSQL时代,解决这个问题的办法就是让问题消失、最高明的解决方案就是让问题消失、无需解决,数据不变仅append、消灭分布式事务代表消灭了相关的锁和同步远程方法调用,这与Scala等函数式语言的immutable何其相似。

    2、磁盘连续存,这样就可以支持性能很高的连续读,由于现代OS的预读优化,读取在磁盘上连续存储的数据时,有统计表明性能高于直读内存。

      HBase相比Hive的突出优点是还支持删改,改靠version版本号、删靠打标记,之后在major compact时真正删除。RDB说你这有一点workaround了,HBase说没错,因为哥的格局就不在这里,哥的征途是云大物移。 其实“不约而同”选择数据不变的还有Cassandra及Kafka.  聪明如你应可体会,数据不变是一把屠龙刀,所斩杀的龙叫做数据共享,这把宝刀函数式语言和HBase都有用。A cell is a combination of row, column family, and column qualifier, and contains a value and a timestamp, which represents the value’s version. 版本号就是时间戳。

    函数式的数据不变,巧合?

      传统小内存当中数据存放需要精打细算,不允许一点冗余,数据共享是直觉选择,随之而来的并发冲突也就成了必然,但其实所有的必然不过都是历史的局限。随着多核时代到来,大内存也来了,上百G内存已很常见,有个类比,当前再去讲究几个KB的节省无异于买了几万块的东西再去讲价几分钱,已经没有意义了。以Scala为代表的的函数式数据不变避免了内存中数据共享的问题;以HBase为代表的NoSQL/大数据技术栈的数据不变避免了磁盘中数据共享的问题,这是语言和存储两个不同领域为应对大数据殊途同归的选择,它们这样选择的目的都是为了对付数据共享这只难缠的恶龙。Scala语言集合库优先不可变,对于javaer可以从String入手理解,Scala集合库在底层通过共享对象降低了生成新对象的成本,为此Scala去掉了基本类型:Byte、Char、Short、Int、Long、Float、Double、Boolean全是高级类型,scala里敲一个2这就是实实在在的对象:

    Scala的集合是一种“面向对象的数据结构”

      类似Akka Sharding,HBase的数据分片以Region分区表示,Regions分区是表分布存储到集群以及分布式访问的基本单元,它由每个Column Family列族的具体Store组成,对象层次图:

    Table                    (HBase table)                ——抽象层

      Region               (Regions for the table)   ——逻辑层

         ColumnFamily   —— 列族:列式存储层

             StoreFile        —— 物理存储层、你在HDFS实实在在能看到的存储文件,一个StoreFile属于一个列族、一个列族则可能不止一个StoreFile;StoreFile与MemStore平级、一个在磁盘一个在内存、MemStore满了flush到StoreFile、后台compact以StoreFile为单位进行。

                 Block    (Blocks within a StoreFile within a Store for each Region for the table) — HDFS存储层

      如果说HBase是列式存储,那么这个“列式”指的不是列Qualifier而是CF列族,如果你有abc和xyz六列,但是abc和xyz不相关即肯定不会在一起被查询分析,那就可以划分abc是一个列族xyz是另一个列族。这种存储层次在HDFS查看(default空间)可能是这样:

        /hbase/data/default/表/1d843dd20917ce8408b4032908f7f390/列族/storeFile

      1d843dd20917ce8408b4032908f7f390是region的ID,在每一个CF列族到每一个StoreFile级别,都独立存储rowKey、MemStore也存,可见rowKey从硬盘到内存是大量冗余存在的,所以HBase的rowKey不要设计的太长上升为设计注意事项的高度。HBase的regions,具备一定大小(每个在5-20Gb)之后,最好是在每台节点机保持20-200个,不要过多了。

    什么时候可以用HBase

      HBase并不适用于所有问题:首先,你得有足够多的数据需要处理,如果只有几百万行数据,RDBMS就够用了,用HBase的话可能造成你的数据只存在一两个节点上,集群其余节点机全都空闲浪费了,少量数据即使不是关系型,存MySQL+主键,够了;第二,你不是必须要用到RDBMS的一些特性  e.g.  typed columns, secondary indexes, transactions, advanced query languages, etc. 说白了就是你存的数据是不是强关系型。第三,你得有足够多的硬件,比如HDFS在默认三备份情况下、少于5个DataNodes节点就不太好了,还得外加一个NameNode节点。

      第四,HBase的底层存储HDFS分布式文件系统并不是一个通用文件系统,它只特别适合于大文件存储,不适合在文件中查找内容(也就不适合删除修改单条数据),HBase在HDFS之上支持快速的数据记录的查找和更新(以append形式追加小文件StoreFiles、但最终合并compact为大文件,合并期间旧数据真正删除)

      这是一篇不错的博客

      Rowkey加盐问题:“如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个RS实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个RS上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RS,降低查询效率。” —— 这些只是通用化的提示,实际当中还是需要根据你的场景、结合具体情况去考虑,注重性能的少量几个字段条件查询可以结合phoenix、要丰富图表的时序数据存储可以考虑OpenTSDB.

      rowKey如果设计为递增数值,则能在按给定行键起止范围读取相关/相近数据时提供最佳性能,但同时会在大并发写数据时造成热点:writing records with sequential row keys allows the most efficient reading of data range given the start and stop keys, it causes undesirable RegionServer hotspotting at write time.  这便是HBase RS热点问题:RegionServer hotspotting.  它会造成写热点:

    随着Region分裂迁移、写负载热点也在迁移,但总是集中在一台节点机
      平均分布的理想写负载

    目录表

      目录表hbase:meta就是一个普通HBase表,虽然在HBase shel 的list命令中会被滤掉,但它和其他HBase表一样,它记录系统所有regions,我们甚至可以用它来学习如何设计rowKey,hbase:meta表结构如下:

    1、分区键Regionkey作为rowKey,它的格式: ([table],[region start key],[region id]) 从这里可以看出HBase怎么定位一个分区:属于哪个表 + 起始数据记录rowKey + 分区ID;HBase的表下会有诺干个Region,Region存储在某一个节点机上,由节点机上的RS管理;对目录表的查询与时间无关所以我们看到分区键并不包含时间,查询肯定会指定查询的表和数据记录的rowKey/或其范围。

    2、Values是访问该分区所需的所有信息:

      1) info:regioninfo (serialized HRegionInfo instance for this region) 分区信息

      2) info:server (server:port of the RegionServer containing this region) 分区所在的RS地址信息,RS等价于访问这个分区的接口;

      3) info:serverstartcode (start-time of the RegionServer process containing this region) RS进程的启动时间;

      当表处于splitting分裂阶段时,额外的两个列会被创建出来:info:splitA 和info:splitB.  这俩列表示两个分裂目标regions. 其值也是serialized HRegionInfo instances.  分裂结束后、最终会删掉。

      HRegionInfo是用来表示一个region分区的具体类型,它用empty key空键表示一张表的起始和终止位置,具备空的起始键的region就是一张表的起始分区。 If a region has both an empty start and an empty end key, it is the only region in the table —— 如果一个region分区具备一张表的空起始键以及空结束键,那么这个分区就是这张表唯一所在的分区。关于数据的version版本号:It’s possible to have an unbounded number of cells where the row and column are the same but the cell address differs only in its version dimension,注意单个rowkey的region再大也是不会split的,即使版本数量设到最大Integer.MAX_VALUE. 

      HBase自带Rest/Thrift支持来为码农省事儿,web前端走rest、非java客户端走thrift、java编程访问HBase用HBase Client、Async Client也达到了生产级可用,齐活。想尝试的也可以尝试国产HBaseManager表管理系统

      Client在读写数据之前先开始搜索分区,Client关心的是我手上的rowKeys在哪个regions?所以搜索条件是rowKey或其范围,搜索就是查询hbase:meta表、查询到所需regions、再定位到所属RS,之后Client即可直连RS读写数据了(不必再通过Master),而且regions地址信息会被Client缓存,之后的访问也不必反复查询hbase:meta表,当region由于loadRebalancer或者RS宕机造成迁移,Client才会再次查询hbase:meta表获取最新分区信息。因此,HBase的Master宕机下线之后,集群仍然能够运行“一段时间”

      版本号、compaction一定程度上都是为了数据不变的目标服务,事实上,海量数据本身就有不变的天然属性,这些数据如移动互联网的用户行为数据、物联网的传感器量测数据,都属于事实/时序数据,他们是既成事实,不应该改变,所谓时序是只与时间强相关的数据、时间是唯一要素,不可能也不应该回到过去的时间修改数据,与时间强相关意味,如果一条数据其他都完整就是丢了时间,那么这条数据完全失去意义,仅仅是一堆没用的数字了。对于这些海量事实数据的访问,不同于传统关系数据,往往只在两个方面:要么定点快速查明细,就是高效查单条;要么大规模统计分析,看结果。不会像传统RDB/BI,各种姿势SQL翻来覆去的看数据。而HBase的数据访问方式,契合这两方面要求,用rowKey查单条、够简单,列式OLAP数据分析用scan,够粗暴。HBase招牌定点查,和scala的Vector类似:

    IndexedSeq首席实现Vector随机访问性能良好

      Vector以树形结构实现,支持大数据量高性能O(1)随机读(感觉随机这个词翻译的不好,它其实就是查单条,叫定点爆破更好)及随机写(基于随机读),增和删稍差些。每个树节点可以有32个子节点,所以n层树就有32的n次幂个元素。100万元素只需4层树(1million < 32的四次幂),下标访问任意元素只需4跳(List就完了平均需要50万跳),如果你有大量有序元素,需要在内存快速随机访问就用Vector;如果你有海量时序数据,需要在磁盘快速随机访问就用HBase。RS知道rowKey范围数据的所在,这样,所有的按rowKey查应该最多只需一次跨机路由,数据很多吗?集群很大嘛?1k台节点机和三五台,一样是一次路由定位,对于单条的定点查询而言,不管数据量和集群大小,时间成本近乎常数O(1),如果单条体现不出什么优势,和RDB比性能要低一点,木关系,哥的征途是大数据大集群,海量数据超大集群每个单条查询性能不变,RDB你行么?这就是HBase最简单最粗暴的地方

    简单粗暴不好吗

      在Maximum Number of Versions最大版本数量看到这句话:It is not recommended setting the number of max versions to an exceedingly high level (e.g., hundreds or more) unless those old values are very dear to you because this will greatly increase StoreFile size,找这句话好久了,意思是不要把允许的最大版本数量设置的很大比如上百,除非你真的真的需要,因为这样做会显著增大StoreFile大小。潜台词是所有cell,即使你没有存入多个版本,因为磁盘连续存,同样会留出多版本的空间,每个cell都这样会造成StoreFile整体尺寸显著增大?

      一个region就是一张表的整个key空间当中的一段key分布,每个region都有一个唯一名字region Key比如1d843dd20917ce8408b4032908f7f390,包含下列信息:

    1、tableName  : The name of the table

    2、startKey    : The startKey for the region.

    3、regionId    : A timestamp when the region is created.

    4、replicaId  : An id starting from 0 to differentiate replicas of the same region range but hosted in separated servers. The same region range can be hosted in multiple locations.

    5、encodedName : An MD5 encoded string for the region name.

      除了region name,HRegionInfo 还包含信息:

    1、endKey : the endKey for the region (exclusive)

    2、split      : Whether the region is split

    3、offline    : Whether the region is offline

    Standalone部署

      首先在win10系统上安装WSL,在win10家庭版上PowerShell、WSL Ubuntu都可以安装、可以更新:

    要安装WSL你的win10需要更新到2004 19041+,之后即可安装Ubuntu20.04,执行sudo apt update即可装上curl

      在运维工作中可以使用WSL连接服务器,在开发工作中可以在WSL中安装轻便版的本地HBase供本地调试。

      HBase运行模式分两个大类:standalone和分布式模式。standalone模式以多线程模拟多进程;和spark的spark-shell --master local[2]非常类似。分布式模式我们只关注完全分布式,伪分布式没什么用处。

      Standalone又分为两类

    1、standalone纯本地模式:持久化到本地文件系统,会在一个JVM内运行所有HBase程序以及一个本地的zookeeper. 用来做一些本机测试方便,我使用win10+WSL来部署没毛病。但还是要感谢雷锋同志,贡献了winutils模拟posix文件系统。

    2、standalone over HDFS模式:这是一个变种模式,有用,持久化到一个远程HDFS服务实例,当希望在本地快捷使用一个轻量HBase时可以这么用,好处是Standalone模式运行的HBase与Client都在本地运行,此时不需要配置Client免除麻烦,同时数据可靠、共享地保存在远程HDFS上,你可以在任一台机器上随时启停轻量的HBase,而使用的是同一份数据。除了存储部分其他与standalone纯本地模式一样,只是存储不再是file:///、而是hdfs:// .  当希望在本机快捷启动一个轻量HBase进行测试开发,共享使用远程HDFS集群上的数据比如多人开发时可以用这种简便方式。只要如下配置:

    edit your hbase-site.xml setting hbase.rootdir to point at a directory in your HDFS instance but then set hbase.cluster.distributed to false.

      纯本地standalone模式验证WSL可用:使用hbase shell创建表、insert插入行数据、执行put and scan、 enable or disable the table, and start and stop HBase.  可以按照官网来做,不用考虑Hadoop的事非常清爽:

    1、设置hbase.env.sh或.bashrc:

      export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64(对于预装java的可以从软链接找到JDK实际位置:ls -l /usr/bin/java)

    2、设置hbase-site.xml

      hbase.rootdir = file:///usr/HBase/hbase

      hbase.zookeeper.property.dataDir = /usr/HBase/zookeeper

      要minimum最小配置的话,只做第一步就够了,此时hbase.rootdir会默认为tmp目录,对于linux来说重启会清除该目录,WSL bash只是一个窗口重启更简单了,那么为了数据不丢可以设一下hbase.rootdir,注意该目录不要自己创建(You do not need to create the HBase data directory. HBase will do this for you.  If you create the directory, HBase will attempt to do a migration, which is not what you want.)否则会触发一个启动Error

      最新的win10下,Ubuntu文件目录是C:\Users\Khanka\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState\rootfs,可以就像访问本地路径一样访问,方便很多。

    1、将hbase-2.2.5-bin.tar.gz拷贝到rootfs/opt、 tar xzvf hbase-2.2.3-bin.tar.gz

    2、回到WSL bash执行start-hbase.sh启动HBase:

    在WSL中使用shell测试create、list、put、scan、get

    独立HBase集群安装

      1、准备:HDFS安装很简单不说了,首先验证HDFS正常,运行put/get命令可以验证,比如上传pdf文档到HDFS根目录:

             # hdfs dfs put ./apache_hbase_reference_guide.pdf /

        在HDFS web UI 如 NameNode:9870可以看到上传文件并可以get即可。

        下载HBase2.2.5稳定版,上传到所有节点机/usr/hbase目录并解压,以/usr/hbase/hbase-2.2.5作为HBASE_HOME。HBase的所有进程称为HBase daemon 包括:HMaster, HRegionServer和ZooKeeper的HQuorumPeer,类似HDFS,HBase的主节点是HMaster、从节点是诺干台RS,且建议HBase的HMaster与HDFS的NameNode安装在同一台节点机。

        2、编辑conf/regionservers配置文件(类似HDFS的workers都是无后缀文本文件,请从linux解压目录下载空白模板、再编辑上传),一行一个写上所有RS的hostname

        3、编辑conf/backup-masters配置文件,写上备份Master

        4、编辑conf/hbase-site.xml配置文件(xml不存在无后缀文本文件问题,注意所有节点机地址写为hostname,这样xml配置在所有节点机通用,可以直接拷贝),这里只记录几个坑:

        ①异常解决:o.a.h.hbase.util.DynamicClassLoader : Failed to identify the fs of dir hdfs://NameNode:8020/hbase/lib, ignored

                             java.io.IOException: No FileSystem for scheme: hdfs

        stackOverFlow上有帖子讲只要把hbase.dynamic.jars.dir属性设置为空就可以:If you'd like to remedy the issue, you can ensure hbase.dynamic.jars.dir isn't set.  这是信口胡说,需要设置属性:

    HBASE-1936

        ②hbase.unsafe.stream.capability.enforce配置项:

    在HBase2.2.5该配置项在模板当中直接设置为了false

    ③对于写负载比较重的应用:

    启用MSLAB,参考:https://issues.apache.org/jira/browse/HBASE-8163

    ④搭配配置:

    5、在所有节点机为zookeeper创建/opt/HBase/zk目录;在HDFS为HBase创建hbaseWAL、hbase目录分别作为预写日志目录和数据目录:

             # hdfs dfs -mkdir /hbase

             # hdfs dfs -mkdir /hbaseWAL

    在NameNode:9870集群查看页面Utilities菜单浏览文件系统可以看到新创建的目录

    6、编辑conf/hbase-env.sh环境变量配置脚本,增加:

    export JAVA_HOME=...

    export HBASE_OFFHEAPSIZE=16G

    export HBASE_OPTS="$HBASE_OPTS -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction"

    7、问题排除:首次启动遇到master启动问题:http://hbase.apache.org/book.html#trouble.master.startup.hsync

      参考https://www.cnblogs.com/kevin19931015/p/9243230.html解决;

    8、如果出现由于节点机之间未精确对时,导致时间差大于默认的30秒,简单粗暴方式解决:

    <property>               

      <name>hbase.master.maxclockskew</name>               

      <value>9500000</value><!-- 毫秒计的允许时间差 -->

      <description>Time difference of regionserver from master</description>

    </property>

    Akka is the name of a beautiful mountain(that Jonas climbed and skied some years age) in the Laponia region in Northern Sweden. The mountain is also sometimes called 'The Queen of Laponia'. Akka is also the name of a goddness in the Sami(the native Swedish population)mythology. She is the goddness that stands for all the beauty and good in the world. The mountain can be seen as the symbol of this goddness. Also,the name AKKA is the palindrome of letters A and K as in Actor Kernel and returns very few hits on Google.

    相关文章

      网友评论

        本文标题:HBase(单机win10+WSL、集群独立安装)

        本文链接:https://www.haomeiwen.com/subject/ziwduftx.html