Iawen's Blog

我喜欢这样自由的随手涂鸦, 因为我喜欢风......

1. Hadoop 常见问题

1.1 Got too many exceptions to achieve quorum 异常解决办法

  • 1、首先需要备份namenode元数据和journalnode元数据
  • 2、在namenode节点 执行
hdfs namenode -initializeSharedEdits
# 中间会提示是否格式journalnode 回复 Y

Re-format filesystem in QJM to [10.1.5.102:8485, 10.1.5.103:8485, 10.1.5.104:8485] ? (Y or N) y
  • 3、重启hadoop集群 问题解决。

1.2 报错There appears to be a gap in the edit log. We expected txid 6, but got txid xxxx.

  • 原因: namenode元数据被破坏, 需要修复
  • 解决: 恢复一下namenode
/usr/local/hadoop-3.1.3/bin/hdfs namenode -recover
# 一路选择c 进行元数据的恢复.这是重点
# 重新启动。到这里问题真正的结束了, 好舒服。

网上有一种解决方法, 说是把active namenode上的name文件夹拷贝到standby namenode上。我试了, 而且拷贝过来的name目录中也有176531929这条Edits数据, 但启动namenode时还是报同样的错, 说找不到176531929这条edit数据。说明这个方法不可行! 因为Edits是要在启动时去journalnode上读取的。这个问题的根本原因是你的journalnode上存在Edits数据丢失的情况。这一句看懂就基本上找到原因了, 也有方向了, 在HA的解读中就有说明,

所以我去查看我的journalnode目录, 果然发现journalnode/yarncluster/current下面没有176531929这一条Edits数据。所以, 这就是这个错误出现的根本原因。然后解决办法很简单, 从active namenode上拷贝这条Edits数据到所有journalnode中。重新启动, 问题解决, 没有数据丢失, 也不需要recovery。

hdfs dfsadmin -safemode leave

1.3 查看损坏文件、当前hdfs的副本数

hdfs fsck /     # 或者
hadoop fsck -locations

# Under replicated blocks       副本数少于指定副本数的block数量
# Blocks with corrupt replicas   存在损坏副本的block的数据
# Missing blocks            丢失block数量

1.4 更改已经上传文件的副本数, 修复Missing blocks

hadoop fs -setrep -R 3 /
# 通过该命令, 对于存在副本缺失问题(Under replicated blocks)的662个block, 可以从剩下的1-2个副本, 重新生成3个副本, 从而找回了丢失的副本。

1.5 删除损坏文件

hdfs fsck -delete
# 通过多次运行该命令, 对于副本全部丢失(Missing blocks)或损坏的block, 可以从namenode节点删除元信息和损坏文件。

2. Hbase 常见问题

2.1 查看hbase中损坏的block

hbase hbck

2.2 修复hbase

# 关闭balance,防止在停掉服务后, 原先节点上的分片会迁移到其他节点上, 到时候在移回来, 浪费时间。
hbase(main):001:0> balance_switch false
hbase hbck -repair
hbase(main):001:0> balance_switch true

2.3 其他修复

# .META表
hbase hbck -fixMeta

# 当出现漏洞
hbase hbck -fixHdfsHoles

# 缺少regioninfo
hbase hbck -fixHdfsOrphans

# hbase region 引用文件出错
# Found lingering reference file hdfs: 
hbase hbck -fixReferenceFiles

# 修复assignments问题
hbase hbck -fixAssignments

# 手动移动table region
move 'bee0c225ec0c69ecc5872dfe67cec5f0', 'xiaoma05,16020,1607668276810'

# 手动拆分table region
split '5a3af2b7bcffdc93a1433bd80fe1ce04', '42'
split 'aaab390dd96dc8a6cfaf7b045d925738', 'a2'

region自动拆分默认选择Region当中最大Store下的最大Storefile文件中的midkey, 而midkey其实只是在通过HFile获取了这个文件之前记录好的数据。在自动触发Split操作的前提下, 大部分的Split操作都伴随在Compaction操作之后进行的原因, 在于可以对于Region中的文件进行合并, 生成较大的StoreFile文件, 以方便选择更好的SplitPoint。

2.4 Hbase的region合并与拆分

2.4.1 region 拆分机制

