当前位置: 首页 > news >正文

HBase 的 MemStore 详解

一、MemStore 概述

        MemStore 是 HBase 的内存存储区域,它是一个负责缓存数据写入操作的组件。每当有写操作(如 Put 或 Delete)发生时,数据会首先被写入到 MemStore 中,而不是直接写入磁盘。MemStore 类似于数据库中的缓冲区,主要用于提升写操作的性能。当 MemStore 达到一定的容量时,数据会被刷新(flush)到磁盘上,形成 HFile 文件存储在 HDFS 中。

二、MemStore 的工作原理

        HBase 中每个 RegionServer 负责管理多个表的 Region,每个 Region 包含多个列族 (Column Family)。每个列族都拥有自己的 MemStore,这意味着一个 Region 中的每个列族都有一个独立的 MemStore 用于缓存数据写入操作。

        MemStore 的主要功能是缓存数据,以便快速响应写入操作,并在合适的时机将数据刷写到 HDFS 上的 HFile 中。

工作流程:

  1. 数据写入:当客户端执行 Put 操作时,数据会首先写入到 WAL(Write-Ahead Log)中,以确保数据的持久性,之后才写入 MemStore。
  2. 数据缓存:数据在 MemStore 中缓存,多个写操作会先在 MemStore 中进行合并,以减少频繁的磁盘 I/O。
  3. 数据刷写 (Flush):当 MemStore 的数据量达到配置的阈值(通常默认是 128MB)时,MemStore 的数据会被刷写到磁盘,形成新的 HFile。此时,MemStore 会被清空,新的数据将被写入到一个新的 MemStore 中。
  4. Compaction:刷写到磁盘的 HFile 文件在一定时间或条件下会进行合并(称为 Minor 和 Major Compaction),以减少小文件的数量并优化查询性能。

三、MemStore 的结构

        MemStore 实际上是一个多版本并发控制(MVCC)存储系统,它以一种顺序有序的方式存储数据。底层实现上,MemStore 采用的是 ConcurrentSkipListMap 数据结构,这是一种线程安全的跳表结构,具有良好的并发性能和有序性。

MemStore 的关键数据结构:

  1. ConcurrentSkipListMap:跳表是 MemStore 的核心数据结构,所有的写操作(Put 和 Delete)都会被缓存到一个跳表中。跳表是一种基于有序链表的索引结构,具有 O(log n) 的时间复杂度,可以快速查找、插入和删除元素。

  2. KeyValue:MemStore 中存储的每条数据都是一个 KeyValue 对象,KeyValue 包含了 RowKey、列族、列、时间戳和值等信息。通过这种方式,HBase 可以支持多版本数据(MVCC)。

  3. Snapshot:当 MemStore 需要刷写到磁盘时,会创建一个 MemStore 的快照 (Snapshot),这样在进行刷写时,新的写操作仍然可以写入到新的 MemStore 中,而不会阻塞写入操作。快照存储在内存中,直到数据被完全刷写到 HFile 中。

MemStore 中数据版本管理:

        HBase 使用了多版本并发控制 (MVCC) 来确保数据一致性,MemStore 通过存储多个版本的数据来支持数据的历史查询。每个 KeyValue 对象都有一个时间戳,HBase 可以根据这个时间戳来区分不同版本的同一条数据,并且在读取时可以根据查询的时间范围返回指定版本的数据。

public class MemStore {// 存储数据的核心结构private final ConcurrentSkipListMap<KeyValue, KeyValue> kvset;// MemStore 快照private volatile ConcurrentSkipListMap<KeyValue, KeyValue> snapshot;public void add(KeyValue kv) {// 将数据插入到 SkipList 中kvset.put(kv, kv);}public void snapshot() {// 创建 MemStore 的快照,之后会进行刷写操作this.snapshot = kvset;// 清空当前的 MemStore,准备接受新的写入kvset = new ConcurrentSkipListMap<>();}public void flush() {// 将 snapshot 中的数据刷写到 HFilefor (Map.Entry<KeyValue, KeyValue> entry : snapshot.entrySet()) {// 写入 HFile}// 刷写完成后,清空 snapshotsnapshot.clear();}
}

