HBase深度历险

作者:京东物流 于建飞

在这里插入图片描述

简介

HBase 的全称是 Hadoop Database,是一个分布式的,可扩展,面向列簇的数据库,是一个通过大量廉价的机器解决海量数据的高速存储和读取的分布式数据库解决方案。本文会像剥洋葱一样,层层剥开她的心,直到一丝不挂。

特点

首先我们看一下hbase有哪些特点:

•高性能

基于LSM树的数据结构设计,保证了顺序写,并且通过布隆过滤器,compaction等内部优化手段来优化读性能,使得hbase具有很高的读写性能。

•高可靠

hbase在数据写入之前,会先写入WAL预写日志,用来防止机器宕机时,内存中数据的丢失问题。

•易扩展

底层依赖hdfs,当磁盘空间不足时,可以直接水平扩展。

•稀疏性

稀疏性是 HBase 中的一个突出的特点,在其他数据库中,对于空值的处理一般都会填充 null,对于成百上千万列的表来说,通常会存在大量的空值,如果使用填充 null 的策略,势必会造成大量空间的浪费。而对于 HBase 空值不需要任何填充,因此稀疏性是 HBase 的列可以无限扩展的一个重要的条件。

•列簇存储

使用了列簇存储,可以使用户自由选择哪些列来放在同一个列簇中

•多版本

hbase支持数据多版本的保存,通过时间戳来排序。用户可以根据需要选择最新版本或者某个历史版本。

什么是列簇存储

前边提到了hbase是按照列簇存储来存储数据的,我们先来对比一下行式存储,列式存储以及列簇存储的区别。

•行式存储:

传统的关系型数据库都是按行存储的,也就是每行数据都是存储在一起的。

•列式存储:

数据按列存储,就是每列数据是存储在一起的。按列存储有好处呢?

1.可以节约存储空间,只存储有用的内容,按行存储需要为null值进行处理,而按列存储就不需要了。

2.每一列的类型是一致的,在数据落到磁盘时,可以获得更好的数据压缩效率。

3.大多数情况下,我们再查询的时候是不需要查询出整张表的所有列的,只会用到部分列,但是因为按行存储的方式,每次都必须先将所有字段查询出来,在过滤出我们需要的字段。但是按列存储就不一样了,就像是吃自助餐,按需查询,需要什么就只查询什么,很明显也是可以减少磁盘IO。

•列簇存储:

那什么是列簇存储呢?按列存储是每个列单独存储在一起,这种方式对于字段很多的表来说,如果一次查询设计的列数量太多的话,势必会造成大量的磁盘IO,从而影响查询性能。而列簇存储的意思就是,一个列簇下边可以存储多个列,每个列簇存储在一个文件里,这样就能减少一些磁盘IO,从而提升查询性能。

每个列簇的数据存储在一起,每个列簇可以自由选择储存哪些列。所以列簇存储实际上是给用户提供了一种自由选择的权利,如果所有的列都放到一个列簇里,那实际就相当于按行存储一样,每次查询需要把所有的列全部都查出来,而如果每个列单独存一个列簇的话,就像按列存储一样了。

在当前体系中不建议设置太多列簇,后面也会提到,是因为MemStore在进行flush时候的最小单元不是MemStore,而是整个region,因此设置太多的列簇会是flush十分耗能,但是这种架构为 HBase 将来演变成 HTAP(Hybrid Transactional and Analytical Processing)系统提供了最核心的基础。

架构原理

HBase架构整体上分为3个部分Zookeepper集群,HMaster以及Region server。架构图看上去还挺复杂的,但是最核心的是region server,后边会从region server -> region -> store -> hfile-> data block,一点点的拨开它的外衣。

在这里插入图片描述

1.Zookeeper

在这里插入图片描述

Zookeepper是一个分布式的无中心的元数据存储服务,用来探测和记录HBase集群中服务器的状态信息,hmaster和region server通过定时发送心跳和zk维持关系。

Zookeepper中存储了hbase:meta 表,这张表维护了整个集群所有的 Region 信息,client首先会访问zk,查询hbase:meta 表信息,为了查询性能会将hbase:meta 表信息缓存在客户端。

2.HMaster

在这里插入图片描述

HMaster在hbase中是属于一个leader的角色,不参与具体表数据的管理,只负责宏观把控,主要工作内容有两方面,一个是管理Region server,另一个就执行一些高危操作,比如执行DDL(建表,删除表等)。

HBase Master的功能:

•监控所有RegionServer的状态,在集群处于数据恢复或者动态调整负载时,分配Region到某一个Region Server中

•提供DDL相关的API, 新建(create),删除(delete)和更新(update)表结构

3.Region server

Region server是整个habse架构最为核心的模块,负责实际数据的读写,当访问数据时, 客户端与HBase的Region server直接通信。

HBase的表根据Row Key的区域分成多个Region, 一个Region包含这这个区域内所有数据。而Region server负责管理多个Region, 负责在这个Region server上的所有region的读写操作,一个Region server最多可以管理1000个region。

每个 Region server都把自己的数据存储在HDFS中,如果一个服务器既是Region server又是HDFS的Datanode. 那么这个Region server的数据会在把其中一个副本存储在本地的HDFS中, 加速访问速度。

但是, 如果是一个新迁移来的Region server, 这个region server的数据并没有本地副本. 直到HBase运行compaction, 才会把一个副本迁移到本地的Datanode上面。

3.1 Region server架构图

在这里插入图片描述