region中存储的是大量的rowkey数据 ,当region中的数据条数过多的时候,直接影响查询效率.当region过大的时候.hbase会拆分region , 这也是Hbase的一个优点 . HBase的region split策略一共有以下几种:

  • 1、ConstantSizeRegionSplitPolicy (0.94版本前默认切分策略) 当region大小大于某个阈值(hbase.hregion.max.filesize=10G)之后就会触发切分, 一个region等分为2个region。 但是在生产线上这种切分策略却有相当大的弊端: 切分策略对于大表和小表没有明显的区分。阈值(hbase.hregion.max.filesize)设置较大对大表比较友好, 但是小表就有可能不会触发分裂, 极端情况下可能就1个, 这对业务来说并不是什么好事。如果设置较小则对小表友好, 但一个大表就会在整个集群产生大量的region, 这对于集群的管理、资源使用、failover来说都不是一件好事。

  • 2、IncreasingToUpperBoundRegionSplitPolicy (0.94版本~2.0版本默认切分策略) 切分策略稍微有点复杂, 总体看和ConstantSizeRegionSplitPolicy思路相同, 一个region大小大于设置阈值就会触发切分。但是这个阈值并不像ConstantSizeRegionSplitPolicy是一个固定的值, 而是会在一定条件下不断调整, 调整规则和region所属表在当前regionserver上的region个数有关系. region split的计算公式是: regioncount^3 * 128M * 2, 当region达到该size的时候进行split 例如: 第一次split: 1^3 * 256 = 256MB 第二次split: 2^3 * 256 = 2048MB 第三次split: 3^3 * 256 = 6912MB 第四次split: 4^3 * 256 = 16384MB > 10GB, 因此取较小的值10GB 后面每次split的size都是10GB了

  • 3、SteppingSplitPolicy (2.0版本默认切分策略) 这种切分策略的切分阈值又发生了变化, 相比 IncreasingToUpperBoundRegionSplitPolicy 简单了一些, 依然和待分裂region所属表在当前regionserver上的region个数有关系, 如果region个数等于1, 切分阈值为flush size * 2, 否则为MaxRegionFileSize。这种切分策略对于大集群中的大表、小表会比 IncreasingToUpperBoundRegionSplitPolicy 更加友好, 小表不会再产生大量的小region, 而是适可而止。

  • 4、KeyPrefixRegionSplitPolicy 根据rowKey的前缀对数据进行分组, 这里是指定rowKey的前多少位作为前缀, 比如rowKey都是16位的, 指定前5位是前缀, 那么前5位相同的rowKey在进行region split的时候会分到相同的region中。

  • 5、DelimitedKeyPrefixRegionSplitPolicy 保证相同前缀的数据在同一个region中, 例如rowKey的格式为: userid_eventtype_eventid, 指定的delimiter为 _ , 则split的的时候会确保userid相同的数据在同一个region中。

  • 6、DisabledRegionSplitPolicy: 不启用自动拆分, 需要指定手动拆分

2.4.2 region合并机制

  • 1.1 region合并说明 Region的合并不是为了性能, 而是出于维护的目的 . 比如删除了大量的数据 ,这个时候每个Region都变得很小 ,存储多个Region就浪费了 ,这个时候可以把Region合并起来, 进而可以减少一些Region服务器节点

  • 1.2 如何进行region合并 1.2.1 通过Merge类冷合并Region

# 执行合并前, ==需要先关闭hbase集群==
hbase org.apache.hadoop.hbase.util.Merge test test,,1565940912661.62d28d7d20f18debd2e7dac093bc09d8. test,1000,1565940912661.5b6f9e8dad3880bcc825826d12e81436.

1.2.2 通过online_merge热合并Region

# ==不需要关闭hbase集群==, 在线进行合并
# 与冷合并不同的是, online_merge的传参是Region的hash值, 而Region的hash值就是Region名称的最后那段在两个.之间的字符串部分。
# 需要进入hbase shell: 
ruby merge_region 'c2212a3956b814a6f0d57a90983a8515','553dd4db667814cf2f050561167ca030'

2.5 hbase snapshot 和数据迁移

2.5.1 创建hbase snapshot

