|NO.Z.00008|——————————|BigDataEnd|——|Hadoop&OLAP_Kudu.V08|——|kudu.v08|表设计.V1|

一、kudu表设计(扩展)
### --- kudu表设计

~~~     Tablet是kudu表的水平分区,类似于google Bigtable的tablet,或者HBase的region。
~~~     每个tablet存储着一定连续range的数据(key),且tablet两两间的range不会重叠。
~~~     一张表的所有tablet包含了这张表的所有key空间。
~~~     Tablet由RowSet组成,RowSet由一组rows组成(n条数据、n行数据)。
~~~     RowSet是不相交的,即不同的RowSet间的row不会交叉,
~~~     因此一条给定的数据,只会存在于一个RowSet中。虽然Rowset是不相交的,
~~~     但是两两间的key空间是可以相交的(key的range)。
二、Handling Insertions
### --- Handling Insertions

~~~     一个RowSet存储在内存中,它被称为MemRowSet,一个tablet中只有一个MemRowSet。
~~~     MemRowSet是一个inmemory的B-Tree树,且按照表的主键排序。
~~~     所有的insert直接写入进MemRowSet。
~~~     受益于MVCC(Multi-Version Concurrency Control 多版本并发控制,下文中会讲述),
~~~     一旦数据写入到MemRowSet,后续的reader能立马查询到。
~~~     注意:不同于BigTable,Kudu只有插入和插入与flush前的mutation才会被记录到MemRowSet。
~~~     mutation例如基于磁盘数据的update、deletion,下文会有介绍。
~~~     任何一条数据都以entry的形式精确的存在于一个MemRowSet中,
~~~     entry由一个特殊的header和实际的row data内容组成。
~~~     由于MemRowSet只存于内存中,最终会被写满,
~~~     然后Flush到磁盘里(一个或者多个DiskRowSet中)。(下文会详细介绍)
三、MVCC overview
### --- MVCC overview

~~~     Kudu为了提供一些有用的特性,使用多版本并发控制:
~~~     # Snapshot scanner:

~~~     快照查询,当创建了一个查询,系统会操作tablet指定时间的快照(point-in-time)。
~~~     在这个查询过程中的任何针对这个tablet的update都会被忽略。
~~~     另外,指定时间的快照(point-in-time)可以被存储并在其他的查询中重复使用,
~~~     例如,一个应用对一组连续的数据进行多次交互执行分析查询。 
~~~     # Time-travel scanners:

~~~     历史快照查询,与上边的快照查询一样。
~~~     用户可以指定历史的一个时间点创建一个查询,MVCC可以保证历史快照的一致性。
~~~     这个功能可以被用来在某个时间点上的一致性备份。 
~~~     # Change-history queries:

~~~     历史变更查询,给定两个MVCC快照,用户可以查询这两个快照间任务数据。
~~~     这个功能可以用来做增量备份,跨集群同步,或者离线审计分析。
~~~     # Multi-row atomic updates within a tablet:

~~~     tablet内多行数据的原子更新,在一个tablet里,一个操作(mutation)可以修改多行数据,
~~~     而且在一条数据里的原子操作里是可见的。
~~~     (应该是针对column的原子操作) 为了提供MVCC功能,
~~~     每个操作(mutation)会带有一个时间戳(timestamp)。
~~~     Timestamp是由TS-wide Clock实例提供的,
~~~     tablet的MvccManager能保证在这个tablet中timestamp是唯一的不重复的。
~~~     MvccManager决定了数据提交的timestamp~~~     从而这个时间点后的查询都可以获取到刚刚提交的数据。
~~~     查询在被创建的时候,scanner提取了一个MvccManager时间状态的快照,
~~~     所有对于这个scanner可见的数据都会跟这个MvccSnapshot比较,
~~~     从而决定到底是哪个insertion、update或者detete操作后的数据可见。
~~~     每个tablet的Timestamp都是单调递增的。
~~~     我们使用HybridTime技术来创建时间戳,它能保证节点之间的时间戳一致。
~~~     为了支持快照和历史快照功能,多个版本的数据必须被存储。
~~~     为了防止空间无限扩展,用户可以配置一个保留时间,
~~~     并将这个时间之前的记录GC(这个功能可以防止每次查询都从最原始版本开始读取)。
四、MVCC Mutations in MemRowSet
### --- MVCC Mutations in MemRowSet

~~~     为了在MemRowSet中支持MVCC功能,每行插入的数据都会带着时间戳。
~~~     而且,row会有一个指针,指向紧随其后的mutations列表,每个mutation都有带有timestamp~~~     在传统的关系型数据库术语里,这个有序的mutations列表可以被称作“RODO log”。
~~~     任何reader需要访问MemRowSet的row中的mutations,才能得到正确的快照。逻辑如下:
~~~     如果这行数据插入时的timestamp~~~     不在scanner 的MVCC snapshot里(即scanner快照指定的timestamp小于数据插入的时间戳,
~~~     数据还没创建),忽略该行。 
~~~     如上如果不满足,将这行数据放入output缓存里。 
~~~     # 循环list里的mutation:

