HBase Split 简介

Hbase Split 是一个很重要的功能,HBase 通过把数据分配到一定数量的 Region 来达到负载均衡的。当 Region 管理的数据过多时,可以通过手动或自动的方式触发 HBase Split 将一个 Region 分裂成两个新的子 Region,并对父 Region 进行清除处理(不会立即清除)。

HBase 为什么需要 Split?
相比于传统 RDBMS 对大数据表的扩展方式,HBase 天然支持自动分库分表,实现的基础就是 Split 和 Rebalance。
Region 是管理一段连续的 Rowkey 的核心单元,当 Region 管理的 Rowkey 数量多时,或 HFile 文件较大时,都会影响到性能。

Pre-splitting

一个表刚被创建的时候,Hbase 默认分配一个 Region 给表,所有的读写请求都会访问到一个 RegionServer 上的唯一一个 Region。这样就达不到负载均衡的效果了,集群中的其他 RegionServer 就会处于空闲的状态(考虑只有一个表的情况)。解决这个问题可以有两种方法:

  • 如果能很好的预计业务的 Rowkey 分布和数据增长情况,可以在建表时分配好 Region 的数量和每个 Region Rowkey 范围,同时禁用表的自动分区,因为 Split 操作会有额外的开销和维护成本。
  • 另一种方法只需要指定分配的 Region 数量,利用 pre-splitting,生成每个 Region 的 Rowkey 范围

Hbase 自带了两种 pre-split 的算法,分别是 HexStringSplit 和 UniformSplit 。HexStringSplit 适用于十六进制字符的 Rowkey(MD5)。UniformSplit 适用于随机字节组成的 Rowkey(Hash)。

Split 触发时机

HBase 中共有3种情况会触发 HBase Split:

  1. 当 Memstore flush 操作后,HRegion 写入新的 HFile,有可能产生较大的 HFile,会判断是否需要执行 Split。
  2. HStore 执行完成 Compact 操作后可能产生较大的 HFile,会判断是否需要执行 Split。
  3. HBaseAdmin 手动执行 split 命令时,会触发 Split。

Split 触发策略