hbase(main):002:0> create_namespace "test"
hbase(main):004:0> create 'test:snapshot', {NAME=>'CF1',BLOCKCACHE=>'false',BLOOMFILTER=>'ROW'}
hbase(main):006:0> put 'test:snapshot', '123', 'CF1', 'value 01'
hbase(main):007:0> put 'test:snapshot', '256', 'CF1', 'value 01'
hbase(main):008:0> put 'test:snapshot', '345', 'CF1', 'value 01'
hbase(main):009:0> put 'test:snapshot', '348', 'CF1', 'value 02'
hbase(main):010:0> scan 'test:snapshot'
ROW                                             COLUMN+CELL
 123                                            column=CF1:, timestamp=1609396656263, value=value 01
 256                                            column=CF1:, timestamp=1609396664602, value=value 01
 345                                            column=CF1:, timestamp=1609396669585, value=value 01
 348                                            column=CF1:, timestamp=1609396677496, value=value 02
4 row(s)
Took 0.0420 seconds
hbase(main):011:0> snapshot 'test:snapshot', 'test_snapshot_count4'
hbase(main):012:0> put 'test:snapshot', '348', 'CF1', 'update 348 value this'
hbase(main):013:0> scan 'test:snapshot'
ROW                                             COLUMN+CELL
 123                                            column=CF1:, timestamp=1609396656263, value=value 01
 256                                            column=CF1:, timestamp=1609396664602, value=value 01
 345                                            column=CF1:, timestamp=1609396669585, value=value 01
 348                                            column=CF1:, timestamp=1609396759008, value=update 348 value this

hbase(main):014:0> disable 'test:snapshot'
hbase(main):015:0> restore_snapshot 'test_snapshot_count4'
hbase(main):016:0> enable 'test:snapshot'
hbase(main):017:0> scan 'test:snapshot'
ROW                                             COLUMN+CELL
 123                                            column=CF1:, timestamp=1609396656263, value=value 01
 256                                            column=CF1:, timestamp=1609396664602, value=value 01
 345                                            column=CF1:, timestamp=1609396669585, value=value 01
 348                                            column=CF1:, timestamp=1609396677496, value=value 02

2.5.2 数据迁移

在上面创建好快照后, 使用ExportSnapshot命令进行数据迁移, ExportSnapshot也是HDFS层的操作, 本质还是利用MR进行迁移, 这个过程主要涉及IO操作并消耗网络带宽, 在迁移时要指定下map数和带宽, 不然容易造成机房其它业务问题, 如果是单独的MR集群, 可以在MR集群上使用如下命令:

hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot \
-snapshot SNAPSHOT_ZAT_TRACE_20200904093200 \
-copy-from hdfs://172.16.120.199:9000/hbase \
-copy-to hdfs://172.16.120.213:9000/hbase \
-mappers 16 -bandwidth 1024

# 根据快照恢复出一个新表, 恢复过程不涉及数据移动, 可以在秒级完成。
hbase> clone_snapshot 'SNAPSHOT_ZAT_TRACE_20200904093200','ZAT_TRACE_NEW'

2.5.3 验证数据

# 通过HBase自带的VerifyReplication工具, 验证两个集群的数据是否一致: 
hbase org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication -mappers 10 -bandwidth 1024 1 ZAT_TRACE

参考: https://www.cnblogs.com/caoweixiong/p/13607657.html

2.6 Thrift server 参数选择

TServer的选择。这是Thrift框架server端处理模型的选择。有三种, TNonblockingServer, THsHaServer, TThreadPoolServer。可以通过启动命令参数指定, 具体运行./bin/hbase thrift可以看到命令帮助(or ./bin/hbase thrift2)。默认是用TThreadPoolServer, 建议就不用改了, 除非你特别了解你的场景。

  • hbase.regionserver.thrift.compact 是否使用Thrift TCompactProtocol, 默认false。如果你每列数据比较大, 可以试着开启, 减少带宽。
  • hbase.thrift.connection.cleanup-interval server清理与HBase连接的周期, 与HBase的是一个长连接, 默认10秒
  • hbase.thrift.connection.max-idletime 如果与HBase的长连接超过这个时间没有被使用, 则会被清理, 默认10分钟
  • hbase.thrift.minWorkerThreads TThreadPoolServer的线程池中的corePoolSize, 也就是即便空闲时候保持的线程数, 默认16。
  • hbase.thrift.maxWorkerThreads TThreadPoolServer的线程池中的maximumPoolSize, 默认1000。这个会影响server最大处理能力, 需要根据硬件衡量。
  • hbase.thrift.maxQueuedRequests TThreadPoolServer的线程池队列长度上限, 超过这个值时会去创建一个新的线程处理请求(前提是没有达到maxWorkerThreads, 否则拒绝请求)