RegionServer 主要用来响应用户的 IO 请求,是 HBase 中最核心的模块,由 WAL(HLog)、BlockCache 以及多个 Region 构成。

3.2 HLog(WAL)

HLog其实就是WAL (Write-Ahead-Log) 预写日志,就是在写入memstore之前,会先写到HLog,给数据来个备份,HLog是保存在磁盘上的,从而保证高可靠性。HLog是region server级别的,也就是说整个region server共用一个HLog。

HLog在hbase中有两个作用:

•当region server宕机的时候,还在内存中未进行写入磁盘的数据不会丢失,仍然可以通过 HLog 日志恢复。

•用于实现 HBase 集群间主从复制,通过回放主集群推送过来的 HLog 日志实现主从复制。

HLog 的日志文件存放在 HDFS 中,hbase 集群默认会在 hdfs 上创建 hbase 文件夹,在该文件夹下有一个 WAL 目录,其中存放着所有相关的 HLog,HLog 并不会永久存在,在整个 HBase 总 HLog 会经历如下过程:

1.发生写入操作的时候会先构建 HLog。

2.因为 HLog 会不断追加,所以整个文件会越来越大,因此需要支持滚动日志文件存储,所以 HBase 后台每间隔一段时间(默认一小时)会产生一个新的 HLog 文件,历史 HLog 标记为历史文件。

3.一旦数据进入到磁盘,形成 HFile 后,HLog 中的数据就没有存在必要了,因为 HFile 存储在 HDFS 中,HDFS 文件系统保障了其可靠性,因此当该 HLog 中的数据都落地成磁盘后,该 HLog 会变为失效状态,对应的操作是将该文件从 WAL 移动到 oldWAl 目录,此时文件依旧存在,并未进行删除。

4.hbase 有一个后台进程,默认每间隔一分钟会对失效日志文件进行判断,如果没有任何引用操作,那么此时的文件会被彻底的从物理删除。

3.3 BlockCache

HBase会将从HFile查询出的数据缓存到BlockCache,以便后续可以直接从内存读取,减少磁盘IO。

BlockCache是region级别的,每个region只有一个BlockCache。

HBase的数据仅仅独立存在于MemStore和HFile中,BlockCache中缓存的只是HFile中的部分热点数据。

3.4 region

每个region由一个或多个store组成,region是集群负载均衡的基本单位,是MemStore进行flush的基本单元。整个region其实就是一个LSM树,memstore对应C0树,存储在内存中,作为写缓存,HFile对应Cn树,存储在磁盘上。通过保证顺序写,在牺牲部分读性能的前提下,来大幅度提升写入性能,并且通过布隆过滤器和compaction等内部的优化来弥补读性能,从而达到读写性能都很高。

3.4.1 store

每个store由MemStore和多个StoreFile组成,StoreFile底层实际是HFile,StoreFile是hbase对HFile的封装。每个列簇存储在一个store,所以有几个列簇,就会有几个store,列簇太多就会有过多的MemStore,就会占用过多的内存,并且在进行flush的时候,也会造成更大的耗能。

3.4.1.1 MemStore

MemStore是hbase的写缓存,在写入请求时,当写入HLog成功之后,变先写入MemStore,并且会按照rowkey字典序进行排序,当达到一定阈值的时候,才会flush数据到hdfs形成hfile文件。hbase的MemStore是采用了跳表这一数据结构,在这里就不过多介绍了。

MemStore的作用:

•写缓存:攒批数据,批量落盘,减少磁盘IO,提升性能

•排序:维持数据按照 RowKey 的字典序排列

MemStore在读写时都起到了很大的作用,最大的耗能操作时在flush操作,下边我们详细介绍一下。

Memstore Flush触发条件

我们已经知道,当MemStore的大小达到一定的阈值时,就会flush数据到HDFS上,形成hfile文件,但是需要注意的是,MemStore进行flush的最小操作单元不是MemStore,而是整个HRegion。也就是说,有一个MemStore需要进行flush,整个HRegion都会受影响,所以一个HRegion如果有过多的Memstore,每次flush的开销必然会很大,所以每个表不应该设置过多的列簇。下边介绍一下触发flush操作的具体条件:

1.当一个Region中某个MemStore的大小达到hbase.hregion.memstore.flush.size(默认值128MB)时,会触发该Region中所有MemStore Flush,不会阻塞写操作。

2.当一个Region中所有MemStore的大小总和达到hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size(默认值2 * 128 = 256MB)时,会触发该Region中所有MemStore Flush,期间阻塞该Region的写操作。

3.当一个Region准备下线时的MemStore大小总和达到hbase.hregion.preclose.flush.size(默认值5MB)时,会触发该Region中所有MemStore Flush,然后Region才能关闭。

4.当一个RegionServer中所有MemStore的大小总和达到hbase.regionserver.global.memstore.size * HBASE_HEAPSIZE(默认值0.4 * 堆空间大小)时,会从MemStore最大的Region开始,触发该RegionServer中所有Region的Flush,并阻塞整个RegionServer的写操作。直到MemStore大小回落到上一个参数值的hbase.regionserver.global.memstore.size.lower.limit(默认值0.95)倍,才解除阻塞。

5.当一个RegionServer中的WAL(即HLog)数量达到hbase.regionserver.maxlogs(默认值32)时,HBase就选取最早的一个WAL对应的那些Region进行MemStore Flush,期间也会阻塞对应Region的写操作。

