文章插图
- 首先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server;
- 访问对应的 Region Server,获取 hbase:meta 表,将其缓存到连接中,作为连接属性 MetaCache,由于 Meta 表格具有一定的数据量,导致了创建连接比较慢; 之后使用创建的连接获取 Table,这是一个轻量级的连接,只有在第一次创建的时候会检查表格是否存在访问 RegionServer , 之后在获取 Table 时不会访问 RegionServer;
- 调用Table的put方法写入数据,此时还需要解析RowKey,对照缓存的MetaCache,查看具体写入的位置有哪个 RegionServer;
- 将数据顺序写入(追加)到 WAL,此处写入是直接落盘的 , 并设置专门的线程控制 WAL 预写日志的滚动(类似 Flume);
- 根据写入命令的 RowKey 和 ColumnFamily 查看具体写入到哪个 MemStory , 并且在 MemStory 中排序;
- 向客户端发送 ack;
- 等达到 MemStore 的刷写时机后,将数据刷写到对应的 story 中 。
- 当某个 memstroe 的大小达到了 hbase.hregion.memstore.flush.size(默认值 128M) , 其所在 region 的所有 memstore 都会刷写 。当 memstore 的大小达到了hbase.hregion.memstore.flush.size(默认值 128M)* hbase.hregion.memstore.block.multiplier(默认值 4)时,会刷写同时阻止继续往该 memstore 写数据(由于线程监控是周期性的,所有有可能面对数据洪峰,尽管可能性比较?。?/li>
- 由 HRegionServer 中的属性 MemStoreFlusher 内部线程 FlushHandler 控制 。标准为LOWER_MARK(低水位线)和 HIGH_MARK(高水位线),意义在于避免写缓存使用过多的内存造成 OOM 。当 region server 中 memstore 的总大小达到低水位线java_heapsize * hbase.regionserver.global.memstore.size(默认值 0.4) * hbase.regionserver.global.memstore.size.lower.limit(默认值 0.95),region 会按照其所有 memstore 的大小顺序(由大到?。┮来谓兴⑿?。直到 region server 中所有 memstore 的总大小减小到上述值以下 。当 region server 中 memstore 的总大小达到高水位线java_heapsize * hbase.regionserver.global.memstore.size(默认值 0.4)时 , 会同时阻止继续往所有的 memstore 写数据 。
- 为了避免数据过长时间处于内存之中,到达自动刷写的时间 , 也会触发 memstore flush 。由 HRegionServer 的属性 PeriodicMemStoreFlusher 控制进行,由于重要性比较低 , 5min才会执行一次 。自动刷新的时间间隔由该属性进行配置 hbase.regionserver.optionalcacheflushinterval(默认1 小时) 。
- 当 WAL 文件的数量超过 hbase.regionserver.max.logs,region 会按照时间顺序依次进行刷写,直到 WAL 文件数量减小到 hbase.regionserver.max.log 以下(该属性名已经废弃,现无需手动设置,最大值为 32) 。
- rowlength -----------→ key 的长度
- row -----------------→ key 的值
- columnfamilylength --→ 列族长度
- columnfamily --------→ 列族
- columnqualifier -----→ 列名
- timestamp -----------→ 时间戳(默认系统时间)
- keytype -------------→ Put
文章插图
# hbase hfile -m -f /hbase/data/命名空间/表名/regionID/列族/HFile 名hbase hfile -m -f /hbase/data/test/student/ddb70e9c7d26db051de3811155495d51/info/761e9ab212d746b49f4c8b06e775e979
文章插图
读流程如下
文章插图