~~~     如果mutation的timestamp在MVCC snapshot里,在内存的缓存中执行这个更新。
~~~     如果不在,则跳过此mutation。
~~~     如果mutation是一个DELETE操作,则在buffer中标记为已经被删除了,
~~~     并清空之前加载缓存里的数据。
~~~     # 注意,mutation可以是如下的任何一种:

~~~     UPDATE:更新value,一行数据里的一列或者多列 DELETE: 删除一行数据 REINSERT:
~~~     重新插入一行数据(这种情况只在之前有一个DELETE mutation且数据在MemRowSet里时发生。)
~~~     举个真实例子,表结构(key STRING, valUINT32),
~~~     # 经过如下操作:

~~~     INSERT INTO t VALUES (“row”, 1); [timestamp 1] UPDATE t SET val = 2 WHERE key =row”; 
~~~     [timestamp 2]DELETE FROM t WHERE key =row”; 
~~~     [timestamp 3] INSERT INTO t VALUES (“row”, 3); [timestamp 4] 在MemRowSet中,会有如下结构:
~~~     # 注意,当更新过于频繁时,会有如下的影响:

~~~     readers需要追踪linked list指针,导致生成很多CPU cache任务 更新需要追加到linked list的末尾,
~~~     导致每次更新的时间复杂度是O(n)。 
~~~     # 考虑到如上低效率的操作,我们给出如下假设:

~~~     Kudu适用于相对低频率更新的场景,即假设数据不会过于频繁的更新。 
~~~     整个数据中,只有一小部分存于MemRowSet中:
~~~     一旦MemRowSet达到一定阈值,它会被flush到disk。
~~~     因此即使MemRowSet的mutation会导致性能低,也只是占用整体查询时间的一小部分。 
~~~     如果如上提到的低效率影响到了实际应用,后续会有很多降低开销的优化可以去做。
五、MemRowSet Flushes

~~~     # MemRowSet Flushes

~~~     当MemRowSet满了,会触发Flush操作,它会持续将数据写入disk。
~~~     数据flush到disk成了CFiles文件(参见src/kudu/cfile/README)。
~~~     数据里的每行都通过一个有序的rowid标识了,
~~~     而且这个rowid在DiskRowSet中是密集的、不可变的、唯一的。
~~~     举个例子,如果一个给定的DiskRowSet包含有5行数据,
~~~     那么它们会以key上升的顺序被分配为rowid0~4。不同的DiskRowSet,会有不同的行(rows),
~~~     但却可能有相同rowid。
~~~     读取时,系统会使用一个索引结构,把用户可见的主键key和系统内部的rowid映射起来。
~~~     上述例子中的主键是一个简单的key,它的结构嵌入在主键列的cfile里。
~~~     另外,一个独立的index cfile保存了编码后的组合key,使用了提供了类似的方法。(不懂)
~~~     注意:rowid不是精确的跟每行数据的data存在一起,
~~~     而是在这个cfile里根据数据有序的index的一个隐式识别。
~~~     在一部分源码中,将rowid定义为 “row indexes” 或者 “ordinal indexes”。
~~~     注意:其他系统,例如C-Store把MemRowSet称为”write optimized store” (WOS),
~~~     把DiskRowSet称为”readoptimizedstore” (ROS)。
六、Historical MVCC in DiskRowSets

### --- HistoricalMVCCinDiskRowSets

~~~     为了让on-disk data具备MVCC功能,每个on-disk的Rowset不仅仅包含当前版本row的data
~~~     还包含UNDO的记录,如此,可以获取这行数据的历史版本。
~~~     当用户想读取flush后最新版本的数据时,只需要获取base data
~~~     因为base data是列式存储的,这种查询性能是非常高的。
~~~     如果不是读取最新数据,而是time-travel查询,就得回滚到指定历史时间的一个版本,
~~~     此时就需要借助UNDO record数据。
### --- 当一个查询拿到一条数据,它处理MVCC信息的流程是:
~~~     读取base data 循环每条UNDO record:
~~~     如果相关的操作timestamp还未提交,则执行回滚操作。
~~~     即查询指定的快照timestamp小于mutation的timestamp,mutation还未发生。 

~~~     # 举个例子,回顾一下之前MVCC Mutations in MemRowSet章节例子的一系列操作:
~~~     当这条数据flush进磁盘,它将会被存成如下形式:
~~~     每条UNDO record是执行处理的反面。
~~~     例如在UNDO record里,第一条INSERT事务会被转化成DELETE~~~     UNDOrecod旨在保留插入或者更新数据的时间戳:
~~~     查询的MVCC快照指定的时间早于Tx1时,Tx1还未提交,
~~~     此时将会执行DELETE操作,那么这时这条数据是不存在的。
### --- 再举两个不同查询的例子:

~~~     每个例子都处理了正确时间的UNDO record,以产生正确的数据。
~~~     最常见的场景是查询最新的数据。
~~~     此时,我们需要优化查询策略,避免处理所有的UNDO records。
~~~     为了达到这个目标,我们引入文件级别的元数据,指向UNDO record的数据范围。
~~~     如果查询的MVCC快照符合的所有事务都已经提交了(查询最新的数据),
~~~     这组deltas就会短路(不处理UNDO record),这时查询将没有MVCC开销。

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

posted on   yanqi_vip  阅读(29)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示