如果你对分布式存储这方面感兴趣的话,请放弃对传统RDBMS数据库的幻想,要学着拥抱NoSQL。
分布式存储这块其实说起来,就是这几部分:数据如何写入、数据如何查询、数据分片方法和数据副本方法。
分布式集群系统中大多数的分布式存储系统都拥有着非常优异的写入能力,我就说说分布式文件系统和分布式K/V数据库的写入场景。
分布式文件系统(DFS)
DFS中商业支持比较好的有Hadoop HDFS、GlusterFS、MooseFS等。对HDFS的商业支持最为广泛,例如:cloudera,HDFS之父应该还在那里上班,GlusterFS是Redhat的嫡系,MooseFS主要来自于波兰一家商业公司的支持。
DFS的特征就是以封装成小块的形式顺序的写入较大的文件块,在小块写入的过程一般都会进行多副本节点的复制,复制方式上HDFS和MooseFS都通过管道形式,节点自上而下顺序复制,而GlusterFS是去中心化通过Hash共识,因此GlusterFS的副本卷都是由客户端完成复制。DFS的写入因为是二进制顺序的方式,不构建任何索引,因此写入文件的速度会非常快。
DFS在写入过程中一般默认都是三副本,但是HDFS和GlusterFS都不约而同的支持了EC冗余方案,类似于Raid5、6,可以在满足高可靠的情况下,提升存储利用率,从33.3%提升到66.7%及以上。
写入的文件块都需要元数据来组织成文件树,不同之处在于HDFS、MooseFS这种中心化的DFS,会对写入的元数据描述都交给主节点来管理,因此就有了HDFS的NN,MooseFS的MFS Master,但是GlusterFS是去中心化的方式,它的元数据存在于不同Brick节点文件目录的属性中,因为是去中心和结构,就需要大量依赖客户端通过Hash共识机制,根据不同文件目录的属性创建和组织文件树。
最后有一点就是对Linux内核FUSE机制的结合上(包括:大部分Unix系统),MooseFS、GlusterFS可以无缝对接,这就在客户端形成了普通文件目录访问的便利性,但是HDFS仍需要通过HDFS客户端命令实现模拟的文件目录访问。
分布式K/V数据库
分布式K/V数据库大多数都是基于LSM-Tree的数据模型,我们就简单说一下:HBase、Cassandra和InfluxDB的写入场景。
HBase
HBase完全参考Google BigTable论文实现了分布式CP系统,强调写入的强一致性,Cassandra部分参考了Google BigTable论文中的数据模型,在分布式方面则完全参考了Amazon Dynamo,强调读写的最终一致性;InfluxDB属于专业的时序数据库(TSDB),数据模型参考LSM-Tree,根据时序数据特性,创造了TSM数据模型,在分布式方面的数据读写与复制方面非常类似Cassandra的去中心化方式,但仍是在此基础上针对时序进行了优化,InfluxDB是弱一致性。详细可以参考我写的另外两篇:
HBase 与 Cassandra 架构对比分析的经验分享
深入浅出:了解时序数据库 InfluxDB
HBase的写入首先需要在Meta中寻址定位,客户端通过写入数据的行键找到对应的Region,通过Region找到所在的RegionServer节点,当该Region写得足够多以至于达到设定阀值后,Region就开始拆分(Split),通过Region的拆分实现子Region向多个RegionServer节点的数据分布。因此HBase看起来总是顺序的,并且对于某个列簇,即便拆分成了多个Region,但总是朝唯一的Region写入,并且写入过程保证了行级事务,这是HBase在分布式环境下强调写入的强一致性的根本所在。
Cassandra
Cassandra是去中心化的分布式K/V数据库,侧重分布式AP,强调高可用。大家一定记住,只要是去中心化的集群,基本上都离不开Hash共识算法,需要用此方式来实现数据的分布。Cassandra在写入过程中客户端可以连接任意一个节点,该节点就作为协调节点,每个协调节点都有一份整个集群的令牌环(Token Ring),这个Token就是一致性哈希算法组成的逻辑环,在环上布满了虚拟令牌,通过虚拟令牌与集群节点的交错映射,就优雅的实现了写入数据在不同节点的均匀分布。协调节点通过复制策略,在令牌环上顺时针逐一放置副本数据。
上述HBase和Cassandra都是LSM-Tree机制,先写入内存和WAL,WAL用于内存崩溃恢复,内存定时或者达到阀值在Flush到磁盘到SSTable,SSTable定期进行合并成更大的SSTable,用于去重和删除过期数据,也便于提升查询效率。
InfluxDB
InfluxDB基于TSM结构,这种结构也是LSM-Tree的大体机制,有Cache,WAL和TSM文件。不同之处在于数据结构上按照了时序(TS)的形态,时序的一个数据点的结构是:数据源(标签集合)+指标+时间戳,对应一个点的数据,InfluxDB对这种结构做了优化,实现了数据源(标签集合)+指标(字段)作为主键对应了一组大量连续的TimeStamp:Value,这样TS也好方便压缩(delta-delta算法),Value也方便压缩(基于不同数据类型压缩)。那么Influx可以做成什么效果呢?单机就能轻松应对超大规模的时序吞吐,而存储的TSM文件还非常奇妙的小巧。
另外InfluxDB在分布式方面更侧重AP,保证高可用,和Cassandra如出一辙的使用hint-handoff机制,来暂时屏蔽故障副本节点,由当前协调节点临时代存数据,满足极端情况下,面对客户端的写入仍能正常进行。
InfluxDB的特色在于针对时序的分布式设计:用连续的间隔时长作为一个时间范围,叫做ShardGroup,例如1小时作为一个时间分组,那么这1小时的写入数据,再通过Hash取模的方式分布在不同的节点上。分片数量=集群数量/副本因子,例如4个节点的副本因子是2,那么就有2个分片,当每次写入时,Hash定位到1个分片,就等于需要复制到这个分片所属的2个节点。这样就非常适应时序结构的需要,从而实现了从时间范围分布到Hash分布的层次设计,使数据按照TS为主线均匀的分布在集群的不同节点。