四、MemStore 刷写策略

MemStore 不会一直保持数据在内存中,通常会在以下几种情况下触发刷写操作:

  1. MemStore 达到阈值:当 MemStore 中的数据量达到一定阈值时(如 128MB),MemStore 的数据会被刷写到磁盘。

  2. RegionServer 内存压力:当 RegionServer 的整体内存使用量接近系统允许的上限时,HBase 会主动触发 MemStore 的刷写,以释放内存。

  3. 手动触发:在某些运维场景下,管理员可以通过命令手动触发 MemStore 刷写操作。

刷写过程:

刷写时,MemStore 中的所有数据会被转换成 HFile 格式,并存储在 HDFS 上的磁盘中。刷写过程包括以下步骤:

  1. 创建快照:首先,MemStore 会创建一个快照来冻结当前的状态,以便在刷写期间仍然可以处理新的写请求。
  2. 数据排序:将快照中的数据按照 RowKey 进行排序。
  3. 写入 HFile:排序后的数据会写入到新的 HFile 中,并保存到 HDFS。
  4. 更新元数据:刷写完成后,更新元数据以使新的 HFile 生效,并清空 MemStore 快照。
public void flushSnapshot() {// 将 snapshot 中的数据刷写到 HFileHFile.Writer writer = ...; // HFile 写入器for (Map.Entry<KeyValue, KeyValue> entry : snapshot.entrySet()) {writer.append(entry.getKey(), entry.getValue());}writer.close(); // 完成 HFile 写入snapshot.clear(); // 清空 snapshot
}

刷写触发的配置项

  • hbase.hregion.memstore.flush.size:MemStore 的最大容量,当 MemStore 达到这个阈值时会触发刷写。默认值为 128MB。
hbase.hregion.memstore.flush.size=128MB

  • hbase.regionserver.global.memstore.size:RegionServer 中所有 MemStore 的总内存占用比例。当内存使用超过这个比例时,HBase 会选择最老的 MemStore 进行刷写,释放内存。默认值为 40%。
hbase.regionserver.global.memstore.size=0.4

五、MemStore 和 WAL 的关系

        每次写入 HBase 时,数据首先会写入 WAL(Write-Ahead Log),然后写入 MemStore。WAL 是一种日志机制,确保在系统崩溃时能够通过 WAL 进行数据恢复。当 RegionServer 崩溃或宕机时,HBase 可以通过 WAL 恢复 MemStore 中未刷写到磁盘的数据。因此,WAL 的存在保证了数据的可靠性。

  • WAL 和 MemStore 的同步:每次写入时,数据会首先写入 WAL 并刷盘,确保数据不会丢失,然后才会写入 MemStore。MemStore 中的数据在达到阈值时才会刷写到 HFile,而 WAL 则会在每次写操作时进行日志写入。

六、MemStore 的优化配置

MemStore 的合理配置和调优是提升 HBase 性能的重要手段之一。以下是常见的优化策略:

    1. 调整 MemStore 大小:增加 MemStore 的大小可以减少刷写的频率,从而减少磁盘 I/O。但过大的 MemStore 会占用大量内存,影响系统的整体内存使用效率。

hbase.hregion.memstore.flush.size=256MB # 增大每个列族的 MemStore 大小

    2. MemStore 压缩:HBase 支持在内存中对 MemStore 数据进行压缩,减少内存占用。可以通过 hbase.hregion.memstore.inmemory.compaction 参数来启用。

hbase.hregion.memstore.inmemory.compaction=true

    3. 调整 RegionServer 内存使用比例:根据系统内存大小和业务需求,调整 hbase.regionserver.global.memstore.size 和 hfile.block.cache.size 参数的值,合理分配 MemStore 和 BlockCache 的内存使用比例。

# 将 MemStore 总内存占用比例调整为 50% 
hbase.regionserver.global.memstore.size=0.5

七、MemStore 和 HBase 性能的关系