目前已经的支持触发策略多达6种,每种触发策略都有各自的适用场景,可以根据业务在表级别(Column family 级别)选择不同的切分触发策略。一般情况下使用默认切分策略即可。

  • ConstantSizeRegionSplitPolicy:0.94版本前默认切分策略。
    一个 Region 中最大 Store 的大小大于设置阈值之后才会触发切分,Store 大小为压缩后的文件大小(启用压缩的场景)
    切分策略对于大表和小表没有明显的区分
  • IncreasingToUpperBoundRegionSplitPolicy:0.94版本~2.0版本默认切分策略。
    和 ConstantSizeRegionSplitPolicy 思路相同,一个 Region 中最大 Store 大小大于设置阈值就会触发切分,区别是这个阈值并不像 ConstantSizeRegionSplitPolicy 是一个固定的值,而是会在不断调整。
    调整规则和 Region 所属表在当前 RegionServer 上的 Region 个数有关系 :(#regions) * (#regions) * (#regions) * flush_size * 2,最大值为用户设置的 MaxRegionFileSize
    能够自适应大表和小表,这种策略下很多小表会在大集群中产生大量小 Region,分散在整个集群中
  • SteppingSplitPolicy:2.0版本默认切分策略。
    相比 IncreasingToUpperBoundRegionSplitPolicy 简单了一些,依然和待分裂 Region 所属表在当前 RegionServer 上的 Region 个数有关系:如果 Region 个数等于1,切分阈值为 flush_size * 2,否则为 MaxRegionFileSize
  • DisableSplitPolicy:禁止 Region split
  • KeyPrefixRegionSplitPolicy:切分策略依然依据默认切分策略,根据 Rowkey 指定长度的前缀来切分 Region,保证相同的前缀的行保存在同一个 Region 中。由 KeyPrefixRegionSplitPolicy.prefix_length 属性指定 Rowkey 前缀长度。按此长度对splitPoint进行截取。
    此种策略比较适合有固定前缀的 Rowkey。当没有设置前缀长度,切分效果等同与 IncreasingToUpperBoundRegionSplitPolicy。
  • DelimitedKeyPrefixRegionSplitPolicy:切分策略依然依据默认切分策略,同样是保证相同 RowKey 前缀的数据在一个Region中,但是是以指定分隔符前面的前缀为来切分 Region。

Split 流程

Region split 的过程可以简单的理解为:在 Region 中找到一个合适的 split point,在这个 split point 上将该 Region 的数据划分为两个新的 Region。当然这个过程的实现起来很复杂,Split 发生时,新创建的子 Region 不会立即将所有数据重新写入新文件,而是会创建类似于符号链接文件的小文件,称为引用文件(reference files),根据 split point,指向父存储文件的顶部或底部(父 Region 的一半数据)。

下文引用官方博客对 HBase split 流程的解释:

HBase Split

HBase Split

HBase 将整个切分过程包装成了一个事务,为了保证切分事务的原子性。整个分裂事务过程分为三个阶段:prepare – execute – (rollback)

  • prepare阶段:在内存中初始化两个子 Region,具体是生成两个 HRegionInfo 对象,包含 TableName、RegionName、Startkey、Endkey等。同时会生成一个 transaction journal,这个对象用来记录切分的进展
  • execute阶段:切分的核心操作
    (1)在ZK节点 /hbase/region-in-transition/region-name 下创建一个 znode,并设置状态为SPLITTING
    (2)Master 通过监听ZK节点,检测到 Region 状态的变化
    (3)RegionServer 在父 Region 的数据目录(HDFS)下创建一个名称为 .splits 的子目录
    (4)RegionServer 关闭父 Region,强制将数据 flush 到磁盘,并这个 Region 标记为 offline 的状态。此时,落到这个 Region 的请求都会返回 NotServingRegionException 这个错误,客户端需要进行一些重试,直到新的 Region 上线。
    (5)RegionServer 在 .splits 目录(HDFS)下创建 daughterA 和 daughterB 子目录,并在文件夹中创建对应的 reference 文件,分别指向父 Region 的数据文件中的一部分。
    (6)RegionServer 创建子 Region 的目录(HDFS),并将 daughterA 和 daughterB 目录下的文件拷贝到 Region 目录。
    (7)在 .META. 表中设置父 Region 为 offline 状态,不再提供服务。并将子 Region 的信息添加到 .META. 表中父 Region 的信息中(splitA 和 splitB 两列)。这个时候如果扫描 hbase:meta 表,会发现父 Region 正在执行 split,并不能看到子 Region 的信息。如果 RegionServer 执行这个过程失败,Master 和下一个分配了这个 Region 的 Regionserver 会清除 split 相关的状态数据。
    (8)RegionServer 并行启用两个子 Region,并正式提供对外服务
    (9)RegionSever 将 daughterA 和 daughterB 添加到 .META. 表中,并设置为 online 状态,这样就可以从 .META. 找到子 Region,并可以对子 Region 进行访问了。
    (10)RegionServr 修改ZK节点 /hbase/region-in-transition/region-name 的状态为SPLIT,Master 就可以监听到 Region 状态的更新。Split 事务就此结束。

再次强调,为了减少对业务的影响,Region 的 Split 并不涉及到数据迁移的操作,而只是创建了对父Region的指向。只有在做大合并的时候,才会将数据进行迁移。

  • rollback阶段:如果 execute 阶段出现异常,则执行 rollback 操作。为了实现回滚,整个切分过程被分为很多子阶段,回滚程序会根据当前进展到哪个子阶段清理对应的垃圾数据。JournalEntryType 类定义了各个子阶段。

Region 事务性保证

整个region切分是一个比较复杂的过程,涉及子步骤,因此必须保证整个 Split 过程的事务性,即要么完全成功,要么完全未开始,在任何情况下也不能出现 Split 只完成一半的情况。为了实现事务性,Hbase 设计了使用状态机(见 SplitTransaction 类)的方式保存切分过程中的每个子步骤状态,这样一旦出现异常,系统可以根据当前所处的状态决定是否回滚,以及如何回滚。

目前实现中这些中间状态都只存储在内存中,因此一旦在切分过程中出现 RegionServer 宕机的情况,有可能会出现切分处于中间状态的情况,也就是RIT状态。这种情况下可使用 hbck 工具,根据实际情况查看并分析解决方案。

在2.0版本 HBase 实现了新的分布式事务框架 Procedure V2(HBASE-12439),使用 HLog 存储这种单机事务(DDL、Split、Move 等操作)的中间状态。保证即使在事务执行过程中参与者发生了宕机,依然可以使用 HLog 作为协调者对事务进行回滚操作或重新提交。

通过 reference 文件如何查找到对应的数据

根据文件名来判断是否是 reference 文件:

  1. reference 文件的命名规则为前半部分为父 Region 对应的 HFile 的文件名,后半部分是父 Region 的名称,因此读取的时候也根据前半部分和后半部分来定位文件。
  2. 根据 reference 文件的内容来确定扫描的范围,reference 的内容包含两部分:一部分是切分点 splitkey,另一部分是 boolean 类型的变量,如果为 true 则扫描文件的上半部分,反之则扫描文件的下半部分
  3. 接下来确定了扫描的文件,以及文件的扫描范围,那就按照正常的文件检索了

Split 对其他模块的影响

执行 Region Split 过程不涉及数据的移动,所以可以很快完成。新生成的子 Region 文件中没有任何用户数据,而是一个 reference 文件,文件中存储的是一些元数据信息,包括切分点的 Rowkey 等。引入了以下问题:

  1. 父 Region 的数据什么时候会迁移到子 Region 目录
    子 Region 发生 major_compaction 时。将父 Region 目录中属于该子 Region 的所有数据读出来并写入子 Region 数据文件目录中,这一操作符合 compaction 本身的处理逻辑,因此在 compaction 中操作。
  2. 父 Region 什么时候会被删除
    HMaster 会启动一个线程定期检查所有处于 splitting 状态的父 Region,确定其是否可以被清理。检测线程首先会在 .META. 表中找到 splitting region,并找出其生成的两个子 Region(.META. 表中 splitA 和 splitB 列)。然后检查两个子 Region 是否保留引用文件,如果都不存在就认为该 splitting region 可以被删除和下线。.META. 表中的信息参考下图:

注意事项

使用 Split 时有以下需要注意的:

  1. 不能对元数据表进行 Split
  2. 不能对正在恢复的 Region 进行 Split
  3. 如果某个 Region 存在引用文件的不能 Split
  4. 当 Split 执行到将父 Region 下线之后,子 Region还未创建之前,如果此刻正访问的是父 Region,在客户端没有更新 Region 地址缓存的情况下,会报 NotServingRegionException 异常,因此客户端需要做好重试机制。
  5. Split 的完整过程中有个关键的时间点是无法回退的点(PONR: point of no return),发生在将 .META. 表中的父 Region 下线之前,如果进入 PONR 之后,由于种种原因更新 .META. 失败,需要重启所在的 RegionServer。

Reference:
https://zh.hortonworks.com/blog/apache-hbase-region-splitting-and-merging/
http://hbase.apache.org/book.html

转载自:
https://jianshu.com/p/53459997c814

CentOS 6.5 升级 PHP 到5.6

wordpress升级版本需要提高PHP的版本,所以只能做升级了,综合几个帖子的内容整理一下比较简单的操作方案。

  1. 首先先看下已安装的版本
    • php -v
  2. 升级之前需要卸载一下旧版本,不卸载直接安装新版会提示失败
    • yum remove php*
  3. 然后更新一下yum源
    • sudo yum install epel-release -y
  4. 最后安装 5.6版 php 和 php-fpm 以及一些其他扩展,按需选择
    • yum install php56w php56w-fpm php56w-mysql php56w-mbstring php56w-gd php56w-dom
    • 其中 php-fpm 是 nginx 里要用的 fast-cgi 进程管理器,重新安装后可能还需要重启一下fpm
    • /etc/init.d/php-fpm restart
    • 注:如果要升级php7,把上面命令中的 php56w 改为 php70w 即可
  5. 参考文章
    • https://www.cnblogs.com/savokiss/p/6259816.html
    • https://my.oschina.net/HeAlvin/blog/2050980

《氛围美食影像学》—随笔

总想着休息了带着相机出去各种拍,不想加班加班,久而久之有空了几乎都不想出门,一个是觉得难得用空,另外一个主要原因还是因为累,想在家休息。所以寻思着是不是可以换个方向,在家可以做饭,然后可以看看没美食摄影相关的,拍拍美食应该还是可以的,于是乎就买书了;

以下是我的书单:

1、《氛围美食影像学》

2、《看得见的美味 商业美食摄影技法》

3、《Photoshop商业摄影后期高级修图技法》

4、《商业摄影实拍案例没事摄影一本通》

目前《氛围美食影像学》已经看完,在这里做个小结吧。

第一章介绍美食摄影相关的概念:广义上讲美食摄影通常还包含场景摄影、空间摄影、人像摄影、风光摄影等众多摄影范畴;摄影风格分类及演化:具体来说提到日式和风风格和欧美自然风格。

第二章 美食摄影的基础知识。于我而言关于摄影设备、相机设定等篇幅基本都是相通的不做过多的了解,到了光源、场景布置才进入了比较紧密的部分。而对于拍摄角度和构图则有了比较好的理解。

第三章美食摄影进阶部分。这章算是这本书的价值所在,至少我是这么理解的,光源造型,这里面都给出了作者的一些心得和经验体会,特别是食品造型小技巧中,冰激淋用土豆泥替换,玉米片的牛奶,剃须刀泡沫做的奶油等,这些应该是作者多次实践的结果体会。

第四章趣味及延伸:这一章节也就回归到生活了,艺术终究还是得回归到生活中,个人感觉对于全书来说这部分得价值贡献比较低。比较受用的一句话:永远分享你拍的最好的照片。通读全书,整体来看10分满分的化只能给6分,刚及格,不是特别推荐,如果有想要了解的我更推荐《看得见的美味 商业美食摄影技法》,目前正在看。以上仅代表个人观点。

微服务架构与SOA服务化的对比

微服务架构是服务化架构相应特定历史时期的使用场景的延续,是服务化进行升华并落地的一种实现方式。SOA服务化的理念在微服务架构中仍然有效,微服务在SOA服务化的基础上进行了演进和叠加,形成了适合现代化应用场景的一个方法论。

微服务架构与SOA服务化差异:

1、目的不同SOA服务化涉及的范围更广一些,强调的是不同的异构服务之间的协作和契约,并强调有效集成、业务流程编排、历史应用集成等,典型代表为Web Service和ESB。微服务使用一系列的微小服务来实现整体的业务流程,目的是有效地拆分应用,实现敏捷开发和部署,在每个微小服务在团队里,减少跨团队的沟通,让专业的人做专业的事,缩小变更和迭代影响的范围,并达到单一微服务更容易水平扩展的目的。

2、部署方式不同微服务将完整的应用拆分成多个细小的服务,通常使用敏捷扩容,缩容的Docker技术来实现自动化的 容器管理,每个微服务运行在单一的进程内,微服务中的部署相互独立,互不影响。SOA服务化通常将多个业务服务通过组件化模块方式打包在一个war包里,然后统一部署在一个应用服务器上。

3、服务粒度不同微服务倡导将服务拆分成更细的力度,通过多个服务来组合实现业务流程的处理,拆分到指责单一,甚至小到不能再进行拆分。SOA对粒度没有要求,在实践中服务通常是粗粒度的,强调接口契约的规范化,内部实现可以更粗粒度。

Mac安装mysql

运行环境

查看系统环境

操作步骤

1、安装Homebrew,详细步骤参见Homebrew官网。

2、brew doctor确认brew在正常工作。

3、brew update更新包。

4、brew install mysql 安装mysql。

5、按照brew的提示运行 mysql_secure_installation.

莫慌,提示说找不到mysql.sock。原因是mysql进程还没启动。 

6. 启动mysql服务

7、再运行

8、最后测试一下登陆

安装问题

此问题的处理如提示所示,只需要执行mysql_upgrade就可以,具体操作如下:

执行完成以后再运行,就可以看到第7步中的提示,按照提示操作即可