注: 上述最后三个值对thrift2无效。1.3之前的版本中, thrift2无法设定这些值。2.0版本中在thrift2启动命令里通过指定’w’选项来设置maxWorkerThreads。具体可以运行上文中提到的命令, 查看是否支持’w’选项, 如果不支持, 默认max=int最大值。

3. Hadoop元数据备份与恢复方案

3.1 Namenode

周期性备份namenode、standby namenode的dfs.namenode.name.dir 因为主从切换可能导致edits log分散在两台机器上, 需要两台机器共同提供完整的edits log 恢复步骤:

  • 1,删除journalnode数据文件, 启动服务(所有jn均执行)
  • 2,登陆namenode
  • 3,下载最新的备份文件
  • 4,解压, 移至dfs.namenode.name.dir
  • 5,执行hdfs namenode –initializeSharedEdits(hdfs namenode -initializeSharedEdits will initialize the shared edits directory with the edits data from the local NameNode edits directories)
  • 6,启动zkfc
  • 7,启动namenode
  • 8,登陆standby namenode
  • 9,执行hdfs namenode -bootstrapStandby(The bootstrapStandby command will download the most recent fsimage from the active NameNode into the $dfs.name.dir directory of the standby NameNode.)
  • 10,启动zkfc
  • 11,启动namenode

适用场景: namenode、standby namenode全部故障 如果只是一台namenode故障, 可以清空name文件夹, 执行hdfs namenode -bootstrapStandby

3.2 Journalnode

恢复方法: 从正常的jn节点拷贝数据, 启动, 即可。 无需停止正常节点再拷贝, 直接拷贝即可。这样拷贝会有部分缺失数据, 故障节点启动后, 不会补齐这些缺失数据, 但不影响新数据的写入。对于缺失的edits, 只要有一台机器上有, namenode就可以启动。

适用场景: 单个节点故障

3.3 Zookeeper

周期性备份

<dataDir>/version-2/acceptedEpoch
<dataDir>/version-2/currentEpoch
<dataDir>/version-2/snapshot.
<dataLogDir>/version-2/log.

其中snapshot、log备份最近的几份就行 恢复步骤:

  • 1,登陆一台zookeeper服务器
  • 2,下载最新的备份文件
  • 3,解压, 将data、datalog移至< dataDir>, 并创建data/myid文件(与配置文件一致)
  • 4,启动服务(其余节点配置data/myid文件, 启动即可)

适用场景: 部分或全部数据丢失 如果只是单个节点故障, 清空故障节点的data、datalog文件夹, 启动后会自动从正常节点复制数据, 无需人工恢复

http://hbasefly.com/2016/06/18/hbase-practise-ram/ https://blog.csdn.net/ddxygq/article/details/86418081

3.4 内存配置

目前hbase内存主要如下几个配置项: 1)HBASE_HEAPSIZE HBase RegionServer是内存贪婪性的, 按照经验判断至少8~16G内存, 但也不宜过大, 更多内存应该分配给HBASE_OFFHEAPSIZE 2)HBASE_OFFHEAPSIZE Hbase offheap内存为非堆内存, 主要在hbase缓存数据时使用, 需要配合如下配置项使用,其中hbase.bucketcache.size的配置经验值为: HBASE_OFFHEAPSIZE10240.8 MB

<property>
    <name>hbase.bucketcache.ioengine</name>
    <value>offheap</value>
</property>
<property>
    <name>hbase.bucketcache.size</name>
    <value>HBASE_OFFHEAPSIZE*1024*0.8</value>
</property>

4. Phoenix

phoenix是一个客户端的库, 它在HBase基础上提供SQL功能层, 让我们可以使用标准的JDBC接口操作HBase。 全部支持的特性可以浏览官方最新版本支持的SQL语法, 下面列举一些phoenix 4.6版本不支持的特性及与普通MySQL SQL用法有差异的地方:

  • CHAR类型只能保存单字节的字符, 不能保存中文字符, 中文需要使用VARCHAR。
  • 非主键字段不能指定为NOT NULL, 不支持指定字段默认值(4.9版本以上支持)。
  • UPDATE table SET col=val WHERE: 不支持该语法, phoenix更新和插入使用同样的UPSERT INTO语法, 如果主键存在则更新, 不存在则插入。但可以使用UPSERT INTO table SELECT语句来实现条件更新, 需要把主键按条件选出来, 如:
