CAP 理论指出,在分布式系统中,不能同时满足一致性、可用性和分区容错性,指导了分布式数据存储系统的设计。
随着数据量和访问量的增加,单机性能已经不能满足用户需求,分布式集群存储成为一种常用方式。把数据分布在多台存储节点上,可以为大规模应用提供大容量、高性能、高可用、 高扩展的存储服务。而分布式存储系统就是其具体实现。
分布式存储系统的关键三要素:顾客、导购与货架。
什么是分布式数据存储系统?
分布式存储系统的核心逻辑:将用户需要存储的数据根据某种规则存储到不同的机器上,当用户想要获取指定数据时,再按照规则到存储数据的机器里获取。
如下图所示,当用户(即应用程序)想要访问数据 D,分布式操作引擎通过一些映射方式,比如 Hash、一致性 Hash、数据范围分类等,将用户引导至数据 D 所属的存储节点获取数据。
生产者和消费者生产和消费的数据通常是多种多样的,不同应用场景中数据的类型、格式等都不一样。根据数据的特征,这些不同的数据通常被划分为三类:结构化数据、半结构化数据和非结构化数据: 结构化数据:指关系模型数据,其特征是数据关联较大、格式固定。火车票信息比如起点站、终点站、车次、票价等,就是一种结构化数据。结构化数据具有格式固定的特征,因此一般采用分布式关系数据库进行存储和查询。半结构化数据:指非关系模型的,有基本固定结构模式的数据,其特征是数据之间关系比较简单。比如 HTML 文档,使用标签书写内容。半结构化数据大多可以采用键值对形式来表示,比如 HTML 文档可以将标签设置为 key,标签对应的内容可以设置为 value,因此一般采用分布式键值系统进行存储和使用。非结构化数据:指没有固定模式的数据,其特征是数据之间关联不大。比如文本数据就是一种非结构化数据。这种数据可以存储到文档中,通过 ElasticSearch(一个分布式全文搜索引擎)等进行检索。
导购:确定数据位置
导购是分布式存储系统必不可少的要素,如果没有导购, 顾客就需要逐个货架去寻找自己想要的商品。如果去订票网站订火车票,按照自己的需求点击查询车票后,系统会逐个扫描分布式存储系统中每台机器的数据,寻找你想要购买的火车票。如果系统中存储的数据不多,响应时间也不会太长,毕竟计算机的速度还是很快的;但如果数据分布在几千台甚至上万台机器中,系统逐个机器扫描后再给你响应,严重影响购票体验。
因此在分布式存储系统中,必须有相应的数据导购,否则系统响应会很慢,效率很低。为解决这个问题,数据分片技术就走入了分布式存储系统中。
数据分片技术:指分布式存储系统按照一定的规则将数据存储到相对应的存储节点中,或者到相对应的存储节点中获取想要的数据,优点:
降低单个存储节点的存储和访问压力;通过规定好的规则快速找到数据所在的存储节点,从而大大降低搜索延迟,提高用户体验。
当铁路局发布各个线路的火车票信息时,会按照一定规则存储到相应的机器中, 比如北京到上海的火车票存储到机器 A 中,西安到重庆的火车票存储到机器 B 中。当乘客查询火车票时,系统就可以根据查询条件迅速定位到相对应的存储机器,然后将数据返回给用户,响应时间就大大缩短了。如图所示,当查询北京 - 上海的火车票相关信息时,可以与机器 A 进行数据交互。
例子中按照数据起点、终点的方式划分数据,将数据分为几部分存储到不同的机器节点中,就是数据分片技术的一种。当查询数据时,系统可以根据查询条件迅速找到对应的存储节点,从而实现快速响应。 还有其他很多数据分片的方案。比如,按照数据范围,采用哈希映射、一致性哈希环等对数据划分。
针对数据范围的数据分片方案:按照某种规则划分数据范围,然后将在这个范围内的数据归属到一个集合中。这就好比数学中通常讲的整数区间,比如 1~1000 的整数,[1,100] 的整数属于一个子集、[101,1000] 的整数属于另一个子集。
对于前面讲的火车票的案例,按照数据范围分片的话,可以将属于某条线的所有火车票数据划分到一个子集或分区进行存储,比如机器 A 存储京广线的火车票数据,机器 B 存储京沪线的火车票数据。数据范围的方案是按照范围或区间进行存储或查询。
如图所示,当用户查询北京 - 上海的火车票相关信息时,首先判断查询条件属于哪个范围,由于北京 - 上海的火车线路属于京沪线,因此系统按照规则将查询请求转到存取京沪线火车票数据的机器 B,然后由机器 B 进行处理并给用户返回响应结果。