1.概述
ColumnStore(2016.12.14 GA)实际是 mariaDB 版的 InfiniDB。InfiniDB 倒闭于2014年9月,开源版本继续放在 github 上开源。老版本InfiniDB 的 mysql 版本是5.1.39(数据来源网络)。ColumnStore目前使用 MariaDB 10.1。
2.主要开发者
Daniel Lee
Nishant Vyas
3.使用协议
GPL
特性
- 列存,同时支持行存引擎 Innodb
- 横向扩展的 MPP 构架存储引擎
- 内建冗余和高可用机制
- 支持全部 SQL(MYSQL)语法包括 join,window function 和跨引擎 join
- 可与 HDFS 协同工作
- 在线 shema 变更
4.架构
由构架图可见,主要有两个组件,User Module(UM),Performance Module(PM)
所有 ColumnStore 的数据的获取和管理都是通过 PM 节点进行。
存储构架
- 列是存储单元,而不像行存储引擎 InnoDB。列存系统存储数据的文件格式是 每列一个文件,而不是一行都在一个文件中。
- Partitions 用来实际存储一列。在 MariaDB ColumnStore 中,Partition 是多个 Segment 组成的逻辑概念,默认1个 Partition 有4个 Sement。
- Segment 是实际的存储文件,每个 Segment 包含一定数量的 Extents,默认是2个 Extents。系统需要时会创建 Segment 文件。
- Extent 是800万个列数据的集合。每个 Extent 有需要 Blocks 组成。
- Block 存储8K bytes 数据,是实际磁盘 I/O 的最小单位。
存储实现细节
在每个 Extent 和 Block 中,MC 存储列的值使用固定长度的数据类型在1到8 bytes 长。对于 string 类型超过这个长度的情况,一个额外的Dictionary extent 会创建来存储 string 的值。这种情况下,column extent 存储对应 string 在 Dictionary extent 的指针。
因为MC 使用固定长度的数据类型,对于同一行的其他列,可以直接定位。例如,如果我们有“NAME”列的 extent 里的行234的,query engine 可以快速定位行234的列“AMOUNT”。这对于快速形成一行的查询有极大帮助(因为通常来说,单条查询对于列存是比较弱的)。
默认,列和字典值都是压缩的。这个设定消耗 CPU 来换取 I/O 的减少,可以加快 query 的响应时间。MC 使用 Snappy library (https://google.github.io/snappy/) 提供压缩特性。这种压缩算法在列的去重值较少时非常优秀,在一些场景下能提供10倍的压缩。
物理上,Segment 文件存储在 DBRoot 文件夹里。一个 DBRoot 包含一个物理存储单元,并且指定给一个物理 PM 服务器。系统会自动分布数据到可用的 DBRoots 上。
Extent Map
系统维护Extent 的元数据依靠 Extent Map。这个 Extent Map 包括 Extent 的最大值和最小值。这将帮助 MariaDB ColumnStore 提供一个简单但是有用的 horizontal partitioning scheme。在查询时,优化器可以消除不在 WHERE 条件里的 Extents。
例如:
如果一个查询的 WHERE 语句有“COL1 BETWEEN 220 and 250”,那优化器就可以消除 COL1的 Extent1,2和4。这就节省了75%的 IO以及很多比较操作。并且这个支持多个 column 的比较。原理相同就不细说了。
在时间序列,半排序的数据以及时间列中使用这个 MAP 非常有效。
额外的,系统在使用 Extent Map 的最大值和最小值可以进行 Bulk deletion 操作。(没有明说,但是猜测,一个 extent 如果没有全部清空,空间应该不释放,这一条不一定对。)