UPSERT INTO table(id, col1) SELECT id, 'val1' FROM table WHERE col2 = val2
  • DATE/TIME字段类型: 这两个字段类型对应java.sql.Date类型, 其JDBC驱动不会对java.util.Date类型进行转换, 所以在PreparedStatement中setObject(int, java.util.Date)会报下面的错误。如果使用jfinal ActiveRecord保存实体, 当实体字段是java.util.Date类型时要注意。
  • java.util.Date cannot be cast to org.apache.phoenix.schema.types.PhoenixArray
  • LIMIT OFFSET分页: phoenix 4.6不支持使用OFFSET分页, 在4.8以上版本才支持。
  • ALTER不支持改变表名、字段名与字段类型, 只能增加与删除字段。在设计的时候要注意使用合适的字段类型。
  • 大小写: phoenix默认不区分大小写, 所有表名、列名都是大写。
  • 不支持的函数: IFNULL, ISNULL等; IFNULL有对等的COALESCE()函数
  • 连接池: phoenix不推荐使用连接池, 因为其基于HBase的连接的创建成本很低, 并且用过的HBase连接不能共享使用, 因此用过的Connection需要关闭。
  • Phoenix’s Connection objects are different from most other JDBC Connections due to the underlying HBase connection. The Phoenix Connection object is designed to be a thin object that is inexpensive to create. If Phoenix Connections are reused, it is possible that the underlying HBase connection is not always left in a healthy state by the previous user. It is better to create new Phoenix Connections to ensure that you avoid any potential issues.
  • JDBC Connection: AutoCommit默认为false, 其他JDBC Driver一般默认是true, 需要手动条用connnection.commit()或者在连接url后面加上";autocommit=true"
  • 索引使用: 使用CREATE INDEX idx创建的是全局索引(GLOBAL INDEX), 还有一种本地索引(LOCAL INDEX), 相对于本地索引, 全局索引可以让读的性能更佳, 但写入的时候成本会高一点; 而本地索引在写入的时候成本较低, 但读的时候成本较高。使用全局索引的时候, 如果SELECT字段含有非索引的字段, 则索引不会被使用, 大多数情况下我们SELECT都会有索引之外的字段, 这时候需要考虑建立覆盖索引(CREATE INDEX INCLUDING …)或使用hint来让phoenix使用索引: SELECT /*+ INDEX(table idx) */ col FROM table WHERE …。
  • PreparedStatement不支持Statement.RETURN_GENERATED_KEYS, getGeneratedKeys()。
  • 日期类型保存为UTC时间, 在shell/squirrel查询的时候要用CONVERT_TZ做转换, CONVERT_TZ(col, ‘UTC’, ‘Asia/Shanghai’), 但有个bug, 如果col字段是timestamp的话, 会报Type mismatch. expected: [DATE]。实在需要转换的话先转成Date类型: CONVERT_TZ(TO_DATE(TO_CHAR(col,‘yyyy-MM-dd HH:mm:ss’),‘yyyy-MM-dd HH:mm:ss’),‘UTC’,‘Asia/Shanghai’)

4.1 安装phoenix

  • 安装 python2.7: apt-get install python2.7
  • 下载phoenix
  • 复制 phoenix 目录下的 phoenix-5.0.0-HBase-2.0-server.jar, phoenix-5.0.0-HBase-2.0-client.jar, phoenix-core-5.0.0-HBase-2.0.jar 到hbase的lib目录下

4.2 配置 phoenix

  • 修改 hbase-site.xml (hbase用2.0.5)
<property>
    <name>hbase.regionserver.wal.codec</name>
    <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
    <description>支持可变索引</description>
</property>

<property>
    <name>phoenix.transactions.enabled</name>
    <value>true</value>
</property>
<property>
    <name>data.tx.snapshot.dir</name>
    <value>/tmp/tephra/snapshots</value>
</property>

<!-- Phoenix4.8以上版本需要配置在Region Server配置hbase-site.xml, 不用再配置Master的hbase-site.xml。配置如下 -->
<property>
    <name>hbase.regionserver.wal.codec</name>
    <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>
<property>
    <name>hbase.region.server.rpc.scheduler.factory.class</name>
    <value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value>
    <description>Factory to create the Phoenix RPC Scheduler that uses separate queues for index and metadata updates</description>