MemStore 的性能和配置直接影响 HBase 的整体写性能。以下是 MemStore 对性能的影响:

  1. 写性能:MemStore 的存在大大提升了写操作的性能,因为写入数据首先被缓存到内存中,减少了频繁的磁盘 I/O。
  2. 刷写性能:MemStore 的刷写操作会对系统性能产生一定的影响,特别是在高写入负载时,频繁的刷写会导致较多的磁盘操作,进而影响整体性能。
  3. 内存占用:MemStore 占用了系统的大部分内存资源,合理配置 MemStore 大小和刷写策略,可以平衡写性能和内存使用效率。

八、总结

        HBase 中的 MemStore 是一个核心的缓存机制,它通过缓存写操作来提升写性能,并在合适的时机将数据刷写到磁盘。在实现上,MemStore 使用了 ConcurrentSkipListMap 数据结构,保证了数据的有序性和高效的并发操作。通过合理配置 MemStore 的大小和刷写策略,可以在 HBase 中实现高效的写入和查询性能。在实际应用中,针对不同的业务场景和负载需求,需要对 MemStore 进行调优,以最大化系统性能。

相关文章:

HBase 的 MemStore 详解

一、MemStore 概述 MemStore 是 HBase 的内存存储区域&#xff0c;它是一个负责缓存数据写入操作的组件。每当有写操作&#xff08;如 Put 或 Delete&#xff09;发生时&#xff0c;数据会首先被写入到 MemStore 中&#xff0c;而不是直接写入磁盘。MemStore 类似于数据库中的缓…...

【嵌入式软件-数据结构与算法】01-数据结构

摘录于老师的教学课程~~(*๓╰╯๓)~~内含链表、队列、栈、循环队列等详细介绍~~ 基础知识系列 有空再继续更~~~ 目录 【链表】 一、单链表 1、存储结构&#xff1a;带头结点的单链表 2、单链表结点类型的定义 3、创建单链表 1&#xff09;头插法 2&#xff09;尾插法 …...

Windows应用开发-解析AVI视频文件

本Windows应用解析AVI视频文件&#xff0c;以表格的方式显示AVI文件结构。并可以将结果保存到bmp图片。下面是&#xff0c;使用该应用解析一部AVI电影获得的图片。 应用开发信息 定义一个INFO结构&#xff0c;包含两个字符串对象&#xff0c;一个ULONGLONG变量&#xff0c;和…...

探索TCP协议的奥秘:Python中的网络通信

引言 在网络通信的世界里&#xff0c;TCP协议&#xff08;传输控制协议&#xff09;就如同一座桥梁&#xff0c;连接着数据的发送方和接收方。作为一名拥有20年实战经验的编码专家&#xff0c;我深知TCP协议在构建稳定、可靠的网络应用中的重要性。今天&#xff0c;我将带领大…...

每日学习一个数据结构-树

文章目录 树的相关概念一、树的定义二、树的基本术语三、树的分类四、特殊类型的树五、树的遍历六、树的应用场景 树的遍历一、前序遍历二、中序遍历三、后序遍历使用java代码实现遍历总结 树的相关概念 树是一种重要的非线性数据结构&#xff0c;在计算机科学中有着广泛的应用…...

简单PCL库读文件(linux vscode编译)

#include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/common/common.h> #include <iostream>int main(int argc, char** argv) {if (argc ! 2) {std::cerr << "请指定 PCD 文件路径" << std::endl;return -…...

【自动驾驶】最近计划看的论文

将对应的论文链接贴出来&#xff0c;当作监督自己。 方向&#xff1a;端到端自动驾驶 方法论文代码UniADhttps://arxiv.org/pdf/2212.10156https://github.com/OpenDriveLab/UniADVADhttps://arxiv.org/pdf/2303.12077https://github.com/hustvl/VADUADhttps://arxiv.org/pdf…...

vue3学习:axios输入城市名称查询该城市天气

说来惭愧&#xff0c;接触前端也有很长一段时间了&#xff0c;最近才学习axios与后端的交互。今天学习了一个查询城市天气的案例&#xff0c;只需输入城市名称&#xff0c;点击“查询”按钮便可以进行查询。运行效果如下&#xff1a; 案例只实现了基本的查询功能&#xff0c;没…...

影刀RPA实战:Excel拆分与合并工作表

