快速,持续,稳定,傻瓜式
支持Mysql,Sqlserver数据同步

聊聊MySQL、HBase、ES的特点和区别

在线QQ客服:1922638

专业的SQL Server、MySQL数据库同步软件

本文来自:https://www.jianshu.com/p/4e412f48e820

在Internet时代,各种各样的存储框架层出不穷,例如传统的关系数据库:Oracle,MySQL;新兴的NoSQL:HBase,Cassandra,Redis;全文检索框架:ES,Solr等。如何为您的业务选择合适的存储解决方案,我相信每个人都已经考虑过这个问题。本文简要讨论了我对Mysql,HBase,ES的理解。我希望与您讨论进展。请指出是否有问题。

MySQL:关系数据库,主要用于OLTP,支持事务,支持二级索引,支持sql,支持主从,组复制体系结构模型(本文以Innodb为例,不涉及其他存储引擎)。

HBase:基于HDFS,支持海量数据读写(尤其是写入),并支持具有数亿行和数百万列的面向列的分布式NoSql数据库。自然分布的主从体系结构,不支持事务,不支持二级索引,不支持sql。

ElasticSearch:ES是一个分布式的全文本搜索框架。底层基于Lucene。尽管ES还提供存储和检索功能,但我从未想到ES是数据库,但是随着ES功能变得越来越强大,与数据库的界限越来越模糊。自然分布的p2p体系结构不支持事务,它使用倒排索引提供全文本搜索。

下面从数据存储方法,读写方法,索引和分布方面对它们进行了比较。

参考链接:

ES:http://www.jianshu.com/p/e8ee319a238d

HBase:http://www.cnblogs.com/songlee/p/5738027.html

—————————————————我是分界线———————————————————


MySQL使用行存储。 HBase是面向列的NoSql数据库。本文介绍了行存储和列存储之间的区别。至于ES,呃我不知道它是什么存储方法。现在将其称为索引存储。

栗子

假设有这样的人员信息表:

需要在MySQL中预先定义表结构,即需要预先定义表的列数(属性),同时需要定义每列所占用的存储空间。数据按行组织。如果行或列中没有数据,则还需要存储空间。

HBase将数据存储在列中。每列都是一个键值。 HBase表列(属性)不需要预先定义,并且可以动态扩展这些列。例如,需要将新的”地址”添加到人员信息表。 “字段,如果直接插入HBase,MySQL需要提前进行变更表。

ES更灵活。索引中的字段类型可以预先定义(定义映射),也可以未定义。如果未定义,则将使用默认类型,但是对于可控制性,最好事先定义关键字段,这是很好的。 (必须在Solr中预先定义schema.xml文件)

上面的图片仅显示了MySQL和HBase之间的数据存储差异(与实际情况仍然存在差距)。您可以看到,即使第二条记录的sex字段为空,MySQL仍将为此字段保留空间。因为可能存在随后的更新语句来更新记录,所以是对性内容的补充。 HBase将每一列视为一条记录,将行+列名用作键,将数据用作值,它们按顺序存储。如果一行的某一列中没有数据,请直接跳过该列。对于矩阵稀疏的大型表,HBase可以节省空间。

看到这一点,每个人都会有一个问题:使用HBase存储时,如果此时需要添加第二行的性内容,该如何实现?数据是连续的吗?稍后将说明读写过程。

不同的ES

在讨论MySQL和HBase之后,让我们集中讨论ES。 ES的存储方法与以上两种不同。 MySQL和HBase以不同的方式存储数据,无论它们存储数据还是ES都存储反向索引。首先让我们了解什么是反向索引以及为什么需要反向索引(Inverted Index):

我们一定会有这样的经历:我不小心看到了一篇不错的文字,但我不知道其出处。这时,我去了图书馆,一一搜寻。毫无疑问,它是大海捞针。全文搜索技术,其核心是倒排索引。如果有以下文件:

我们想知道哪些文档包含您的关键字,我们首先可以创建以下格式的反向索引:

