HBase的数据的update

本文详细解析了HBase中如何通过rowkey、column和timestamp三个维度来区分数据,并介绍了HBase是如何确保每次获取的都是最新数据的方法。文章还深入探讨了HBase在内存中的数据排序规则及get操作的具体流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hbase是以rowkey,column,timestamp这三个维度来区分的。

即如果两条记录其rowkey,column,timestamp一样的话,那么hbase就会认为其是相同的数据。

 

Java代码  收藏代码
  1.          row     column   value   time  
  2. put      r1     cf:c1      '5'       10  
  3. put      r1     cf:c1      '6'       10  
  4. put      r1     cf:c2      '7'    
  5. put      r1     af:c2      '8'  
  6. put      r2     cf:c1      '9'  

 

 如上所示首先插入一条数据其值为5,然后又插入一条数据其值为6.

此时用客户端接口取到的都是value=‘6’的数据,这可以认为是对原数据的一个覆盖。

我们知道hbase的write数据是以append的形式追加的。只有当前compact的时候才会进行无效数据删除。

那么在compact之前hbase的存储文件就存在该记录的两份不同的数据,那么hbase是怎么区别这两份数据,并返回给用户的呢,下面从代码角度来分析

首先我们来看hbase的put过程,这个逻辑比较清除,首先根据table,和row找到相对应的region,然后和该region的regionserver通信。

其写入过程是一个wal过程,即先写日志后写内存,保证数据不会因为regionserver down而丢失。

 

写日志的过程不赘述了。

 

主要来看看写memstore的过程:

 

Java代码  收藏代码
  1. private long applyFamilyMapToMemstore(Map<byte[], List<KeyValue>> familyMap) {  
  2.   ReadWriteConsistencyControl.WriteEntry w = null;  
  3.   long size = 0;  
  4.   try {  
  5.     w = rwcc.beginMemstoreInsert();  
  6.   
  7.     for (Map.Entry<byte[], List<KeyValue>> e : familyMap.entrySet()) {  
  8.       byte[] family = e.getKey();  
  9.       List<KeyValue> edits = e.getValue();  
  10.   
  11.       Store store = getStore(family);  
  12.       for (KeyValue kv: edits) {  
  13.         kv.setMemstoreTS(w.getWriteNumber());  
  14.         size += store.add(kv);  
  15.       }  
  16.     }  
  17.   } finally {  
  18.     rwcc.completeMemstoreInsert(w);  
  19.   }  
  20.   return size;  
  21. }  

 

rwcc是用来控制读写一致性的,对于任何一个put,当其写入memstore的时候,都会设置其MemstoreTs的值。

而这个值在内存中是以一个递增的形式存在的,即新写入内存的数据比旧的其MemstoreTs大。而这个值就是用来保证在内存中的update的可靠性。举个例子,还是上面的两个put

1. put      r1     cf:c1      '5'       10
2. put      r1     cf:c1      '6'       10

第一条记录首先写进内存其memstoreTs为1,第二条记录的memstoreTs为二,那么第二条记录在内存中就排在第一条记录前面,说到这来看看内存中数据是怎么排序的。

 

我们知道hbase 是以key-value存放数据的,其底层存储完全依赖HDFS文件系统。

同样在内存中存储的也是key-value,在磁盘上是以storefile(hfile)存储,且都是有序的

其排序规则如下:

(以自然序列排序 a<b,2<3,23<3)

首先比较 rowkey 小的排前面

然后是  family小的排前面

接下来按排 column

然后是timestamp 排序 时间越大的拍前面

接下来是按key的TYPE排序 有min,delete,deleteFamily,put,deletecolumn,max

最后比较文件的maxsequenceId,越大的说明越新排在前面。memstore的maxsequenceId默认是整数最大值

如果是两个相同key的put的数据都在内存里那么上面的比较规则就都不适用了,此时就会比较这两个put的memstoreTs, 大的排在前面。

我们知道一个put里面可以有很多cf,那么如果在一个put当中有两个一样的数据,此时会如何呢。

这个hbase也做了处理。一个put中维护的是一个familymap<family,map<>>格式,显然当有两条一致的数据插入时,map自动会覆盖前一条数据。

 

 

那么此时用户以指定key取该条数据的话,会遵循以下原则:

 

首先从定位memstore和每个storefile(一个family就是一个Hstore,包裹一个Memstore和n个storefile)的target value的row的起始处。,比较当前memstoe和storefile的keyvalue,选取最靠前的数据,若满足则返回,若不满足则取下一条知道找到为止。

 显然在这个过程中上述的put的第二条数据肯定是在第一条数据前面的,所以首先会取到第二条即最新的数据~~~

 

hbase就是通过keyvalue的排序和get的机制来保证取到的都是最新的value

### HBase 实时数据更新的方法 HBase 是一种分布式 NoSQL 数据库,支持高效的实时读写操作。为了实现实时数据更新,HBase 提供了几种机制来满足不同的需求。 #### 1. **基于 Put 和 Delete 的更新** HBase 中的数据更新主要依赖 `Put` 和 `Delete` 操作。当执行 `Put` 操作时,新版本的数据会被追加到存储中,并带有时间戳标记[^3]。如果需要删除某些数据,则可以通过 `Delete` 命令移除指定的单元格或整行数据。由于 HBase 支持多版本控制 (MVCC),旧版本的数据仍然保留直到被垃圾回收机制清理掉。 #### 2. **利用 Phoenix 进行 SQL 风格的更新** Apache Phoenix 是构建在 HBase 上的一个开源项目,它允许开发者通过标准 SQL 接口访问 HBase 表中的数据[^5]。借助 Phoenix,用户可以直接使用 `UPDATE` 或 `UPSERT` 语句完成复杂的批量修改任务。这种方式不仅简化了开发流程,还提供了更强大的索引管理能力,从而加速查询性能并保障一致性。 #### 3. **增量加载与同步策略** 对于大规模生产环境下的应用来说,仅仅依靠单条记录级别的变更可能不够高效。此时可以考虑采用增量导入的方式定期捕获源系统的最新变动部分再将其同步至目标端——即此处提到的 HBase 。具体做法包括但不限于依据预设的时间范围筛选符合条件的新增/修改项作为待迁移对象列表;随后针对该集合发起针对性检索请求获取实际内容最后实施持久化入库动作[^2]。 #### 4. **事务处理的支持** 尽管传统意义上的 ACID 特性并非原生存在于 HBase 当中 ,但是随着技术发展目前已经存在多种途径达成近似效果比如 Coprocessor 执行框架配合自定义逻辑或者引入第三方工具包如 Apache Kudu 来弥补这一短板以便更好地服务于那些对可靠度要求极高的场景下运行的应用程序实例们. 综上所述,Hbase 可以通过以上几种方式实现其内部结构里所保存着的信息元素们的即时刷新调整过程. ```python from happybase import Connection def update_hbase_data(table_name, row_key, data_dict): connection = Connection('localhost') table = connection.table(table_name) with table.batch() as b: for column_family, columns in data_dict.items(): for col, value in columns.items(): full_col = f"{column_family}:{col}" b.put(row_key, {full_col: str(value)}) connection.close() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值