1.影刀操作excel的优势 Excel&#xff0c;大家都不陌生&#xff0c;它是微软公司推出的一款电子表格软件&#xff0c;它是 Microsoft Office 套件的一部分。Excel 以其强大的数据处理、分析和可视化功能而闻名&#xff0c;广泛应用于商业、教育、科研等领域。可以说&#xff0…...

STM32三种启动模式:【详细讲解】

STM32在上电后&#xff0c;从那里启动是由BOOT0和BOOT1引脚的电平决定的&#xff0c;如下表&#xff1a; BOOT模式选引脚启动模式BOOT0BOOT1X0主Flash启动01系统存储器启动11内置SRAM启动 BOOT 引脚的值在重置后 SYSCLK 的第四个上升沿时被锁定。在重置后,由用户决定是如何设…...

Ray_Tracing_The_Next_Week

1动态模糊 动态模糊在摄影中就是快门的速度慢&#xff0c;捕捉光的时间长&#xff0c;物体运动时进行捕捉成像&#xff0c;拍出来的结果是这个运动过程每一帧的平均值 我们的思路是&#xff1a; 每一条光线都拥有自己存在的一个时间点。随着时间变化随机生成光线,一般来说我…...

DBT hook 实战教程

本文将介绍dbt中在模型和seed级别使用post-hook的几个具体示例。dbt中的Post-hooks是一个强大而简单的特性&#xff0c;它在构建模型之后(如果是pre-hook&#xff0c;甚至在此之前)执行SQL语句。这些语句实际上(几乎)可以是任何东西&#xff0c;从将表复制到另一个数据库/模式&…...

SpringBoot整合JPA详解

SpringBoot版本是2.0以上(2.6.13) JDK是1.8 一、依赖 <dependencies><!-- jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><!--…...

【微服务】springboot 实现动态修改接口返回值

目录 一、前言 二、动态修改接口返回结果实现方案总结 2.1 使用反射动态修改返回结果参数 2.1.1 认识反射 2.1.2 反射的作用 2.1.3 反射相关的类 2.1.4 反射实现接口参数动态修改实现思路 2.2 使用ControllerAdvice 注解动态修改返回结果参数​​​​​​​ 2.2.1 注解…...

【前端开发入门】html快速入门

目录 引言一、html基础模板内容二、html文档流三、html 标签1.块级元素2.行内元素3.功能性元素4.标签嵌套 四、html编码习惯五、总结 引言 本系列教程旨在帮助一些零基础的玩家快速上手前端开发。基于我自学的经验会删减部分使用频率不高的内容&#xff0c;并不代表这部分内容不…...

python配置环境变量

方法一&#xff1a;首先卸载重新安装&#xff0c;在安装时勾选增加环境变量 方法二&#xff1a;我的电脑-属性-高级系统配置 手动添加环境变量&#xff0c;路径为python的安装路径 检查&#xff1a;查看环境变量是否安装成功 安装第三方lib winr&#xff0c;输入cmd pip ins…...

从0到1:培训机构排课小程序开发笔记一

业务调研 随着人们生活水平的提高&#xff0c;健康意识和学习需求日益增强&#xff0c;私教、健身和培训机构的市场需求迅速增长。高效的排课系统不仅可以提升机构的管理效率&#xff0c;还能提高学员的满意度。解决传统的排课方式存在的时间冲突、信息不对称、人工操作繁琐等…...

方法重载(Overload)

前言 在前面的学习中&#xff0c;我们学到了重写(Override),这里我们主要进行重载(Overload)的介绍&#xff0c;同时对重写和重载的区别进行分析。 1. 重载(Overload) #方法重载 在同一个类中定义多个同名但参数不同的方法。我们称方法与方法之间构成方法重载 在Java中&…...

[论文笔记]SGPT: GPT Sentence Embeddings for Semantic Search

引言 解码器Transformer的规模不断壮大&#xff0c;轻松达到千亿级参数。同时由于该规模&#xff0c;基于提示或微调在各种NLP任务上达到SOTA结果。但目前为止解码器Transformer还无法应用在语义搜索或语句嵌入上。 为了简单&#xff0c;下文中以翻译的口吻记录&#xff0c;比…...