我们将前一部分称为字典,其中的每个单词称为术语,随后的文档列表称为psoting-list。该列表记录了包含该术语的所有文档ID。两者的结合是一个完成倒排索引(Inverted Index)。可以看出,如果需要查找包含”您”的文档,则可以根据词典找到相应的投递清单。

在全文搜索中,创建倒排索引是最关键且最耗时的过程,并且真正的倒排索引结构比图中所示复杂得多,不仅需要对文档进行分段(ES中的中文可以自定义细分),还可以计算TF-IDF,以方便对得分进行排名(当您查找时,得分确定哪个文档显示在前面,即所谓的搜索排名),压缩和其他操作。每次接收到文档时,ES都会以反向索引更新其信息。

从这里我们可以看到ES,MySQL,HBase存储仍然非常不同。 ES不仅包括一个反向索引,而且默认情况下还存储文档doc,因此当我们使用ES时,我们还可以获得完整的文档信息,因此在某种程度上感觉就像在使用数据库,还可以对其进行配置不存储文档信息。此时,只能根据查询条件获取文档id,无法获取完整的文档内容。

摘要:MySQL行存储更适合OLTP业务。列存储方法更适合OLAP业务,HBase使用列族方法来平衡OLTP和OLAP,并支持水平扩展。如果数据量比较大,对性能的要求不是很高,而对于事务则没有要求,那么HBase也是一个很好的考虑因素。 ES默认情况下会为所有字段建立索引,因此它更适合于复杂的检索或全文检索。

—————————————————我是分界线———————————————————


存储方法和读写方法在很大程度上决定了系统的吞吐量。本节主要介绍MySQL,HBase和ES如何分别读写数据。


让我们先谈谈MySQL。 MySQL的Innodb中的数据按主键的顺序存储。主键是聚簇索引。文章),索引使用B +树结构进行组织。

 webp  uploading.4e448015.gif 传输失败重新上传已取消

从图中可以看出,假设以下场景,数据按聚类索引的顺序存储:

1.查询

Innodb中的主键是聚集索引。如果查询基于主键,则将聚簇索引的叶节点存储为真实数据,并可以直接找到相应的记录。

如果是二级索引查询,则需要先通过二级索引找到记录的主键,然后再根据主键通过聚簇索引找到对应的记录。这是一个附加的索引搜索过程。

2.插入

顺序插入:因为Innodb的数据按聚簇索引的顺序存储,所以如果按照主键索引的顺序插入,即插入数据的主键是连续的,因为是连续的,因此插入效率会更高。

随机插入:如果插入的数据的主键不连续,则MySQL需要删除与每个记录相对应的物理块,这将导致大量的io随机。随机io操作和顺序io的性能非常不同,尤其是机械磁盘。

(Kafka官方网站提到机械磁盘的顺序写入速度可以达到600M/s,而随机写入可能仅为100k/s。因此,在具有六个7200rpm SATA的JBOD配置上,线性写入的性能RAID-5阵列的速度约为600MB/秒,但随机写入的性能仅约100k/秒,相差超过6000倍,这就是HBase和ES将所有插入,更新和删除操作视为顺序写入操作的原因,从而避免了随机写入io)

注意:这就是为什么MySQL的主键通常被定义为自动递增的id,并且不涉及业务逻辑,因此可以按io的顺序插入新数据的原因。为了提高随机io的性能,MySQL提供了插入缓冲区的功能。

3.更新\删除

如果更新和删除顺序不正确,它们还将包含大量随机io。当然,MySQL对随机io进行了一些优化,以最小化由随机io引起的性能损失。


HBase不支持二级索引,它只有一个主键索引,并且使用LSM树(LSM可以参考此博客)。

HBase是一个分布式系统。这与MySQL不同。其数据分布在不同的服务器上。每个表由一个或多个区域组成。区域分散在群集中的服务器上。一台服务器可以负责多个区域。

有一点需要特别注意:用于在表的每个区域中存储数据的行键(主键)的范围不会重叠。可以认为,该区域上的数据是基于行键进行全局排序的,每个区域负责其自己的零件数据。

