date: 2020-10-26 15:43:00
updated: 2020-10-26 18:45:00
master负责管理多个region server,一个region server里有多个region。
一个表会划分多个region,起初只有一个,数据增多,region增大到一定程度会拆分成2个region
一个表最终被保存在多个region server里
hmaster挂了不影响读写,但是 create table 这种涉及元数据的操作,如果hmaster挂了就会报错
一个region里有多个store,一个store代表一个列族。(region按照行键来划分,所以相当于每一行有几个列族就有几个store)
store包括两部分:内存中的memstore和磁盘的storefile。写数据会先写到memstore,当数据达到阈值(默认64M)后 region server 会启动 flushcache 进行将数据写到 storefile里,每次形成一个storefile
当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、major ),在合并过程中会进行版本合并和删除工作(major),形成更大的storefile
当一个region所有storefile的大小和数量超过一定阈值后,会把当前的region分割为两个,并由hmaster分配到相应的regionserver,实现负载均衡
客户端检索数据,先在memstore找,找不到再去blockcache查找,找不到再找storefile,即:client->memstore->blockcache->storefile。如果读到了会把数据放到blockcache里缓存,方便下次读取
Region是HBase中存储和负载均衡的最小单元,不同的Region可以分布在不同的 Region Server上
Region由一个或者多个Store组成,每个store保存一个columns family
每个Strore又由一个memStore和0至多个StoreFile组成
memstore为写入缓存,blockcache为读取缓存
Client 向 zk 发送请求,请求 meta 表所有的 regionServer
zk 返回 regionServer 地址
Client 获取到 meta 表,请求对应的 region 所在的 regionServer
返回 meta 表数据
Client 向 regionServer 发送写数据请求
写入 wal(write ahead log)
将数据写入 memstore
regionServer 反馈给 Client 写入成功
在 0.9 版本(低版本)时,还存在一个 -ROOT- 表,作用是为了避免meta表过大而拆分为多个子表,可以通过 -ROOT- 表来对meta表进行管理
第6步和第7步 具体流程如下:
hbase-server-2.3 版本 搜索 HRegion 类,再搜索 STEP 1,doMiniBatchMutate(BatchOperation<?> batchOp) 方法即为写数据的部分
// STEP 1. Try to acquire as many locks as we can and build mini-batch of operations with locked rows => 写入之前先获取锁 // STEP 2. Update mini batch of all operations in progress with LATEST_TIMESTAMP timestamp // We should record the timestamp only after we have acquired the rowLock, // otherwise, newer puts/deletes are not guaranteed to have a newer timestamp => client如果不传时间戳,会自动获取服务器端的时间戳 // STEP 3. Build WAL edit // STEP 4. Append the WALEdits to WAL and sync. // STEP 5. Write back to memStore
hbase-server-1.3 版本 doMiniBatchMutate(BatchOperation<?> batchOp) 方法不一样。也是先 Build WAL edit,写入日志,但是并没有先同步,而且先写入memstore,在 finally 那里去判断 wal log 是否同步成功,如果不成功,回滚 memstore 记录
写数据时会先向hlog写(方便memstore里的数据丢失后根据hlog恢复,向hlog中写数据的时候也是优先写入内存,后台会有一个线程定期异步刷写数据到hdfs,如果hlog的数据也写入失败,那么数据就会发生丢失)
频繁的溢写会导致产生很多的小文件,因此会进行文件的合并,文件在合并的时候有两种方式,minor和major,minor表示小范围文件的合并,major表示将所有的storefile文件都合并成一个
当写数据到一定程度之后,会把内存中的数据flush到磁盘,配置项在 hbase-default.xml
1. habse.regionserver.global.memstore.size 默认大小为内存大小的0.4。当regionserver的所有的memstore的大小超过这个值的时候,会阻塞客户端的读写 2. habse.regionserver.global.memstore.size.lower.limit 默认大小为第一个配置项的大小的0.95。即从这个值开始flush到内存,如果写数据过快,超过flush的速度,导致memstore逐渐变大,达到堆大小的0.4,那么就会暂停读写操作,专注于flush,直到memstore的大小下降 3. hbase.regionserver.optionalcacheflushinterval 默认为1个小时(当前内存最后一次编辑时间+1个小时),自动flush到磁盘 4. hbase.hregion.memstore.flush.size 单个region里memstore大小。默认为128M,超过这个大小就会刷写 5. hbase.regionserver.max.logs 如果wal的文件数量达到这个值(默认32),就会刷写 6. hbase.regionserver.hlog.blocksize 默认HDFS 2.x版本默认的blocksize大小 4. 读数据Client 向 zk 发送请求,请求 meta 表所有的 regionServer
zk 返回 regionServer 地址
Client 获取到 meta 表,请求对应的 region 所在的 regionServer
返回 meta 表数据
Client 向 regionServer 发送读数据请求