????声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识?内容详细全面, 言辞官方的文章 ??????????????2. 由于是个人总结, 所以用最精简的话语来写文章 ??????????????3. 若有错误不当之处, 请指出
BigTable
一、出现的原因
没有BigTable时 如MySQL集群的痛点:
-
单机存储数据量低 -
随机读写性能慢 -
可伸缩性太差:
- 扩容后, ip = hash % 集群数量, 将受到很大影响(数据查不到, 或者说得大量迁移数据)
- 某一个节点可能存储负载过重
-
可运维性 高可用差: 小部分节点的故障,不应该影响整个集群的运行; 集群自身也要有很强的容错能力,能够把对应的请求和服务,调度到其他节点去
如何解决伸缩性 和可运维性 高可用 ?
使用动态区间分区
我们不再是一开始就定义好需要多少个机器 以及应该怎么分区,
而是采用了一种自动去"分裂" (split)的方式来动态地进行分区, 自动进行分区 或合并
二、架构
组成架构:
-
Master
- 调度 哪些 Tablets 分配给哪个 Tablet Server
- 平衡 Tablet Server 的负载
- 检测 Tablet Server 的新增和过期
- 管理表(Table)和列族的 Schema 变更,比如表和列族的创建与删除
- 对于 GFS 上的数据进行GC垃圾回收
-
TabletServer 只负责在线服务,不负责数据存储 数据存储 和在线服务 的职责是完全分离的: 我们调度 Tablet 的时候 只是调度在线服务的负载,并不需要把数据也一并搬运走 (类似于Hive & metastore) -
Chubby 分布式锁和目录服务
-
确保集群里只有一个 Master(防止脑裂) -
记录 METADATA 所在的 TabletSever -
发现 Tablet Servers 以及在它们终止之后完成清理工作 -
存储 BigTable 的 Schema 信息 -
存储 ACL信息 -
GFS 存储数据
为什么数据读写不需要 Master?
分区 和 Tablets 的分配 信息,并没有放在 Master, 而是存成了 TabletSever 的一张 METADATA 表
即使Master 节点已经挂掉了,一时也不会影响数据的正常读写?
Master不存储分区 和 Tablets 的分配 信息 , 客户端不依赖 Master 提供数据读写服务
三、具体实现
timestamp: 让顺序写 实现了增删改功能
LSM Tree结构: MemStore + SSTable, Split & Compact
WAL保证了数据的高可靠性
MemTable的优化:
使用跳表作为数据结构, O(LogN)实现数据的高效查询 & 插入
MemTable里是有随机写 的
MemTable 只有三种操作:
-
根据 RowKey 的随机数据插入 ,这个在数据写入的时候需要用到; -
根据 RowKey 的随机数据读取 ,这个在数据读取的时候需要用到; -
根据 RowKey 的有序遍历 ,在 MemTable 转化成 SSTable 的时候会被用到
查询SSTable的优化:
-
先查缓存 两级缓存:
-
高层的缓存(Scan Cache) 是对查询结果 如 www.baidu.com 进行缓存 -
低层的缓存(Block Cache) 是对查询所获取到的整个数据块 进行缓存 因为一个块里存储的数据都是排好序的, 所以下次查询 www.baidu.com1 这个行键时 就可以直接从 Block Cache 中获取到,而不需要再次访问SSTable 文件 这两层缓存都是针对单个 SSTable 上的,而不是在单个 Tablet 上 只要不出现 Compaction,或者整个SSTable 文件过期,这些缓存都不会主动失效; 新写入的数据更新都体现在 MemTable 中,不会影响到我们的 SSTable -
再用 布隆过滤器的预判 -
再 布隆预判存在后, 还有索引块
访问MemTable: 跳表
访问SSTable: 缓存->布隆过滤器->索引
Compaction 的优化:
SSTable 里面的数据块是顺序存储的, Compact时 其实就是有序链表的多路归并
压缩:
以时间换空间
|