1.查询

如果要查询rowkey = 150的记录,请首先从zk获取hbase:meta表(存储区域和键之间的对应关系的元数据表)的位置,然后通过查询元表数据位于哪个服务器的哪个区域中。

2.插入

上图大致显示了HBase区域的结构。区域不仅仅是一个文件,它还由一个内存存储区和多个storeFiles(可以配置storeFile的上限)组成。插入数据时,首先将数据写入memstore。当内存大小达到某个阈值时,将其刷新到硬盘并将其转换为新的storeFile。刷新时,将对内存存储中的数据进行排序和压缩。您可以看到单个storeFile中的数据是有序的,但是区域中storeFiles之间的数据不是全局排序的。

这具有的优点:无论主键是否连续,所有插入都将成为顺序写入,这大大提高了写入性能。

看到此消息时,您可能会遇到一个问题:如果此写入方法导致一次插入一条记录,则该记录可能分散在不同的storeFiles中。您如何查询该区域的记录?您要寻找哪个storeFile?答案是:所有查询。 HBase将使用多路合并方法来查询该区域中的所有storeFiles,直到找到满足条件的记录。因此,HBase具有良好的写入性能,但读取性能较差。

当然,HBase还进行了许多优化,例如每个storeFile都有自己的索引,bloom过滤器以进行过滤,压缩:以可配置的方式将多个storeFiles合并为一个,从而减少了在检索过程中打开的文件数。

3.更新\删除

HBase还将更新和删除视为插入操作,并使用时间戳记和删除标记来区分记录是否为最新记录以及是否需要删除。正因为如此,除了查询之外,其他操作也被统一转换为顺序写入,从而确保了HBase的高效写入性能。


ES也是分布式系统。与ES相似,还有一个名为Solr的项目,该项目基于Lucene的全文检索分布式框架。如果您有兴趣,可以访问Lucene官方网站进行了解。进行比较。

 webp  uploading.4e448015.gif 传输失败重新上传已取消

上面显示了ES概念与传统数据库的比较。在下面的介绍中,索引用于对应于DB中的表,doc对应于表中的记录,而field对应于行中的列。

ES群集由一个或多个节点组成,并且一个节点是ES服务进程。索引由多个分片组成。碎片散布在每个节点上。每个分片都使用Lucene创建一个反向索引并维护自己的索引数据。

图中的小方框是碎片。对于灾难恢复,每个分片将有多个副本。可以配置份数。默认值为2,绿色为主要分片,灰色为副本分片。

1.插入

让我们先谈谈写作。由于存在多个分片,如何确定请求到来时写入哪个分片? ES中的每个文档都会有一个唯一的ID。分片的数量被设置为相应的分片。默认情况下,分片中的数据ID不是全局排序的,这与Mysql和HBase完全不同。

ES编写有点类似于HBase。它还会将所有写入操作转换为顺序写入。它还先将数据写入内存,然后在一段时间后将内存数据刷新到磁盘,并且磁盘索引文件将定期合并以确保不会有太多影响检索性能的索引文件。

另外,将数据存储在ES 中后不会立即检索数据,这与MySQL和HBase或数据库系统完全不同。主要原因是由于Inverted Index结构的复杂性,需要特殊的indexReader来查询数据,但是indexReader是由快照打开的索引,这意味着indexReader之后无法看到新数据。因此ES提供了刷新功能,刷新后将重新打开indexReader,以便它可以读取最新数据。默认刷新间隔为1s,因此ES声称是近实时检索功能。

关于顺序写入,您此时可能会想到:那么ES的写入速度几乎与HBase的相同?这是不对的,不仅劣等,而且还差一点,因为ES还有两个更关键的步骤:构建索引和刷新索引!这两个过程非常耗时:复杂的操作,例如分词并需要计算权重以建立索引(有关创建反向索引和检索的信息,请参阅”信息检索简介”)。刷新将重新打开索引,这两个过程加起来等于ES的接收率文献s不高(您可以加快批量导入数据的速度)。但是正是由于这些过程,ES才具有强大的搜索功能。 (尽管我的插入速度很慢,但是我有很多技巧^ ^)