</property>
<property>
    <name>hbase.rpc.controllerfactory.class</name>
    <value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value>
    <description>Factory to create the Phoenix RPC Scheduler that uses separate queues for index and metadata updates</description>
</property>
  • 复制 hbase-site.xml 到 phoenix/bin 目录下
  • 复制 hadoop目录下的core-site.xml hdfs-site.xml到 phoenix/bin 目录下
  • 补丁 hbase-common-2.0.5.jar
for i in `seq 2 5`; do \
    scp phoenix-5.0.0-HBase-2.0-server.jar phoenix-5.0.0-HBase-2.0-client.jar phoenix-core-5.0.0-HBase-2.0.jar hbase-common-2.0.5.jar xiaoma0$i:/usr/local/hbase-2.0.5/lib/; \
done

for i in `seq 2 5`; do scp hbase-site.xml xiaoma0$i:/usr/local/hbase-2.0.5/conf/; done

4.3 Go 客户端

4.4 启动 phoenix

export PHOENIX_HOME=/usr/local/phoenix
# 测试运行
$PHOENIX_HOME/bin/sqlline.py xiaoma01,xiaoma02,xiaoma03:2181

# 查询服务
$PHOENIX_HOME/bin/queryserver.py start|stop

4.5 二级索引和oracle 的索引不一样。

SELECT v2 FROM my_table WHERE v1 = 'foo'
-- 这样查询, 要用上索引, 需要v1, v2一起建索引。如果查询结果中字段有多的, 将用不上索引。查询结果是rowkey的话, 可以不要INCLUDE。
CREATE INDEX my_index ON my_table (v1) INCLUDE (v2)

4.6 一些针对phoenix的优化措施

由于phoenix本质上在HBase读写数据, 所以HBase集群的性能影响是最大的, 一般使用多节点(一般hadoop集群节点要大于等于5个)、SSD、更大的内存与缓存和对phoenix/hbase/hadoop配置参数进行调优能获得更大性能的提升。

  • 主键: 主键对应HBase的row key, HBase会把相近的row key放到相同的region里, 如果选择的主键是单调递增的, 那么某个region就会变成热点, 写入的性能会变差, 这种情况需要在建表的使用SALT_BUCKETS=N来自动对数据分片。
  • 优化读: 使用全局索引, 这会对写入的速度有一定影响。查询时注意使用exlain来看执行计划是否使用了索引。
  • 优化写: 使用本地索引, 建表时预先指定好分区方案(pre-split)。
  • 数据是否可变: 如果数据只是写入, 以后不会变更, 可以在建表的时候指定IMMUTABLE_ROWS=true, 这样可以提高写入的性能。
  • 适当使用查询hint来优化执行计划: 用explain查看执行计划, 用hint来优化。支持的语法见hinting。

4.7 异步创建索引

一般我们可以使用CREATE INDEX来创建一个索引, 这是一种同步的方法。但是有时候我们创建索引的表非常大, 我们需要等很长时间。Phoenix 4.5以后有一个异步创建索引的方式, 使用关键字ASYNC来创建索引:

CREATE INDEX index1_c ON hao1 (age) INCLUDE(name) ASYNC;

这时候创建的索引表中不会有数据。你还必须要单独的使用命令行工具来执行数据的创建。当语句给执行的时候, 后端会启动一个map reduce任务, 只有等到这个任务结束, 数据都被生成在索引表中后, 这个索引才能被使用。启动工具的方法:

${HBASE_HOME}/bin/hbase org.apache.phoenix.mapreduce.index.IndexTool --schema MY_SCHEMA --data-table MY_TABLE --index-table ASYNC_IDX
# 这个任务不会因为客户端给关闭而结束, 是在后台运行。你可以在指定的文件ASYNC_IDX_HFILES中找到最终实行的结果。

5. 其他

5.1 对于数据库应用, 不推荐使用透明大页

cat /sys/kernel/mm/transparent_hugepage/enabled
# 如果返回 [always] madvise never 则表示处于启用状态
# 如果输出 always madvise [never] 表示透明大页处于禁用状态。

# 如果不希望重启机器, 也可以修改当前的内核配置来立即生效
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

5.2 常见错误提示

  • regionserver.HRegionServer: Failed construction RegionServer
  • hbase Master not initialized after 200000 ms
  • master.HMasterCommandLine: Master exiting