1.GreenPlum实现了基于数据库的分布式数据存储和并行计算,而MapReduce是基于文件的分布式数据存储和计算; 2.GreenPlum 选择PostGresql做为数据库底层引擎,通过Interconnect核心软件组件实现了对统一集群中多个 Postgresql实例的高效协同和并行计算,Interconnect承载了并行查询计划产生和分发,协调节点上执行器的 并行工作,负责数据分布、Pipeline计算、镜像复制、健康探测等等诸多任务。 3. GreenPlum选择Postgresql出于以下考虑: 1)Postgresql号称最先进的数据库,有非常强大的SQL支持能力和丰富的统计函数和统计语法支持, 支持分析函数(OLAP window函数),可以通过多种语言编写存储过程,对Madlib、R支持很好; 2)扩展方面强大,支持Python、C、Perl、TCL、PLSQL等语言扩展功能,支持扩展用户自定义函数(UDF)功能; 3)诸如ACID事务处理、数据强一致性、数据类型支持、独特的MVCC带来高效数据更新能力; 4) Postgresql许可是仿照BSD许可模式, 没有被大公司控制,社区比较纯洁; 5) 支持odbc、jdbc等接口,与第三方工具、BI报表集成非常容易; 4. MPP采用两阶段提交和全局事务管理机制来保证集群上分布式事务一致性,Greenplum像Postgresql一样 满足关系型数据库的包括ACID在内所有特征; 5. GreenPlum架构 数据库由Master Severs和Segment Severs通过Interconnect互联组成。 Master主机负责: 访问系统的入口,建立与客户端的连接和管理 SQL的解析并形成执行计划; 执行计划向Segment的分发收集Segment的执行结果; Master不存储业务数据 只存储数据字典(系统目录表和元数据) Segment主机负责: 业务数据的存储和存取; 用户查询SQL的执行。 NetWork InterConnect: 并行调度功能 Master Node支持高可用,类似于Hadoop的namenode和second namenode, 实现主备的高可用。 当Primary Master出现故障时,Standby Master担它全部工作, Standby Master通过同步进程, 保持与Primary Maser的数据一致。 Segment Server: 每个Segment存放一部分用户数据; 一个节点可以有多段; 用户不能直接存取访问,所有对段的访问都经过Master; 数据库监听进程监听来自于Master的链接; 6.GreenPlum最小并行单元不是节点层级,而是在实例层级(非Oracle实例概念,指一个分布式子库),每个实例都有 自己的Postgresql目录结构,都有各自一套Postgresql数据库守护进程(可进行单实例访问),甚至一个运行在 单节点的GP也是一个小型并行计算框架,一个节点配置6~8个实例,相当于一个节点有6~8个PG数据库同时工作, 可以充分利用每个节点的CPU和IO; 7.Greenplum还研发了非常多的高级数据分析管理功能和企业级管理模块: 外部表并行数据加载 可更新数据压缩表 行、列混合存储 数据表多级分区 BitMap索引 Hadoop外部表 Gptext全文检索 并行查询计划优化器和Orca优化器 Primary/Mirror镜像保护机制 资源列表管理 WEB/Brower监控 8.Greenplum的分布式并行计算架构,其中每个节点上所有Postgresql实例都是并行工作的, 外部表数据加载是并行的、 查询计划执行是并行的、 索引的建立和使用是并行的, 统计信息收集是并行的、 表关联(包括其中的重分布或广播及关联计算)是并行的, 排序和分组聚合都是并行的, 备份恢复也是并行的, 甚而数据库启停和元数据检查等维护工具也按照并行方式来设计,得益于这种无所不在的并行,Greenplum在数据加载和数据计算中表现出强悍的性能 9.Greenplum最大的特点总结就一句话:基于低成本的开放平台基础上提供强大的并行数据计算性能和海量数据管理能力 但如果你指望MPP并行数据库能够像OLTP数据库一样,在极短的时间处理大量的并发小任务,这个并非MPP数据库所长 并行和并发是两个完全不同的概念,MPP数据库是为了解决大问题而设计的并行计算技术,而不是大量的小问题的高并发请求。 Greenplum主要定位在OLAP领域,而MPP数据库都不擅长做OLTP交易系统 10. GP和HADOOP的相似处 分布式存储数据在多个节点服务器上 采用分布式并行计算框架 支持横向扩展来提高整体的计算能力和存储容量 都支持X86开放集群架构 差异: MPP按照关系数据库行列表方式存储数据(有模式),Hadoop按照文件切片方式分布式存储(无模式) 两者采用的数据分布机制不同, MPP采用Hash分布, 计算节点和存储紧密耦合, 数据分布粒度在记录级的更小粒度(一般在1k以下) Hadoop FS按照文件切块后随机分配, 节点和数据无耦合, 数据分布粒度在文件块级(缺省64MB)。 MPP采用SQL并行查询计划, Hadoop采用Mapreduce框架 11.计算效率 Mapreduce在整个MAP->Shuffle->Reduce过程中通过文件来交换数据,效率很低, MapReduce要求每个步骤间的数据都要序列化到磁盘,这意味着MapReduce作业的I/O成本很高,导致交互分析和迭代算法开销很大, MPP数据库采用Pipline方式在内存数据流中处理数据,效率比文件方式高很多 12. SQL-On-Hadoop比原始的Mapreduce虽然在易用上有所提高,但在SQL成熟度和关系分析上目前还与MPP数据库有较大差距: 1.除了HAWQ外,对SQL的支持都非常有限,特别是分析型复杂SQL,如SQL 2003 OLAP WINDOW函数,几乎都不支持, 以TPC-DS测试(用于评测决策支持系统(大数据或数据仓库)的标准SQL测试集,99个SQL)为例,包括SPARK、Impala、Hive只支持其中1/3左右 2.由于HADOOP 本身Append-only特性,SQL-On-Hadoop大多不支持数据局部更新和删除功能(update/delete);而有些,例如Spark计算时,需要预先将数据装载到DataFrames模型中; 3.基本上都缺少索引和存储过程等等特征 4.除HAWQ外,大多对于ODBC/JDBC/DBI/OLEDB/.NET接口的支持有限,与主流第三方BI报表工具兼容性不如MPP数据库 5.SQL-ON-HADOOP不擅长于交互式(interactive)的Ad-hoc查询,多通过预关联的方式来规避这个问题;另外,在并发处理方面能力较弱,高并发场景下,需要控制计算请求的并发度,避免资源过载导致的稳定性问题和性能下降问题; 13.扩展性问题 Hadoop架构支持单独增加数据节点或计算节点,HDFS数据存储对计算层来说是透明的 MPP数据库扩展时,一般情况下是计算节点和数据节点一起增加的,在增加节点后, 需要对数据做重分布才能保证数据与节点的紧耦合(重新hash数据),进而保证系统的性能; Hadoop在增加存储层节点后,虽然也需要Rebalance数据,但相较MPP而言,不是那么紧迫。 14.节点宕机方面 Hadoop节点宕机退服,对系统的影响较小,并且系统会自动将数据在其它节点扩充到3份;MPP数据库节点宕机时,系统的性能损耗大于Hadoop节点。 15.总结 Hadoop MapReduce和SQL-on-HADOOP技术目前都还不够成熟,性能和功能上都有很多待提升的空间 如果你的数据需要频繁的被计算和统计、并且你希望具有更好的SQL交互式支持和更快计算性能及复杂SQL语法的支持,那么你应该选择MPP数据库 SQL-on-Hadoop技术还没有Ready。特别如数据仓库、集市、ODS、交互式分析数据平台等系统,MPP数据库有明显的优势。 你的数据加载后只会被用于读取少数次的任务和用于少数次的访问,而且主要用于Batch(不需要交互式), 对计算性能不是很敏感,那Hadoop也是不错的选择,因为Hadoop不需要你花费较多的精力来模式化你的数据,节省数据模型设计和数据加载设计方面的投入。 这些系统包括:历史数据系统、ETL临时数据区、数据交换平台等等。 Greenplum MPP数据库支持用“Hadoop外部表”方式来访问、加载Hadoop FS的数据,虽然Greenplum的Hadoop外部表性能大幅低于MPP内部表, 但比Hadoop 自身的HIVE要高很多(在某金融客户的测试结果,比HIVE高8倍左右), 因此可以考虑在项目中同时部署MPP数据库和Hadoop,MPP用于交互式高性能分析, Hadoop用于数据Staging、MPP的数据备份或一些ETL batch的数据清洗任务,两者相辅相成,在各自最擅长的场景中发挥其特性和优势 总之,千万不要为了大数据而大数据(就好像不要为了创新而创新一个道理), 否则,你项目最后的产出与你的最初设想可能将差之千里,行业内不乏失败案例 16.Greenplum提供称为“多态存储”的灵活存储方式。多态存储可以根据数据热度或者访问模式的不同而使用不同的存储方式。 一张表的不同数据可以使用不同的物理存储方式。支持的存储方式包含: 行存储:行存储是传统数据库常用的存储方式,特点是访问比较快,多列更新比较容易。 列存储:列存储按列保存,不同列的数据存储在不同的地方(通常是不同文件中)。适合一次只访问宽表中某几个字段的情况。列存储的另外一个优势是压缩比高。 外部表:数据保存在其他系统中例如HDFS,数据库只保留元数据信息。 17.Greenplum数据分布策略random与hash-distribution hash分布。指定一个或多个分布键,计算hash值,并且通过hash值路由到特定的Segment节点上,语法为Distributed by(..)。 如果不指定分布键,默认将第一个字段作为分布键。 当选择 Random Distribution 时,数据将会随机分配至 Segment,相同值的数据行不一定会分发至同一个 Segment。 虽然 Random Distribution 策略可以确保平均分散至所有 Segment,但是在进行表关联分析时, 仍然会按照关联键重分布数据,所以 Random Distribution 策略通常不是一个明智的选择。 在数据建模时,表的分片规则选取一定要慎重,尽可能选择唯一且常用语 Join 的列作为 Distributed Key。 这样数据才会均匀分散至所以 Segment 实例,相应的查询及计算的负责也会平摊至整个集群,进而最大程度体现分布式计算的优势。 假如 Distributed Key 选取不当(如选择性别列作为 Distribution Key),数据将只会分散至少数几个 Segment, 这样将只有少数 Segment 处理相应的计算请求,完全不能发挥整个集群的计算资源,实现并行计算。 18. 跨库关联 gp 数据库将表数据分散至所有 Segment 实例,当需要进行表关联分析时,由于各个表的 Distributed Key 不同, 相同值的行数据可能分布在不同服务器的不同 Segment 实例,因此不可避免需要在不同 Segment 间移动数据才能完成 Join 操作。 跨库关联也正是分布式数据库的难点之一 gp 数据库是如何解决这个问题的: (1)Join 操作的两个表的 Distributed Key 即 Join Key 由于 Join Key 即为两个表的 Distributed Key,故两个表关联的行本身就在本地数据库(即同一个 Segment 实例),直接关联即可。 在这种情况下,性能也是最佳的。在进行模型设计时,尽可能将经常关联的字段且唯一的字段设置为 Distributed Key (2)Join 操作的两个表中的一个 Distributed Key 与 Join Key 相同 由于其中一个表的 Join Key 和 Distributed Key 不一致,故两个表关联的行不在同一个数据库中,便无法完成 Join 操作。 在这种情况下就不可避免地需要数据跨节点移动,将关联的行组织在同一个 Segment实例,最终完成 Join 操作。 gp 可以选择两种方式将关联的行组织在同一个 Segment 中,其中一个方式是将 Join Key 和 Distributed Key 不一致的表按照关联字段重分布 (Redistribute Motion),另一种方式是可以将 Join Key 和 Distributed Key 不一致的表在每个 Segment 广播(Broadcast Motion) (3)Join 操作的两个表的 Distributed Key 和 Join Key 都不同 由于两个表的 Join Key 和 Distributed Key 都不一致,故两个表关联的行不在同一个数据库中,便无法完成 Join 操作。同样在这种情况下, 一种方式将两个表都按照关联字段重分布(Redistribute Motion),另一种方式可以将其中一个表在每个 Segment 广播(Broadcase Motion), 也就是每个 Segment 都复制一份全量。 若数据量相差比较大的情况下,将小表广播到各个seg节点上,会执行的更快。 若数据量基本相当,则使用数据重分布的方式,通常代价比较小。 20.select 查询数据顺序不固定 gp的数据切分放在所有的Segment上。当从一个表查询数据的时候,Master的数据展现顺序是以Master先接收到的数据的顺序, 每个Segment的数据到达Master的顺序是随机的,不是固定的,所以执行SELECT的结果的顺序是随机的,即使表中数据一点变化都没有。 这一点跟其他数据库是不一样的 21.几点数据切片带来的问题 insert:在执行insert语句的时候,要留意分布键不要为空,否则分布键默认会编程null,数据都被保存在一个节点上,造成数据分布不均 update:不能批量对分布键执行update,因为对分布键执行update需要将数据重分布,而gp暂时不支持这个功能 在gp 3.x的版本中,如果delete操作涉及子查询,并且子查询的结果还会涉及数据重分布,这样的删除语句会报错,如下(gp 4.x中支持该操作) 22.就是一张表的数据是指向数据库之外的数据文件的。在gp中,我们可以对一个外部表执行正常的DML操作,当读取数据时,数据库就从数据文件中加载数据。 外部表支持在Segment上并发地告诉从gpfdist导入数据,由于是直接从Segment上导入数据,所以效率非常高。 使用COPY命令可以实现将文件导出和导入,只不过要通过Master,效率没有外部表高,但是在数据量比较小的情况下,COPY命令比外部表要方便很多 23.分布式事务处理是指一个事务可能涉及多个数据库操作,而分布式的关联在于两阶段提交(Two Phase Commit,2PC)。 两阶段提交用于确保所有分布式事务能够同时提交或者回滚,以便数据库能够处于一致性状态。 两阶段提交: 第一阶段,Master 向每个 Segment 发出“准备提交”请求,数据库收到请求后执行相同的数据修改和日志记录等处理, 处理完成后只是把事务的状态改成“可以提交”,然后把执行的结果返回给 Master 第二阶段,Master 收到回应后进入第二阶段,如果所有 Segment 都返回成功, 那么 Master 向所有的 Segment 发出“确认提交”请求,数据库服务器把事务的“可以提交”状态改为“提交完成”状态, 这个事务就算正常完成了, 如果在第一阶段内有 Segment 执行发生了错误,Master 收不到 Segment 回应或者 Segment 返回失败,则认为事务失败,回撤事务, Segment 收到 Rollback 的命令,即将当前事务全部回滚。 两阶段提交并不能保证数据一定会恢复到一致性状态。例如,当 Master 向 Segment 发出提交命令的时候,在提交过程中, 有一个 Segment 失败了,但是其他 Segment 已经提交成功了,那么这个事务是不能再次回滚的,这样就会造成不一致的情况。 两阶段提交的核心思想就是将可能发生不一致的时间降低到最小,因为提交过程对数据库来说应该是一个瞬间完成的动作, 而且发生错误的概率极小,危险期比较短。 24. gp 有一个很重要的概念:Slice(切片)。每一个广播或重分布会产生一个切片, 每一个切片在每个数据节点上都会对应发起一个进程来处理该 Slice 负责的数据, 上一层负责该 Slice 的进程会读取下级 Slice 广播或重分布的数据,然后进行相应的计算。 由于在每个 Segment 上每一个 Slice 都会发起一个进程来处理,所以在 sql 中要严格控制切片的个数, 如果重分布或者广播太多,应适当将 sql 拆分,避免由于进程太多给数据库或者是机器带来太多的负担。 进程太多也比较容易导致 sql 失败 25.id Scan:通过隐藏字段 ctid 扫描 ctid 是pgsql 中标记数据位置的字段,通过这个字段来查找数据,速度非常快,类似于 oracle 的 rowid。 gp 是 一个分布式数据库,每一个子节点都是一个pgsql 数据库,每一个子节点都单独维护自己的一套 ctid 字段。 如果想确定到具体一行数据,还必须通过制定另外一个隐藏字段(gp_segment_id)来确定取哪一个数据库的 ctid 值。 select * from test1 where ctid='(1,1)' and gp_segment_id=1;