2.阅读

每个节点都可以接收读取的请求,然后该节点会将请求分发到包含索引分片的节点。相应的节点将查询并计算符合条件的文档。排序的结果将汇总到分发请求中。节点(因此默认情况下,查询请求将以循环方式发送到每个节点,以防止所有请求都到达节点),并且该节点会将数据返回给客户端。 (ES还支持指定分片查询。默认情况下,路由基于文档ID,等效于主键查询,但是如果您无法确定数据位于哪个分片上,则仍然需要查询所有分片)

在这里我想强调一点,因为ES支持全文搜索,根据倒排索引的特性,在大多数情况下,关键字对应于很多doc,如果全部返回,则会导致大量数据集群上的压力更大,因此ES默认情况下仅返回权重最高的前20条记录(可配置),或者您可以通过滚动功能获取所有数据。类似的情况与我们通常使用baidu和google的情况相同。当我们使用搜索引擎时,我们经常希望获得关联性最强的前N个文档。我们不在乎所有文档的数量。这就是为什么我们需要计算重量。 。

ES的功能越来越丰富,不仅包括全文搜索功能,还包括统计分析和其他功能。说这是一个全文搜索框架。它比全文搜索功能更丰富。 ,但是它不支持事务,只能说各个框架之间的界限越来越模糊。

3.更新\删除

ES更新和删除与HBase类似,它们都被视为插入操作,通过时间戳和删除标记来区分。

还是问题链接:D :由于这种将它们更新,删除和统一为顺序写入的方式可以提高写入性能,这不是无害的吗?

答案是肯定的,这种方法可以有效地提高写入性能,但是存在一个很大的问题,即后台经常需要合并,并且合并是一个非常耗资源的过程,对于某些稳定性要求对于更高的服务来说,这是不能接受,但是没有合并,它将降低查询性能(太多的小文件会影响查询性能)。当前的常见做法是尝试为合并操作选择业务的高峰期。

—————————————————我是分界线———————————————————


在数据库系统中,数据完整性和一致性是非常重要的问题。数据库进程已挂起,可以恢复,但是数据丢失了,您将找不到它。让我们谈谈每个系统的灾难恢复方法。

MySQL


单节点:

当前数据库通常使用预写日志策略来避免数据丢失。 wal机制的简单解释是:提交CUD操作并将数据写入内存时,还必须将副本写入日志文件,并且必须保证日志。成功放置数据后,成功的操作只能返回给客户端。如果此时数据库已关闭,则已提交到内存的数据将没有时间闪回磁盘。重新启动数据库后,可以通过重播日志文件来恢复内存中的数据。

问题又来了:写日志是否会对性能产生重大影响?实际上,它仍然影响不大,但是日志文件是按顺序写入的。为了确保数据完整性,这种性能损失仍然可以接受。

在单机情况下,MySQL的innodb使用重做日志和检查点机制来确保数据完整性。因为恐怕日志越大,占用的磁盘越多,并且当日志特别大时,恢复时间比较耗时。检查点的出现就是为了解决这些问题。

检查点机制可确保以前的日志数据必须已闪回磁盘。当数据库关闭时,您只需要在检查点之后重播日志。数据库将定期检查点,以确保数据库恢复的效率。

但是,考虑到如果在硬件出现故障时机器无法启动,或者在磁盘出现故障时无法恢复数据,则检查点+重做日志解决方案将无法工作。为了防止此类故障,MySQL还提供了主从复制和组复制群集级灾难恢复解决方案。 ?

Master-Slave体系结构的主要思想是:主机负责业务读写请求,然后通过binlog复制到从机节点,这样如果由于不可抗拒的原因无法恢复主机库,从属库可以提供服务。 在这里我们使用单词” replication”代替” synchronization”,因为基于binlog复制的方案无法实现主数据和从数据之间的强一致性。在主库挂起之后,这种主从同步方法将导致从属库丢失少量。数据。