基于微信小程序的旅游拼团系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

富格林:警悟可信经验安全投资

富格林指出&#xff0c;黄金具有不错的投资价值&#xff0c;一直以来备受投资者的喜爱&#xff0c;近年来大家也纷纷加入现货黄金市场为己增值财富。但是要为投资安全护航的前提&#xff0c;是需要投资者使用合适可信的方法以及掌握相对应的投资技巧。下面富格林将总结以下可信…...

【Linux】使Ubuntu自适应窗口大小并与主机共享文件

LInux虚拟机版本ubuntu-20.04.6&#xff0c;VM版本VMware Workstation 17 Pro VMware Tools™ 是一组服务和模块&#xff0c;是VMware公司在其虚拟化平台中提供的一套工具集&#xff0c;旨在提高虚拟机的性能和稳定性。它们支持 VMware 产品中的多种功能特性&#xff0c;有助于…...

C++ 语言特性18 - static_assert 介绍

一&#xff1a;概述 在 C 中&#xff0c;static_assert 是一种用于在编译时进行断言的机制&#xff0c;确保某些编译时条件成立。如果条件不成立&#xff0c;则编译器会生成错误&#xff0c;阻止代码的编译。static_assert 在 C11 中引入&#xff0c;目的是帮助程序员在编译时捕…...

centos 7.9系统redis6.2.6哨兵模式部署

由于系统需要处理大量的数据并发请求,所以借助于Redis的高性能,可以有效提升整个系统的处理效率。这里采用redis6.2版本源码编译部署哨兵模式,提高整个系统的可用性,避免单点故障。 1. Redis基本环境安装 centos7安装redis 6.2.6 采用源码编译方式安装。 服务器主机名:…...

编程基础:详解 C++ 中的 `std::sort` 函数

编程基础&#xff1a;详解 C 中的 std::sort 函数 在C编程中&#xff0c;排序是非常常见的操作&#xff0c;而std::sort是C标准库中用于排序的一个高效函数。它提供了灵活的排序功能&#xff0c;可以使用默认排序规则或自定义的比较函数。本文将深入探讨std::sort的用法、参数要…...

51单片机的宠物自动投喂系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块温湿度传感器DS1302时钟模块蓝牙步进电机按键、蜂鸣器等模块构成。适用于猫猫/狗狗宠物自动喂食器等相似项目。 可实现基本功能: 1、LCD1602实时显示北京时间和温湿度 2、温湿度传感器DHT11采集环境温湿度 3、时…...

MongoDB快速实战与基本原理

目录 链接:https://note.youdao.com/ynoteshare/index.html?id=5e038498891617c552667b853742fdc1&type=note&_time=1727935558812 Mongo数据库的特点: mongo数据库和关系型数据库的区别: ​编辑 关系型数据库和文档型数据库的主要概念对比: 下载和启动(具体…...

编程技巧:优化

第一种&#xff1a;构造回文串---构造法 题目描述 [NOIP2016 普及组] 回文日期 - 洛谷 那么这道题我们总结一些题目要求&#xff1a; 1.输入两个字符串&#xff0c;为起始和终止日期 2.年份不会出现前导0 3.如果是回文日期&#xff0c;答案1 4.如果月份是2&#xff0c;要…...

pycharm中使用anaconda创建多环境,无法将“pip”项识别为 cmdlet、函数、脚本文件或可运行程序的名称

问题描述 用的IDE是&#xff1a; 使用anaconda创建了一个Python 3.9的环境 结果使用pip命令的时候&#xff0c;报错 无法将“pip”项识别为 cmdlet、函数、脚本文件或可运行程序的名称 解决方案 为了不再增加系统变量&#xff0c;我们直接将变量添加在当前项目中你的Ter…...

【Linux】进程周边之优先级

目录 一、优先级 1.为什么要有进程优先级&#xff1f; 2.什么是进程优先级&#xff1f; 3.优先级的初始设定 3.1 PRI 和 NI 3.2如何修改优先级&#xff1f;&#xff08;sudo/root&#xff09; 3.2.1 概念&#xff1a; 3.2.2 如何查看进程的优先级&#xff1f; 3.3.3 或…...