6.RegionServer会定期Flush MemStore,周期为hbase.regionserver.optionalcacheflushinterval(默认值1小时)。为了避免所有Region同时Flush,定期刷新会有随机的延时。

7.用户可以通过执行flush [table]或flush [region]命令来手动Flush一张表或一个Region的MemStore。

3.4.1.2 HFile

在这里插入图片描述

HFile是HBase存储数据的文件组织形式,参考BigTable的SSTable和Hadoop的TFile实现。下图是HFile扥物理结构示意图,如图所示,HFile会被切分为多个大小相等的block块,HFile内部结构还是比较复杂的,有兴趣的同学可以看下(http://hbasefly.com/2016/03/25/hbase-hfile/),本文我们主要看下存储实际数据的data block。

3.4.1.2.1 DataBlock

DataBlock是HBase中数据存储的最小单元。DataBlock中主要存储用户的KeyValue数据(KeyValue后面一般会跟一个timestamp,图中未标出),而KeyValue结构是HBase存储的核心,每个数据都是以KeyValue结构在HBase中进行存储。KeyValue结构磁盘中可以表示为:

在这里插入图片描述

每个KeyValue都由4个部分构成,分别为key length,value length,key和value。其中key length和value length是两个固定长度的数值,而key是一个复杂的结构,首先是rowkey的长度,接着是rowkey,然后是ColumnFamily的长度,再是ColumnFamily,之后是ColumnQualifier,最后是时间戳和KeyType(keytype有四种类型,分别是Put、Delete、 DeleteColumn和DeleteFamily),value就没有那么复杂,就是一串纯粹的二进制数据。

3.4.1.2.2 基本概念

从上图可以看出一些长度是固定的值,所以把key做一些简化,然后重点看下这些内容的具体含义。Key由RowKey(行键) + ColumnFamily(列族)+ Column Qualifier(列修饰符)+ TimeStamp(时间戳–版本)+ KeyType(类型)组成,而Value就是实际上的值。

在这里插入图片描述

•Rowkey:每行数据的主键,是hbase的唯一的查询条件,因此Rowkey的设计至关重要。

•Column family:列簇,每个列簇的数据存储在一起,每个列簇用户可以自由选择存储哪些列,同一个列簇的所有成员具有相同的列簇前缀,通常将同一类型的列存放在一个列簇下,但是要注意不要设置过多的列簇,后边会讲到。

•Qualifier:列,就是具体的列,以列簇作为前缀,格式为 Column family:Qualifier。

•Timestamp:时间戳,插入单元格时的时间戳,默认作为单元格的版本号。不同版本的数据按照时间戳倒序排序,即最新的数据排在最前面。当数据需要更新的时候,不会向mysql一样,直接对源数据就行更新,而是会新增一条数据,新数据的时间戳更大,因此会排在前面。可以根据时间戳来设置TTL,以及保存的版本个数。

•Type:数据类型,用来区别是不是delete的数据,删除数据和更新数据一样,也不会直接进行数据的物理删除,也会新插入一条数据,只是这条数据的type会被标记为delete,在查询是默认会进行过滤。只有在执行Major Compaction操作时,才会进行delete数据的清理。

•Cell:单元格,在 HBase 中,值作为一个单元保存在单元格中。要定位一个单元,需要满足 “rowkey + column family + qualifier + timestamp+KeyType” 五个要素。每个 cell 保存着同一份数据的多个版本。cell 中没有数据类型,完全是字节存储。

4.读写流程

在介绍读写流程之前,先介绍一下Meta table,为什么要先介绍它,因为它是读写操作的必经之路,是rowkey的引路人。

Meta table

Meta table存储了所有的region信息,Meta table储存在zk中,客户端在第一次读写访问或者region失效时,都会先访问zk,根据rowkey从Meta table获取region server的信息,然后客户端再去访问对应的region server,进行对应的读写操作。

在这里插入图片描述

写流程

在这里插入图片描述

1.Client 先访问 zookeeper,获取Meta table表位于哪个 Region Server。

2.访问对应的 Region Server,获取Meta table表,查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 Region 信息以及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。

3.客户端直接与目标 Region Server 进行通信。

4.将数据顺序写入(追加)到 HLog(WAL),防止机器宕机而丢失内存中的数据。

5.将数据写入对应的 MemStore,数据会在 MemStore 进行排序。

6.向客户端发送 ack。

7.等达到 MemStore 的触发条件后,将数据flush到 HFile。

读流程

在这里插入图片描述

1.Client 先访问 zookeeper,获取Meta table表位于哪个 Region Server。

2.访问对应的 Region Server,获取Meta table表,查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 Region 信息以及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。

3.客户端直接与目标 Region Server 进行通信。

4.分别在内存中还未落盘的MemStore和已经落入磁盘的HFile中(对于HFile数据优先从缓存在内存中的BlockCache读取,读缓存没有再从HFile中加载)读取数据,并将查到的所有数据进行合并。注意hbase的数据仅仅独立的存在于内存和磁盘中,就是说MemStore和HFile中的数据一定是全量的数据,而BlockCache (读缓存)只是HFile缓存在内存中的部分热点数据,BlockCache的作用是在读取HFile的数据时,可以直接从内存中读取,减少磁盘IO次数。

5.将从文件 HFile 中查询到的数据块 (Block,HFile 数据存储单元,默认大小为 64KB) 缓存到 Block Cache。

6.将合并后的最终结果,然后返回时间最新的数据返回给客户端。

读流程详解

hbase的写操作十分方便,更新实际上只是新加了一条最新时间戳的数据,删除数据也只是添加了一个delete的标记,只有再Major Compaction的时候才会进行物理删除。而因为hbase中同一个rowkey是保存了多版本的数据,以及不同的keytype的数据,所以同一个rowkey会对应多条数据,因此这里不像我们想的那样,如果rowkey命中BlockCache或者MemStore就会直接返回,远没有想象中的简单,因此也不存在先从BlockCache读还是先从MemStore中读的概念,这种说法本身就是不对的。

在读取数据的时候,内存MemStore和磁盘HFile中的数据都要读取,会创建两种类型的Scanner(StoreFileScanner和MemstoreScanner),分别用来探查HFile和MemStore中的数据,然后会根据用户选择的时间范围以及rowkey的范围过滤掉一些Scanner,最后对于HFile的数据会先查找对应的Block,查找Block时会优先从Blockcache中查找,找不到再从HFile中加载。而MemstoreScanner会从Memstore中查询数据,最后将内存和磁盘中的数据进行合并,返回最新的数据给到客户端。简化的流程如下:

1.构建Scanner

每个StoreScanner会为当前该Store中每个HFile构造一个StoreFileScanner,用于实际执行对应文件的检索。同时会为对应Memstore构造一个MemstoreScanner,用于执行该Store中Memstore的数据检索。

1.过滤Scanner

根据Time Range以及RowKey Range对StoreFileScanner以及MemstoreScanner进行过滤,淘汰肯定不存在待检索结果的Scanner。

1.Seek rowkey

所有StoreFileScanner开始做准备工作,在负责的HFile中定位到满足条件的起始Row。Seek过程(此处略过Lazy Seek优化)也是一个很核心的步骤,它主要包含下面三步:

•定位Block Offset:在Blockcache中读取该HFile的索引树结构,根据索引树检索对应RowKey所在的Block Offset和Block Size

•Load Block:根据BlockOffset首先在BlockCache中查找Data Block,如果不在缓存,再在HFile中加载

•Seek Key:在Data Block内部通过二分查找的方式定位具体的RowKey。

6.HBase Compaction

HBase 的 MemStore 在达到触发条件的时候,会把MemStore中的数据flush到HDFS上,每次都会形成一个新的HFile文件,所以随着时间的不断累积,同一个 Store 下的 HFile 会越来越多,进而会降低 HBase 查询性能,主要体现在查询数据的 IO 次数增加。为了优化查询性能,HBase 会合并小的 HFile 以减少文件数量,这种合并 HFile 的操作称为 Compaction。

•Minor Compaction:会将邻近的若干个 HFile 合并,在合并过程中会清理 TTL 的数据,但不会清理被删除的数据。Minor Compaction 消耗的资源较少,通过少量的 IO 减少文件的个数,提升读取操作的性能,适合高频率地跑。

•Major Compaction:会将一个 Store 下的所有 HFile 进行合并,并且会清理掉过期的和被删除的数据,即在 Major Compaction 会删除全部需要删除的数据。一般情况下,Major Compaction 时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此,生产环境下通常关闭自动触发 Major Compaction 功能,改为手动在业务低峰期触发。

在这里插入图片描述

HBase与传统关系型数据库的对比

•数据类型:

没有数据类型,都是字节数组(有一个工具类Bytes,将java对象序列化为字节数组),而传统的关系型数据库有丰富的数据类型。

•数据操作:

HBase只有很基本的插入、查询、删除等操作,表和表之间是没有关系的,而传统数据库一般都会有很多的函数,并且表之间有关联的特点。

•存储模式:

Hbase基于列簇存储,而传统关系型数据库是基于行存储。

•数据更新:

habse中对于数据update情况,不会向传统数据库一样,直接修改这条记录,而是新插入了一条状态为delete的数据,这么设计的原因是为了保证顺序写,提高数据IO效率,进而提高性能。并且旧数据也不会马上删除,会在compaction时才会进行删除。

•时间版本:

Hbase数据写入cell时,还会附带时间戳,默认为数据写入时RegionServer的时间,但是也可以指定一个不同的时间。数据可以有多个版本,并且可以设置TTL,以及保留的版本个数。

•索引:mysql支持多种类型的索引,而hbase只有rowkey

•易扩展性

搞过mysql分库分表的同学一定体会过它的魅力,十分的麻烦,但是hbase可以动态水平扩展,十分便捷

Rowkey的设计

访问方式

HBase访问只有3种方式

1.通过单个 rowkey 访问

2.通过 rowkey 的 range

3.全表扫描

RowKey设计原则

•长度原则

RowKey是一个二进制码流,可以是任意字符串,最大长度为64kb,实际应用中一般为10-100byte,以byte[]形式保存,一般设计成定长。建议越短越好,不要超过16个字节

•唯一原则

必须在设计上保证RowKey的唯一性。由于在HBase中数据存储是Key-Value形式,若向HBase中同一张表插入相同RowKey的数据,则原先存在的数据会被新的数据覆盖。

•排序原则

HBase的RowKey是按照ASCII有序排序的

•散列原则

RowKey应均匀的分布在各个HBase节点上,防止热点数据造成数据倾斜。

避免数据热点的方法

•Reversing

顾名思义,直接反转的意思。比如用户id,手机号等,rowkey的头部不具有随机性,但是尾部具有良好的随机性,那这时我们可以将rowkey直接翻转过来。Reversing可以有效的使RowKey随机分布,但是牺牲了RowKey的有序性。利于Get操作,但不利于Scan操作,因为数据在原RowKey上的自然顺序已经被打乱。

•Salting

Salting(加盐)的原理是在原RowKey的前面添加固定长度的随机数,从而保障数据在所有Regions间的负载均衡。

•Hashing

Hashing和加盐是类似的,只是Hashing要求前缀不能是随机的,需要使用一些hash算法,这样客户端可以重构出Hashing后的rowkey。

推荐方案:

一般情况,可以选择业务主键的后3位取余hbase分区数的余数作为加盐的前缀,然后在拼接上业务主键作为rowkey。

HBase的缺点

•数据分析能力弱:数据分析是HBase的弱项,比如聚合运算、多维度复杂查询、多表关联查询等。所以,我们一般在HBase之上架设Phoenix或Spark等组件,增强HBase数据分析处理的能力。

•原生不支持二级索引:默认HBase只对rowkey做了单列索引,因此正常情况下对非rowkey列做查询比较慢。所以,我们一般会选择一个HBase二级索引解决方案,目前比较成熟的解决方案是Phoenix,此外还可以选择Elasticsearch/Solr等搜索引擎自己设计实现。

•原生不支持SQL:SQL查询也是HBase的一个弱项,好在这块可以通过引入Phoenix解决,Phoenix是专为HBase设计的SQL层。

•HBase原生不支持全局跨行事务,只支持单行事务模型。同样,可以使用Phoenix提供的全局事务模型组件来弥补HBase的这个缺陷。

•故障恢复时间长

注意点总结

1.设计表结构的时候,一定要注意列簇的个数不要设置的过多,不要超过3个,最好就只有一个

2.rowkey的设计一定要注意加盐或hash处理,避免出现热点数据的问题

3.Major Compaction默认开启需要关闭,因为十分耗费资源,影响写入,可以在业务低峰期手动执行

4.MemStore的flush的触发条件,一定要关注Region Server中所有Memstore是否达到阈值这个条件,因为这个会影响整个Region Server的写入

5.BlockCache一定不要理解偏了,hbase中的数据,要么还在写缓存MemStore中未写入磁盘,要么就是已经写入磁盘的数据,这两部分一定包含了全量的数据,BlockCache只是HFile缓存在内存中的部分热点数据。

Q&A

  1. 常说HBase数据读取要读Memstore、HFile和Blockcache,为什么上面Scanner只有StoreFileScanner和MemstoreScanner两种?没有BlockcacheScanner?

HBase中数据仅仅独立地存在于Memstore和StoreFile中,Blockcache中的数据只是StoreFile中的部分数据(热点数据),即所有存在于Blockcache的数据必然存在于StoreFile中。因此MemstoreScanner和StoreFileScanner就可以覆盖到所有数据。实际读取时StoreFileScanner通过索引定位到待查找key所在的block之后,首先检查该block是否存在于Blockcache中,如果存在直接取出,如果不存在再到对应的StoreFile中读取。

  1. 数据更新操作先将数据写入Memstore,再落盘。落盘之后需不需要更新Blockcache中对应的kv?如果不更新,会不会读到脏数据?

如果理清楚了第一个问题,相信很容易得出这个答案:不需要更新Blockcache中对应的kv,而且不会读到脏数据。数据写入Memstore落盘会形成新的文件,和Blockcache里面的数据是相互独立的,以多版本的方式存在。

参考资料:

https://my.oschina.net/u/4511602/blog/4916109

https://www.jianshu.com/p/f911cb9e42de

https://www.jianshu.com/p/0e178bce8f63

http://hbasefly.com/2016/12/21/hbase-getorscan/

http://hbasefly.com/2017/06/11/hbase-scan-2/

https://zhuanlan.zhihu.com/p/145551967

https://blog.youkuaiyun.com/u012151684/article/details/109040581

https://xie.infoq.cn/article/76f8caba743f8be2beb81441d

https://zhuanlan.zhihu.com/p/159052841?utm_id=0

http://hbasefly.com/2016/04/03/hbase_hfile_index/

http://hbasefly.com/2016/03/25/hbase-hfile/

相关推荐

AI 会写代码之后,交付为什么还没变快?

AI 写代码,只是这场变革的起点,而不是终点。真正决定一个组织能否吃到 AI 红利的,不是"能不能用 AI 写出代码",而是敢不敢用 AI 重新设计交付流程、重新划分角色分工、重新组织团队结构。研发视角能把工具和个人推到极致,却会在组织的边界前止步;只有站上组织视角,把AI × 工具一路推进到AI × 组织,那些被 AI 照出来的摩擦,才会真正被抹平。国际技术部 Multi AI Native 想做的,正是这件事——让 Agent 成为你可靠的数字战友,让每一次迭代交付都快一个量级;

京东科技开发者 256

OxygenData-Vibe搭建:用 AI Coding重新定义数据看板搭建

长期以来,数据看板开发主要有两种方式:一种是使用标准化 BI 工具,交付快、成本低,但图表样式、交互体验和功能扩展都受限于 BI 本身的能力;另一种是自研定制开发,能够充分满足复杂和个性化需求,但需要投入大量研发资源,交付周期也更长。比如一个通过 BI 只需要 1 天就能搭建出来的看板,如果采用自研方式,可能需要投入 30 PD 的研发人力。既然 BI 交付这么快,为什么不把所有看板需求都交给 BI?原因在于,业务某些场景需要的不只是把数据展示出来。

京东科技开发者 318

当我谈数据库高可用时我谈些什么

大家都经常听到说数据库的双1,那双1指的是什么呢?参数=1(最安全)≠1(更快但可能丢)每次提交都把 redo 刷盘0/2:攒着刷,崩溃丢最近 1 秒每次提交都把 binlog 刷盘0/N:攒着刷,崩溃丢最近若干条"双 1"(都设为 1)= 单机不丢已提交事务的前提。生产核心库必须双 1;代价是每次提交两次 fsync。小结:单机层用 WAL 提速、用 2PC 保证 redo/binlog 一致、用崩溃恢复裁决半成品事务、用双 1 兜底持久性。

京东科技开发者 277

ScoAI:面向供应链的运筹原生决策智能

ScoAI 关注的并非 AI 能否进入供应链,而是 AI 参与供应链决策之后,哪些内容适合通过数据学习,哪些关系必须显式计算,以及哪些结果需要依据执行记录进行验证。其基本分工是:供应链业务定义问题、资源与行动后果,运筹学表达目标、约束和协同关系,AI 提供可复用的估计与判断。真正用于改进后续决策的,不仅是模型生成的初始结果,还包括实际采取的行动及其产生的业务反馈。

京东科技开发者 372

拆解海博 AI-Native 落地保障:海博团队 AI 知识库能力建设

绕了一大圈,回头看,我们其实一直在解开头那三个结:AI 读不懂系统、影响面靠人脑记、测试预期没处查。做到这里,本质上是把"AI 用不好"这个问题,从"是不是该换个更强的模型"重新定义成了"怎么把上下文经营好"。顺着这个思路,我们攒下了这么几样东西:•。

京东科技开发者 523

从零构建一个生产级记忆型 AI Agent —— AgentScope 项目全景技术与学习指南

domain 层端口接口(domain)职责适配器实现(infra)对话流水账读写经验记忆检索/落库请求级幂等四态会话元数据 CRUD会话级 Skill 选择态Skill 元数据HITL 权限网关(domain 内含逻辑,见第四篇)StreamSink技术中立的流式下沉(client 层桥接)以幂等端口为例,头部注释明确写道:实现 domain 端口,持有实体不出 infra 边界,对外只暴露嵌套视图GateResult。

京东科技开发者 573

数据涅槃:Agentic 重塑搜推数据生产体系

当前大模型已经能够理解需求、生成代码和解释错误,但数据生产的难点并不只是“写出一段 SQL”。一个需求还要经过数据源确认、口径澄清、加工编排、资源规划、任务提交、调度运行、结果交付和故障处置。任何一步缺少都可能让“看起来正确”的任务变成生产事故。

京东科技开发者 339

81.8 秒的视频,我们改了 15 个版本:一次纯 Codex 驱动的 AI-native 视频实践

81.8 秒、15 个版本,这些数字真正想说明什么?视频制作正在从一组专业软件里的复杂操作,变成一场围绕目标、参考和反馈展开的持续对话。AI 已经可以接住从脚本到交付的大量工作。你可以把精力留给更重要的部分:理解观众、选择故事、判断好坏。过去停在 PPT 和脑海里的想法,现在有机会被快速做成一支能看、能改、也愿意转发的视频。如果明天就要介绍你手头的项目,你最想先把哪一步交给 AI?

京东科技开发者 435

Codex 驱动的移动端AI全栈开发:从 Relay 原型图到可交付链路

AI 编程工具降低了跨端开发门槛,但“让 AI 写页面”并不等于“完成移动端交付”。PC 运营端页面通常以功能闭环为中心,设计约束较弱,研发可以基于组件库快速搭建;移动端 C 端页面直接面对用户,Relay 原型图和 UI 设计稿不仅是视觉参考,更是交互、信息层级、状态反馈和业务信任感的综合契约。

京东科技开发者 570

Claude Code vs Codex 记忆体系深度对比

Claude Code —— 分层自动记忆系统四层分层架构(CLAUDE.md / Auto Memory / Session Memory / AutoDream)构成自优化闭环,系统主动捕获、分类、去冗并跨会话接力经验。走的是自动化优先路线——让机器替人记忆、替人整理,以少量可控性的不确定换取强大的经验积累能力。Codex —— 声明式契约系统两层扁平架构(AGENTS.md 静态声明层 + 会话上下文层),记忆完全由人显式订立、显式修改,系统只读契约、绝不擅自变更。走的是可控性优先。

京东科技开发者 607

上游给空、下游拿到 -1,我把故障一直追到了 commons-beanutils 的构造函数

这篇手记是一份事后复盘,写在我们已经把修复推上线、把测试用例跑绿、把约束文档沉淀进团队库之后。非研发同事,可以直接从第八章开始看,前七章都是讲排障和代码分析。故障本身不复杂,修复也不复杂,但这次排查真正让我想写下来的,不是技术本身——而是从问题提报到解决全程AI的作用:问题定位:业务方反馈了一个异常单号说「下发失败」,一线运维同事直接在日志系统捞到相关的系统日志,用IDE打开下游代码库,把异常信息给到JoyCode——AI 直接指向了问题是serialType值非法,系统只接受0和1,而当前上游给的是-1。

京东科技开发者 706

SKill测评:谁才是真正的Skill之王?

巧合的是,阿里近期开源了一款名为 Skill-Up 的测评工具——它专门面向 Agent Skill 开发者,支持在 Claude Code、Codex、Qoder CLI 等真实 Agent Engine 环境中验证 Skill 的功能正确性,并可将失败用例转化为精准的修复指引,同时支持本地与 CI 环境的持续回归。2026年,Skill 的热度不减,已成为 AI 辅助编程领域的标配。在日常研发中,无论是沉淀个人经验,还是将团队的优秀范本标准化,将知识“蒸馏”为 Skill 已是大家的常规操作。

京东科技开发者 621

让AI真正参与工作!JoyDesk已上线京东云

JoyDesk提供覆盖AI资产管理、权限控制、安全策略、审批审计、运营监控等企业级治理能力,支持按组织、角色和项目进行精细化权限管理,并支持私有化部署,确保企业数据边界清晰、AI行为全程可追溯、安全策略灵活可配置,满足金融、政企等行业对数据安全和合规治理的要求,让AI真正成为企业可信赖的生产力。JoyDesk支持MCP协议、标准API、技能等多种开放接入方式,可快速连接企业现有业务系统,将业务能力封装为AI可调用的技能和专家,让AI能够理解业务流程、调用业务系统、完成业务任务,而无需改变企业原有IT架构。

京东科技开发者 657

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手【最终版】

这个项目展示了AI Agent 在垂直内容创作领域端到端自动化:从内容理解到播客输出,全流程 AI 驱动多模态融合:文字、图片、音频、视频统一处理专业级音频质量:音色设计 + 智能混音,输出广播级品质低门槛使用:可视化配置 + 自然语言交互,无需技术背景。

京东科技开发者 557

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(高级篇)

这是一个 AI 驱动的播客创作助手,专注于从文字/视频/音频内容识别到播客制作的全流程。你可以用自然语言与它对话,也可以上传视频和音频,它会理解意图、调用相应的语音合成工具,把他们变成真实的播客音频。

京东科技开发者 721

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(进阶篇)

这是一个AI 驱动的音频内容创作助手。你可以用自然语言与它对话,它会理解意图、调用相应的语音合成工具,把文字变成真实的播客音频,并保存在本地。关于项目的详细介绍见第一篇文章:第一个 AI Agent 项目:从零搭建 AI 音频创作助手(入门篇)这篇文章更多介绍进阶篇添加的功能。

京东科技开发者 545

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(入门篇)

这个项目让我第一次把前端、后端、AI Agent 三块内容独立串联起来。技术选型上每一块都是当下主流的方案,实际跑通整条链路之后对"全栈"有了更具体的感受。框架版本要锁定:LangChain 这类快速迭代的框架,版本差异带来的问题远比你想象的多先跑通链路,再追求完美:新手阶段能把用户输入 → AI 处理 → 结果展示这条链跑通,比深入某个技术点更有价值多看官方文档:相比博客和教程,官方文档更新及时,特别是 LangGraph 这种新框架后续计划继续迭代,欢迎交流!

京东科技开发者 604

ICLR 2026 | 面向序列决策的贝叶斯集成方法

在这篇工作中,我们关注的是。

京东科技开发者 294

ICML 2026|NaviAgent:面向 Oxygen 智能体的可扩展工具编排

大型语言模型(LLM)越来越多地作为函数调用代理,调用外部工具来处理超出其静态知识范围的任务。然而,它们通常一次只调用一个工具,缺乏对任务结构的全局视图。由于工具之间往往相互依赖,这会导致错误累积和可扩展性差,尤其是在扩展到数百或数千个工具时。为了解决这些局限性,我们提出了NaviAgent,一种显式的双层架构,它通过基于图的工具关系建模将任务规划与工具执行解耦。在规划层,基于 LLM 的代理决定是直接响应、澄清意图,还是检索并执行一个独立于工具间复杂性的工具链。

京东科技开发者 385

实测 9 款 AI 架构图工具:从 Mermaid 美化到 GPT-Image2,一份选型清单

支持 5 类图(架构图、工作流图、时序图、数据流图、生命周期/状态机图),主题 4 种(Classic、Signal Flow、Blueprint、Editorial)+ 3 种色彩模式(Dark / Light / System Auto),输出格式含 HTML、PNG、SVG、WebM、Share Card PNG、JSON IR。它把提示词图库、图像生成案例、参考图编辑流程和命令行工具整合在一起,让 AI Agent 能直接调用 GPT Image 2 模型完成文生图、图生图、参考图编辑等任务。

京东科技开发者 898

别再守着 Claude Code 了——学会指挥它自主干活

回到开头那句:别再一句一句地喂它、然后守着屏幕。真正的用法是——把一件事想清楚、划好边界、给它一个能自我验证的目标,然后交出去。你会发现,省下来的时间不是一点半点。把重复的判断和执行还给机器,把真正需要你的判断留给自己。

京东科技开发者 585

CVPR 2026|Oxygen XR 团队在原生鱼眼高斯泼溅技术上带来新突破

京东零售技术团队联合清华大学提出DirectFisheye-GS框架,创新性地将鱼眼相机模型原生嵌入3D高斯泼溅管线,通过跨视角联合优化策略直接处理鱼眼图像,避免了传统去畸变预处理导致的信息损失。该方案在多个公开数据集上达到SOTA性能,有效解决了单视角优化引起的几何畸变和视角不一致问题,同时保持与现有3DGS工具链的兼容性。技术已应用于电商3D重建和4D体积视频等场景,显著提升了沉浸式体验。相关论文被CVPR 2026接收,为宽视场场景重建提供了高效解决方案。

京东科技开发者 354

拆解海博 AI-Native 落地保障:Harness、双 Loop、知识库与技能自主迭代实践

海博研发RoadMap 的落地,彻底终结了 AI 编程“对话式玄学”的旧模式,真正落地了AI Native 研发工程化。它证明 AI 规模化赋能研发的核心,不在于堆砌大模型能力,而在于用工程思维重构 AI 的工作范式:用结构化流程替代随机对话,用固化规则约束模型行为,用持续沉淀实现能力复利,用分层架构支撑规模化落地。

京东科技开发者 634

让 AI 快速「读懂」你的代码仓:Joy-Code-Graph 云端图谱服务的三次进化

代码知识图谱不是要取代 AI 的智能,而是要补齐它对代码全局关系的认知盲区。当 AI 能一眼看清「谁调用了谁、改动会波及哪里」,它写出的代码才真正靠谱;当这份认知安全地留在自己手里、随时被 Joygen 调用、并且永久沉淀在代码仓里——AI 编程的体验,才算真正上了一个台阶。这,就是我们做 Joy-Code-Graph 云端服务的初衷。能力共享,数据自主;一次建图,长期受用。

京东科技开发者 751

【Coding生态】从代码托管到 AI 能力底座:与Coding一起共建 AI 研发生态

前两种框架能够很好地支撑对话式能力和预设流程式能力。它们适合基于提示词或预设工作流完成研发问答、知识查询、流程编排等任务。但在更复杂的研发场景中,仅仅“回答问题”还不够。当用户业务逻辑复杂时,一旦场景进入真实落地阶段,例如下载代码、修改文件、执行命令、安装依赖、运行测试、读取完整代码文件,或者与自有系统联动、将结果渲染到 Coding 页面、推送到京 ME,AI 应用需要的不只是知识能力,还需要真实的代码库操作能力和独立可执行环境。

京东科技开发者 768

GPT-5.6、ChatGPT Work 与 Codex 更新食用指南

三档模型当前都提供 1,050,000 tokens 上下文、922,000 tokens 最大输入和 128,000 tokens 最大输出,接受文本与图像输入、输出文本,并支持 web search、file search、Computer Use、MCP、Tool Search、Skills、Apply Patch 等工具。Work 可以读取你提供的文件,通过插件连接 Slack、Google Drive、SharePoint、邮箱、日历、CRM 或项目系统,调用获批工具,并在执行中展示进度。

京东科技开发者 861

把业务流程沉淀成高质量 Skill 的实践路径

使用Record & Replay创建的Skill,尽管创建流程简单,但它的本质实际是让 AI 去操作页面,这不但有可能影响我们对电脑的操作,还有可能无法稳定复现。创建Skill时,可以使用 Codex 的 Record & Replay 插件,把一次手工操作录下来,再让 AI 生成可复用流程。刚开始切换时,很容易遇到接口报错,可以让Codex排查原因进行优化,直到可以稳定执行;补充相应业务背景,说明这件事为什么要做,谁会用,输入从哪来,输出给谁看。电脑休眠、关机、软件没开时,本地任务可能无法执行。

京东科技开发者 835

政企前台AI-Agent的架构实践:打造可复用的 AI 服务平台-【灯塔计划】

不止是爆火的龙虾,还是各种Skills,MCP、Agent,脱离的具体的场景谈方案,最后只会是一场空。这一套可复用的 AI 服务平台,截止目前,通过前后端对接规范文档,多项能力已快速接入到各个场域的不同端平台,大幅降低研发成本, 并且各业务线新场景的接入从原来的 “开发驱动” 转为 “配置驱动”,接入周期从天维度缩短至小时级。

京东科技开发者 860

京东 Oxygen xLLM 大模型推理引擎正式捐赠开放原子开源基金会,共建国产 AI Infra 生态

下一阶段 AI 基础设施的核心命题,不是简单的算力堆叠,而是让工程本身变得智能——让调度系统能自主感知负载特征并动态优化,让推理引擎能根据模型结构和硬件特性自动生成最优执行方案,让整个 AI 工程链路具备自感知、自决策、自优化的能力。未来,Oxygen xLLM 的项目官网、社区沟通渠道及微信社区将陆续向开发者开放,诚邀芯片厂商、模型厂商、云厂商、企业用户及个人开发者共同参与,让国产大模型推理引擎在开放生态中加速成长。硬件层,原生支持 GPU / NPU / MLU 多类 AI 芯片,深度适配国产芯片。

京东科技开发者 1000

【京东云】全球首个!京东全栈开源JoyAI-VL-Interaction,让大模型从“一问一答”走向“边看边说”

开源一套系统,而不只是一个模型在实时视频流中,JoyAI-VL-Interaction每秒都会做一次判断,比如,继续观察、保持沉默,发现关键事件、主动回应,遇到复杂任务,交给后台Agent处理。一个好的AI 助手,不应该一直打扰用户,而应该知道什么时候该出现,什么时候该安静,以及什么时候自己解决,什么时候交由agent解决。深耕零售、物流、健康、工业等实体产业二十余年,京东拥有全球领先的物理世界运营网络,覆盖仓储、配送、门店、直播、客服、售后海量真实场景,每天都在发生人、货、场的实时互动。

京东科技开发者 1030
上一篇: 记录一次RPC服务有损上线的分析过程
下一篇: 稳定性方法论:可灰度 & 可监控 & 可回滚
京东云开发者
京东云开发者 企业官方账号 企业官方账号
博客等级 码龄8年 1万+粉丝 2139原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值