由于主从架构中数据不一致的问题,MySQL 5.7提供了Mysql组复制解决方案。 mgr使用paxos协议来实现数据节点的强同步,确保所有节点都可以写入数据,并且所有节点还可以读取最新数据。 (请原谅我为有限的水平,我不知道为什么主从体系结构会丢失数据,也不知道mgr是如何实现的,但这是前同事推荐的一本书: 《 MySQL Operation and Maintenance Internal Reference》详细解释了主从和组复制的体系结构,是深入了解Mysql的最佳选择。据说这本书的出现降低了本书的功能。 DBA的门槛,也没有怀疑广告^ ^)

HBase:

HBase的灾难恢复在某种程度上类似于MySQL的独立灾难恢复,但是具体实现仍然具有其自身的特征。在介绍HBase灾难恢复之前,让我们首先了解HBase与HDFS之间的关系:HBase中的数据存储在HDFS上,您可以简单地了解HBase分为两层:一层是NoSql服务(即,它提供分布式检索服务)),第一层是分布式文件系统(当前使用HDFS实际存储数据)在HBase中,区域分布在不同的区域服务器上,客户端使用元表来定位区域。数据所在的区域服务器,然后获取数据,但是数据不一定存储在区域服务器中,并且每个区域都知道自己的对应关系,通过最终访问HDFS数据来访问HDFS数据的哪些数据块,尤其是当HBase和HDFS部署在不同的集群上时,完全通过RPC实现数据的读写,以减少RPC的开销并确保服务Stable,HBase和H DFS通常部署在同一群集中。 同样,当一个区域服务器挂起时,该区域可以快速切换到另一个区域服务器,因为它仅涉及日志的回放,并且不会移动已放置的数据,并且HBase还将控制日志的大小减少恢复时间

HBase还使用写入日志的方法来防止数据丢失。将数据写入内存时,也会将其写入HLog。 HLog也存储在HDFS上。写入HLog之后,认为已成功写入数据,并且挂起了区域服务器。此后,主服务器将发生故障的计算机上的区域调度到另一个区域服务器。区域服务器通过重播HLog来还原区域的数据。恢复成功后,区域将恢复联机状态。由于日志直接写入HDFS,因此无需担心单个节点挂起。日志问题数据丢失。

此处出现问题:播放HLog时,要恢复HLog的播放成功之前,要恢复的区域将在短时间内不可用。 HBase 1.0版本添加了区域副本功能,该功能用于提供从属区域。当主区域挂起时,从属副本仍可用于读取数据,但从属不提供写操作,并且从属副本与主要区域之间没有强烈同步。是的,并非总是能够读取最新数据,因此,当您打开此功能时,还必须考虑您的业务是否需要强一致性。

HBase还提供群集复制,以用于计算机机房级灾难恢复。老板说,集群复制中仍然存在一些错误,并且它正在积极地进行优化和改进。我相信集群复制在将来会越来越完善。

ES:


ES灾难恢复还使用写入日志的方式。与HBase不同,ES节点存储自己的日志。这类似于MySQL。日志存储在本地,也存在。 MySQL有同样的问题。如果计算机关闭或硬盘出现故障,日志数据也将丢失,因此索引的每个碎片也都有一个主数据库和备份数据库。默认配置是主碎片和副本碎片。当然,也可以配置多个副本。

默认情况下,主分片首先接收客户端发送的数据,然后将数据同步到副本分片。当副本分片也被成功写入时,将通知客户端数据该数据已正确写入,这可以防止数据当副本分片尚未写入时,由于主挂起而导致数据丢失。

现在该再次询问问题。如果副本节点出现问题,例如无法写入网络故障,这是否表示数据写入失败?因此,ES主服务器维护一个同步集,该同步集存储当前处于活动状态并与主数据库同步的副本集。只要集合中副本的同步完成,就可以认为数据写入成功。考虑一种情况:由于网络故障,所有副本均处于脱机状态,此时同步集为空,数据仅保留在主数据库中,很可能会由于主数据库故障而导致数据丢失,因此将ES与wait_for_active_shards参数,只有当尚存副本数大于此参数时,它才能正常写入。如果不满意,则停止写服务。

(这是5.X版本的实现。由于ES版本更新太快,因此与2.X之前的版本略有不同。5.X和7.x中的同步设置方法Kafka的灾难恢复模式非常相似,但与Kafka有所不同:ES的主数据库负责编写服务,但是主数据库和副本服务器都可以提供读取服务,而Kafka仅提供主分区的读写服务,副本仅同步主数据库上的数据,不提供读取为何Kafka不使用副本提供读取服务的具体原因,您可以考虑一下,还有ES 2之前版本的灾难恢复。 X更像ZK,使用定额方法,如果不正确,请纠正我)


我已经说了很多。实际上,我仍然希望比较MySQL,HBase和ES的各个实现,以便我们可以根据业务特征选择最合适的存储和检索方案。让我谈谈我的工作经历:

MySQL是这三种模型中最成熟的,并且支持事务和二级索引。灾难恢复备份解决方案也是最成熟的,因此在线核心业务Mysql是最佳选择(当然,如果还不错,Oracle也非常好;如果无法自己解决问题,请致电,只是手动斜视)。

由于HBase具有强大的写入能力和水平扩展能力,因此它更适用于存储包含大量数据(例如日志和用户行为)的数据。这种数据通常不涉及事务级别的读写,并且对二级索引的需求也不是很高。而且HBase的主键与Mysql不同,它经常涉及业务逻辑。如果查询条件是单个的,则可以直接使用要查询的字段作为主键的一部分,类似于MySQL的联合索引以提供检索功能。

ES现在不仅提供全文搜索,还提供统计功能,并且提供的Restful界面非常易于使用。它也可以通过Kibana以图形方式显示,并且第三方插件也非常丰富。尽管ES可以水平扩展,但是考虑到ES的大部分检索都将检索索引的所有分片,但是如果单个索引数据太大,则性能会受到一定程度的影响,因此最好将单个索引的大小控制在在一定范围内,例如可以将存储用户行为日志的索引按固定的时间间隔划分为多个文件,以创建新的索引来分隔热和冷。 ES也可以用作MySQL或HBase的索引。尽管Mysql也具有索引功能,但是太多的索引会降低MySQL的性能,并且在线MySQL数据库通常不允许执行统计sql。您可以使用ES帮助执行统计信息。由于HBase仅具有主键检索,因此它需要辅助索引的功能。

一种情况,作者的前任公司使用该组合:跟踪系统的日志数据使用HBase作为主要存储。同时,最近三个月的数据也保存在ES中。 ES主要用于完成各种复杂的搜索和统计。 。但是,数据同步需要由服务本身实现。当然,跟踪服务需要较少的一致性,并且此问题也可以忽略。

提示:将数据库数据同步到ES时,由于网络延迟和其他问题,到达顺序可能不正确。此时,旧数据可能会覆盖新数据。 ES提供了版本功能,可以将数据的时间戳记用作版本值,以防止旧版本数据覆盖新版本数据。

传统的关系数据库具有强大的事务处理能力,可以满足大多数在线业务需求,但是水平可伸缩性一直令人头疼。尽管NoSql数据库解决了水平扩展的问题,但是它的功能太单一,现在越来越多的公司开始研究新一代的NewSQL数据库,它结合了关系数据库的优点并且具有水平可伸缩性,例如淘宝的Oceanbase,PingCAP的TiDB和国外的CockroachDB。让我们准备好拥抱NewSQL。

作者:运行番茄酱

链接:https://www.jianshu.com/p/4e412f48e820

资料来源:简书

版权归作者所有。对于商业复制,请联系作者以获得授权,对于非商业复制,请注明出处。

相关推荐

 
QQ在线咨询
售前咨询热线
QQ1922638